25 #include <fvutils/compression/jpeg_compressor.h> 26 #include <fvutils/compression/jpeg_compressor_libjpeg.h> 27 #include <fvutils/color/yuvrgb.h> 28 #include <fvutils/color/rgbyuv.h> 30 #include <core/exception.h> 50 struct jpeg_error_mgr pub;
51 jmp_buf setjmp_buffer;
52 } fv_jpeg_error_mgr_t;
59 struct jpeg_destination_mgr pub;
63 } fv_jpeg_memory_destination_mgr_t;
71 fv_jpeg_init_destination (j_compress_ptr cinfo)
73 fv_jpeg_memory_destination_mgr_t *dest = (fv_jpeg_memory_destination_mgr_t *) cinfo->dest;
74 dest->pub.next_output_byte = dest->buffer;
75 dest->pub.free_in_buffer = dest->bufsize;
84 fv_jpeg_empty_output_buffer (j_compress_ptr cinfo)
86 fv_jpeg_memory_destination_mgr_t *dest = (fv_jpeg_memory_destination_mgr_t *) cinfo->dest;
87 dest->pub.next_output_byte = dest->buffer;
88 dest->pub.free_in_buffer = dest->bufsize;
99 fv_jpeg_term_destination (j_compress_ptr cinfo)
103 fv_jpeg_memory_destination_mgr_t *dest = (fv_jpeg_memory_destination_mgr_t *) cinfo->dest;
104 dest->datacount = dest->bufsize - dest->pub.free_in_buffer;
113 fv_jpeg_memory_destination_setup(j_compress_ptr cinfo, JOCTET *buffer,
int bufsize)
115 fv_jpeg_memory_destination_mgr_t *dest;
116 if ( cinfo->dest == NULL ) {
117 cinfo->dest = (
struct jpeg_destination_mgr *)
118 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
119 sizeof(fv_jpeg_memory_destination_mgr_t));
123 dest = (fv_jpeg_memory_destination_mgr_t *) cinfo->dest;
124 dest->bufsize = bufsize;
125 dest->buffer = buffer;
126 dest->pub.init_destination = fv_jpeg_init_destination;
127 dest->pub.empty_output_buffer = fv_jpeg_empty_output_buffer;
128 dest->pub.term_destination = fv_jpeg_term_destination;
132 init_source(j_decompress_ptr cinfo)
138 fill_input_buffer(j_decompress_ptr cinfo)
145 skip_input_data(j_decompress_ptr cinfo,
long num_bytes)
147 if ((
size_t)num_bytes > cinfo->src->bytes_in_buffer) {
148 cinfo->src->next_input_byte = NULL;
149 cinfo->src->bytes_in_buffer = 0;
151 cinfo->src->next_input_byte += (size_t) num_bytes;
152 cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
157 term_source(j_decompress_ptr cinfo)
163 fv_jpeg_error_exit(j_common_ptr cinfo)
166 fv_jpeg_error_mgr_t *myerr = (fv_jpeg_error_mgr_t *) cinfo->err;
169 longjmp(myerr->setjmp_buffer, 1);
180 fv_jpeg_memory_source_setup(j_decompress_ptr cinfo,
unsigned char *ptr,
size_t size)
182 struct jpeg_source_mgr *src;
183 src = cinfo->src = (
struct jpeg_source_mgr *)
184 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo,
187 src->init_source = init_source;
188 src->fill_input_buffer = fill_input_buffer;
189 src->skip_input_data = skip_input_data;
190 src->resync_to_restart = jpeg_resync_to_restart;
191 src->term_source = term_source;
192 src->next_input_byte = ptr;
193 src->bytes_in_buffer = size;
210 this->quality = quality;
235 struct jpeg_compress_struct cinfo;
236 fv_jpeg_error_mgr_t jerr;
237 unsigned int row_stride;
238 unsigned char *row_buffer;
241 fv_jpeg_memory_destination_mgr_t *dest;
244 FILE *outfile = NULL;
248 memset (&cinfo, 0,
sizeof(cinfo));
249 cinfo.err = jpeg_std_error(&jerr.pub);
250 jerr.pub.error_exit = fv_jpeg_error_exit;
253 if (setjmp(jerr.setjmp_buffer)) {
254 char buffer[JMSG_LENGTH_MAX];
255 (*cinfo.err->format_message) ((jpeg_common_struct *)&cinfo, buffer);
260 jpeg_destroy_compress(&cinfo);
264 jpeg_create_compress(&cinfo);
267 cinfo.image_width = width;
268 cinfo.image_height = height;
269 cinfo.input_components = 3;
271 cinfo.in_color_space = JCS_RGB;
273 cinfo.in_color_space = JCS_YCbCr;
276 row_stride = cinfo.image_width * cinfo.input_components;
278 if ( compdest == COMP_DEST_MEM ) {
280 fv_jpeg_memory_destination_setup(&cinfo, (JOCTET *)jpeg_buffer, jpeg_buffer_size);
282 outfile = fopen(filename,
"wb");
283 if (outfile == NULL) {
284 throw fawkes::Exception(
"JpegImageCompressorLibJpeg: cannot open %s\n", filename);
286 jpeg_stdio_dest( &cinfo, outfile );
289 jpeg_set_defaults(&cinfo);
290 jpeg_set_quality (&cinfo, quality,
true );
291 jpeg_start_compress(&cinfo,
true);
294 row_buffer = (
unsigned char *)malloc( row_stride );
299 while (cinfo.next_scanline < cinfo.image_height) {
300 convert_line_yuv422planar_to_rgb(
302 cinfo.image_width, cinfo.image_height,
303 cinfo.image_height - cinfo.next_scanline - 1, 0);
304 jpeg_write_scanlines(&cinfo, &row_buffer, 1);
307 while (cinfo.next_scanline < cinfo.image_height) {
308 convert_line_yuv422planar_to_rgb(
310 cinfo.image_width, cinfo.image_height,
311 cinfo.next_scanline, 0 );
312 jpeg_write_scanlines(&cinfo, &row_buffer, 1);
317 while (cinfo.next_scanline < cinfo.image_height) {
318 convert_line_yuv422planar_to_yuv444packed(
320 cinfo.image_width, cinfo.image_height,
321 cinfo.image_height - cinfo.next_scanline - 1, 0 );
322 jpeg_write_scanlines(&cinfo, &row_buffer, 1);
325 while (cinfo.next_scanline < cinfo.image_height) {
326 convert_line_yuv422planar_to_yuv444packed(
328 cinfo.image_width, cinfo.image_height,
329 cinfo.next_scanline, 0 );
330 jpeg_write_scanlines(&cinfo, &row_buffer, 1);
336 jpeg_finish_compress(&cinfo);
338 if ( compdest == COMP_DEST_MEM ) {
340 dest=(fv_jpeg_memory_destination_mgr_t *)cinfo.dest;
341 jpeg_bytes = dest->datacount;
347 jpeg_destroy_compress(&cinfo);
356 this->height = height;
363 if ( cspace == YUV422_PLANAR ) {
364 this->buffer = buffer;
387 jpeg_buffer_size = buf_size;
400 return width * height / 4;
407 this->filename = filename;
virtual bool supports_compression_destination(ImageCompressor::CompressionDestination cd)
Check if compressor supports desired compression destination.
virtual void set_image_buffer(colorspace_t cspace, unsigned char *buffer)
Set image buffer to compress.
virtual void compress()
Compress image.
virtual bool supports_vflip()
Check if image compressor can do vflip during compress.
virtual void set_compression_destination(ImageCompressor::CompressionDestination cd)
Set compression destination.
JpegColorspace
JPEG color space.
virtual void set_image_dimensions(unsigned int width, unsigned int height)
Set dimensions of image to compress.
CompressionDestination
Where to put the compressed image.
JpegImageCompressorLibJpeg(unsigned int quality=80, JpegImageCompressor::JpegColorspace jcs=JpegImageCompressor::JPEG_CS_RGB)
Constructor.
Base class for exceptions in Fawkes.
virtual size_t compressed_size()
Get compressed size.
virtual void set_vflip(bool enable)
Enable or disable vflipping.
virtual void set_destination_buffer(unsigned char *buf, unsigned int buf_size)
Set destination buffer (if compressing to memory).
virtual ~JpegImageCompressorLibJpeg()
Destructor.
virtual void set_filename(const char *filename)
Set file name.
virtual size_t recommended_compressed_buffer_size()
Get the recommended size for the compressed buffer.