//========================================================================
//
// JpegWriter.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
// Copyright (C) 2010, 2012 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2010 Harry Roberts <harry.roberts@midnight-labs.org>
// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de>
//
//========================================================================

#include "JpegWriter.h"

#ifdef ENABLE_LIBJPEG

#include "poppler/Error.h"

void outputMessage(j_common_ptr cinfo)
{
	char buffer[JMSG_LENGTH_MAX];

	// Create the message
	(*cinfo->err->format_message) (cinfo, buffer);

	// Send it to poppler's error handler
	error(errInternal, -1, "{0:s}", buffer);
}

JpegWriter::JpegWriter(int q, bool p, J_COLOR_SPACE cm)
: progressive(p), quality(q), colorMode(cm)
{
}

JpegWriter::JpegWriter(J_COLOR_SPACE cm)
: progressive(false), quality(-1), colorMode(cm)
{
}

JpegWriter::~JpegWriter()
{
	// cleanup
	jpeg_destroy_compress(&cinfo);
}

bool JpegWriter::init(FILE *f, int width, int height, int hDPI, int vDPI)
{
	// Setup error handler
	cinfo.err = jpeg_std_error(&jerr);
	jerr.output_message = &outputMessage;

	// Initialize libjpeg
	jpeg_create_compress(&cinfo);
	
        // Set colorspace and initialise defaults
	cinfo.in_color_space = colorMode; /* colorspace of input image */
	jpeg_set_defaults(&cinfo);

	// Set destination file
	jpeg_stdio_dest(&cinfo, f);
	
	// Set libjpeg configuration
	cinfo.image_width = width;
	cinfo.image_height = height;
	cinfo.density_unit = 1; // dots per inch
	cinfo.X_density = hDPI;
	cinfo.Y_density = vDPI;
	/* # of color components per pixel */
	switch (colorMode) {
		case JCS_GRAYSCALE:
			cinfo.input_components = 1;     
			break;
		case JCS_RGB:
			cinfo.input_components = 3;     
			break;
		case JCS_CMYK:
			cinfo.input_components = 4;     
			break;
		default:
			return false;
	}
	if (cinfo.in_color_space == JCS_CMYK) {
		jpeg_set_colorspace(&cinfo, JCS_YCCK);
		cinfo.write_JFIF_header = TRUE;
	}
	
	// Set quality
	if( quality >= 0 && quality <= 100 ) { 
		jpeg_set_quality(&cinfo, quality, true);
	}
	
	// Use progressive mode
	if( progressive) {
		jpeg_simple_progression(&cinfo);
	}
	
	// Get ready for data
	jpeg_start_compress(&cinfo, TRUE);
	
	return true;
}

bool JpegWriter::writePointers(unsigned char **rowPointers, int rowCount)
{
	if (colorMode == JCS_CMYK) {
		for (int y = 0; y < rowCount; y++) {
			unsigned char *row = rowPointers[y];
			for (unsigned int x = 0; x < cinfo.image_width; x++) {
				for (int n = 0; n < 4; n++) {
					*row = 0xff - *row;
					row++;
				}
			}
		}
	}
	// Write all rows to the file
	jpeg_write_scanlines(&cinfo, rowPointers, rowCount);
	
	return true;
}

bool JpegWriter::writeRow(unsigned char **rowPointer)
{
	if (colorMode == JCS_CMYK) {
		unsigned char *row = rowPointer[0];
		for (unsigned int x = 0; x < cinfo.image_width; x++) {
			for (int n = 0; n < 4; n++) {
				*row = 0xff - *row;
				row++;
			}
		}
	}
	// Write the row to the file
	jpeg_write_scanlines(&cinfo, rowPointer, 1);
	
	return true;
}

bool JpegWriter::close()
{
	jpeg_finish_compress(&cinfo);
	
	return true;
}

#endif
