chiark / gitweb /
Initial checking of support functions for JPEG
[clg] / cairo / alien / cairo-jpeg.c
1 /* Modified for clg by esj */
2
3 /* Copyright 2005 Google Inc. All Rights Reserved.
4  * Author: yangzh@google.com (Zhonghao Yang)
5  *
6  * Google's own patch to add jpeg I/O support for cairo.
7  *
8  */
9
10 /* cairo - a vector graphics library with display and print output
11  *
12  * Copyright © 2003 University of Southern California
13  *
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.
21  *
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
27  *
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/
32  *
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.
36  *
37  * The Original Code is the cairo graphics library.
38  *
39  * The Initial Developer of the Original Code is University of Southern
40  * California.
41  *
42  * Contributor(s):
43  *      Carl D. Worth <cworth@cworth.org>
44  *      Kristian Høgsberg <krh@redhat.com>
45  */
46
47 #include <stdio.h>
48 #include <stdint.h>
49 #include <string.h>
50 #include <stdlib.h>
51 #include <setjmp.h>
52 #include <errno.h>
53 #include <jpeglib.h>
54 #include <cairo.h>
55 #include "cairo-lut-private.h"
56 #include "cairo-prebuilt-lut.h"
57
58 #define BUF_SIZE_JPEG 4096
59
60 struct clg_error_mgr {
61   struct jpeg_error_mgr pub;
62   jmp_buf setjmp_buffer;
63 };
64         
65 typedef struct clg_error_mgr *error_ptr;
66         
67 static void
68 _error_exit (j_common_ptr cinfo)
69 {
70   error_ptr err = (error_ptr) cinfo->err;
71         
72   (*cinfo->err->output_message) (cinfo);
73   longjmp(err->setjmp_buffer, 1);
74 }
75
76
77 typedef unsigned int (*cairo_jpeg_read_func_t)
78                       (void *closure,
79                        unsigned char *data,
80                        unsigned int  length);
81
82 struct read_closure {
83   /**
84    * Model underlying system's read behavior:
85    * data can be read from stdio, stream, or anything.
86    */
87   cairo_jpeg_read_func_t jpeg_func;
88
89   /**
90    * Auxiliary data:
91    * For stdio, this should be struct file_closure *
92    */
93   void *user_data;
94   /*
95    * Buffer for reading from
96    */
97   unsigned char block[BUF_SIZE_JPEG];
98
99   cairo_status_t status;
100 };
101
102 /*
103  * Read function for stdio.
104  * Check length of read and return error if necessary.
105  */
106 static
107 unsigned int stdio_read_func (void *closure,
108                               unsigned char *data,
109                               unsigned int length)
110 {
111   return fread((void *)data, 1, length, (FILE *)closure);
112 }
113
114 /*
115  * Initialize source.
116  * called by jpeg_read_header before any data is actually read.
117  */
118 static void init_source_custom (j_decompress_ptr cinfo)
119 {
120   cinfo->src->bytes_in_buffer = 0;
121 }
122
123 /*
124  * Fill the input buffer.
125  * called whenever buffer is emptied.
126  */
127 static boolean fill_input_buffer_custom (j_decompress_ptr cinfo)
128 {
129   struct read_closure *closure = (struct read_closure*) (cinfo->client_data);
130   unsigned int len;
131
132   len = (*closure->jpeg_func) (closure->user_data,
133                                closure->block, BUF_SIZE_JPEG);
134
135   if (len == 0) {
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;
140   } else {
141       cinfo->src->bytes_in_buffer = len;
142       cinfo->src->next_input_byte = closure->block;
143   }
144   return TRUE;
145 }
146
147
148 /*
149  * Skip data.
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.
158  */
159 static void skip_input_data_custom (j_decompress_ptr cinfo, long num_bytes)
160 {
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);
164   }
165
166   cinfo->src->next_input_byte += (size_t) num_bytes;
167   cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
168 }
169
170 /*
171  * Terminate source.
172  * called by jpeg_finish_decompress after all data has been read.
173  * Often a no-op.
174  */
175 static void term_source_custom (j_decompress_ptr cinfo)
176 {
177 }
178
179 /*
180  * read jpeg from any source.
181  */
182 static cairo_surface_t *
183 read_jpeg (struct read_closure *closure)
184 {
185   cairo_surface_t *surface = NULL;
186
187   struct jpeg_decompress_struct cinfo;
188   struct clg_error_mgr jerr;
189   struct jpeg_source_mgr src;
190
191   int channels;
192   uint8_t *data;
193   int stride;
194   
195   JSAMPROW row = NULL;
196   JSAMPROW rowptr[1];
197
198   register JSAMPROW src_pixel;
199   register uint32_t *dst_pixel;
200   unsigned int i, j;
201
202   closure->status = CAIRO_STATUS_SUCCESS;
203   
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));
208
209   cinfo.err = jpeg_std_error (&jerr.pub);
210   jerr.pub.error_exit = _error_exit;
211   if (setjmp(jerr.setjmp_buffer))
212     goto ERROR;
213
214   jpeg_create_decompress (&cinfo);
215
216   cinfo.client_data = closure;
217
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. */
225   cinfo.src = &src;
226
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);
230
231   /* Step 3: Call jpeg_read_header() to obtain image info. */
232   if (jpeg_read_header (&cinfo, TRUE) != JPEG_HEADER_OK)
233     goto ERROR;
234
235   /* if (cinfo.image_height > INT_MAX || cinfo.image_width > INT_MAX) */
236   /*   goto BAIL1; */
237
238   /* NOTE(yangzh): do not support these two yet. */
239   if (cinfo.jpeg_color_space == JCS_CMYK || cinfo.jpeg_color_space == JCS_YCCK)
240     goto ERROR;
241     
242   cinfo.out_color_space = JCS_RGB;
243
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;
247
248   /* Step 4: Set target cairo image.
249    * for CAIRO_FORMAT_ARGB32, every pixel will take 4 bytes.
250    */
251   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
252                                         cinfo.image_width,
253                                         cinfo.image_height);
254   if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) {
255     closure->status = cairo_surface_status (surface);
256     goto ERROR;
257   }
258
259   /* Step 5: jpeg_start_decompress(...); */
260   jpeg_start_decompress (&cinfo);
261
262   /* Step 6: while (scan lines remain to be read) */
263   /*           jpeg_read_scanlines(...); */
264   channels = 3;
265   row = (JSAMPROW) malloc (cinfo.output_width * channels * sizeof (JSAMPLE));
266   if (row == NULL) {
267     closure->status = CAIRO_STATUS_NO_MEMORY;
268     goto ERROR;
269   }
270
271   data = cairo_image_surface_get_data (surface);
272   stride = cairo_image_surface_get_stride (surface);
273   
274   rowptr[0] = row;
275   for (i = 0; i < cinfo.output_height; i++) {
276     jpeg_read_scanlines (&cinfo, rowptr, 1);
277     src_pixel = row;
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)
284                    + (src_pixel[2]);
285     }
286   }
287
288   /* Step 7: jpeg_finish_decompress(...); */
289   jpeg_finish_decompress (&cinfo);
290   goto EXIT;
291   
292  ERROR:
293   if (surface) {
294     cairo_surface_destroy (surface);
295     surface = NULL;
296   }
297   if (closure->status == CAIRO_STATUS_SUCCESS)
298     closure->status = CAIRO_STATUS_READ_ERROR;
299
300  EXIT:
301   /* Release other buffers used in this function. */
302   if (row)
303     free (row);
304
305   /* Step 8: Release the JPEG decompression object. */
306   jpeg_destroy_decompress (&cinfo);
307
308   return surface;
309 }
310
311 cairo_surface_t *
312 cairo_image_surface_create_from_jpeg (const char *filename,
313                                       cairo_status_t *status)
314 {
315   struct read_closure jpeg_closure;
316   FILE *fp;
317   cairo_surface_t *surface;
318
319   fp = fopen (filename, "rb");
320   if (fp == NULL) {
321     switch (errno) {
322       case ENOMEM:
323         *status = CAIRO_STATUS_NO_MEMORY;
324         return NULL;
325       case ENOENT:
326         *status = CAIRO_STATUS_FILE_NOT_FOUND;
327         return NULL;
328       default:
329         *status = CAIRO_STATUS_READ_ERROR;
330         return NULL;
331     }
332   }
333
334   jpeg_closure.jpeg_func = stdio_read_func;
335   jpeg_closure.user_data = (void*) fp;
336   
337   surface = read_jpeg (&jpeg_closure);
338   fclose (fp);
339
340   *status = jpeg_closure.status;
341   return surface;
342 }
343
344 cairo_surface_t *
345 cairo_image_surface_create_from_jpeg_stream (cairo_jpeg_read_func_t read_func,
346                                              void *closure,
347                                              cairo_status_t *status)
348 {
349   struct read_closure jpeg_closure;
350   jpeg_closure.jpeg_func = read_func;
351   jpeg_closure.user_data = closure;
352
353   cairo_surface_t *surface = read_jpeg (&jpeg_closure);
354
355   *status = jpeg_closure.status;
356   return surface;
357 }
358
359
360 typedef struct _cairo_jpeg_parameter {
361   int quality;
362   cairo_bool_t interlace;
363 } cairo_jpeg_parameter_t;
364
365 void cairo_get_default_jpeg_parameter (cairo_jpeg_parameter_t *param);
366
367 typedef unsigned int (*cairo_jpeg_write_func_t)
368                       (void *closure,
369                        const unsigned char *data,
370                        unsigned int length);
371
372 struct write_closure {
373   cairo_jpeg_write_func_t jpeg_func;
374
375   /**
376    * Auxiliary data:
377    * For stdio, this should be struct file_closure *
378    */
379   void *user_data;
380   /*
381    * Buffer for writing to.
382    */
383   unsigned char block[BUF_SIZE_JPEG];
384 };
385
386 /*
387  * write func for stdio.
388  * since closure_data->byte_written contains enough diagnostic information,
389  * we always return SUCCESS here.
390  */
391 static
392 cairo_status_t stdio_write_func (void *closure,
393                                  const unsigned char *data,
394                                  unsigned int length)
395 {
396   return fwrite(data, 1, length, (FILE *)closure);
397 }
398
399 /*
400  * Initialize destination.
401  * called by jpeg_start_compress before any data is actually written.
402  */
403 static void init_destination_jpeg_custom (j_compress_ptr cinfo)
404 {
405   struct write_closure *closure = (struct write_closure*) (cinfo->client_data);
406   cinfo->dest->next_output_byte = closure->block;
407   cinfo->dest->free_in_buffer = BUF_SIZE_JPEG;
408 }
409
410 /*
411  * Empty buffer.
412  * called whenever buffer fills up.
413  * In typical applications, this should write the entire output buffer
414  * (ignoring the current state of next_output_byte & free_in_buffer),
415  * reset the pointer & count to the start of the buffer, and return TRUE
416  * indicating that the buffer has been dumped.
417  *
418  * In applications that need to be able to suspend compression due to output
419  * overrun, a FALSE return indicates that the buffer cannot be emptied now.
420  * In this situation, the compressor will return to its caller (possibly with
421  * an indication that it has not accepted all the supplied scanlines).  The
422  * application should resume compression after it has made more room in the
423  * output buffer.  Note that there are substantial restrictions on the use of
424  * suspension --- see the documentation.
425  *
426  * When suspending, the compressor will back up to a convenient restart point
427  * (typically the start of the current MCU). next_output_byte & free_in_buffer
428  * indicate where the restart point will be if the current call returns FALSE.
429  * Data beyond this point will be regenerated after resumption, so do not
430  * write it out when emptying the buffer externally.
431  */
432 static boolean empty_output_buffer_jpeg_custom (j_compress_ptr cinfo)
433 {
434   struct write_closure *closure = (struct write_closure*) (cinfo->client_data);
435   int len;
436   len = (*closure->jpeg_func) (closure->user_data,
437                                closure->block, BUF_SIZE_JPEG);
438   if (len != BUF_SIZE_JPEG) {
439     /* seems not all remaining bytes in buffer has been dumped yet. */
440     /* by return FALSE, we reply on JPEG's error handling machnism?  */
441     return FALSE;
442   }
443   cinfo->dest->next_output_byte = closure->block;
444   cinfo->dest->free_in_buffer = BUF_SIZE_JPEG;
445   return TRUE;
446 }
447
448 /*
449  * Terminate destination.
450  * called by jpeg_finish_compress afer all data has been written.
451  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
452  * application must deal with any cleanup that should happen even
453  * for error exit.
454  */
455 static void term_destination_jpeg_custom (j_compress_ptr cinfo)
456 {
457   struct write_closure *closure = (struct write_closure*) (cinfo->client_data);
458   unsigned int len;
459   len = BUF_SIZE_JPEG - cinfo->dest->free_in_buffer;
460   if (len > 0)
461     (*closure->jpeg_func) (closure->user_data, closure->block, len);
462 }
463
464 static cairo_status_t
465 write_jpeg (cairo_surface_t *surface, void* closure,
466             const cairo_jpeg_parameter_t *parameter)
467 {
468   cairo_status_t status = CAIRO_STATUS_SUCCESS;
469
470   struct jpeg_compress_struct cinfo;
471   struct clg_error_mgr jerr;
472   struct jpeg_destination_mgr dest;
473   cairo_jpeg_parameter_t *param, default_parameters;
474
475   JSAMPROW row = NULL;
476   JSAMPROW rowptr[1];
477
478   register uint32_t *src_pixel;
479   register uint8_t *src_pixel_gray;
480   register JSAMPROW dst_pixel;
481   unsigned int i, j;
482   int convert_alpha;
483
484   param = (cairo_jpeg_parameter_t *)parameter;
485   if (param == NULL) {
486       param = &default_parameters;
487       cairo_get_default_jpeg_parameter(param);
488   }
489
490
491   /* Step 1:  Allocate and initialize a JPEG compression object. */
492   memset (&cinfo, 0, sizeof (cinfo));
493   memset (&jerr, 0, sizeof (jerr));
494
495   cinfo.err = jpeg_std_error (&jerr.pub);
496   jerr.pub.error_exit = _error_exit;
497   if (setjmp(jerr.setjmp_buffer))
498     goto BAIL;
499
500   jpeg_create_compress (&cinfo);
501
502   /* Step 2:  Specify the destination for the compressed data. */
503   cinfo.client_data = closure;
504
505   dest.init_destination = init_destination_jpeg_custom;
506   dest.empty_output_buffer = empty_output_buffer_jpeg_custom;
507   dest.term_destination = term_destination_jpeg_custom;
508   dest.next_output_byte = NULL;
509   dest.free_in_buffer = 0;
510   cinfo.dest = &dest;
511
512   /* Step 3: Set parameters for compression, image size & colorspace, etc. */
513   cinfo.image_width = cairo_image_surface_get_width (surface);
514   cinfo.image_height = cairo_image_surface_get_height (surface);
515   convert_alpha = 0;
516
517   switch (cairo_image_surface_get_format (surface)) {
518     case CAIRO_FORMAT_RGB24:
519       cinfo.input_components = 3;       /* # of color components per pixel */
520       cinfo.in_color_space = JCS_RGB;   /* colorspace of input image */
521       break;
522     case CAIRO_FORMAT_ARGB32:
523       cinfo.input_components = 3;       /* # of color components per pixel */
524       cinfo.in_color_space = JCS_RGB;   /* colorspace of input image */
525       convert_alpha = 1;
526       break;
527     case CAIRO_FORMAT_A8: /* Put A channel into a grayscale JPEG image. */
528     case CAIRO_FORMAT_A1: /* Put A channel into a "binary" JPEG image. */
529       cinfo.input_components = 1;
530       cinfo.in_color_space = JCS_GRAYSCALE;
531     default:
532       status = CAIRO_STATUS_NULL_POINTER;
533       goto BAIL;
534   }
535
536   jpeg_set_defaults (&cinfo);  /* set compression parameters all default values. */
537
538   /* the fastest, but less accurate integer method for DCT. */
539   /* not recommende if high quality is a concern. we do not have this issue. */
540   cinfo.dct_method = JDCT_IFAST;
541
542   if (param->quality >= 0)
543     jpeg_set_quality(&cinfo, param->quality, TRUE);
544
545   /* If user requests interlace, translate that to progressive JPEG */
546   if (param->interlace)
547     jpeg_simple_progression(&cinfo);
548
549   row = (JSAMPROW) malloc (cinfo.image_width * cinfo.input_components
550                            * sizeof (JSAMPLE));
551   if (row == NULL) {
552     status = CAIRO_STATUS_NO_MEMORY;
553     goto BAIL;
554   }
555
556   rowptr[0] = row;
557
558   /* Step 4:  jpeg_start_compress(...); */
559   jpeg_start_compress (&cinfo, TRUE);
560
561   /* Step 5:  while (scan lines remain to be written) */
562   /*            jpeg_write_scanlines(...); */
563   uint8_t *data = cairo_image_surface_get_data (surface);
564   int stride = cairo_image_surface_get_stride (surface);
565   
566   if (cinfo.input_components == 3) {  /* truecolor JPEG. */
567     for (i = 0; i < cinfo.image_height; i++) {
568       src_pixel = (uint32_t *) (data + i * stride);
569       dst_pixel = row;
570       /*
571        * If the pixels have an alpha channel, convert
572        * the pixels to normal RGB
573        */
574       if (convert_alpha) {
575         for (j = 0; j < cinfo.image_width; j++, dst_pixel += 3) {
576           uint8_t r, g, b;
577           cairo_to_rgb(*src_pixel++, &r, &g, &b);
578           dst_pixel[0] = r;
579           dst_pixel[1] = g;
580           dst_pixel[2] = b;
581         }
582       } else {
583         for (j = 0; j < cinfo.image_width; j++, dst_pixel += 3) {
584           unsigned int pix;
585           pix = *src_pixel++;
586           dst_pixel[0] = _get_red(pix);
587           dst_pixel[1] = _get_green(pix);
588           dst_pixel[2] = _get_blue(pix);
589         }
590       }
591       jpeg_write_scanlines (&cinfo, rowptr, 1);
592     }
593   } else {  /* write to a grayscale JPEG. */
594     src_pixel_gray = (uint8_t *) data;
595     for (i = 0; i < cinfo.image_height; i++) {
596       memcpy (row, src_pixel_gray, cinfo.image_width);
597       src_pixel_gray += stride;
598       jpeg_write_scanlines (&cinfo, rowptr, 1);
599     }
600   }
601
602   /* Step 6:  jpeg_finish_compress(...); */
603   jpeg_finish_compress (&cinfo);
604
605  BAIL:
606   if (row)
607     free (row);
608
609   /* Step 7:  Release the JPEG compression object. */
610   jpeg_destroy_compress (&cinfo);
611
612   return status;
613 }
614
615 void
616 cairo_get_default_jpeg_parameter (cairo_jpeg_parameter_t *param)
617 {
618   param->quality = 75;
619   param->interlace = TRUE;
620 }
621
622 cairo_status_t
623 cairo_surface_write_to_jpeg (cairo_surface_t *surface,
624                              const char *filename,
625                              const cairo_jpeg_parameter_t *parameter)
626 {
627   FILE *fp;
628   struct write_closure jpeg_closure;
629   cairo_status_t status;
630
631   fp = fopen (filename, "wb");
632   if (fp == NULL)
633     return CAIRO_STATUS_WRITE_ERROR;
634
635   jpeg_closure.jpeg_func = stdio_write_func;
636   jpeg_closure.user_data = fp;
637
638   status = write_jpeg (surface, &jpeg_closure, parameter);
639   if (fclose(fp) < 0)
640     status = CAIRO_STATUS_WRITE_ERROR;
641
642   return status;
643 }
644
645 cairo_status_t
646 cairo_surface_write_to_jpeg_stream (cairo_surface_t *surface,
647                                     cairo_jpeg_write_func_t write_func,
648                                     void *closure,
649                                     const cairo_jpeg_parameter_t *parameter)
650 {
651   struct write_closure jpeg_closure;
652   jpeg_closure.jpeg_func = write_func;
653   jpeg_closure.user_data = closure;
654
655   return write_jpeg (surface, &jpeg_closure, parameter);
656 }