/******************************************************************************
 *
 * This software module was originally developed by
 *
 *   Martina Eckert (UPM-GTI / ACTS-MoMuSys)
 *
 * and edited by
 *
 *   Fernando jaureguizar (UPM-GTI / ACTS-MoMuSys)
 *   Robert Danielsen (Telenor / ACTS-MoMuSys)
 *   Angel Pacheco (UPM-GTI / ACTS-MoMuSys)
 *   Michael Frater (UNSW)
 *
 * in the course of development of the MPEG-4 Video (ISO/IEC 14496-2) standard.
 * This software module is an implementation of a part of one or more MPEG-4
 * Video (ISO/IEC 14496-2) tools as specified by the MPEG-4 Video (ISO/IEC
 * 14496-2) standard.
 *
 * ISO/IEC gives users of the MPEG-4 Video (ISO/IEC 14496-2) standard free
 * license to this software module or modifications thereof for use in hardware
 * or software products claiming conformance to the MPEG-4 Video (ISO/IEC
 * 14496-2) standard.
 *
 * Those intending to use this software module in hardware or software products
 * are advised that its use may infringe existing patents. The original
 * developer of this software module and his/her company, the subsequent
 * editors and their companies, and ISO/IEC have no liability for use of this
 * software module or modifications thereof in an implementation. Copyright is
 * not released for non MPEG-4 Video (ISO/IEC 14496-2) standard conforming
 * products.
 *
 * ACTS-MoMuSys partners retain full right to use the code for his/her own
 * purpose, assign or donate the code to a third party and to inhibit third
 * parties from using the code for non MPEG-4 Video (ISO/IEC 14496-2) standard
 * conforming products. This copyright notice must be included in all copies or
 * derivative works.
 *
 * Copyright (c) 1997
 *
 *****************************************************************************/

/***********************************************************HeaderBegin*******
 *
 * File:        io_raw.c
 *
 * Author:      UPM - M. Eckert / Fernando Jaureguizar
 * Created:     12.03.96
 *
 * Description: IO-Functions to read and write a VOP in raw format.
 *
 * Flags:       -D_DEBUG_IO_ : prints out to the stdout I/O messages.
 *
 * Modified:
 *      21.03.96 Fernando Jaureguizar: several modifications added.
 *      21.04.96 Robert Danielsen: Reformatted. New headers.
 *      02.07.96 Fernando Jaureguizar: Reformatted.
 *      14.01.96 Robert Danielsen: Definitions of SEEK_SET etc.,
 *               solution by F.Jaureguizar
 *      28.07.97 Fernando Jaureguizar: changed _DEBUG_ by _DEBUG_IO_.
 *      13.11.97 Angel Pacheco (UPM-GTI): formating and new header.
 *      03.01.98 Michael Frater: support for non-8-bit video
 *      09.03.98 Fernando Jaureguizar: New formating.
 *
 ***********************************************************HeaderEnd*********/

/************************    INCLUDE FILES    ********************************/

#include <stdio.h>
#include <stdlib.h>

/* Set the following constants instead of including unistd.h, which is not
   available on all systems. We define them here conditionally, since they
   should be defined in stdio.h */

#ifndef SEEK_SET
#define SEEK_SET        0
#endif
#ifndef SEEK_CUR
#define SEEK_CUR        1
#endif
#ifndef SEEK_END
#define SEEK_END        2
#endif

#include "momusys.h"
#include "mom_structs.h"
#include "mom_vop.h"
#include "io_raw.h"

