/* render/jpgfile.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ /* Notes: http://www.zarb.org/~gc/html/libpng.html */ #include #include #include "sys/sys.h" #include "filesystem/filesystem.h" #include "render/jpgfile.h" // work-around for a jpeglib problem, needed on win32 and osx #ifdef HAVE_STDLIB_H #undef HAVE_STDLIB_H #endif extern "C" { #include "jpeglib.h" } namespace render { Image *JPG::load(const char *filename) { struct jpeg_decompress_struct jpeg_decompression_info; struct jpeg_error_mgr jerr; int row_stride = 0; Image *image = 0; if (!filename) return 0; filesystem::File *jpg_file = filesystem::open(filename); if (!jpg_file) { //con_warn << "Could not open " << filename << std::endl; return 0; } // initialize decompression structures jpeg_decompression_info.err = jpeg_std_error(&jerr); jpeg_create_decompress(&jpeg_decompression_info); jpeg_stdio_src(&jpeg_decompression_info, jpg_file->handle()); // read JPEG header jpeg_read_header(&jpeg_decompression_info, TRUE); jpeg_start_decompress(&jpeg_decompression_info); row_stride = jpeg_decompression_info.output_width * jpeg_decompression_info.output_components; image = new Image(jpeg_decompression_info.output_width, jpeg_decompression_info.output_height, jpeg_decompression_info.output_components); // read pixel data JSAMPLE *row_pointer; while (jpeg_decompression_info.output_scanline < jpeg_decompression_info.output_height) { row_pointer = (*image)[jpeg_decompression_info.output_scanline*row_stride]; jpeg_read_scanlines(&jpeg_decompression_info, &row_pointer, 1); } jpeg_finish_decompress(&jpeg_decompression_info); // destroy decompression structures jpeg_destroy_decompress(&jpeg_decompression_info); filesystem::close(jpg_file); con_debug << " " << filename << " " << image->width() << "x" << image->height() << "x" << image->bpp() << "bpp" << std::endl; return image; } void JPG::save(const char *filename, Image & image, int jpeg_quality) { struct jpeg_compress_struct jpeg_compression_info; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; int row_stride; FILE *jpg_file = fopen(filename, "wb"); if (!jpg_file) { con_warn << "Could not write " << filename << std::endl; return; } jpeg_compression_info.err = jpeg_std_error(&jerr); jpeg_create_compress(&jpeg_compression_info); jpeg_stdio_dest(&jpeg_compression_info, jpg_file); jpeg_compression_info.image_width = image.width(); jpeg_compression_info.image_height = image.height(); jpeg_compression_info.input_components = image.channels(); jpeg_compression_info.in_color_space = JCS_RGB; jpeg_set_defaults(&jpeg_compression_info); jpeg_set_quality(&jpeg_compression_info, jpeg_quality, TRUE); jpeg_start_compress(&jpeg_compression_info, TRUE); row_stride = image.width() * image.channels(); while (jpeg_compression_info.next_scanline < jpeg_compression_info.image_height) { row_pointer[0] = image[jpeg_compression_info.next_scanline * row_stride]; jpeg_write_scanlines(&jpeg_compression_info, row_pointer, 1); } jpeg_finish_compress(&jpeg_compression_info); fclose(jpg_file); jpeg_destroy_compress(&jpeg_compression_info); //con_print << "Wrote " << filename << std::endl; } }