1 /* Modified for clg by esj */
3 /* Copyright 2005 Google Inc. All Rights Reserved.
4 * Author: yangzh@google.com (Zhonghao Yang)
6 * Google's own patch to add jpeg I/O support for cairo.
10 /* cairo - a vector graphics library with display and print output
12 * Copyright © 2003 University of Southern California
14 * This library is free software; you can redistribute it and/or
15 * modify it either under the terms of the GNU Lesser General Public
16 * License version 2.1 as published by the Free Software Foundation
17 * (the "LGPL") or, at your option, under the terms of the Mozilla
18 * Public License Version 1.1 (the "MPL"). If you do not alter this
19 * notice, a recipient may use your version of this file under either
20 * the MPL or the LGPL.
22 * You should have received a copy of the LGPL along with this library
23 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * You should have received a copy of the MPL along with this library
26 * in the file COPYING-MPL-1.1
28 * The contents of this file are subject to the Mozilla Public License
29 * Version 1.1 (the "License"); you may not use this file except in
30 * compliance with the License. You may obtain a copy of the License at
31 * http://www.mozilla.org/MPL/
33 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
34 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
35 * the specific language governing rights and limitations.
37 * The Original Code is the cairo graphics library.
39 * The Initial Developer of the Original Code is University of Southern
43 * Carl D. Worth <cworth@cworth.org>
44 * Kristian Høgsberg <krh@redhat.com>
55 #include "cairo-lut-private.h"
56 #include "cairo-prebuilt-lut.h"
58 #define BUF_SIZE_JPEG 4096
60 struct clg_error_mgr
{
61 struct jpeg_error_mgr pub
;
62 jmp_buf setjmp_buffer
;
65 typedef struct clg_error_mgr
*error_ptr
;
68 _error_exit (j_common_ptr cinfo
)
70 error_ptr err
= (error_ptr
) cinfo
->err
;
72 (*cinfo
->err
->output_message
) (cinfo
);
73 longjmp(err
->setjmp_buffer
, 1);
77 typedef unsigned int (*cairo_jpeg_read_func_t
)
84 * Model underlying system's read behavior:
85 * data can be read from stdio, stream, or anything.
87 cairo_jpeg_read_func_t jpeg_func
;
91 * For stdio, this should be struct file_closure *
95 * Buffer for reading from
97 unsigned char block
[BUF_SIZE_JPEG
];
99 cairo_status_t status
;
103 * Read function for stdio.
104 * Check length of read and return error if necessary.
107 unsigned int stdio_read_func (void *closure
,
111 return fread((void *)data
, 1, length
, (FILE *)closure
);
116 * called by jpeg_read_header before any data is actually read.
118 static void init_source_custom (j_decompress_ptr cinfo
)
120 cinfo
->src
->bytes_in_buffer
= 0;
124 * Fill the input buffer.
125 * called whenever buffer is emptied.
127 static boolean
fill_input_buffer_custom (j_decompress_ptr cinfo
)
129 struct read_closure
*closure
= (struct read_closure
*) (cinfo
->client_data
);
132 len
= (*closure
->jpeg_func
) (closure
->user_data
,
133 closure
->block
, BUF_SIZE_JPEG
);
136 /* really hit EOF in the beginning: insert a fake EOI marker. */
137 static const unsigned char jpeg_eof
[] = { 0xFF, JPEG_EOI
};
138 cinfo
->src
->bytes_in_buffer
= 2;
139 cinfo
->src
->next_input_byte
= jpeg_eof
;
141 cinfo
->src
->bytes_in_buffer
= len
;
142 cinfo
->src
->next_input_byte
= closure
->block
;
150 * used to skip over a potentially large amount of uninteresting
151 * data (such as APPn marker).
152 * Writers of suspendable-input applications must note that skip_input_data
153 * is not granted the right to give a suspension return. If the skip extends
154 * beyond the data currently in the buffer, the buffer can be marked empty so
155 * that the next read will cause a fill_input_buffer call that can suspend.
156 * Arranging for additional bytes to be discarded before reloading the input
157 * buffer is the application writer's problem.
159 static void skip_input_data_custom (j_decompress_ptr cinfo
, long num_bytes
)
161 while (num_bytes
> (long) (cinfo
->src
->bytes_in_buffer
)) {
162 num_bytes
-= (long) (cinfo
->src
->bytes_in_buffer
);
163 fill_input_buffer_custom (cinfo
);
166 cinfo
->src
->next_input_byte
+= (size_t) num_bytes
;
167 cinfo
->src
->bytes_in_buffer
-= (size_t) num_bytes
;
172 * called by jpeg_finish_decompress after all data has been read.
175 static void term_source_custom (j_decompress_ptr cinfo
)
180 * read jpeg from any source.
182 static cairo_surface_t
*
183 read_jpeg (struct read_closure
*closure
)
185 cairo_surface_t
*surface
= NULL
;
187 struct jpeg_decompress_struct cinfo
;
188 struct clg_error_mgr jerr
;
189 struct jpeg_source_mgr src
;
198 register JSAMPROW src_pixel
;
199 register uint32_t *dst_pixel
;
202 closure
->status
= CAIRO_STATUS_SUCCESS
;
204 /* Step 1: Allocate and initialize a JPEG decompression object */
205 /* Step 2: Specify the source of the compressed data (eg, a file) */
206 memset (&cinfo
, 0, sizeof (cinfo
));
207 memset (&jerr
, 0, sizeof (jerr
));
209 cinfo
.err
= jpeg_std_error (&jerr
.pub
);
210 jerr
.pub
.error_exit
= _error_exit
;
211 if (setjmp(jerr
.setjmp_buffer
))
214 jpeg_create_decompress (&cinfo
);
216 cinfo
.client_data
= closure
;
218 src
.init_source
= init_source_custom
;
219 src
.fill_input_buffer
= fill_input_buffer_custom
;
220 src
.skip_input_data
= skip_input_data_custom
;
221 src
.resync_to_restart
= jpeg_resync_to_restart
; /* JPEG library default */
222 src
.term_source
= term_source_custom
;
223 src
.bytes_in_buffer
= 0; /* forces fill_input_buffer on first read. */
224 src
.next_input_byte
= NULL
; /* until buffer loaded. */
227 /* save the APP14 marker to check for Adobe Photoshop CMYK */
228 /* files with inverted components. */
229 jpeg_save_markers (&cinfo
, JPEG_APP0
+ 14, 256);
231 /* Step 3: Call jpeg_read_header() to obtain image info. */
232 if (jpeg_read_header (&cinfo
, TRUE
) != JPEG_HEADER_OK
)
235 /* if (cinfo.image_height > INT_MAX || cinfo.image_width > INT_MAX) */
238 /* NOTE(yangzh): do not support these two yet. */
239 if (cinfo
.jpeg_color_space
== JCS_CMYK
|| cinfo
.jpeg_color_space
== JCS_YCCK
)
242 cinfo
.out_color_space
= JCS_RGB
;
244 /* the fastest, but less accurate integer method for DCT. */
245 /* not recommende if high quality is a concern. we do not have this issue. */
246 cinfo
.dct_method
= JDCT_IFAST
;
248 /* Step 4: Set target cairo image.
249 * for CAIRO_FORMAT_ARGB32, every pixel will take 4 bytes.
251 surface
= cairo_image_surface_create (CAIRO_FORMAT_ARGB32
,
254 if (cairo_surface_status (surface
) != CAIRO_STATUS_SUCCESS
) {
255 closure
->status
= cairo_surface_status (surface
);
259 /* Step 5: jpeg_start_decompress(...); */
260 jpeg_start_decompress (&cinfo
);
262 /* Step 6: while (scan lines remain to be read) */
263 /* jpeg_read_scanlines(...); */
265 row
= (JSAMPROW
) malloc (cinfo
.output_width
* channels
* sizeof (JSAMPLE
));
267 closure
->status
= CAIRO_STATUS_NO_MEMORY
;
271 data
= cairo_image_surface_get_data (surface
);
272 stride
= cairo_image_surface_get_stride (surface
);
275 for (i
= 0; i
< cinfo
.output_height
; i
++) {
276 jpeg_read_scanlines (&cinfo
, rowptr
, 1);
278 dst_pixel
= (uint32_t*)(data
+ i
* stride
);
279 for (j
= 0; j
< cinfo
.output_width
; j
++, src_pixel
+= channels
, dst_pixel
++) {
280 /* Store ARGB in native endian. */
281 *dst_pixel
= (0xFF << 24) /* always 0xFF in alpha channel. */
282 + (src_pixel
[0] << 16)
283 + (src_pixel
[1] << 8)
288 /* Step 7: jpeg_finish_decompress(...); */
289 jpeg_finish_decompress (&cinfo
);
294 cairo_surface_destroy (surface
);
297 if (closure
->status
== CAIRO_STATUS_SUCCESS
)
298 closure
->status
= CAIRO_STATUS_READ_ERROR
;
301 /* Release other buffers used in this function. */
305 /* Step 8: Release the JPEG decompression object. */
306 jpeg_destroy_decompress (&cinfo
);
312 cairo_image_surface_create_from_jpeg (const char *filename
,
313 cairo_status_t
*status
)
315 struct read_closure jpeg_closure
;
317 cairo_surface_t
*surface
;
319 fp
= fopen (filename
, "rb");
323 *status
= CAIRO_STATUS_NO_MEMORY
;
326 *status
= CAIRO_STATUS_FILE_NOT_FOUND
;
329 *status
= CAIRO_STATUS_READ_ERROR
;
334 jpeg_closure
.jpeg_func
= stdio_read_func
;
335 jpeg_closure
.user_data
= (void*) fp
;
337 surface
= read_jpeg (&jpeg_closure
);
340 *status
= jpeg_closure
.status
;
345 cairo_image_surface_create_from_jpeg_stream (cairo_jpeg_read_func_t read_func
,
347 cairo_status_t
*status
)
349 struct read_closure jpeg_closure
;
350 jpeg_closure
.jpeg_func
= read_func
;
351 jpeg_closure
.user_data
= closure
;
353 cairo_surface_t
*surface
= read_jpeg (&jpeg_closure
);
355 *status
= jpeg_closure
.status
;
360 typedef struct _cairo_jpeg_parameter
{
362 cairo_bool_t interlace
;
363 } cairo_jpeg_parameter_t
;
365 void cairo_get_default_jpeg_parameter (cairo_jpeg_parameter_t
*param
);
367 typedef unsigned int (*cairo_jpeg_write_func_t
)
369 const unsigned char *data
,
370 unsigned int length
);
372 struct write_closure
{
373 cairo_jpeg_write_func_t jpeg_func
;
377 * For stdio, this should be struct file_closure *
381 * Buffer for writing to.
383 unsigned char block
[BUF_SIZE_JPEG
];
387 * write func for stdio.
388 * since closure_data->byte_written contains enough diagnostic information,
389 * we always return SUCCESS here.
392 cairo_status_t
stdio_write_func (void *closure
,
393 const unsigned char *data
,
398 bytes_written
= fwrite(data
, 1, length
, (FILE *)closure
);
399 data
+= bytes_written
;
400 length
-= bytes_written
;
401 } while (bytes_written
> 0 && length
> 0);
403 return CAIRO_STATUS_SUCCESS
;
407 * Initialize destination.
408 * called by jpeg_start_compress before any data is actually written.
410 static void init_destination_jpeg_custom (j_compress_ptr cinfo
)
412 struct write_closure
*closure
= (struct write_closure
*) (cinfo
->client_data
);
413 cinfo
->dest
->next_output_byte
= closure
->block
;
414 cinfo
->dest
->free_in_buffer
= BUF_SIZE_JPEG
;
419 * called whenever buffer fills up.
420 * In typical applications, this should write the entire output buffer
421 * (ignoring the current state of next_output_byte & free_in_buffer),
422 * reset the pointer & count to the start of the buffer, and return TRUE
423 * indicating that the buffer has been dumped.
425 * In applications that need to be able to suspend compression due to output
426 * overrun, a FALSE return indicates that the buffer cannot be emptied now.
427 * In this situation, the compressor will return to its caller (possibly with
428 * an indication that it has not accepted all the supplied scanlines). The
429 * application should resume compression after it has made more room in the
430 * output buffer. Note that there are substantial restrictions on the use of
431 * suspension --- see the documentation.
433 * When suspending, the compressor will back up to a convenient restart point
434 * (typically the start of the current MCU). next_output_byte & free_in_buffer
435 * indicate where the restart point will be if the current call returns FALSE.
436 * Data beyond this point will be regenerated after resumption, so do not
437 * write it out when emptying the buffer externally.
439 static boolean
empty_output_buffer_jpeg_custom (j_compress_ptr cinfo
)
441 struct write_closure
*closure
= (struct write_closure
*) (cinfo
->client_data
);
443 len
= (*closure
->jpeg_func
) (closure
->user_data
,
444 closure
->block
, BUF_SIZE_JPEG
);
445 if (len
!= BUF_SIZE_JPEG
) {
446 /* seems not all remaining bytes in buffer has been dumped yet. */
447 /* by return FALSE, we reply on JPEG's error handling machnism? */
450 cinfo
->dest
->next_output_byte
= closure
->block
;
451 cinfo
->dest
->free_in_buffer
= BUF_SIZE_JPEG
;
456 * Terminate destination.
457 * called by jpeg_finish_compress afer all data has been written.
458 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
459 * application must deal with any cleanup that should happen even
462 static void term_destination_jpeg_custom (j_compress_ptr cinfo
)
464 struct write_closure
*closure
= (struct write_closure
*) (cinfo
->client_data
);
466 len
= BUF_SIZE_JPEG
- cinfo
->dest
->free_in_buffer
;
468 (*closure
->jpeg_func
) (closure
->user_data
, closure
->block
, len
);
471 static cairo_status_t
472 write_jpeg (cairo_surface_t
*surface
, void* closure
,
473 const cairo_jpeg_parameter_t
*parameter
)
475 cairo_status_t status
= CAIRO_STATUS_SUCCESS
;
477 struct jpeg_compress_struct cinfo
;
478 struct clg_error_mgr jerr
;
479 struct jpeg_destination_mgr dest
;
480 cairo_jpeg_parameter_t
*param
, default_parameters
;
485 register uint32_t *src_pixel
;
486 register uint8_t *src_pixel_gray
;
487 register JSAMPROW dst_pixel
;
491 param
= (cairo_jpeg_parameter_t
*)parameter
;
493 param
= &default_parameters
;
494 cairo_get_default_jpeg_parameter(param
);
498 /* Step 1: Allocate and initialize a JPEG compression object. */
499 memset (&cinfo
, 0, sizeof (cinfo
));
500 memset (&jerr
, 0, sizeof (jerr
));
502 cinfo
.err
= jpeg_std_error (&jerr
.pub
);
503 jerr
.pub
.error_exit
= _error_exit
;
504 if (setjmp(jerr
.setjmp_buffer
))
507 jpeg_create_compress (&cinfo
);
509 /* Step 2: Specify the destination for the compressed data. */
510 cinfo
.client_data
= closure
;
512 dest
.init_destination
= init_destination_jpeg_custom
;
513 dest
.empty_output_buffer
= empty_output_buffer_jpeg_custom
;
514 dest
.term_destination
= term_destination_jpeg_custom
;
515 dest
.next_output_byte
= NULL
;
516 dest
.free_in_buffer
= 0;
519 /* Step 3: Set parameters for compression, image size & colorspace, etc. */
520 cinfo
.image_width
= cairo_image_surface_get_width (surface
);
521 cinfo
.image_height
= cairo_image_surface_get_height (surface
);
524 switch (cairo_image_surface_get_format (surface
)) {
525 case CAIRO_FORMAT_RGB24
:
526 cinfo
.input_components
= 3; /* # of color components per pixel */
527 cinfo
.in_color_space
= JCS_RGB
; /* colorspace of input image */
529 case CAIRO_FORMAT_ARGB32
:
530 cinfo
.input_components
= 3; /* # of color components per pixel */
531 cinfo
.in_color_space
= JCS_RGB
; /* colorspace of input image */
534 case CAIRO_FORMAT_A8
: /* Put A channel into a grayscale JPEG image. */
535 case CAIRO_FORMAT_A1
: /* Put A channel into a "binary" JPEG image. */
536 cinfo
.input_components
= 1;
537 cinfo
.in_color_space
= JCS_GRAYSCALE
;
539 status
= CAIRO_STATUS_NULL_POINTER
;
543 jpeg_set_defaults (&cinfo
); /* set compression parameters all default values. */
545 /* the fastest, but less accurate integer method for DCT. */
546 /* not recommende if high quality is a concern. we do not have this issue. */
547 cinfo
.dct_method
= JDCT_IFAST
;
549 if (param
->quality
>= 0)
550 jpeg_set_quality(&cinfo
, param
->quality
, TRUE
);
552 /* If user requests interlace, translate that to progressive JPEG */
553 if (param
->interlace
)
554 jpeg_simple_progression(&cinfo
);
556 row
= (JSAMPROW
) malloc (cinfo
.image_width
* cinfo
.input_components
559 status
= CAIRO_STATUS_NO_MEMORY
;
565 /* Step 4: jpeg_start_compress(...); */
566 jpeg_start_compress (&cinfo
, TRUE
);
568 /* Step 5: while (scan lines remain to be written) */
569 /* jpeg_write_scanlines(...); */
570 uint8_t *data
= cairo_image_surface_get_data (surface
);
571 int stride
= cairo_image_surface_get_stride (surface
);
573 if (cinfo
.input_components
== 3) { /* truecolor JPEG. */
574 for (i
= 0; i
< cinfo
.image_height
; i
++) {
575 src_pixel
= (uint32_t *) (data
+ i
* stride
);
578 * If the pixels have an alpha channel, convert
579 * the pixels to normal RGB
582 for (j
= 0; j
< cinfo
.image_width
; j
++, dst_pixel
+= 3) {
584 cairo_to_rgb(*src_pixel
++, &r
, &g
, &b
);
590 for (j
= 0; j
< cinfo
.image_width
; j
++, dst_pixel
+= 3) {
593 dst_pixel
[0] = _get_red(pix
);
594 dst_pixel
[1] = _get_green(pix
);
595 dst_pixel
[2] = _get_blue(pix
);
598 jpeg_write_scanlines (&cinfo
, rowptr
, 1);
600 } else { /* write to a grayscale JPEG. */
601 src_pixel_gray
= (uint8_t *) data
;
602 for (i
= 0; i
< cinfo
.image_height
; i
++) {
603 memcpy (row
, src_pixel_gray
, cinfo
.image_width
);
604 src_pixel_gray
+= stride
;
605 jpeg_write_scanlines (&cinfo
, rowptr
, 1);
609 /* Step 6: jpeg_finish_compress(...); */
610 jpeg_finish_compress (&cinfo
);
616 /* Step 7: Release the JPEG compression object. */
617 jpeg_destroy_compress (&cinfo
);
623 cairo_get_default_jpeg_parameter (cairo_jpeg_parameter_t
*param
)
626 param
->interlace
= TRUE
;
630 cairo_surface_write_to_jpeg (cairo_surface_t
*surface
,
631 const char *filename
,
632 const cairo_jpeg_parameter_t
*parameter
)
635 struct write_closure jpeg_closure
;
636 cairo_status_t status
;
638 fp
= fopen (filename
, "wb");
640 return CAIRO_STATUS_WRITE_ERROR
;
642 jpeg_closure
.jpeg_func
= stdio_write_func
;
643 jpeg_closure
.user_data
= fp
;
645 status
= write_jpeg (surface
, &jpeg_closure
, parameter
);
647 status
= CAIRO_STATUS_WRITE_ERROR
;
653 cairo_surface_write_to_jpeg_stream (cairo_surface_t
*surface
,
654 cairo_jpeg_write_func_t write_func
,
656 const cairo_jpeg_parameter_t
*parameter
)
658 struct write_closure jpeg_closure
;
659 jpeg_closure
.jpeg_func
= write_func
;
660 jpeg_closure
.user_data
= closure
;
662 return write_jpeg (surface
, &jpeg_closure
, parameter
);