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