OLD | NEW |
1 /* | 1 /* |
2 * wrbmp.c | 2 * wrbmp.c |
3 * | 3 * |
4 * This file was part of the Independent JPEG Group's software. | 4 * This file was part of the Independent JPEG Group's software: |
5 * Copyright (C) 1994-1996, Thomas G. Lane. | 5 * Copyright (C) 1994-1996, Thomas G. Lane. |
6 * Modifications: | 6 * libjpeg-turbo Modifications: |
7 * Copyright (C) 2013, Linaro Limited. | 7 * Copyright (C) 2013, Linaro Limited. |
8 * Copyright (C) 2014, D. R. Commander. | 8 * Copyright (C) 2014-2015, D. R. Commander. |
9 * For conditions of distribution and use, see the accompanying README file. | 9 * For conditions of distribution and use, see the accompanying README.ijg |
| 10 * file. |
10 * | 11 * |
11 * This file contains routines to write output images in Microsoft "BMP" | 12 * This file contains routines to write output images in Microsoft "BMP" |
12 * format (MS Windows 3.x and OS/2 1.x flavors). | 13 * format (MS Windows 3.x and OS/2 1.x flavors). |
13 * Either 8-bit colormapped or 24-bit full-color format can be written. | 14 * Either 8-bit colormapped or 24-bit full-color format can be written. |
14 * No compression is supported. | 15 * No compression is supported. |
15 * | 16 * |
16 * These routines may need modification for non-Unix environments or | 17 * These routines may need modification for non-Unix environments or |
17 * specialized applications. As they stand, they assume output to | 18 * specialized applications. As they stand, they assume output to |
18 * an ordinary stdio stream. | 19 * an ordinary stdio stream. |
19 * | 20 * |
20 * This code contributed by James Arthur Boucher. | 21 * This code contributed by James Arthur Boucher. |
21 */ | 22 */ |
22 | 23 |
23 #include "cdjpeg.h"» » /* Common decls for cjpeg/djpeg applications */ | 24 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ |
| 25 #include "jconfigint.h" |
24 | 26 |
25 #ifdef BMP_SUPPORTED | 27 #ifdef BMP_SUPPORTED |
26 | 28 |
27 | 29 |
28 /* | 30 /* |
29 * To support 12-bit JPEG data, we'd have to scale output down to 8 bits. | 31 * To support 12-bit JPEG data, we'd have to scale output down to 8 bits. |
30 * This is not yet implemented. | 32 * This is not yet implemented. |
31 */ | 33 */ |
32 | 34 |
33 #if BITS_IN_JSAMPLE != 8 | 35 #if BITS_IN_JSAMPLE != 8 |
34 Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ | 36 Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ |
35 #endif | 37 #endif |
36 | 38 |
37 /* | 39 /* |
38 * Since BMP stores scanlines bottom-to-top, we have to invert the image | 40 * Since BMP stores scanlines bottom-to-top, we have to invert the image |
39 * from JPEG's top-to-bottom order. To do this, we save the outgoing data | 41 * from JPEG's top-to-bottom order. To do this, we save the outgoing data |
40 * in a virtual array during put_pixel_row calls, then actually emit the | 42 * in a virtual array during put_pixel_row calls, then actually emit the |
41 * BMP file during finish_output. The virtual array contains one JSAMPLE per | 43 * BMP file during finish_output. The virtual array contains one JSAMPLE per |
42 * pixel if the output is grayscale or colormapped, three if it is full color. | 44 * pixel if the output is grayscale or colormapped, three if it is full color. |
43 */ | 45 */ |
44 | 46 |
45 /* Private version of data destination object */ | 47 /* Private version of data destination object */ |
46 | 48 |
47 typedef struct { | 49 typedef struct { |
48 struct djpeg_dest_struct pub;»/* public fields */ | 50 struct djpeg_dest_struct pub; /* public fields */ |
49 | 51 |
50 boolean is_os2;» » /* saves the OS2 format request flag */ | 52 boolean is_os2; /* saves the OS2 format request flag */ |
51 | 53 |
52 jvirt_sarray_ptr whole_image;»/* needed to reverse row order */ | 54 jvirt_sarray_ptr whole_image; /* needed to reverse row order */ |
53 JDIMENSION data_width;» /* JSAMPLEs per row */ | 55 JDIMENSION data_width; /* JSAMPLEs per row */ |
54 JDIMENSION row_width;»» /* physical width of one row in the BMP file */ | 56 JDIMENSION row_width; /* physical width of one row in the BMP file */ |
55 int pad_bytes;» » /* number of padding bytes needed per row */ | 57 int pad_bytes; /* number of padding bytes needed per row */ |
56 JDIMENSION cur_output_row;» /* next row# to write to virtual array */ | 58 JDIMENSION cur_output_row; /* next row# to write to virtual array */ |
57 } bmp_dest_struct; | 59 } bmp_dest_struct; |
58 | 60 |
59 typedef bmp_dest_struct * bmp_dest_ptr; | 61 typedef bmp_dest_struct *bmp_dest_ptr; |
60 | 62 |
61 | 63 |
62 /* Forward declarations */ | 64 /* Forward declarations */ |
63 LOCAL(void) write_colormap | 65 LOCAL(void) write_colormap |
64 » JPP((j_decompress_ptr cinfo, bmp_dest_ptr dest, | 66 (j_decompress_ptr cinfo, bmp_dest_ptr dest, int map_colors, |
65 » int map_colors, int map_entry_size)); | 67 int map_entry_size); |
66 | 68 |
67 | 69 |
68 static inline boolean is_big_endian(void) | 70 static INLINE boolean is_big_endian(void) |
69 { | 71 { |
70 int test_value = 1; | 72 int test_value = 1; |
71 if(*(char *)&test_value != 1) | 73 if(*(char *)&test_value != 1) |
72 return TRUE; | 74 return TRUE; |
73 return FALSE; | 75 return FALSE; |
74 } | 76 } |
75 | 77 |
76 | 78 |
77 /* | 79 /* |
78 * Write some pixel data. | 80 * Write some pixel data. |
79 * In this module rows_supplied will always be 1. | 81 * In this module rows_supplied will always be 1. |
80 */ | 82 */ |
81 | 83 |
82 METHODDEF(void) | 84 METHODDEF(void) |
83 put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, | 85 put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, |
84 » » JDIMENSION rows_supplied) | 86 JDIMENSION rows_supplied) |
85 /* This version is for writing 24-bit pixels */ | 87 /* This version is for writing 24-bit pixels */ |
86 { | 88 { |
87 bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; | 89 bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; |
88 JSAMPARRAY image_ptr; | 90 JSAMPARRAY image_ptr; |
89 register JSAMPROW inptr, outptr; | 91 register JSAMPROW inptr, outptr; |
90 register JDIMENSION col; | 92 register JDIMENSION col; |
91 int pad; | 93 int pad; |
92 | 94 |
93 /* Access next row in virtual array */ | 95 /* Access next row in virtual array */ |
94 image_ptr = (*cinfo->mem->access_virt_sarray) | 96 image_ptr = (*cinfo->mem->access_virt_sarray) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 } | 130 } |
129 | 131 |
130 /* Zero out the pad bytes. */ | 132 /* Zero out the pad bytes. */ |
131 pad = dest->pad_bytes; | 133 pad = dest->pad_bytes; |
132 while (--pad >= 0) | 134 while (--pad >= 0) |
133 *outptr++ = 0; | 135 *outptr++ = 0; |
134 } | 136 } |
135 | 137 |
136 METHODDEF(void) | 138 METHODDEF(void) |
137 put_gray_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, | 139 put_gray_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, |
138 » JDIMENSION rows_supplied) | 140 JDIMENSION rows_supplied) |
139 /* This version is for grayscale OR quantized color output */ | 141 /* This version is for grayscale OR quantized color output */ |
140 { | 142 { |
141 bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; | 143 bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; |
142 JSAMPARRAY image_ptr; | 144 JSAMPARRAY image_ptr; |
143 register JSAMPROW inptr, outptr; | 145 register JSAMPROW inptr, outptr; |
144 register JDIMENSION col; | 146 register JDIMENSION col; |
145 int pad; | 147 int pad; |
146 | 148 |
147 /* Access next row in virtual array */ | 149 /* Access next row in virtual array */ |
148 image_ptr = (*cinfo->mem->access_virt_sarray) | 150 image_ptr = (*cinfo->mem->access_virt_sarray) |
149 ((j_common_ptr) cinfo, dest->whole_image, | 151 ((j_common_ptr) cinfo, dest->whole_image, |
150 dest->cur_output_row, (JDIMENSION) 1, TRUE); | 152 dest->cur_output_row, (JDIMENSION) 1, TRUE); |
151 dest->cur_output_row++; | 153 dest->cur_output_row++; |
152 | 154 |
153 /* Transfer data. */ | 155 /* Transfer data. */ |
154 inptr = dest->pub.buffer[0]; | 156 inptr = dest->pub.buffer[0]; |
155 outptr = image_ptr[0]; | 157 outptr = image_ptr[0]; |
156 for (col = cinfo->output_width; col > 0; col--) { | 158 for (col = cinfo->output_width; col > 0; col--) { |
157 *outptr++ = *inptr++;» /* can omit GETJSAMPLE() safely */ | 159 *outptr++ = *inptr++; /* can omit GETJSAMPLE() safely */ |
158 } | 160 } |
159 | 161 |
160 /* Zero out the pad bytes. */ | 162 /* Zero out the pad bytes. */ |
161 pad = dest->pad_bytes; | 163 pad = dest->pad_bytes; |
162 while (--pad >= 0) | 164 while (--pad >= 0) |
163 *outptr++ = 0; | 165 *outptr++ = 0; |
164 } | 166 } |
165 | 167 |
166 | 168 |
167 /* | 169 /* |
(...skipping 16 matching lines...) Expand all Loading... |
184 * First, routines to write the Windows and OS/2 variants of the file header. | 186 * First, routines to write the Windows and OS/2 variants of the file header. |
185 */ | 187 */ |
186 | 188 |
187 LOCAL(void) | 189 LOCAL(void) |
188 write_bmp_header (j_decompress_ptr cinfo, bmp_dest_ptr dest) | 190 write_bmp_header (j_decompress_ptr cinfo, bmp_dest_ptr dest) |
189 /* Write a Windows-style BMP file header, including colormap if needed */ | 191 /* Write a Windows-style BMP file header, including colormap if needed */ |
190 { | 192 { |
191 char bmpfileheader[14]; | 193 char bmpfileheader[14]; |
192 char bmpinfoheader[40]; | 194 char bmpinfoheader[40]; |
193 #define PUT_2B(array,offset,value) \ | 195 #define PUT_2B(array,offset,value) \ |
194 » (array[offset] = (char) ((value) & 0xFF), \ | 196 (array[offset] = (char) ((value) & 0xFF), \ |
195 » array[offset+1] = (char) (((value) >> 8) & 0xFF)) | 197 array[offset+1] = (char) (((value) >> 8) & 0xFF)) |
196 #define PUT_4B(array,offset,value) \ | 198 #define PUT_4B(array,offset,value) \ |
197 » (array[offset] = (char) ((value) & 0xFF), \ | 199 (array[offset] = (char) ((value) & 0xFF), \ |
198 » array[offset+1] = (char) (((value) >> 8) & 0xFF), \ | 200 array[offset+1] = (char) (((value) >> 8) & 0xFF), \ |
199 » array[offset+2] = (char) (((value) >> 16) & 0xFF), \ | 201 array[offset+2] = (char) (((value) >> 16) & 0xFF), \ |
200 » array[offset+3] = (char) (((value) >> 24) & 0xFF)) | 202 array[offset+3] = (char) (((value) >> 24) & 0xFF)) |
201 INT32 headersize, bfSize; | 203 long headersize, bfSize; |
202 int bits_per_pixel, cmap_entries; | 204 int bits_per_pixel, cmap_entries; |
203 | 205 |
204 /* Compute colormap size and total file size */ | 206 /* Compute colormap size and total file size */ |
205 if (cinfo->out_color_space == JCS_RGB) { | 207 if (cinfo->out_color_space == JCS_RGB) { |
206 if (cinfo->quantize_colors) { | 208 if (cinfo->quantize_colors) { |
207 /* Colormapped RGB */ | 209 /* Colormapped RGB */ |
208 bits_per_pixel = 8; | 210 bits_per_pixel = 8; |
209 cmap_entries = 256; | 211 cmap_entries = 256; |
210 } else { | 212 } else { |
211 /* Unquantized, full color RGB */ | 213 /* Unquantized, full color RGB */ |
212 bits_per_pixel = 24; | 214 bits_per_pixel = 24; |
213 cmap_entries = 0; | 215 cmap_entries = 0; |
214 } | 216 } |
215 } else if (cinfo->out_color_space == JCS_RGB565) { | 217 } else if (cinfo->out_color_space == JCS_RGB565) { |
216 bits_per_pixel = 24; | 218 bits_per_pixel = 24; |
217 cmap_entries = 0; | 219 cmap_entries = 0; |
218 } else { | 220 } else { |
219 /* Grayscale output. We need to fake a 256-entry colormap. */ | 221 /* Grayscale output. We need to fake a 256-entry colormap. */ |
220 bits_per_pixel = 8; | 222 bits_per_pixel = 8; |
221 cmap_entries = 256; | 223 cmap_entries = 256; |
222 } | 224 } |
223 /* File size */ | 225 /* File size */ |
224 headersize = 14 + 40 + cmap_entries * 4; /* Header and colormap */ | 226 headersize = 14 + 40 + cmap_entries * 4; /* Header and colormap */ |
225 bfSize = headersize + (INT32) dest->row_width * (INT32) cinfo->output_height; | 227 bfSize = headersize + (long) dest->row_width * (long) cinfo->output_height; |
226 | 228 |
227 /* Set unused fields of header to 0 */ | 229 /* Set unused fields of header to 0 */ |
228 MEMZERO(bmpfileheader, SIZEOF(bmpfileheader)); | 230 MEMZERO(bmpfileheader, sizeof(bmpfileheader)); |
229 MEMZERO(bmpinfoheader, SIZEOF(bmpinfoheader)); | 231 MEMZERO(bmpinfoheader, sizeof(bmpinfoheader)); |
230 | 232 |
231 /* Fill the file header */ | 233 /* Fill the file header */ |
232 bmpfileheader[0] = 0x42;» /* first 2 bytes are ASCII 'B', 'M' */ | 234 bmpfileheader[0] = 0x42; /* first 2 bytes are ASCII 'B', 'M' */ |
233 bmpfileheader[1] = 0x4D; | 235 bmpfileheader[1] = 0x4D; |
234 PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */ | 236 PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */ |
235 /* we leave bfReserved1 & bfReserved2 = 0 */ | 237 /* we leave bfReserved1 & bfReserved2 = 0 */ |
236 PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */ | 238 PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */ |
237 | 239 |
238 /* Fill the info header (Microsoft calls this a BITMAPINFOHEADER) */ | 240 /* Fill the info header (Microsoft calls this a BITMAPINFOHEADER) */ |
239 PUT_2B(bmpinfoheader, 0, 40);»/* biSize */ | 241 PUT_2B(bmpinfoheader, 0, 40); /* biSize */ |
240 PUT_4B(bmpinfoheader, 4, cinfo->output_width); /* biWidth */ | 242 PUT_4B(bmpinfoheader, 4, cinfo->output_width); /* biWidth */ |
241 PUT_4B(bmpinfoheader, 8, cinfo->output_height); /* biHeight */ | 243 PUT_4B(bmpinfoheader, 8, cinfo->output_height); /* biHeight */ |
242 PUT_2B(bmpinfoheader, 12, 1);»/* biPlanes - must be 1 */ | 244 PUT_2B(bmpinfoheader, 12, 1); /* biPlanes - must be 1 */ |
243 PUT_2B(bmpinfoheader, 14, bits_per_pixel); /* biBitCount */ | 245 PUT_2B(bmpinfoheader, 14, bits_per_pixel); /* biBitCount */ |
244 /* we leave biCompression = 0, for none */ | 246 /* we leave biCompression = 0, for none */ |
245 /* we leave biSizeImage = 0; this is correct for uncompressed data */ | 247 /* we leave biSizeImage = 0; this is correct for uncompressed data */ |
246 if (cinfo->density_unit == 2) { /* if have density in dots/cm, then */ | 248 if (cinfo->density_unit == 2) { /* if have density in dots/cm, then */ |
247 PUT_4B(bmpinfoheader, 24, (INT32) (cinfo->X_density*100)); /* XPels/M */ | 249 PUT_4B(bmpinfoheader, 24, (long) (cinfo->X_density*100)); /* XPels/M */ |
248 PUT_4B(bmpinfoheader, 28, (INT32) (cinfo->Y_density*100)); /* XPels/M */ | 250 PUT_4B(bmpinfoheader, 28, (long) (cinfo->Y_density*100)); /* XPels/M */ |
249 } | 251 } |
250 PUT_2B(bmpinfoheader, 32, cmap_entries); /* biClrUsed */ | 252 PUT_2B(bmpinfoheader, 32, cmap_entries); /* biClrUsed */ |
251 /* we leave biClrImportant = 0 */ | 253 /* we leave biClrImportant = 0 */ |
252 | 254 |
253 if (JFWRITE(dest->pub.output_file, bmpfileheader, 14) != (size_t) 14) | 255 if (JFWRITE(dest->pub.output_file, bmpfileheader, 14) != (size_t) 14) |
254 ERREXIT(cinfo, JERR_FILE_WRITE); | 256 ERREXIT(cinfo, JERR_FILE_WRITE); |
255 if (JFWRITE(dest->pub.output_file, bmpinfoheader, 40) != (size_t) 40) | 257 if (JFWRITE(dest->pub.output_file, bmpinfoheader, 40) != (size_t) 40) |
256 ERREXIT(cinfo, JERR_FILE_WRITE); | 258 ERREXIT(cinfo, JERR_FILE_WRITE); |
257 | 259 |
258 if (cmap_entries > 0) | 260 if (cmap_entries > 0) |
259 write_colormap(cinfo, dest, cmap_entries, 4); | 261 write_colormap(cinfo, dest, cmap_entries, 4); |
260 } | 262 } |
261 | 263 |
262 | 264 |
263 LOCAL(void) | 265 LOCAL(void) |
264 write_os2_header (j_decompress_ptr cinfo, bmp_dest_ptr dest) | 266 write_os2_header (j_decompress_ptr cinfo, bmp_dest_ptr dest) |
265 /* Write an OS2-style BMP file header, including colormap if needed */ | 267 /* Write an OS2-style BMP file header, including colormap if needed */ |
266 { | 268 { |
267 char bmpfileheader[14]; | 269 char bmpfileheader[14]; |
268 char bmpcoreheader[12]; | 270 char bmpcoreheader[12]; |
269 INT32 headersize, bfSize; | 271 long headersize, bfSize; |
270 int bits_per_pixel, cmap_entries; | 272 int bits_per_pixel, cmap_entries; |
271 | 273 |
272 /* Compute colormap size and total file size */ | 274 /* Compute colormap size and total file size */ |
273 if (cinfo->out_color_space == JCS_RGB) { | 275 if (cinfo->out_color_space == JCS_RGB) { |
274 if (cinfo->quantize_colors) { | 276 if (cinfo->quantize_colors) { |
275 /* Colormapped RGB */ | 277 /* Colormapped RGB */ |
276 bits_per_pixel = 8; | 278 bits_per_pixel = 8; |
277 cmap_entries = 256; | 279 cmap_entries = 256; |
278 } else { | 280 } else { |
279 /* Unquantized, full color RGB */ | 281 /* Unquantized, full color RGB */ |
280 bits_per_pixel = 24; | 282 bits_per_pixel = 24; |
281 cmap_entries = 0; | 283 cmap_entries = 0; |
282 } | 284 } |
283 } else if (cinfo->out_color_space == JCS_RGB565) { | 285 } else if (cinfo->out_color_space == JCS_RGB565) { |
284 bits_per_pixel = 24; | 286 bits_per_pixel = 24; |
285 cmap_entries = 0; | 287 cmap_entries = 0; |
286 } else { | 288 } else { |
287 /* Grayscale output. We need to fake a 256-entry colormap. */ | 289 /* Grayscale output. We need to fake a 256-entry colormap. */ |
288 bits_per_pixel = 8; | 290 bits_per_pixel = 8; |
289 cmap_entries = 256; | 291 cmap_entries = 256; |
290 } | 292 } |
291 /* File size */ | 293 /* File size */ |
292 headersize = 14 + 12 + cmap_entries * 3; /* Header and colormap */ | 294 headersize = 14 + 12 + cmap_entries * 3; /* Header and colormap */ |
293 bfSize = headersize + (INT32) dest->row_width * (INT32) cinfo->output_height; | 295 bfSize = headersize + (long) dest->row_width * (long) cinfo->output_height; |
294 | 296 |
295 /* Set unused fields of header to 0 */ | 297 /* Set unused fields of header to 0 */ |
296 MEMZERO(bmpfileheader, SIZEOF(bmpfileheader)); | 298 MEMZERO(bmpfileheader, sizeof(bmpfileheader)); |
297 MEMZERO(bmpcoreheader, SIZEOF(bmpcoreheader)); | 299 MEMZERO(bmpcoreheader, sizeof(bmpcoreheader)); |
298 | 300 |
299 /* Fill the file header */ | 301 /* Fill the file header */ |
300 bmpfileheader[0] = 0x42;» /* first 2 bytes are ASCII 'B', 'M' */ | 302 bmpfileheader[0] = 0x42; /* first 2 bytes are ASCII 'B', 'M' */ |
301 bmpfileheader[1] = 0x4D; | 303 bmpfileheader[1] = 0x4D; |
302 PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */ | 304 PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */ |
303 /* we leave bfReserved1 & bfReserved2 = 0 */ | 305 /* we leave bfReserved1 & bfReserved2 = 0 */ |
304 PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */ | 306 PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */ |
305 | 307 |
306 /* Fill the info header (Microsoft calls this a BITMAPCOREHEADER) */ | 308 /* Fill the info header (Microsoft calls this a BITMAPCOREHEADER) */ |
307 PUT_2B(bmpcoreheader, 0, 12);»/* bcSize */ | 309 PUT_2B(bmpcoreheader, 0, 12); /* bcSize */ |
308 PUT_2B(bmpcoreheader, 4, cinfo->output_width); /* bcWidth */ | 310 PUT_2B(bmpcoreheader, 4, cinfo->output_width); /* bcWidth */ |
309 PUT_2B(bmpcoreheader, 6, cinfo->output_height); /* bcHeight */ | 311 PUT_2B(bmpcoreheader, 6, cinfo->output_height); /* bcHeight */ |
310 PUT_2B(bmpcoreheader, 8, 1);» /* bcPlanes - must be 1 */ | 312 PUT_2B(bmpcoreheader, 8, 1); /* bcPlanes - must be 1 */ |
311 PUT_2B(bmpcoreheader, 10, bits_per_pixel); /* bcBitCount */ | 313 PUT_2B(bmpcoreheader, 10, bits_per_pixel); /* bcBitCount */ |
312 | 314 |
313 if (JFWRITE(dest->pub.output_file, bmpfileheader, 14) != (size_t) 14) | 315 if (JFWRITE(dest->pub.output_file, bmpfileheader, 14) != (size_t) 14) |
314 ERREXIT(cinfo, JERR_FILE_WRITE); | 316 ERREXIT(cinfo, JERR_FILE_WRITE); |
315 if (JFWRITE(dest->pub.output_file, bmpcoreheader, 12) != (size_t) 12) | 317 if (JFWRITE(dest->pub.output_file, bmpcoreheader, 12) != (size_t) 12) |
316 ERREXIT(cinfo, JERR_FILE_WRITE); | 318 ERREXIT(cinfo, JERR_FILE_WRITE); |
317 | 319 |
318 if (cmap_entries > 0) | 320 if (cmap_entries > 0) |
319 write_colormap(cinfo, dest, cmap_entries, 3); | 321 write_colormap(cinfo, dest, cmap_entries, 3); |
320 } | 322 } |
321 | 323 |
322 | 324 |
323 /* | 325 /* |
324 * Write the colormap. | 326 * Write the colormap. |
325 * Windows uses BGR0 map entries; OS/2 uses BGR entries. | 327 * Windows uses BGR0 map entries; OS/2 uses BGR entries. |
326 */ | 328 */ |
327 | 329 |
328 LOCAL(void) | 330 LOCAL(void) |
329 write_colormap (j_decompress_ptr cinfo, bmp_dest_ptr dest, | 331 write_colormap (j_decompress_ptr cinfo, bmp_dest_ptr dest, |
330 » » int map_colors, int map_entry_size) | 332 int map_colors, int map_entry_size) |
331 { | 333 { |
332 JSAMPARRAY colormap = cinfo->colormap; | 334 JSAMPARRAY colormap = cinfo->colormap; |
333 int num_colors = cinfo->actual_number_of_colors; | 335 int num_colors = cinfo->actual_number_of_colors; |
334 FILE * outfile = dest->pub.output_file; | 336 FILE *outfile = dest->pub.output_file; |
335 int i; | 337 int i; |
336 | 338 |
337 if (colormap != NULL) { | 339 if (colormap != NULL) { |
338 if (cinfo->out_color_components == 3) { | 340 if (cinfo->out_color_components == 3) { |
339 /* Normal case with RGB colormap */ | 341 /* Normal case with RGB colormap */ |
340 for (i = 0; i < num_colors; i++) { | 342 for (i = 0; i < num_colors; i++) { |
341 » putc(GETJSAMPLE(colormap[2][i]), outfile); | 343 putc(GETJSAMPLE(colormap[2][i]), outfile); |
342 » putc(GETJSAMPLE(colormap[1][i]), outfile); | 344 putc(GETJSAMPLE(colormap[1][i]), outfile); |
343 » putc(GETJSAMPLE(colormap[0][i]), outfile); | 345 putc(GETJSAMPLE(colormap[0][i]), outfile); |
344 » if (map_entry_size == 4) | 346 if (map_entry_size == 4) |
345 » putc(0, outfile); | 347 putc(0, outfile); |
346 } | 348 } |
347 } else { | 349 } else { |
348 /* Grayscale colormap (only happens with grayscale quantization) */ | 350 /* Grayscale colormap (only happens with grayscale quantization) */ |
349 for (i = 0; i < num_colors; i++) { | 351 for (i = 0; i < num_colors; i++) { |
350 » putc(GETJSAMPLE(colormap[0][i]), outfile); | 352 putc(GETJSAMPLE(colormap[0][i]), outfile); |
351 » putc(GETJSAMPLE(colormap[0][i]), outfile); | 353 putc(GETJSAMPLE(colormap[0][i]), outfile); |
352 » putc(GETJSAMPLE(colormap[0][i]), outfile); | 354 putc(GETJSAMPLE(colormap[0][i]), outfile); |
353 » if (map_entry_size == 4) | 355 if (map_entry_size == 4) |
354 » putc(0, outfile); | 356 putc(0, outfile); |
355 } | 357 } |
356 } | 358 } |
357 } else { | 359 } else { |
358 /* If no colormap, must be grayscale data. Generate a linear "map". */ | 360 /* If no colormap, must be grayscale data. Generate a linear "map". */ |
359 for (i = 0; i < 256; i++) { | 361 for (i = 0; i < 256; i++) { |
360 putc(i, outfile); | 362 putc(i, outfile); |
361 putc(i, outfile); | 363 putc(i, outfile); |
362 putc(i, outfile); | 364 putc(i, outfile); |
363 if (map_entry_size == 4) | 365 if (map_entry_size == 4) |
364 » putc(0, outfile); | 366 putc(0, outfile); |
365 } | 367 } |
366 } | 368 } |
367 /* Pad colormap with zeros to ensure specified number of colormap entries */ | 369 /* Pad colormap with zeros to ensure specified number of colormap entries */ |
368 if (i > map_colors) | 370 if (i > map_colors) |
369 ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, i); | 371 ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, i); |
370 for (; i < map_colors; i++) { | 372 for (; i < map_colors; i++) { |
371 putc(0, outfile); | 373 putc(0, outfile); |
372 putc(0, outfile); | 374 putc(0, outfile); |
373 putc(0, outfile); | 375 putc(0, outfile); |
374 if (map_entry_size == 4) | 376 if (map_entry_size == 4) |
375 putc(0, outfile); | 377 putc(0, outfile); |
376 } | 378 } |
377 } | 379 } |
378 | 380 |
379 | 381 |
380 METHODDEF(void) | 382 METHODDEF(void) |
381 finish_output_bmp (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) | 383 finish_output_bmp (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) |
382 { | 384 { |
383 bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; | 385 bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; |
384 register FILE * outfile = dest->pub.output_file; | 386 register FILE *outfile = dest->pub.output_file; |
385 JSAMPARRAY image_ptr; | 387 JSAMPARRAY image_ptr; |
386 register JSAMPROW data_ptr; | 388 register JSAMPROW data_ptr; |
387 JDIMENSION row; | 389 JDIMENSION row; |
388 register JDIMENSION col; | 390 register JDIMENSION col; |
389 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; | 391 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; |
390 | 392 |
391 /* Write the header and colormap */ | 393 /* Write the header and colormap */ |
392 if (dest->is_os2) | 394 if (dest->is_os2) |
393 write_os2_header(cinfo, dest); | 395 write_os2_header(cinfo, dest); |
394 else | 396 else |
(...skipping 30 matching lines...) Expand all Loading... |
425 | 427 |
426 GLOBAL(djpeg_dest_ptr) | 428 GLOBAL(djpeg_dest_ptr) |
427 jinit_write_bmp (j_decompress_ptr cinfo, boolean is_os2) | 429 jinit_write_bmp (j_decompress_ptr cinfo, boolean is_os2) |
428 { | 430 { |
429 bmp_dest_ptr dest; | 431 bmp_dest_ptr dest; |
430 JDIMENSION row_width; | 432 JDIMENSION row_width; |
431 | 433 |
432 /* Create module interface object, fill in method pointers */ | 434 /* Create module interface object, fill in method pointers */ |
433 dest = (bmp_dest_ptr) | 435 dest = (bmp_dest_ptr) |
434 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, | 436 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, |
435 » » » » SIZEOF(bmp_dest_struct)); | 437 sizeof(bmp_dest_struct)); |
436 dest->pub.start_output = start_output_bmp; | 438 dest->pub.start_output = start_output_bmp; |
437 dest->pub.finish_output = finish_output_bmp; | 439 dest->pub.finish_output = finish_output_bmp; |
438 dest->is_os2 = is_os2; | 440 dest->is_os2 = is_os2; |
439 | 441 |
440 if (cinfo->out_color_space == JCS_GRAYSCALE) { | 442 if (cinfo->out_color_space == JCS_GRAYSCALE) { |
441 dest->pub.put_pixel_rows = put_gray_rows; | 443 dest->pub.put_pixel_rows = put_gray_rows; |
442 } else if (cinfo->out_color_space == JCS_RGB) { | 444 } else if (cinfo->out_color_space == JCS_RGB) { |
443 if (cinfo->quantize_colors) | 445 if (cinfo->quantize_colors) |
444 dest->pub.put_pixel_rows = put_gray_rows; | 446 dest->pub.put_pixel_rows = put_gray_rows; |
445 else | 447 else |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 | 484 |
483 /* Create decompressor output buffer. */ | 485 /* Create decompressor output buffer. */ |
484 dest->pub.buffer = (*cinfo->mem->alloc_sarray) | 486 dest->pub.buffer = (*cinfo->mem->alloc_sarray) |
485 ((j_common_ptr) cinfo, JPOOL_IMAGE, row_width, (JDIMENSION) 1); | 487 ((j_common_ptr) cinfo, JPOOL_IMAGE, row_width, (JDIMENSION) 1); |
486 dest->pub.buffer_height = 1; | 488 dest->pub.buffer_height = 1; |
487 | 489 |
488 return (djpeg_dest_ptr) dest; | 490 return (djpeg_dest_ptr) dest; |
489 } | 491 } |
490 | 492 |
491 #endif /* BMP_SUPPORTED */ | 493 #endif /* BMP_SUPPORTED */ |
OLD | NEW |