1 /*
2     Copyright (C) 2002 Jeremy Madea <jeremymadea@mindspring.com>
3 
4     This file is part of jpgtn.
5 
6     Jpgtn is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 
20     Jpgtn is based on two programs: tnpic (distributed with zgv) and gtnpic.
21     The original "gtnpic" program was Copyright (C) 1997      Willie Daniel.
22     The original "tnpic"  program was Copyright (C) 1993-1996 Russell Marks.
23     Both tnpic and gtnpic were distributed under the GNU Public License.
24 */
25 
26 #if HAVE_CONFIG_H
27 #    include <config.h>
28 #endif
29 
30 #include "common.h"
31 #include "jpgtn.h"
32 
33 
34 struct my_error_mgr {
35     struct jpeg_error_mgr pub;  /* "public" fields      */
36     jmp_buf setjmp_buffer;      /* for return to caller */
37 };
38 typedef struct my_error_mgr * my_error_ptr;
39 
my_error_exit(j_common_ptr cinfo)40 static void my_error_exit(j_common_ptr cinfo)
41 {
42     my_error_ptr myerr=(my_error_ptr) cinfo->err;
43     char buf[JMSG_LENGTH_MAX];
44     (*cinfo->err->format_message)(cinfo,buf);
45     longjmp(myerr->setjmp_buffer, 1);
46 }
47 
read_JPEG_file(char * filename,unsigned char ** palette)48 unsigned char *read_JPEG_file(char *filename, unsigned char **palette)
49 {
50     FILE *infile;
51     struct jpeg_decompress_struct cinfo;
52     struct my_error_mgr jerr;
53     int row_stride;
54     unsigned char *image;
55     unsigned char *pal;
56     int f;
57     unsigned char *ptr;
58 
59     image = NULL;
60 
61     if (((*palette) = (unsigned char *)calloc(1,768))==NULL) {
62         return NULL;
63     }
64 
65     pal = *palette;
66 
67     if (NULL == (infile=fopen(filename,"rb"))) {
68         return NULL;
69     }
70 
71     cinfo.err = jpeg_std_error(&jerr.pub);
72     jerr.pub.error_exit = my_error_exit;
73 
74     if (setjmp(jerr.setjmp_buffer)) {
75         jpeg_destroy_decompress(&cinfo);
76         fclose(infile);
77         free(pal);
78         return NULL;
79     }
80 
81     /* Now we can initialize the JPEG decompression object. */
82     jpeg_create_decompress(&cinfo);
83 
84     jpeg_stdio_src(&cinfo,infile);
85 
86     jpeg_read_header(&cinfo,TRUE);
87 
88     /* setup parameters for decompression */
89     cinfo.dct_method=JDCT_ISLOW;
90     cinfo.quantize_colors=TRUE;
91     cinfo.desired_number_of_colors=256;
92     cinfo.two_pass_quantize=TRUE;
93 
94     /* Fix to greys if greyscale. (required to read greyscale JPEGs) */
95     if (cinfo.jpeg_color_space == JCS_GRAYSCALE) {
96 
97         cinfo.out_color_space = JCS_GRAYSCALE;
98         cinfo.desired_number_of_colors = 256;
99         cinfo.quantize_colors = FALSE;
100         cinfo.two_pass_quantize = FALSE;
101 
102         for(f=0;f<256;f++) {
103             pal[f]=pal[256+f]=pal[512+f]=f;
104         }
105     }
106 
107     width = cinfo.image_width;
108     height = cinfo.image_height;
109     image = (unsigned char *)calloc(1,width*height);
110 
111     if (image==NULL) {
112         printf("Out of memory");
113         longjmp(jerr.setjmp_buffer,1);
114     }
115 
116     jpeg_start_decompress(&cinfo);
117 
118     /* read the palette (if greyscale, this has already been done) */
119     if (cinfo.jpeg_color_space != JCS_GRAYSCALE) {
120 
121         for (f=0; f<cinfo.actual_number_of_colors; f++) {
122             pal[    f]=cinfo.colormap[0][f];
123             pal[256+f]=cinfo.colormap[1][f];
124             pal[512+f]=cinfo.colormap[2][f];
125         }
126     }
127 
128     ptr = image;
129     row_stride = width;
130 
131     /* read the image */
132     while (cinfo.output_scanline<height) {
133         jpeg_read_scanlines(&cinfo, &ptr, 1);
134         ptr += row_stride;
135     }
136 
137     jpeg_finish_decompress(&cinfo);
138     jpeg_destroy_decompress(&cinfo);
139     fclose(infile);
140     return image;
141 }
142