Line data Source code
1 : /* Copyright (C) 2000-2012 by George Williams */
2 : /*
3 : * Redistribution and use in source and binary forms, with or without
4 : * modification, are permitted provided that the following conditions are met:
5 :
6 : * Redistributions of source code must retain the above copyright notice, this
7 : * list of conditions and the following disclaimer.
8 :
9 : * Redistributions in binary form must reproduce the above copyright notice,
10 : * this list of conditions and the following disclaimer in the documentation
11 : * and/or other materials provided with the distribution.
12 :
13 : * The name of the author may not be used to endorse or promote products
14 : * derived from this software without specific prior written permission.
15 :
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 :
28 : #include <fontforge-config.h>
29 :
30 : #ifdef _NO_LIBJPEG
31 :
32 : static int a_file_must_define_something=0; /* ANSI says so */
33 :
34 : #else /* We can build with jpeglib - therefore import jpg files */
35 :
36 : #include <basics.h>
37 : #include <sys/types.h>
38 : #include <stdio.h>
39 : #include <jpeglib.h>
40 : #include <jerror.h>
41 : #include <setjmp.h>
42 : #include "gimage.h"
43 :
44 : /******************************************************************************/
45 :
46 : struct jpegState {
47 : struct jpeg_decompress_struct *cinfo;
48 : int state;
49 : struct _GImage *base;
50 : JSAMPLE *buffer;
51 : int scanpos;
52 : };
53 :
54 : struct my_error_mgr {
55 : struct jpeg_error_mgr pub; /* "public" fields */
56 :
57 : jmp_buf setjmp_buffer; /* for return to caller */
58 : int padding[8]; /* On my solaris box jmp_buf is the wrong size */
59 : };
60 :
61 : typedef struct my_error_mgr * my_error_ptr;
62 :
63 : METHODDEF(void)
64 0 : my_error_exit (j_common_ptr cinfo)
65 : {
66 : /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
67 0 : my_error_ptr myerr = (my_error_ptr) cinfo->err;
68 :
69 : /* Always display the message. */
70 : /* We could postpone this until after returning, if we chose. */
71 0 : (*cinfo->err->output_message) (cinfo);
72 :
73 : /* Return control to the setjmp point */
74 0 : longjmp(myerr->setjmp_buffer, 1);
75 : }
76 :
77 : /* jpeg routines use 24 bit pixels, xvt routines pad out to 32 */
78 0 : static void transferBufferToImage(struct jpegState *js,int ypos) {
79 0 : struct jpeg_decompress_struct *cinfo = js->cinfo;
80 : JSAMPLE *pt, *end;
81 : Color *ppt;
82 :
83 0 : ppt = (Color *) (js->base->data+ypos*js->base->bytes_per_line);
84 0 : for ( pt = js->buffer, end = pt+3*cinfo->image_width; pt<end; ) {
85 : register int r,g,b;
86 0 : r = *(pt++); g= *(pt++); b= *(pt++);
87 0 : *(ppt++) = COLOR_CREATE(r,g,b);
88 : }
89 0 : }
90 :
91 0 : GImage *GImageRead_Jpeg(FILE *infile) {
92 : GImage *ret;
93 : struct _GImage *base;
94 : struct jpeg_decompress_struct cinfo;
95 : struct my_error_mgr jerr;
96 : JSAMPLE *rows[1];
97 : struct jpegState js;
98 : int ypos;
99 :
100 :
101 0 : cinfo.err = jpeg_std_error(&jerr.pub);
102 0 : jerr.pub.error_exit = my_error_exit;
103 0 : if (setjmp(jerr.setjmp_buffer)) {
104 0 : jpeg_destroy_decompress(&cinfo);
105 0 : return( NULL );
106 : }
107 :
108 0 : jpeg_CreateDecompress(&cinfo,JPEG_LIB_VERSION,(size_t) sizeof(struct jpeg_decompress_struct));
109 0 : jpeg_stdio_src(&cinfo, infile);
110 0 : (void) jpeg_read_header(&cinfo, TRUE);
111 :
112 0 : if ( cinfo.jpeg_color_space == JCS_GRAYSCALE )
113 0 : cinfo.out_color_space = JCS_RGB;
114 0 : ret = GImageCreate(it_true,cinfo.image_width, cinfo.image_height);
115 0 : if ( ret==NULL ) {
116 0 : jpeg_destroy_decompress(&cinfo);
117 0 : return( NULL );
118 : }
119 0 : base = ret->u.image;
120 :
121 0 : (void) jpeg_start_decompress(&cinfo);
122 0 : rows[0] = (JSAMPLE *) malloc(3*cinfo.image_width);
123 0 : js.cinfo = &cinfo; js.base = base; js.buffer = rows[0];
124 0 : while (cinfo.output_scanline < cinfo.output_height) {
125 0 : ypos = cinfo.output_scanline;
126 0 : (void) jpeg_read_scanlines(&cinfo, rows, 1);
127 0 : transferBufferToImage(&js,ypos);
128 : }
129 :
130 0 : (void) jpeg_finish_decompress(&cinfo);
131 0 : jpeg_destroy_decompress(&cinfo);
132 0 : free(rows[0]);
133 :
134 0 : return( ret );
135 : }
136 :
137 0 : GImage *GImageReadJpeg(char *filename) {
138 : /* Import a jpeg image, else return NULL if error */
139 : GImage *ret;
140 : FILE * infile; /* source file */
141 :
142 0 : if ((infile = fopen(filename, "rb")) == NULL) {
143 0 : fprintf(stderr,"Can't open \"%s\"\n", filename);
144 0 : return( NULL );
145 : }
146 :
147 0 : ret = GImageRead_Jpeg(infile);
148 0 : fclose(infile);
149 0 : return( ret );
150 : }
151 : #endif
|