/************************************************************************
 * merge blocks into frame                                              *
 ************************************************************************/

#include <stdio.h>
#include "mergeframe.h"
#include <string.h>

#include "mjpeg.c"

void mergeframe_init(DOLProcess *p) {
    Mergeframe_State *local = (Mergeframe_State *)p->local;

    local->disp_nb = 0;
    local->send_size = 1;
    local->num_iter = 0;
}

int mergeframe_fire(DOLProcess *p) {
    int rx_size, ry_size;
    int mx_size, my_size; //picture size in units of MCUs
    int goodrows, goodcolumns;
    Mergeframe_State *local = (Mergeframe_State *)p->local;
    unsigned char *ColorBuffer = local->ColorBuffer;
    unsigned char *LineBuffer  = local->LineBuffer;
    int *dataBuff = local->dataBuff;

    //dbgprintf(VERBOSE, "\tMERGEFRAME\tthread is alive !\n");

    //read picture size from demux
    DOL_read((void*)PORT_MERGEFRAME_IN2, &local->y_s, sizeof(local->y_s), p);
    DOL_read((void*)PORT_MERGEFRAME_IN2, &local->x_s, sizeof(local->x_s), p);

    //send size for each frame
    DOL_write((void*)PORT_MERGEFRAME_OUT2, &local->x_s, sizeof(local->x_s), p);
    DOL_write((void*)PORT_MERGEFRAME_OUT2, &local->y_s, sizeof(local->y_s), p);

    mx_size = intceil(local->x_s, MCU_sx);
    my_size = intceil(local->y_s, MCU_sy);
    //floor video frame size in pixel units, multiple of MCU
    rx_size = MCU_sx * intfloor(local->x_s, MCU_sx);
    ry_size = MCU_sy * intfloor(local->y_s, MCU_sy);
    goodrows = MCU_sy;
    goodcolumns = MCU_sx;

    //piece-wise processing
    int j; for (j = 0; j < my_size; j++) {
        int k; for (k = 0; k < mx_size; k++) {
            int l; for (l = 0; l < NB_SEND; l++){
                DOL_read((void*)PORT_MERGEFRAME_IN1, &ColorBuffer[MAX_SEND * l],
                         MAX_SEND * sizeof(unsigned char), p);
            }

            //cut last row/column as needed
            //if ((p->local->y_s != ry_size) && (j == my_size - 1)) {
            //    goodrows = p->local->y_s - ry_size;
            //} else {
            //    goodrows = MCU_sy;
            //}

            //if ((p->local->x_s != rx_size) && (k == mx_size - 1)) {
            //    goodcolumns = p->local->x_s - rx_size;
            //} else {
            //    goodcolumns = MCU_sx;
            //}

            for (l = 0; l < goodrows; l++) {
                memcpy(LineBuffer + k * MCU_sx + l * local->x_s,
                       ColorBuffer + l * MCU_sx, goodcolumns);
            }
        }

        int l; for (l = 0; l < (local->x_s * MCU_sy) / 4; l++) {
            dataBuff[l] =(*(LineBuffer + 4 * l))
                + (*(LineBuffer + 4 * l + 1) << 8)
                + (*(LineBuffer + 4 * l + 2) << 16)
                + (*(LineBuffer + 4 * l + 3) << 24);
        }
        DOL_write((void*)PORT_MERGEFRAME_OUT1, dataBuff, local->x_s * MCU_sy, p);
        //        printf("mergeframe: x_s:%d\n", local->x_s);
    }

    local->disp_nb++;
    //dbgprintf(VERBOSE | INFO, "\tMERGEFRAME\tdisplay %d\n", local->disp_nb);

    //end this process
    local->num_iter++;
    if (local->num_iter == NUMBER_OF_FRAMES) {
        DOL_detach(p);
        return 0;
    }
    return 0;
}
