/*
 * JPEGReader.cpp
 *
 * (c) 2002 by Thorsten Scheuermann <tscheuermann@gmx.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include "JPEGReader.h"

JPEGReader::JPEGReader(const char *fileName)
: ImageReader(fileName)
{
	scaleDenom = 1;

	// initialize decompression object
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);

	// open file
  jpegFile = fopen(fileName, "r");
  if(!jpegFile)
  {
    fprintf(stderr, "JPEGReader: Can't open file %s\n", fileName);
    return;
  }
	jpeg_stdio_src(&cinfo, jpegFile);

	// read image information and initialize everything
	jpeg_read_header(&cinfo, TRUE);
}

JPEGReader::~JPEGReader()
{
	// clean up
	jpeg_destroy_decompress(&cinfo);
	fclose(jpegFile);
}

const char *JPEGReader::type()
{
	return "JPEG";
}

void JPEGReader::setScaling(int denom)
{
	scaleDenom = denom;
}

int JPEGReader::imageWidth()
{
  return cinfo.image_width;
}

int JPEGReader::imageHeight()
{
  return cinfo.image_height;
}

void JPEGReader::readImageData()
{
	int i;
	unsigned char **rowPtrs;
	unsigned char *rowData;
	int numLinesRead;

	// choose decompression options
	cinfo.out_color_space = JCS_RGB;
	cinfo.quantize_colors = FALSE;
	cinfo.dct_method = JDCT_ISLOW;	// optionally IFAST

	// pre-scaling in the JPEG reader is likely to increase decompression speed
	cinfo.scale_num = 1;
	cinfo.scale_denom = scaleDenom;

	cinfo.do_block_smoothing = FALSE;

	// initialize decompression and allocate scanline buffers
	jpeg_start_decompress(&cinfo);

/*
	printf("out_color_components: %d\n", cinfo.out_color_components);
	printf("output_components: %d\n", cinfo.output_components);
	printf("rec_outbuf_height: %d\n", cinfo.rec_outbuf_height);
	printf("output dimensions: %dx%d\n", cinfo.output_width, cinfo.output_height);
*/

	rowPtrs = new unsigned char*[cinfo.rec_outbuf_height];
	rowData = new unsigned char[cinfo.rec_outbuf_height * cinfo.output_width *
                              cinfo.output_components];
	for(i=0; i<cinfo.rec_outbuf_height; i++)
 		rowPtrs[i] = rowData + i * cinfo.output_width * cinfo.output_components;

	// initialize consumer
	if(consumer())
	{
		consumer()->setImageDimension(cinfo.output_width, cinfo.output_height);
		consumer()->setNumImageChannels(cinfo.output_components);
		consumer()->startImage();
	}

	// read image data row by row
	while(cinfo.output_scanline < cinfo.output_height)
	{
		numLinesRead = jpeg_read_scanlines(&cinfo, rowPtrs, cinfo.rec_outbuf_height);
   	if(consumer())
		{
	  	for(i=0; i<numLinesRead; i++)
      	consumer()->imageRow(rowPtrs[i]);
  	}
	}
	jpeg_finish_decompress(&cinfo);

	delete[] rowData;
	delete[] rowPtrs;

	if(consumer())
		consumer()->endImage();
}

