/* * Jpeg.cc * * The MIT License (MIT) * * Copyright (c) 2013 ZhangYuanwei * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "Image.h" #ifdef HAVE_JPEG #include #include #include #include typedef struct { char J; char P; char E; char G; uint8_t quality; } jpeg_compress_config; jpeg_compress_config default_compress_config = { 'J','P','E','G', 100, }; jpeg_compress_config *get_compress_config(ImageConfig *config){ if(config == NULL || config->data == NULL || config->length != sizeof(jpeg_compress_config) || config->data[0] != default_compress_config.J || config->data[1] != default_compress_config.P || config->data[2] != default_compress_config.E || config->data[3] != default_compress_config.G) return &default_compress_config; return (jpeg_compress_config*) config->data; } struct my_jpeg_error_mgr { struct jpeg_error_mgr pub; jmp_buf setjmp_buffer; }; void jpeg_cb_error_exit(j_common_ptr cinfo){ struct my_jpeg_error_mgr *mptr; mptr=(struct my_jpeg_error_mgr*) cinfo->err; //(*cinfo->err->output_message) (cinfo); longjmp(mptr->setjmp_buffer, 1); } DECODER_FN(Jpeg){ // {{{ struct jpeg_decompress_struct cinfo; struct my_jpeg_error_mgr jerr; int width, height, line; JSAMPROW row_pointer[1]; cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit=jpeg_cb_error_exit; if (setjmp(jerr.setjmp_buffer)) { jpeg_destroy_decompress(&cinfo); output->Free(); return FAIL; } jpeg_create_decompress(&cinfo); jpeg_mem_src(&cinfo, (unsigned char *) input->data, input->length); jpeg_read_header(&cinfo, TRUE); cinfo.out_color_space = JCS_EXT_RGBA; jpeg_start_decompress(&cinfo); width = cinfo.output_width; height = cinfo.output_height; //components = cinfo.output_components; if(output->Malloc(width, height) != SUCCESS) longjmp(jerr.setjmp_buffer, 1); while((line = cinfo.output_scanline) < height){ row_pointer[0] = (JSAMPROW) output->data[line]; jpeg_read_scanlines(&cinfo, row_pointer, 1); } output->type = SOLID; jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); return SUCCESS; } // }}} ENCODER_FN(Jpeg){ // {{{ struct jpeg_compress_struct cinfo; struct my_jpeg_error_mgr jerr; jpeg_compress_config *conf; int width, height, line; JSAMPROW row_pointer[1]; cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit=jpeg_cb_error_exit; if (setjmp(jerr.setjmp_buffer)) { jpeg_destroy_compress(&cinfo); return FAIL; } jpeg_create_compress(&cinfo); jpeg_mem_dest(&cinfo, (unsigned char **) &(output->data), &output->length); width = input->width; height = input->height; conf = get_compress_config(config); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 4; cinfo.in_color_space = JCS_EXT_RGBA; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, conf->quality, TRUE); jpeg_start_compress(&cinfo, TRUE); //printf("%d %s\n", cinfo.input_components, cinfo.in_color_space == JCS_EXT_RGBA ? "true" : "false"); while((line = cinfo.next_scanline) < height){ row_pointer[0] = (JSAMPROW) input->data[line]; (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); output->position = output->length; return SUCCESS; } // }}} #endif // vim600: sw=4 ts=4 fdm=marker syn=cpp