| 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 |