
//
// Modifications History
//
//$LB (10/11/2004) : i have entirely recoded the JComp and JDecomp functions from the JPEG load ans save source code,
//                   to match with the 24bits pixels process, to improve performance,
//                   and to get a source code that doesn't give the impression to come from the outter space... :)
//
//


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <math.h>

#include "x/Version.h"
#include "x/scolplugin.h"

#include "objstr.h"

#include "objects/bitmap.h"

#include "jpeglib.h"
#include <setjmp.h>


#include "mjpeg.h"



METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
  my_error_ptr myerr = (my_error_ptr) cinfo->err;

  longjmp(myerr->setjmp_buffer, 1);
}




//
// fun [S I I I] S
//

int JDecomp (mmachine m)
{
int s;
PtrObjBitmap B ;        
int R ;        

struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
FILE * infile; /* source file */
JSAMPARRAY buffer; /* Output row buffer */
int row_stride; /* physical row width in output buffer */

OBJBITMAP_BUFFER dst;
int bpl;
int userW, userH;
//$BLG: v4.6a7 - Modif
//int k, size;
int k;
size_t size;

/****************************/
 #ifdef DEBUG_LIB2DOS
   MMechostr (0 , "\nJDecomp");
#endif
/****************************/

  MMpull(m); // don't the need the quality argument anymore...
  userH = MMpull(m)>>1;
  userW = MMpull(m)>>1;

  s = MMpull(m);

  if (s == NIL)
  {
	MMechostr(0, "\nJDecomp error : the source is NIL!\n");
	return MMpush (m, NIL);
  }

  s >>= 1;

  //$BLG: v4.6a5 - Modif (No - suspected some buffer overflow and try to force Binary mode - Pb still here)
  if ((infile = tmpfile ()) == NULL)
  //if ((infile = fopen("c:/jcomp.dat","w+b")) == NULL)
  {
	MMechostr (0, "\nJDecomp error : could not create the temp file!\n");
	return MMpush(m, NIL);
  }

  size = MMsizestr (m, s);

  if (fwrite (MMstartstr (m, s), sizeof(char), size, infile) < size)
  {
	MMechostr(0, "\nJDecomp error in writing the source down the temp. file!\n");
	rmtmp ();
	return MMpush(m, NIL);
  }


  fseek (infile, 0, SEEK_SET);

 
  cinfo.err = jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit = my_error_exit;

  if (setjmp(jerr.setjmp_buffer))
  {
	MMechostr(MSKDEBUG,"jpeg : error\n");
	MMechostr(MSKDEBUG,(char*)jerr.pub.jpeg_message_table[jerr.pub.msg_code]
		,jerr.pub.msg_parm.i[0],jerr.pub.msg_parm.i[1]);

    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    MMpull(m);
    MMpull(m);
    return MMpush(m,NIL);
  }
 
  jpeg_create_decompress(&cinfo);
  jpeg_stdio_src(&cinfo, infile);
  jpeg_read_header(&cinfo, TRUE);
  jpeg_start_decompress(&cinfo);



  B = (PtrObjBitmap) malloc (sizeof(struct ObjBitmap));
  B->TailleH = cinfo.output_height;
  B->TailleW = cinfo.output_width;
  B->BPP = 24;
  B->BytesPP = B->BPP>>3;
  B->handler = ObjBitmap_New ( B , NULL ) ;
 
        
  dst = (OBJBITMAP_BUFFER)B->bits;
  bpl = B->BPL;
  ////////////////////////////////////////



  if ( B->bits == NULL )
  {
      MMechostr ( 0, "\nJDecomp error : Creation of graphical Buffer failed.\n" ) ;
      return MERRMEM ;
  }       
        

  R = B->handler ;

  row_stride = cinfo.output_width * cinfo.output_components;

  buffer = (*cinfo.mem->alloc_sarray)
		((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
  k=0;
  while (cinfo.output_scanline < cinfo.output_height)
  {
    jpeg_read_scanlines(&cinfo, buffer, 1);
	//$LB (17/12/2002)
    tramconvert24to24(dst,buffer[0],cinfo.output_width,k++);
	dst+=bpl;
  }

  jpeg_finish_decompress(&cinfo);
  jpeg_destroy_decompress(&cinfo);

  rmtmp();

  k = Mpushstrblocn (m, B->bits, B->BPL * B->TailleH);

  free (B->bits);
  free (B);

  return k;
}
