/src/libjpeg-turbo.2.0.x/rdtarga.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * rdtarga.c |
3 | | * |
4 | | * This file was part of the Independent JPEG Group's software: |
5 | | * Copyright (C) 1991-1996, Thomas G. Lane. |
6 | | * Modified 2017 by Guido Vollbeding. |
7 | | * libjpeg-turbo Modifications: |
8 | | * Copyright (C) 2018, 2021, D. R. Commander. |
9 | | * For conditions of distribution and use, see the accompanying README.ijg |
10 | | * file. |
11 | | * |
12 | | * This file contains routines to read input images in Targa format. |
13 | | * |
14 | | * These routines may need modification for non-Unix environments or |
15 | | * specialized applications. As they stand, they assume input from |
16 | | * an ordinary stdio stream. They further assume that reading begins |
17 | | * at the start of the file; start_input may need work if the |
18 | | * user interface has already read some data (e.g., to determine that |
19 | | * the file is indeed Targa format). |
20 | | * |
21 | | * Based on code contributed by Lee Daniel Crocker. |
22 | | */ |
23 | | |
24 | | #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ |
25 | | |
26 | | #ifdef TARGA_SUPPORTED |
27 | | |
28 | | |
29 | | /* Macros to deal with unsigned chars as efficiently as compiler allows */ |
30 | | |
31 | | #ifdef HAVE_UNSIGNED_CHAR |
32 | | typedef unsigned char U_CHAR; |
33 | 377M | #define UCH(x) ((int)(x)) |
34 | | #else /* !HAVE_UNSIGNED_CHAR */ |
35 | | #ifdef __CHAR_UNSIGNED__ |
36 | | typedef char U_CHAR; |
37 | | #define UCH(x) ((int)(x)) |
38 | | #else |
39 | | typedef char U_CHAR; |
40 | | #define UCH(x) ((int)(x) & 0xFF) |
41 | | #endif |
42 | | #endif /* HAVE_UNSIGNED_CHAR */ |
43 | | |
44 | | |
45 | | #define ReadOK(file, buffer, len) \ |
46 | 7.76k | (JFREAD(file, buffer, len) == ((size_t)(len))) |
47 | | |
48 | | |
49 | | /* Private version of data source object */ |
50 | | |
51 | | typedef struct _tga_source_struct *tga_source_ptr; |
52 | | |
53 | | typedef struct _tga_source_struct { |
54 | | struct cjpeg_source_struct pub; /* public fields */ |
55 | | |
56 | | j_compress_ptr cinfo; /* back link saves passing separate parm */ |
57 | | |
58 | | JSAMPARRAY colormap; /* Targa colormap (converted to my format) */ |
59 | | |
60 | | jvirt_sarray_ptr whole_image; /* Needed if funny input row order */ |
61 | | JDIMENSION current_row; /* Current logical row number to read */ |
62 | | |
63 | | /* Pointer to routine to extract next Targa pixel from input file */ |
64 | | void (*read_pixel) (tga_source_ptr sinfo); |
65 | | |
66 | | /* Result of read_pixel is delivered here: */ |
67 | | U_CHAR tga_pixel[4]; |
68 | | |
69 | | int pixel_size; /* Bytes per Targa pixel (1 to 4) */ |
70 | | int cmap_length; /* colormap length */ |
71 | | |
72 | | /* State info for reading RLE-coded pixels; both counts must be init to 0 */ |
73 | | int block_count; /* # of pixels remaining in RLE block */ |
74 | | int dup_pixel_count; /* # of times to duplicate previous pixel */ |
75 | | |
76 | | /* This saves the correct pixel-row-expansion method for preload_image */ |
77 | | JDIMENSION (*get_pixel_rows) (j_compress_ptr cinfo, cjpeg_source_ptr sinfo); |
78 | | } tga_source_struct; |
79 | | |
80 | | |
81 | | /* For expanding 5-bit pixel values to 8-bit with best rounding */ |
82 | | |
83 | | static const UINT8 c5to8bits[32] = { |
84 | | 0, 8, 16, 25, 33, 41, 49, 58, |
85 | | 66, 74, 82, 90, 99, 107, 115, 123, |
86 | | 132, 140, 148, 156, 165, 173, 181, 189, |
87 | | 197, 206, 214, 222, 230, 239, 247, 255 |
88 | | }; |
89 | | |
90 | | |
91 | | |
92 | | LOCAL(int) |
93 | | read_byte(tga_source_ptr sinfo) |
94 | | /* Read next byte from Targa file */ |
95 | 20.8M | { |
96 | 20.8M | register FILE *infile = sinfo->pub.input_file; |
97 | 20.8M | register int c; |
98 | | |
99 | 20.8M | if ((c = getc(infile)) == EOF) |
100 | 1.04k | ERREXIT(sinfo->cinfo, JERR_INPUT_EOF); |
101 | 20.8M | return c; |
102 | 20.8M | } |
103 | | |
104 | | |
105 | | LOCAL(void) |
106 | | read_colormap(tga_source_ptr sinfo, int cmaplen, int mapentrysize) |
107 | | /* Read the colormap from a Targa file */ |
108 | 428 | { |
109 | 428 | int i; |
110 | | |
111 | | /* Presently only handles 24-bit BGR format */ |
112 | 428 | if (mapentrysize != 24) |
113 | 36 | ERREXIT(sinfo->cinfo, JERR_TGA_BADCMAP); |
114 | | |
115 | 21.8k | for (i = 0; i < cmaplen; i++) { |
116 | 21.4k | sinfo->colormap[2][i] = (JSAMPLE)read_byte(sinfo); |
117 | 21.4k | sinfo->colormap[1][i] = (JSAMPLE)read_byte(sinfo); |
118 | 21.4k | sinfo->colormap[0][i] = (JSAMPLE)read_byte(sinfo); |
119 | 21.4k | } |
120 | 428 | } |
121 | | |
122 | | |
123 | | /* |
124 | | * read_pixel methods: get a single pixel from Targa file into tga_pixel[] |
125 | | */ |
126 | | |
127 | | METHODDEF(void) |
128 | | read_non_rle_pixel(tga_source_ptr sinfo) |
129 | | /* Read one Targa pixel from the input file; no RLE expansion */ |
130 | 11.0k | { |
131 | 11.0k | register int i; |
132 | | |
133 | 22.6k | for (i = 0; i < sinfo->pixel_size; i++) { |
134 | 11.5k | sinfo->tga_pixel[i] = (U_CHAR)read_byte(sinfo); |
135 | 11.5k | } |
136 | 11.0k | } |
137 | | |
138 | | |
139 | | METHODDEF(void) |
140 | | read_rle_pixel(tga_source_ptr sinfo) |
141 | | /* Read one Targa pixel from the input file, expanding RLE data as needed */ |
142 | 231M | { |
143 | 231M | register int i; |
144 | | |
145 | | /* Duplicate previously read pixel? */ |
146 | 231M | if (sinfo->dup_pixel_count > 0) { |
147 | 218M | sinfo->dup_pixel_count--; |
148 | 218M | return; |
149 | 218M | } |
150 | | |
151 | | /* Time to read RLE block header? */ |
152 | 13.4M | if (--sinfo->block_count < 0) { /* decrement pixels remaining in block */ |
153 | 2.65M | i = read_byte(sinfo); |
154 | 2.65M | if (i & 0x80) { /* Start of duplicate-pixel block? */ |
155 | 1.95M | sinfo->dup_pixel_count = i & 0x7F; /* number of dups after this one */ |
156 | 1.95M | sinfo->block_count = 0; /* then read new block header */ |
157 | 1.95M | } else { |
158 | 702k | sinfo->block_count = i & 0x7F; /* number of pixels after this one */ |
159 | 702k | } |
160 | 2.65M | } |
161 | | |
162 | | /* Read next pixel */ |
163 | 31.6M | for (i = 0; i < sinfo->pixel_size; i++) { |
164 | 18.1M | sinfo->tga_pixel[i] = (U_CHAR)read_byte(sinfo); |
165 | 18.1M | } |
166 | 13.4M | } |
167 | | |
168 | | |
169 | | /* |
170 | | * Read one row of pixels. |
171 | | * |
172 | | * We provide several different versions depending on input file format. |
173 | | */ |
174 | | |
175 | | |
176 | | METHODDEF(JDIMENSION) |
177 | | get_8bit_gray_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
178 | | /* This version is for reading 8-bit grayscale pixels */ |
179 | 630k | { |
180 | 630k | tga_source_ptr source = (tga_source_ptr)sinfo; |
181 | 630k | register JSAMPROW ptr; |
182 | 630k | register JDIMENSION col; |
183 | | |
184 | 630k | ptr = source->pub.buffer[0]; |
185 | 18.0M | for (col = cinfo->image_width; col > 0; col--) { |
186 | 17.4M | (*source->read_pixel) (source); /* Load next pixel into tga_pixel */ |
187 | 17.4M | *ptr++ = (JSAMPLE)UCH(source->tga_pixel[0]); |
188 | 17.4M | } |
189 | 630k | return 1; |
190 | 630k | } |
191 | | |
192 | | METHODDEF(JDIMENSION) |
193 | | get_8bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
194 | | /* This version is for reading 8-bit colormap indexes */ |
195 | 4.20k | { |
196 | 4.20k | tga_source_ptr source = (tga_source_ptr)sinfo; |
197 | 4.20k | register int t; |
198 | 4.20k | register JSAMPROW ptr; |
199 | 4.20k | register JDIMENSION col; |
200 | 4.20k | register JSAMPARRAY colormap = source->colormap; |
201 | 4.20k | int cmaplen = source->cmap_length; |
202 | | |
203 | 4.20k | ptr = source->pub.buffer[0]; |
204 | 71.9M | for (col = cinfo->image_width; col > 0; col--) { |
205 | 71.9M | (*source->read_pixel) (source); /* Load next pixel into tga_pixel */ |
206 | 71.9M | t = UCH(source->tga_pixel[0]); |
207 | 71.9M | if (t >= cmaplen) |
208 | 10 | ERREXIT(cinfo, JERR_TGA_BADPARMS); |
209 | 71.9M | *ptr++ = colormap[0][t]; |
210 | 71.9M | *ptr++ = colormap[1][t]; |
211 | 71.9M | *ptr++ = colormap[2][t]; |
212 | 71.9M | } |
213 | 4.20k | return 1; |
214 | 4.20k | } |
215 | | |
216 | | METHODDEF(JDIMENSION) |
217 | | get_16bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
218 | | /* This version is for reading 16-bit pixels */ |
219 | 5.03M | { |
220 | 5.03M | tga_source_ptr source = (tga_source_ptr)sinfo; |
221 | 5.03M | register int t; |
222 | 5.03M | register JSAMPROW ptr; |
223 | 5.03M | register JDIMENSION col; |
224 | | |
225 | 5.03M | ptr = source->pub.buffer[0]; |
226 | 144M | for (col = cinfo->image_width; col > 0; col--) { |
227 | 139M | (*source->read_pixel) (source); /* Load next pixel into tga_pixel */ |
228 | 139M | t = UCH(source->tga_pixel[0]); |
229 | 139M | t += UCH(source->tga_pixel[1]) << 8; |
230 | | /* We expand 5 bit data to 8 bit sample width. |
231 | | * The format of the 16-bit (LSB first) input word is |
232 | | * xRRRRRGGGGGBBBBB |
233 | | */ |
234 | 139M | ptr[2] = (JSAMPLE)c5to8bits[t & 0x1F]; |
235 | 139M | t >>= 5; |
236 | 139M | ptr[1] = (JSAMPLE)c5to8bits[t & 0x1F]; |
237 | 139M | t >>= 5; |
238 | 139M | ptr[0] = (JSAMPLE)c5to8bits[t & 0x1F]; |
239 | 139M | ptr += 3; |
240 | 139M | } |
241 | 5.03M | return 1; |
242 | 5.03M | } |
243 | | |
244 | | METHODDEF(JDIMENSION) |
245 | | get_24bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
246 | | /* This version is for reading 24-bit pixels */ |
247 | 111k | { |
248 | 111k | tga_source_ptr source = (tga_source_ptr)sinfo; |
249 | 111k | register JSAMPROW ptr; |
250 | 111k | register JDIMENSION col; |
251 | | |
252 | 111k | ptr = source->pub.buffer[0]; |
253 | 3.37M | for (col = cinfo->image_width; col > 0; col--) { |
254 | 3.26M | (*source->read_pixel) (source); /* Load next pixel into tga_pixel */ |
255 | 3.26M | *ptr++ = (JSAMPLE)UCH(source->tga_pixel[2]); /* change BGR to RGB order */ |
256 | 3.26M | *ptr++ = (JSAMPLE)UCH(source->tga_pixel[1]); |
257 | 3.26M | *ptr++ = (JSAMPLE)UCH(source->tga_pixel[0]); |
258 | 3.26M | } |
259 | 111k | return 1; |
260 | 111k | } |
261 | | |
262 | | /* |
263 | | * Targa also defines a 32-bit pixel format with order B,G,R,A. |
264 | | * We presently ignore the attribute byte, so the code for reading |
265 | | * these pixels is identical to the 24-bit routine above. |
266 | | * This works because the actual pixel length is only known to read_pixel. |
267 | | */ |
268 | | |
269 | 240 | #define get_32bit_row get_24bit_row |
270 | | |
271 | | |
272 | | /* |
273 | | * This method is for re-reading the input data in standard top-down |
274 | | * row order. The entire image has already been read into whole_image |
275 | | * with proper conversion of pixel format, but it's in a funny row order. |
276 | | */ |
277 | | |
278 | | METHODDEF(JDIMENSION) |
279 | | get_memory_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
280 | 1.78M | { |
281 | 1.78M | tga_source_ptr source = (tga_source_ptr)sinfo; |
282 | 1.78M | JDIMENSION source_row; |
283 | | |
284 | | /* Compute row of source that maps to current_row of normal order */ |
285 | | /* For now, assume image is bottom-up and not interlaced. */ |
286 | | /* NEEDS WORK to support interlaced images! */ |
287 | 1.78M | source_row = cinfo->image_height - source->current_row - 1; |
288 | | |
289 | | /* Fetch that row from virtual array */ |
290 | 1.78M | source->pub.buffer = (*cinfo->mem->access_virt_sarray) |
291 | 1.78M | ((j_common_ptr)cinfo, source->whole_image, |
292 | 1.78M | source_row, (JDIMENSION)1, FALSE); |
293 | | |
294 | 1.78M | source->current_row++; |
295 | 1.78M | return 1; |
296 | 1.78M | } |
297 | | |
298 | | |
299 | | /* |
300 | | * This method loads the image into whole_image during the first call on |
301 | | * get_pixel_rows. The get_pixel_rows pointer is then adjusted to call |
302 | | * get_memory_row on subsequent calls. |
303 | | */ |
304 | | |
305 | | METHODDEF(JDIMENSION) |
306 | | preload_image(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
307 | 2.03k | { |
308 | 2.03k | tga_source_ptr source = (tga_source_ptr)sinfo; |
309 | 2.03k | JDIMENSION row; |
310 | 2.03k | cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress; |
311 | | |
312 | | /* Read the data into a virtual array in input-file row order. */ |
313 | 1.86M | for (row = 0; row < cinfo->image_height; row++) { |
314 | 1.86M | if (progress != NULL) { |
315 | 0 | progress->pub.pass_counter = (long)row; |
316 | 0 | progress->pub.pass_limit = (long)cinfo->image_height; |
317 | 0 | (*progress->pub.progress_monitor) ((j_common_ptr)cinfo); |
318 | 0 | } |
319 | 1.86M | source->pub.buffer = (*cinfo->mem->access_virt_sarray) |
320 | 1.86M | ((j_common_ptr)cinfo, source->whole_image, row, (JDIMENSION)1, TRUE); |
321 | 1.86M | (*source->get_pixel_rows) (cinfo, sinfo); |
322 | 1.86M | } |
323 | 2.03k | if (progress != NULL) |
324 | 0 | progress->completed_extra_passes++; |
325 | | |
326 | | /* Set up to read from the virtual array in unscrambled order */ |
327 | 2.03k | source->pub.get_pixel_rows = get_memory_row; |
328 | 2.03k | source->current_row = 0; |
329 | | /* And read the first row */ |
330 | 2.03k | return get_memory_row(cinfo, sinfo); |
331 | 2.03k | } |
332 | | |
333 | | |
334 | | /* |
335 | | * Read the file header; return image size and component count. |
336 | | */ |
337 | | |
338 | | METHODDEF(void) |
339 | | start_input_tga(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
340 | 7.76k | { |
341 | 7.76k | tga_source_ptr source = (tga_source_ptr)sinfo; |
342 | 7.76k | U_CHAR targaheader[18]; |
343 | 7.76k | int idlen, cmaptype, subtype, flags, interlace_type, components; |
344 | 7.76k | unsigned int width, height, maplen; |
345 | 7.76k | boolean is_bottom_up; |
346 | | |
347 | 7.76k | #define GET_2B(offset) \ |
348 | 23.7k | ((unsigned int)UCH(targaheader[offset]) + \ |
349 | 23.7k | (((unsigned int)UCH(targaheader[offset + 1])) << 8)) |
350 | | |
351 | 7.76k | if (!ReadOK(source->pub.input_file, targaheader, 18)) |
352 | 1.84k | ERREXIT(cinfo, JERR_INPUT_EOF); |
353 | | |
354 | | /* Pretend "15-bit" pixels are 16-bit --- we ignore attribute bit anyway */ |
355 | 7.76k | if (targaheader[16] == 15) |
356 | 730 | targaheader[16] = 16; |
357 | | |
358 | 7.76k | idlen = UCH(targaheader[0]); |
359 | 7.76k | cmaptype = UCH(targaheader[1]); |
360 | 7.76k | subtype = UCH(targaheader[2]); |
361 | 7.76k | maplen = GET_2B(5); |
362 | 7.76k | width = GET_2B(12); |
363 | 7.76k | height = GET_2B(14); |
364 | 7.76k | source->pixel_size = UCH(targaheader[16]) >> 3; |
365 | 7.76k | flags = UCH(targaheader[17]); /* Image Descriptor byte */ |
366 | | |
367 | 7.76k | is_bottom_up = ((flags & 0x20) == 0); /* bit 5 set => top-down */ |
368 | 7.76k | interlace_type = flags >> 6; /* bits 6/7 are interlace code */ |
369 | | |
370 | 7.76k | if (cmaptype > 1 || /* cmaptype must be 0 or 1 */ |
371 | 7.76k | source->pixel_size < 1 || source->pixel_size > 4 || |
372 | 7.76k | (UCH(targaheader[16]) & 7) != 0 || /* bits/pixel must be multiple of 8 */ |
373 | 7.76k | interlace_type != 0 || /* currently don't allow interlaced image */ |
374 | 7.76k | width == 0 || height == 0) /* image width/height must be non-zero */ |
375 | 2.03k | ERREXIT(cinfo, JERR_TGA_BADPARMS); |
376 | 7.76k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
377 | 7.76k | if (sinfo->max_pixels && |
378 | 7.76k | (unsigned long long)width * height > sinfo->max_pixels) |
379 | 104 | ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); |
380 | 7.76k | #endif |
381 | | |
382 | 7.76k | if (subtype > 8) { |
383 | | /* It's an RLE-coded file */ |
384 | 3.35k | source->read_pixel = read_rle_pixel; |
385 | 3.35k | source->block_count = source->dup_pixel_count = 0; |
386 | 3.35k | subtype -= 8; |
387 | 4.40k | } else { |
388 | | /* Non-RLE file */ |
389 | 4.40k | source->read_pixel = read_non_rle_pixel; |
390 | 4.40k | } |
391 | | |
392 | | /* Now should have subtype 1, 2, or 3 */ |
393 | 7.76k | components = 3; /* until proven different */ |
394 | 7.76k | cinfo->in_color_space = JCS_RGB; |
395 | | |
396 | 7.76k | switch (subtype) { |
397 | 434 | case 1: /* Colormapped image */ |
398 | 434 | if (source->pixel_size == 1 && cmaptype == 1) |
399 | 422 | source->get_pixel_rows = get_8bit_row; |
400 | 12 | else |
401 | 12 | ERREXIT(cinfo, JERR_TGA_BADPARMS); |
402 | 434 | TRACEMS2(cinfo, 1, JTRC_TGA_MAPPED, width, height); |
403 | 434 | break; |
404 | 2.59k | case 2: /* RGB image */ |
405 | 2.59k | switch (source->pixel_size) { |
406 | 2.21k | case 2: |
407 | 2.21k | source->get_pixel_rows = get_16bit_row; |
408 | 2.21k | break; |
409 | 134 | case 3: |
410 | 134 | source->get_pixel_rows = get_24bit_row; |
411 | 134 | break; |
412 | 240 | case 4: |
413 | 240 | source->get_pixel_rows = get_32bit_row; |
414 | 240 | break; |
415 | 6 | default: |
416 | 6 | ERREXIT(cinfo, JERR_TGA_BADPARMS); |
417 | 6 | break; |
418 | 2.59k | } |
419 | 2.58k | TRACEMS2(cinfo, 1, JTRC_TGA, width, height); |
420 | 2.58k | break; |
421 | 740 | case 3: /* Grayscale image */ |
422 | 740 | components = 1; |
423 | 740 | cinfo->in_color_space = JCS_GRAYSCALE; |
424 | 740 | if (source->pixel_size == 1) |
425 | 734 | source->get_pixel_rows = get_8bit_gray_row; |
426 | 6 | else |
427 | 6 | ERREXIT(cinfo, JERR_TGA_BADPARMS); |
428 | 740 | TRACEMS2(cinfo, 1, JTRC_TGA_GRAY, width, height); |
429 | 740 | break; |
430 | 18 | default: |
431 | 18 | ERREXIT(cinfo, JERR_TGA_BADPARMS); |
432 | 18 | break; |
433 | 7.76k | } |
434 | | |
435 | 3.74k | if (is_bottom_up) { |
436 | | /* Create a virtual array to buffer the upside-down image. */ |
437 | 2.44k | source->whole_image = (*cinfo->mem->request_virt_sarray) |
438 | 2.44k | ((j_common_ptr)cinfo, JPOOL_IMAGE, FALSE, |
439 | 2.44k | (JDIMENSION)width * components, (JDIMENSION)height, (JDIMENSION)1); |
440 | 2.44k | if (cinfo->progress != NULL) { |
441 | 0 | cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress; |
442 | 0 | progress->total_extra_passes++; /* count file input as separate pass */ |
443 | 0 | } |
444 | | /* source->pub.buffer will point to the virtual array. */ |
445 | 2.44k | source->pub.buffer_height = 1; /* in case anyone looks at it */ |
446 | 2.44k | source->pub.get_pixel_rows = preload_image; |
447 | 2.44k | } else { |
448 | | /* Don't need a virtual array, but do need a one-row input buffer. */ |
449 | 1.29k | source->whole_image = NULL; |
450 | 1.29k | source->pub.buffer = (*cinfo->mem->alloc_sarray) |
451 | 1.29k | ((j_common_ptr)cinfo, JPOOL_IMAGE, |
452 | 1.29k | (JDIMENSION)width * components, (JDIMENSION)1); |
453 | 1.29k | source->pub.buffer_height = 1; |
454 | 1.29k | source->pub.get_pixel_rows = source->get_pixel_rows; |
455 | 1.29k | } |
456 | | |
457 | 11.4k | while (idlen--) /* Throw away ID field */ |
458 | 7.75k | (void)read_byte(source); |
459 | | |
460 | 3.74k | if (maplen > 0) { |
461 | 532 | if (maplen > 256 || GET_2B(3) != 0) |
462 | 104 | ERREXIT(cinfo, JERR_TGA_BADCMAP); |
463 | | /* Allocate space to store the colormap */ |
464 | 532 | source->colormap = (*cinfo->mem->alloc_sarray) |
465 | 532 | ((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)maplen, (JDIMENSION)3); |
466 | 532 | source->cmap_length = (int)maplen; |
467 | | /* and read it from the file */ |
468 | 532 | read_colormap(source, (int)maplen, UCH(targaheader[7])); |
469 | 3.20k | } else { |
470 | 3.20k | if (cmaptype) /* but you promised a cmap! */ |
471 | 6 | ERREXIT(cinfo, JERR_TGA_BADPARMS); |
472 | 3.20k | source->colormap = NULL; |
473 | 3.20k | source->cmap_length = 0; |
474 | 3.20k | } |
475 | | |
476 | 3.74k | cinfo->input_components = components; |
477 | 3.74k | cinfo->data_precision = 8; |
478 | 3.74k | cinfo->image_width = width; |
479 | 3.74k | cinfo->image_height = height; |
480 | 3.74k | } |
481 | | |
482 | | |
483 | | /* |
484 | | * Finish up at the end of the file. |
485 | | */ |
486 | | |
487 | | METHODDEF(void) |
488 | | finish_input_tga(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
489 | 2.18k | { |
490 | | /* no work */ |
491 | 2.18k | } |
492 | | |
493 | | |
494 | | /* |
495 | | * The module selection routine for Targa format input. |
496 | | */ |
497 | | |
498 | | GLOBAL(cjpeg_source_ptr) |
499 | | jinit_read_targa(j_compress_ptr cinfo) |
500 | 7.76k | { |
501 | 7.76k | tga_source_ptr source; |
502 | | |
503 | | /* Create module interface object */ |
504 | 7.76k | source = (tga_source_ptr) |
505 | 7.76k | (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, |
506 | 7.76k | sizeof(tga_source_struct)); |
507 | 7.76k | source->cinfo = cinfo; /* make back link for subroutines */ |
508 | | /* Fill in method ptrs, except get_pixel_rows which start_input sets */ |
509 | 7.76k | source->pub.start_input = start_input_tga; |
510 | 7.76k | source->pub.finish_input = finish_input_tga; |
511 | 7.76k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
512 | 7.76k | source->pub.max_pixels = 0; |
513 | 7.76k | #endif |
514 | | |
515 | 7.76k | return (cjpeg_source_ptr)source; |
516 | 7.76k | } |
517 | | |
518 | | #endif /* TARGA_SUPPORTED */ |