/***********************************************************CommentBegin******
 *
 * -- ReadVopRAW --
 *
 * Author:
 *      M. Eckert (UPM-GTI)
 *
 * Created:
 *      12.03.96
 *
 * Description:
 *      Read YUVA raw data from the associated files.
 *
 * Arguments in:
 *      Char   *y_file,      name of the luminance file
 *      Char   *u_file,      name of the u-crominance file
 *      Char   *v_file,      name of the v-luminance file
 *      Char   *alpha_file,  name of the alpha file
 *      Int     frame,       frame to read
 *      Char   *format,      always ignored
 *
 * Arguments in/out:
 *      Vop    *vop          vop to put the image data to
 *
 * Arguments out: none
 *
 *
 * Return values: none
 *
 *
 * Side effects:
 *
 *
 * See also:
 *
 *
 * Modified:
 *      21.03.96 Fernando Jaureguizar (UPM-GTI).
 *
 ***********************************************************CommentEnd********/

Void
ReadVopRAW(
    Char   *y_file,      /* <-  name of the luminance file                   */
    Char   *u_file,      /* <-  name of the u-crominance file                */
    Char   *v_file,      /* <-  name of the v-luminance file                 */
    Char   *alpha_file,  /* ->  name of the alpha file                       */
    Int     frame,       /* ->  frame to read                                */
    Char   *format,      /*     always ignored                               */
    Vop    *vop          /* <-> vop to put the image data to                 */
    )
{
  File   *fichero;
  Byte   *data;
  SInt   *Sdata;
  Int    i, j, error;
  Int    height, width;
  Int    size_y, size_uv, skip, framesize, bits_per_pixel;

  height = (Int)vop->y_chan->y;
  width  = (Int)vop->y_chan->x;
  bits_per_pixel = GetVopBitsPerPixel(vop);

  size_y  = width * height * ((bits_per_pixel > 8) ? 2 : 1);
  size_uv = (bits_per_pixel <= 8) ? size_y / 4 : 0;
  framesize = size_y + 2 * size_uv;

#ifdef _DEBUG_IO_
  fprintf(stdout,"\t\t - READING INPUT FILES - \n");
#endif

  data = (Byte *)malloc(framesize * sizeof(Byte));

  /************************** Y_Data ***************************/

  if((fichero = fopen (y_file,"rb"))==NULL)
    {
    fprintf(stderr," - ERROR: can not open Y file");
    fprintf(stderr,"(%s)\n",y_file);
    return;
    }

  /* No. of bits we have to skip to reach the frame */

  if (strcmp(y_file,u_file) == 0)
    skip = frame * framesize;
  else
    skip = frame * size_y;

  error = fseek (fichero, skip, SEEK_SET);

  /* The data */

  error = fread ((Char*)data, size_y, 1, fichero);
  if (error == 0)
    fprintf(stderr," - ERROR: input Y-Data incomplete\n");

  if (bits_per_pixel <= 8)
    for(i = 0; i < height; i++)
      for(j = 0; j < width; j++)
        vop->y_chan->data->s[i*width + j] = (Byte) data[i*width + j];
  else
    {
    Sdata = (SInt *)data;
    for(i = 0; i < height; i++)
      for(j = 0; j < width; j++)
        vop->y_chan->data->s[i*width + j] = (SInt) Sdata[i*width + j];
    }

#ifdef _DEBUG_IO_
  fprintf(stdout,"\t\t - Read Y-Data\n");
#endif

  fclose (fichero);

  /************************** U_Data ***************************/

  if (bits_per_pixel <= 8)
    {
    if( (fichero = fopen (u_file,"rb"))==NULL)
      {
      fprintf(stderr," - ERROR: can not open U file\n");
      return;
      }

    /* No. of bits we have to skip to reach the frame */

    if (strcmp(y_file,u_file) == 0)
      skip = size_y + frame * framesize;
    else
      skip = frame * size_uv;

    error = fseek (fichero, skip, SEEK_SET);

    /* The data */

    error = fread ((Char*)data, size_uv, 1, fichero);
    if (error == 0)
      fprintf(stderr," - ERROR: input U-Data incomplete\n");

    for(i = 0; i < height/2; i++)
      for(j = 0; j < width/2; j++)
        vop->u_chan->data->s[i*width/2 + j]= (Byte) data[i*width/2 + j];

#ifdef _DEBUG_IO_
    fprintf(stdout,"\t\t - Read U-Data\n");
#endif

    fclose (fichero);

    /************************** V_Data ***************************/

    if( (fichero = fopen (v_file,"rb"))==NULL)
      {
      fprintf(stderr," - ERROR: can not open V file\n");
      return;
      }

    /* No. of bits we have to skip to reach the frame */

    if (strcmp(y_file,u_file) == 0)
      skip = size_y + size_uv + frame * framesize;
    else
      skip = frame * size_uv;

    error = fseek (fichero, skip, SEEK_SET);

    /* The data */

    error = fread ((Char*)data, size_uv, 1, fichero);
    if (error == 0)
      fprintf(stderr," - ERROR: input V-Data incomplete\n");

    for(i = 0; i < height/2; i++)
      for(j = 0; j < width/2; j++)
        vop->v_chan->data->s[i*width/2 + j] = (Byte) data[i*width/2 + j];

#ifdef _DEBUG_IO_
    fprintf(stdout,"\t\t - Read V-Data\n");
#endif

    fclose (fichero);
    }

  /************************** Alpha_Data ***********************/

  if( (fichero = fopen (alpha_file,"rb"))==NULL)
    {
    fprintf(stderr," - ERROR: can not open Alpha file\n");
    return;
    }

  /* No. of bits we have to skip to reach the frame */

  skip = frame * size_y;
  error = fseek (fichero, skip, SEEK_SET);

  /* The data */

  error = fread ((Char*)data, size_y, 1, fichero);
  if (error == 0)
    fprintf(stderr," - ERROR: input Alpha-Data incomplete\n");

  for(i = 0; i < height; i++)
    for(j = 0; j < width; j++)
      vop->a_chan->data->s[i*width + j] = (Short) data[i*width + j];

#ifdef _DEBUG_IO_
  fprintf(stdout,"\t\t - Read Alpha-Data\n");
#endif

  fclose (fichero);
  free((Char*)data);
}

