25#include <core/exception.h>
26#include <fvutils/color/rgbyuv.h>
27#include <fvutils/color/yuvrgb.h>
28#include <fvutils/compression/jpeg_compressor.h>
29#include <fvutils/compression/jpeg_compressor_libjpeg.h>
47 struct jpeg_error_mgr pub;
48 jmp_buf setjmp_buffer;
56 struct jpeg_destination_mgr pub;
60} fv_jpeg_memory_destination_mgr_t;
67fv_jpeg_init_destination(j_compress_ptr cinfo)
69 fv_jpeg_memory_destination_mgr_t *dest = (fv_jpeg_memory_destination_mgr_t *)cinfo->dest;
70 dest->pub.next_output_byte = dest->buffer;
71 dest->pub.free_in_buffer = dest->bufsize;
80fv_jpeg_empty_output_buffer(j_compress_ptr cinfo)
82 fv_jpeg_memory_destination_mgr_t *dest = (fv_jpeg_memory_destination_mgr_t *)cinfo->dest;
83 dest->pub.next_output_byte = dest->buffer;
84 dest->pub.free_in_buffer = dest->bufsize;
95fv_jpeg_term_destination(j_compress_ptr cinfo)
99 fv_jpeg_memory_destination_mgr_t *dest = (fv_jpeg_memory_destination_mgr_t *)cinfo->dest;
100 dest->datacount = dest->bufsize - dest->pub.free_in_buffer;
109fv_jpeg_memory_destination_setup(j_compress_ptr cinfo, JOCTET *buffer,
int bufsize)
111 fv_jpeg_memory_destination_mgr_t *dest;
112 if (cinfo->dest == NULL) {
113 cinfo->dest = (
struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small)(
114 (j_common_ptr)cinfo, JPOOL_PERMANENT,
sizeof(fv_jpeg_memory_destination_mgr_t));
117 dest = (fv_jpeg_memory_destination_mgr_t *)cinfo->dest;
118 dest->bufsize = bufsize;
119 dest->buffer = buffer;
120 dest->pub.init_destination = fv_jpeg_init_destination;
121 dest->pub.empty_output_buffer = fv_jpeg_empty_output_buffer;
122 dest->pub.term_destination = fv_jpeg_term_destination;
126init_source(j_decompress_ptr cinfo)
132fill_input_buffer(j_decompress_ptr cinfo)
139skip_input_data(j_decompress_ptr cinfo,
long num_bytes)
141 if ((
size_t)num_bytes > cinfo->src->bytes_in_buffer) {
142 cinfo->src->next_input_byte = NULL;
143 cinfo->src->bytes_in_buffer = 0;
145 cinfo->src->next_input_byte += (size_t)num_bytes;
146 cinfo->src->bytes_in_buffer -= (size_t)num_bytes;
151term_source(j_decompress_ptr cinfo)
157fv_jpeg_error_exit(j_common_ptr cinfo)
160 fv_jpeg_error_mgr_t *myerr = (fv_jpeg_error_mgr_t *)cinfo->err;
163 longjmp(myerr->setjmp_buffer, 1);
173fv_jpeg_memory_source_setup(j_decompress_ptr cinfo,
unsigned char *ptr,
size_t size)
175 struct jpeg_source_mgr *src;
176 src = cinfo->src = (
struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
179 src->init_source = init_source;
180 src->fill_input_buffer = fill_input_buffer;
181 src->skip_input_data = skip_input_data;
182 src->resync_to_restart = jpeg_resync_to_restart;
183 src->term_source = term_source;
184 src->next_input_byte = ptr;
185 src->bytes_in_buffer = size;
201 this->quality = quality;
225 struct jpeg_compress_struct cinfo;
226 fv_jpeg_error_mgr_t jerr;
227 unsigned int row_stride;
228 unsigned char * row_buffer;
231 fv_jpeg_memory_destination_mgr_t *dest;
234 FILE *outfile = NULL;
238 memset(&cinfo, 0,
sizeof(cinfo));
239 cinfo.err = jpeg_std_error(&jerr.pub);
240 jerr.pub.error_exit = fv_jpeg_error_exit;
243 if (setjmp(jerr.setjmp_buffer)) {
244 char buffer[JMSG_LENGTH_MAX];
245 (*cinfo.err->format_message)((jpeg_common_struct *)&cinfo, buffer);
250 jpeg_destroy_compress(&cinfo);
254 jpeg_create_compress(&cinfo);
257 cinfo.image_width = width;
258 cinfo.image_height = height;
259 cinfo.input_components = 3;
261 cinfo.in_color_space = JCS_RGB;
263 cinfo.in_color_space = JCS_YCbCr;
266 row_stride = cinfo.image_width * cinfo.input_components;
270 fv_jpeg_memory_destination_setup(&cinfo, (JOCTET *)jpeg_buffer, jpeg_buffer_size);
272 outfile = fopen(filename,
"wb");
273 if (outfile == NULL) {
274 throw fawkes::Exception(
"JpegImageCompressorLibJpeg: cannot open %s\n", filename);
276 jpeg_stdio_dest(&cinfo, outfile);
279 jpeg_set_defaults(&cinfo);
280 jpeg_set_quality(&cinfo, quality,
true );
281 jpeg_start_compress(&cinfo,
true);
284 row_buffer = (
unsigned char *)malloc(row_stride);
288 while (cinfo.next_scanline < cinfo.image_height) {
289 convert_line_yuv422planar_to_rgb(buffer,
293 cinfo.image_height - cinfo.next_scanline - 1,
295 jpeg_write_scanlines(&cinfo, &row_buffer, 1);
298 while (cinfo.next_scanline < cinfo.image_height) {
299 convert_line_yuv422planar_to_rgb(
300 buffer, row_buffer, cinfo.image_width, cinfo.image_height, cinfo.next_scanline, 0);
301 jpeg_write_scanlines(&cinfo, &row_buffer, 1);
306 while (cinfo.next_scanline < cinfo.image_height) {
307 convert_line_yuv422planar_to_yuv444packed(buffer,
311 cinfo.image_height - cinfo.next_scanline - 1,
313 jpeg_write_scanlines(&cinfo, &row_buffer, 1);
316 while (cinfo.next_scanline < cinfo.image_height) {
317 convert_line_yuv422planar_to_yuv444packed(
318 buffer, row_buffer, cinfo.image_width, cinfo.image_height, cinfo.next_scanline, 0);
319 jpeg_write_scanlines(&cinfo, &row_buffer, 1);
325 jpeg_finish_compress(&cinfo);
329 dest = (fv_jpeg_memory_destination_mgr_t *)cinfo.dest;
330 jpeg_bytes = dest->datacount;
336 jpeg_destroy_compress(&cinfo);
343 this->height = height;
349 if (cspace == YUV422_PLANAR) {
350 this->buffer = buffer;
371 jpeg_buffer_size = buf_size;
383 return width * height / 4;
389 this->filename = filename;
Base class for exceptions in Fawkes.
CompressionDestination
Where to put the compressed image.
@ COMP_DEST_MEM
write compressed image to buffer in memory
virtual void set_filename(const char *filename)
Set file name.
virtual void compress()
Compress image.
virtual void set_vflip(bool enable)
Enable or disable vflipping.
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 size_t recommended_compressed_buffer_size()
Get the recommended size for the compressed buffer.
virtual bool supports_vflip()
Check if image compressor can do vflip during compress.
JpegImageCompressorLibJpeg(unsigned int quality=80, JpegImageCompressor::JpegColorspace jcs=JpegImageCompressor::JPEG_CS_RGB)
Constructor.
virtual void set_compression_destination(ImageCompressor::CompressionDestination cd)
Set compression destination.
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_image_dimensions(unsigned int width, unsigned int height)
Set dimensions of image to compress.
virtual size_t compressed_size()
Get compressed size.
JpegColorspace
JPEG color space.