| //======================================================================== |
| // |
| // 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(-1, "%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 |