/***********************************************************CommentBegin******
 *
 * -- WriteVopRAW --
 *
 * Author:
 *      M. Eckert (UPM-GTI)
 *
 * Created:
 *      12.03.96
 *
 * Description:
 *      Write the YUVA data from the Vop to the associated files.
 *
 * Arguments in:
 *      Vop    *vop,               VOP with the YUVA data
 *      Char   *y_file,            Y name file
 *      Char   *u_file,            U name file
 *      Char   *v_file,            V name file
 *      Char   *alpha_file,        A name file
 *      Int     frame,             always ignored
 *      Char   *format,            always ignored
 *      Char   *mode,              wirting mode
 *
 * Arguments in/out:
 *
 *
 * Arguments out:
 *
 *
 * Return values:
 *
 *
 * Side effects:
 *
 *
 * Description:
 *
 *
 * See also:
 *
 *
 * Modified :
 *      21.03.96 Fernando Jaureguizar (UPM-GTI)
 *
 ***********************************************************CommentEnd********/

Void
WriteVopRAW(
    Vop    *vop,        /* <-  VOP with the YUVA data                        */
    Char   *y_file,     /* <-  Y name file                                   */
    Char   *u_file,     /* <-  U name file                                   */
    Char   *v_file,     /* <-  V name file                                   */
    Char   *alpha_file, /* <-  A name file                                   */
    Int     frame,      /* <-  always ignored                                */
    Char   *format,     /* <-  always ignored                                */
    Char   *mode,       /* <-  wirting mode                                  */
    Int     write_alpha /* <-  write the alpha data if 1                     */
    )
{
  File   *fichero;
  Int    height    = (Int)vop->a_chan->y;
  Int    width     = (Int)vop->a_chan->x;
  Int    height_uv = (Int)vop->a_chan->y/2;
  Int    width_uv  = (Int)vop->a_chan->x/2;
  Int    i, j;
  Char   datum;
  SInt   Sdatum;
  SInt   *data;
  Int    bits_per_pixel;
  Int    overwrite_mode=0;

  if (strcmp(mode,"OVERWRITE") == 0)
    overwrite_mode=1;

  bits_per_pixel = GetVopBitsPerPixel(vop);

#ifdef _DEBUG_IO_
  fprintf(stdout,"\t\t - WRITING OUTPUT FILES - \n");
#endif

  /************************** Y_Data ***************************/

  if (overwrite_mode)
    {
    if((fichero = fopen (y_file,"wb"))==NULL)
      {
      fprintf(stderr," - ERROR: can not open Y file\n");
      return;
      }
    }
  else
    if ((fichero = fopen (y_file,"ab"))==NULL)
      {
      fprintf(stderr," - ERROR: can not open Y file\n");
      return;
      }


  data = vop->y_chan->data->s;

  if (bits_per_pixel <= 8)
    for(i = 0; i < height; i++)
      for(j = 0; j < width; j++)
        {
        datum = (Char)data[i*width+j];
        fwrite (&datum, 1, 1, fichero);
        }
  else
    for(i = 0; i < height; i++)
      for(j = 0; j < width; j++)
        {
        Sdatum = (SInt)data[i*width+j];
        fwrite (&Sdatum, 2, 1, fichero);
        }

#ifdef _DEBUG_IO_
  fprintf(stdout,"\t\t - Wrote Y-Data\n");
#endif

  fclose (fichero);

  if (bits_per_pixel <= 8)
    {
    /************************** U_Data ***************************/

    if (overwrite_mode && strcmp(y_file,u_file) != 0)
      {
      if((fichero = fopen (u_file,"wb"))==NULL)
        {
        fprintf(stderr," - ERROR: can not open U file\n");
        return;
        }
      }
    else
      if ((fichero = fopen (u_file,"ab"))==NULL)
        {
        fprintf(stderr," - ERROR: can not open U file\n");
        return;
        }

    data = vop->u_chan->data->s;

    for(i = 0; i < height_uv; i++)
      for(j = 0; j < width_uv; j++)
        {
        datum = (Char)data[i*width_uv+j];
        fwrite (&datum, 1, 1, fichero);
        }

#ifdef _DEBUG_IO_
    fprintf(stdout,"\t\t - Wrote U-Data \n");
#endif

    fclose (fichero);

    /************************** V_Data ***************************/

    if (overwrite_mode && strcmp(y_file,v_file) != 0)
      {
      if((fichero = fopen (v_file,"wb"))==NULL)
        {
        fprintf(stderr," - ERROR: can not open V file\n");
        return;
        }
      }
    else
      if ((fichero = fopen (v_file,"ab"))==NULL)
        {
        fprintf(stderr," - ERROR: can not open V file\n");
        return;
        }


    data = vop->v_chan->data->s;

    for(i = 0; i < height_uv; i++)
      for(j = 0; j < width_uv; j++)
        {
        datum = (Char)data[i*width_uv+j];
        fwrite (&datum, 1, 1, fichero);
        }

#ifdef _DEBUG_IO_
    fprintf(stdout,"\t\t - Wrote V-Data\n");
#endif

    fclose (fichero);
    }

  /************************ Alpha_Data *************************/

  if (write_alpha)
    {
    if (overwrite_mode)
      {
      if((fichero = fopen (alpha_file,"wb"))==NULL)
        {
        fprintf(stderr," - ERROR: can not open Alpha file\n");
        return;
        }
      }
    else
      if ((fichero = fopen (alpha_file,"ab"))==NULL)
        {
        fprintf(stderr," - ERROR: can not open Alpha file\n");
        return;
        }


    data = vop->a_chan->data->s;

    for(i = 0; i < height; i++)
      for(j = 0; j < width; j++)
        {
        datum = (Char)data[i*width+j];
        fwrite (&datum, 1, 1, fichero);
        }

#ifdef _DEBUG_IO_
    fprintf(stdout,"\t\t - Wrote Alpha-Data\n");
#endif

    fclose (fichero);
    }
}
