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 * Copyright (C) 1994-1996, Thomas G. Lane. | 5 * Copyright (C) 1994-1996, Thomas G. Lane. |
5 * This file is part of the Independent JPEG Group's software. | 6 * Modifications: |
| 7 * Copyright (C) 2013, Linaro Limited. |
| 8 * Copyright (C) 2014, D. R. Commander. |
6 * For conditions of distribution and use, see the accompanying README file. | 9 * For conditions of distribution and use, see the accompanying README file. |
7 * | 10 * |
8 * This file contains routines to write output images in Microsoft "BMP" | 11 * This file contains routines to write output images in Microsoft "BMP" |
9 * format (MS Windows 3.x and OS/2 1.x flavors). | 12 * format (MS Windows 3.x and OS/2 1.x flavors). |
10 * Either 8-bit colormapped or 24-bit full-color format can be written. | 13 * Either 8-bit colormapped or 24-bit full-color format can be written. |
11 * No compression is supported. | 14 * No compression is supported. |
12 * | 15 * |
13 * These routines may need modification for non-Unix environments or | 16 * These routines may need modification for non-Unix environments or |
14 * specialized applications. As they stand, they assume output to | 17 * specialized applications. As they stand, they assume output to |
15 * an ordinary stdio stream. | 18 * an ordinary stdio stream. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 | 58 |
56 typedef bmp_dest_struct * bmp_dest_ptr; | 59 typedef bmp_dest_struct * bmp_dest_ptr; |
57 | 60 |
58 | 61 |
59 /* Forward declarations */ | 62 /* Forward declarations */ |
60 LOCAL(void) write_colormap | 63 LOCAL(void) write_colormap |
61 JPP((j_decompress_ptr cinfo, bmp_dest_ptr dest, | 64 JPP((j_decompress_ptr cinfo, bmp_dest_ptr dest, |
62 int map_colors, int map_entry_size)); | 65 int map_colors, int map_entry_size)); |
63 | 66 |
64 | 67 |
| 68 static inline boolean is_big_endian(void) |
| 69 { |
| 70 int test_value = 1; |
| 71 if(*(char *)&test_value != 1) |
| 72 return TRUE; |
| 73 return FALSE; |
| 74 } |
| 75 |
| 76 |
65 /* | 77 /* |
66 * Write some pixel data. | 78 * Write some pixel data. |
67 * In this module rows_supplied will always be 1. | 79 * In this module rows_supplied will always be 1. |
68 */ | 80 */ |
69 | 81 |
70 METHODDEF(void) | 82 METHODDEF(void) |
71 put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, | 83 put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, |
72 JDIMENSION rows_supplied) | 84 JDIMENSION rows_supplied) |
73 /* This version is for writing 24-bit pixels */ | 85 /* This version is for writing 24-bit pixels */ |
74 { | 86 { |
75 bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; | 87 bmp_dest_ptr dest = (bmp_dest_ptr) dinfo; |
76 JSAMPARRAY image_ptr; | 88 JSAMPARRAY image_ptr; |
77 register JSAMPROW inptr, outptr; | 89 register JSAMPROW inptr, outptr; |
78 register JDIMENSION col; | 90 register JDIMENSION col; |
79 int pad; | 91 int pad; |
80 | 92 |
81 /* Access next row in virtual array */ | 93 /* Access next row in virtual array */ |
82 image_ptr = (*cinfo->mem->access_virt_sarray) | 94 image_ptr = (*cinfo->mem->access_virt_sarray) |
83 ((j_common_ptr) cinfo, dest->whole_image, | 95 ((j_common_ptr) cinfo, dest->whole_image, |
84 dest->cur_output_row, (JDIMENSION) 1, TRUE); | 96 dest->cur_output_row, (JDIMENSION) 1, TRUE); |
85 dest->cur_output_row++; | 97 dest->cur_output_row++; |
86 | 98 |
87 /* Transfer data. Note destination values must be in BGR order | 99 /* Transfer data. Note destination values must be in BGR order |
88 * (even though Microsoft's own documents say the opposite). | 100 * (even though Microsoft's own documents say the opposite). |
89 */ | 101 */ |
90 inptr = dest->pub.buffer[0]; | 102 inptr = dest->pub.buffer[0]; |
91 outptr = image_ptr[0]; | 103 outptr = image_ptr[0]; |
92 for (col = cinfo->output_width; col > 0; col--) { | 104 |
93 outptr[2] = *inptr++;» /* can omit GETJSAMPLE() safely */ | 105 if(cinfo->out_color_space == JCS_RGB565) { |
94 outptr[1] = *inptr++; | 106 boolean big_endian = is_big_endian(); |
95 outptr[0] = *inptr++; | 107 unsigned short *inptr2 = (unsigned short *)inptr; |
96 outptr += 3; | 108 for (col = cinfo->output_width; col > 0; col--) { |
| 109 if (big_endian) { |
| 110 outptr[0] = (*inptr2 >> 5) & 0xF8; |
| 111 outptr[1] = ((*inptr2 << 5) & 0xE0) | ((*inptr2 >> 11) & 0x1C); |
| 112 outptr[2] = *inptr2 & 0xF8; |
| 113 } else { |
| 114 outptr[0] = (*inptr2 << 3) & 0xF8; |
| 115 outptr[1] = (*inptr2 >> 3) & 0xFC; |
| 116 outptr[2] = (*inptr2 >> 8) & 0xF8; |
| 117 } |
| 118 outptr += 3; |
| 119 inptr2++; |
| 120 } |
| 121 } else { |
| 122 for (col = cinfo->output_width; col > 0; col--) { |
| 123 outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */ |
| 124 outptr[1] = *inptr++; |
| 125 outptr[0] = *inptr++; |
| 126 outptr += 3; |
| 127 } |
97 } | 128 } |
98 | 129 |
99 /* Zero out the pad bytes. */ | 130 /* Zero out the pad bytes. */ |
100 pad = dest->pad_bytes; | 131 pad = dest->pad_bytes; |
101 while (--pad >= 0) | 132 while (--pad >= 0) |
102 *outptr++ = 0; | 133 *outptr++ = 0; |
103 } | 134 } |
104 | 135 |
105 METHODDEF(void) | 136 METHODDEF(void) |
106 put_gray_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, | 137 put_gray_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 if (cinfo->out_color_space == JCS_RGB) { | 205 if (cinfo->out_color_space == JCS_RGB) { |
175 if (cinfo->quantize_colors) { | 206 if (cinfo->quantize_colors) { |
176 /* Colormapped RGB */ | 207 /* Colormapped RGB */ |
177 bits_per_pixel = 8; | 208 bits_per_pixel = 8; |
178 cmap_entries = 256; | 209 cmap_entries = 256; |
179 } else { | 210 } else { |
180 /* Unquantized, full color RGB */ | 211 /* Unquantized, full color RGB */ |
181 bits_per_pixel = 24; | 212 bits_per_pixel = 24; |
182 cmap_entries = 0; | 213 cmap_entries = 0; |
183 } | 214 } |
| 215 } else if (cinfo->out_color_space == JCS_RGB565) { |
| 216 bits_per_pixel = 24; |
| 217 cmap_entries = 0; |
184 } else { | 218 } else { |
185 /* Grayscale output. We need to fake a 256-entry colormap. */ | 219 /* Grayscale output. We need to fake a 256-entry colormap. */ |
186 bits_per_pixel = 8; | 220 bits_per_pixel = 8; |
187 cmap_entries = 256; | 221 cmap_entries = 256; |
188 } | 222 } |
189 /* File size */ | 223 /* File size */ |
190 headersize = 14 + 40 + cmap_entries * 4; /* Header and colormap */ | 224 headersize = 14 + 40 + cmap_entries * 4; /* Header and colormap */ |
191 bfSize = headersize + (INT32) dest->row_width * (INT32) cinfo->output_height; | 225 bfSize = headersize + (INT32) dest->row_width * (INT32) cinfo->output_height; |
192 | 226 |
193 /* Set unused fields of header to 0 */ | 227 /* Set unused fields of header to 0 */ |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 if (cinfo->out_color_space == JCS_RGB) { | 273 if (cinfo->out_color_space == JCS_RGB) { |
240 if (cinfo->quantize_colors) { | 274 if (cinfo->quantize_colors) { |
241 /* Colormapped RGB */ | 275 /* Colormapped RGB */ |
242 bits_per_pixel = 8; | 276 bits_per_pixel = 8; |
243 cmap_entries = 256; | 277 cmap_entries = 256; |
244 } else { | 278 } else { |
245 /* Unquantized, full color RGB */ | 279 /* Unquantized, full color RGB */ |
246 bits_per_pixel = 24; | 280 bits_per_pixel = 24; |
247 cmap_entries = 0; | 281 cmap_entries = 0; |
248 } | 282 } |
| 283 } else if (cinfo->out_color_space == JCS_RGB565) { |
| 284 bits_per_pixel = 24; |
| 285 cmap_entries = 0; |
249 } else { | 286 } else { |
250 /* Grayscale output. We need to fake a 256-entry colormap. */ | 287 /* Grayscale output. We need to fake a 256-entry colormap. */ |
251 bits_per_pixel = 8; | 288 bits_per_pixel = 8; |
252 cmap_entries = 256; | 289 cmap_entries = 256; |
253 } | 290 } |
254 /* File size */ | 291 /* File size */ |
255 headersize = 14 + 12 + cmap_entries * 3; /* Header and colormap */ | 292 headersize = 14 + 12 + cmap_entries * 3; /* Header and colormap */ |
256 bfSize = headersize + (INT32) dest->row_width * (INT32) cinfo->output_height; | 293 bfSize = headersize + (INT32) dest->row_width * (INT32) cinfo->output_height; |
257 | 294 |
258 /* Set unused fields of header to 0 */ | 295 /* Set unused fields of header to 0 */ |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 dest->pub.finish_output = finish_output_bmp; | 437 dest->pub.finish_output = finish_output_bmp; |
401 dest->is_os2 = is_os2; | 438 dest->is_os2 = is_os2; |
402 | 439 |
403 if (cinfo->out_color_space == JCS_GRAYSCALE) { | 440 if (cinfo->out_color_space == JCS_GRAYSCALE) { |
404 dest->pub.put_pixel_rows = put_gray_rows; | 441 dest->pub.put_pixel_rows = put_gray_rows; |
405 } else if (cinfo->out_color_space == JCS_RGB) { | 442 } else if (cinfo->out_color_space == JCS_RGB) { |
406 if (cinfo->quantize_colors) | 443 if (cinfo->quantize_colors) |
407 dest->pub.put_pixel_rows = put_gray_rows; | 444 dest->pub.put_pixel_rows = put_gray_rows; |
408 else | 445 else |
409 dest->pub.put_pixel_rows = put_pixel_rows; | 446 dest->pub.put_pixel_rows = put_pixel_rows; |
| 447 } else if(cinfo->out_color_space == JCS_RGB565 ) { |
| 448 dest->pub.put_pixel_rows = put_pixel_rows; |
410 } else { | 449 } else { |
411 ERREXIT(cinfo, JERR_BMP_COLORSPACE); | 450 ERREXIT(cinfo, JERR_BMP_COLORSPACE); |
412 } | 451 } |
413 | 452 |
414 /* Calculate output image dimensions so we can allocate space */ | 453 /* Calculate output image dimensions so we can allocate space */ |
415 jpeg_calc_output_dimensions(cinfo); | 454 jpeg_calc_output_dimensions(cinfo); |
416 | 455 |
417 /* Determine width of rows in the BMP file (padded to 4-byte boundary). */ | 456 /* Determine width of rows in the BMP file (padded to 4-byte boundary). */ |
418 row_width = cinfo->output_width * cinfo->output_components; | 457 if (cinfo->out_color_space == JCS_RGB565) { |
419 dest->data_width = row_width; | 458 row_width = cinfo->output_width * 2; |
420 while ((row_width & 3) != 0) row_width++; | 459 dest->row_width = dest->data_width = cinfo->output_width * 3; |
421 dest->row_width = row_width; | 460 } else { |
422 dest->pad_bytes = (int) (row_width - dest->data_width); | 461 row_width = cinfo->output_width * cinfo->output_components; |
| 462 dest->row_width = dest->data_width = row_width; |
| 463 } |
| 464 while ((dest->row_width & 3) != 0) dest->row_width++; |
| 465 dest->pad_bytes = (int) (dest->row_width - dest->data_width); |
| 466 if (cinfo->out_color_space == JCS_RGB565) { |
| 467 while ((row_width & 3) != 0) row_width++; |
| 468 } else { |
| 469 row_width = dest->row_width; |
| 470 } |
| 471 |
423 | 472 |
424 /* Allocate space for inversion array, prepare for write pass */ | 473 /* Allocate space for inversion array, prepare for write pass */ |
425 dest->whole_image = (*cinfo->mem->request_virt_sarray) | 474 dest->whole_image = (*cinfo->mem->request_virt_sarray) |
426 ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, | 475 ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, |
427 row_width, cinfo->output_height, (JDIMENSION) 1); | 476 dest->row_width, cinfo->output_height, (JDIMENSION) 1); |
428 dest->cur_output_row = 0; | 477 dest->cur_output_row = 0; |
429 if (cinfo->progress != NULL) { | 478 if (cinfo->progress != NULL) { |
430 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; | 479 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; |
431 progress->total_extra_passes++; /* count file input as separate pass */ | 480 progress->total_extra_passes++; /* count file input as separate pass */ |
432 } | 481 } |
433 | 482 |
434 /* Create decompressor output buffer. */ | 483 /* Create decompressor output buffer. */ |
435 dest->pub.buffer = (*cinfo->mem->alloc_sarray) | 484 dest->pub.buffer = (*cinfo->mem->alloc_sarray) |
436 ((j_common_ptr) cinfo, JPOOL_IMAGE, row_width, (JDIMENSION) 1); | 485 ((j_common_ptr) cinfo, JPOOL_IMAGE, row_width, (JDIMENSION) 1); |
437 dest->pub.buffer_height = 1; | 486 dest->pub.buffer_height = 1; |
438 | 487 |
439 return (djpeg_dest_ptr) dest; | 488 return (djpeg_dest_ptr) dest; |
440 } | 489 } |
441 | 490 |
442 #endif /* BMP_SUPPORTED */ | 491 #endif /* BMP_SUPPORTED */ |
OLD | NEW |