#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "ccnn.h"

/**********************************************************************/
void ProcessObjectsDet(const char *cnfXMLName, char *inBuff, int bufLen)
{
    const float PAB_GATE = 0.25F;
    int outBoxNum;

    ReadPixCnfClassify tmpReadPixCnfClassify;
       
    //利用XML配置，构建深度神经网络
    struct CcnnContext *tmpCtx = LcfNet::CreateNetFromXML(cnfXMLName, 1, 1);

    //读取网络输入图像长宽大小   
    int imgHW = LcfNet::ReadInputHeightWidth(tmpCtx);
    float *imgP = ImgHandle::LoadSquareImg((unsigned char *)inBuff, bufLen, 1, NULL, NULL, NULL, imgHW);
        
    //进行目标检测预测
    struct PredictBox *pBox = LcfNet::NetPredictOneStageDet(tmpCtx, imgP, &outBoxNum, PAB_GATE);
    delete []imgP;
    
    //释放网络结构及内存等
    LcfNet::RealeaseCcnnStructMemory(tmpCtx);

    if (pBox == NULL || outBoxNum == 0) {
        return;
    }
    
    //下面是输出结果框绘制
    int c, h, w;
    float *tmpMatImg = ImgHandle::LoadBGRCHWFloatImg((unsigned char *)inBuff, bufLen, 0, &c, &h, &w);

    for (int i = 0; i < outBoxNum; i++) {
        if (pBox[i].confidence < 0.6F) {
            continue;    
        }
        
        float bx = pBox[i].pBox.bx;
        float by = pBox[i].pBox.by;
        float bw = pBox[i].pBox.bw * 0.5F;
        float bh = pBox[i].pBox.bh * 0.5F;

        float x1 = bx - bw;
        float y1 = by - bh;
        float x2 = bx + bw;
        float y2 = by + bh;
        printf("wdjLabel ID:%d Conf:%f Location: %f %f %f %f\r\n", pBox[i].category, pBox[i].confidence, x1, y1, x2, y2);
        
        int b = 100, g = 10, r = 60;
        int xx1 = x1 * w, yy1 = y1 * h, xx2 = x2 * w, yy2 = y2 * h;
        printf("%d %d %d %d\n", xx1, yy1, xx2, yy2);

        ImgHandle::CHWMatDrawBox(tmpMatImg, c, h, w, xx1, yy1, xx2, yy2, b, g, r);
    }
 
    ImgHandle::CHW_BGR_MatSaveToImg(tmpMatImg, c, h, w, 0, "result.jpg");
    delete []tmpMatImg;

    MemBasicManage::RealeaseArrayPredictBox(pBox);
}

/************************************/
char *ReadImg(char *fileImg, int *len)
{
    FILE *file;
    file = fopen(fileImg, "rb");
    if (file == NULL) {
        return NULL;
    }

    int allocSize = 10240000;
    char *data = new char[allocSize];
    int readNum = (int)fread(data, sizeof(char), allocSize, file);
    fclose(file);

    *len = readNum;
    return data;
}

/******************************/
int main(int argc, char *argv[])
{
    int bufLen;
    char *imgBuff = ReadImg(argv[1], &bufLen);
    if (NULL == imgBuff) {
        printf("Read Img error\n");
        return 0;     
    }

    ProcessObjectsDet("lcfNetfigYOLO3.xml", imgBuff, bufLen);
    return 1;
}
