4 * This file was part of the Independent JPEG Group's software:
5 * Copyright (C) 1994-1996, Thomas G. Lane.
6 * Modified 2009-2017 by Guido Vollbeding.
7 * libjpeg-turbo Modifications:
8 * Modified 2011 by Siarhei Siamashka.
9 * Copyright (C) 2015, 2017-2018, D. R. Commander.
10 * For conditions of distribution and use, see the accompanying README.ijg
13 * This file contains routines to read input images in Microsoft "BMP"
14 * format (MS Windows 3.x, OS/2 1.x, and OS/2 2.x flavors).
15 * Currently, only 8-bit and 24-bit images are supported, not 1-bit or
16 * 4-bit (feeding such low-depth images into JPEG would be silly anyway).
17 * Also, we don't support RLE-compressed files.
19 * These routines may need modification for non-Unix environments or
20 * specialized applications. As they stand, they assume input from
21 * an ordinary stdio stream. They further assume that reading begins
22 * at the start of the file; start_input may need work if the
23 * user interface has already read some data (e.g., to determine that
24 * the file is indeed BMP format).
26 * This code contributed by James Arthur Boucher.
30 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
35 /* Macros to deal with unsigned chars as efficiently as compiler allows */
37 #ifdef HAVE_UNSIGNED_CHAR
38 typedef unsigned char U_CHAR;
39 #define UCH(x) ((int)(x))
40 #else /* !HAVE_UNSIGNED_CHAR */
41 #ifdef __CHAR_UNSIGNED__
43 #define UCH(x) ((int)(x))
46 #define UCH(x) ((int)(x) & 0xFF)
48 #endif /* HAVE_UNSIGNED_CHAR */
51 #define ReadOK(file, buffer, len) \
52 (JFREAD(file, buffer, len) == ((size_t)(len)))
54 static int alpha_index[JPEG_NUMCS] = {
55 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0, -1
59 /* Private version of data source object */
61 typedef struct _bmp_source_struct *bmp_source_ptr;
63 typedef struct _bmp_source_struct {
64 struct cjpeg_source_struct pub; /* public fields */
66 j_compress_ptr cinfo; /* back link saves passing separate parm */
68 JSAMPARRAY colormap; /* BMP colormap (converted to my format) */
70 jvirt_sarray_ptr whole_image; /* Needed to reverse row order */
71 JDIMENSION source_row; /* Current source row number */
72 JDIMENSION row_width; /* Physical width of scanlines in file */
74 int bits_per_pixel; /* remembers 8- or 24-bit format */
75 int cmap_length; /* colormap length */
77 boolean use_inversion_array; /* TRUE = preload the whole image, which is
78 stored in bottom-up order, and feed it to
79 the calling program in top-down order
81 FALSE = the calling program will maintain
82 its own image buffer and read the rows in
85 U_CHAR *iobuffer; /* I/O buffer (used to buffer a single row from
86 disk if use_inversion_array == FALSE) */
91 read_byte(bmp_source_ptr sinfo)
92 /* Read next byte from BMP file */
94 register FILE *infile = sinfo->pub.input_file;
97 if ((c = getc(infile)) == EOF)
98 ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
104 read_colormap(bmp_source_ptr sinfo, int cmaplen, int mapentrysize)
105 /* Read the colormap from a BMP file */
109 switch (mapentrysize) {
111 /* BGR format (occurs in OS/2 files) */
112 for (i = 0; i < cmaplen; i++) {
113 sinfo->colormap[2][i] = (JSAMPLE)read_byte(sinfo);
114 sinfo->colormap[1][i] = (JSAMPLE)read_byte(sinfo);
115 sinfo->colormap[0][i] = (JSAMPLE)read_byte(sinfo);
116 if (sinfo->colormap[2][i] != sinfo->colormap[1][i] ||
117 sinfo->colormap[1][i] != sinfo->colormap[0][i])
122 /* BGR0 format (occurs in MS Windows files) */
123 for (i = 0; i < cmaplen; i++) {
124 sinfo->colormap[2][i] = (JSAMPLE)read_byte(sinfo);
125 sinfo->colormap[1][i] = (JSAMPLE)read_byte(sinfo);
126 sinfo->colormap[0][i] = (JSAMPLE)read_byte(sinfo);
127 (void)read_byte(sinfo);
128 if (sinfo->colormap[2][i] != sinfo->colormap[1][i] ||
129 sinfo->colormap[1][i] != sinfo->colormap[0][i])
134 ERREXIT(sinfo->cinfo, JERR_BMP_BADCMAP);
138 if (sinfo->cinfo->in_color_space == JCS_UNKNOWN && gray)
139 sinfo->cinfo->in_color_space = JCS_GRAYSCALE;
141 if (sinfo->cinfo->in_color_space == JCS_GRAYSCALE && !gray)
142 ERREXIT(sinfo->cinfo, JERR_BAD_IN_COLORSPACE);
147 * Read one row of pixels.
148 * The image has been read into the whole_image array, but is otherwise
149 * unprocessed. We must read it out in top-to-bottom row order, and if
150 * it is an 8-bit image, we must expand colormapped pixels to 24bit format.
153 METHODDEF(JDIMENSION)
154 get_8bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
155 /* This version is for reading 8-bit colormap indexes */
157 bmp_source_ptr source = (bmp_source_ptr)sinfo;
158 register JSAMPARRAY colormap = source->colormap;
159 int cmaplen = source->cmap_length;
160 JSAMPARRAY image_ptr;
162 register JSAMPROW inptr, outptr;
163 register JDIMENSION col;
165 if (source->use_inversion_array) {
166 /* Fetch next row from virtual array */
167 source->source_row--;
168 image_ptr = (*cinfo->mem->access_virt_sarray)
169 ((j_common_ptr)cinfo, source->whole_image,
170 source->source_row, (JDIMENSION)1, FALSE);
171 inptr = image_ptr[0];
173 if (!ReadOK(source->pub.input_file, source->iobuffer, source->row_width))
174 ERREXIT(cinfo, JERR_INPUT_EOF);
175 inptr = source->iobuffer;
178 /* Expand the colormap indexes to real data */
179 outptr = source->pub.buffer[0];
180 if (cinfo->in_color_space == JCS_GRAYSCALE) {
181 for (col = cinfo->image_width; col > 0; col--) {
182 t = GETJSAMPLE(*inptr++);
184 ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
185 *outptr++ = colormap[0][t];
187 } else if (cinfo->in_color_space == JCS_CMYK) {
188 for (col = cinfo->image_width; col > 0; col--) {
189 t = GETJSAMPLE(*inptr++);
191 ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
192 rgb_to_cmyk(colormap[0][t], colormap[1][t], colormap[2][t], outptr,
193 outptr + 1, outptr + 2, outptr + 3);
197 register int rindex = rgb_red[cinfo->in_color_space];
198 register int gindex = rgb_green[cinfo->in_color_space];
199 register int bindex = rgb_blue[cinfo->in_color_space];
200 register int aindex = alpha_index[cinfo->in_color_space];
201 register int ps = rgb_pixelsize[cinfo->in_color_space];
204 for (col = cinfo->image_width; col > 0; col--) {
205 t = GETJSAMPLE(*inptr++);
207 ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
208 outptr[rindex] = colormap[0][t];
209 outptr[gindex] = colormap[1][t];
210 outptr[bindex] = colormap[2][t];
211 outptr[aindex] = 0xFF;
215 for (col = cinfo->image_width; col > 0; col--) {
216 t = GETJSAMPLE(*inptr++);
218 ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
219 outptr[rindex] = colormap[0][t];
220 outptr[gindex] = colormap[1][t];
221 outptr[bindex] = colormap[2][t];
231 METHODDEF(JDIMENSION)
232 get_24bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
233 /* This version is for reading 24-bit pixels */
235 bmp_source_ptr source = (bmp_source_ptr)sinfo;
236 JSAMPARRAY image_ptr;
237 register JSAMPROW inptr, outptr;
238 register JDIMENSION col;
240 if (source->use_inversion_array) {
241 /* Fetch next row from virtual array */
242 source->source_row--;
243 image_ptr = (*cinfo->mem->access_virt_sarray)
244 ((j_common_ptr)cinfo, source->whole_image,
245 source->source_row, (JDIMENSION)1, FALSE);
246 inptr = image_ptr[0];
248 if (!ReadOK(source->pub.input_file, source->iobuffer, source->row_width))
249 ERREXIT(cinfo, JERR_INPUT_EOF);
250 inptr = source->iobuffer;
253 /* Transfer data. Note source values are in BGR order
254 * (even though Microsoft's own documents say the opposite).
256 outptr = source->pub.buffer[0];
257 if (cinfo->in_color_space == JCS_EXT_BGR) {
258 MEMCOPY(outptr, inptr, source->row_width);
259 } else if (cinfo->in_color_space == JCS_CMYK) {
260 for (col = cinfo->image_width; col > 0; col--) {
261 /* can omit GETJSAMPLE() safely */
262 JSAMPLE b = *inptr++, g = *inptr++, r = *inptr++;
263 rgb_to_cmyk(r, g, b, outptr, outptr + 1, outptr + 2, outptr + 3);
267 register int rindex = rgb_red[cinfo->in_color_space];
268 register int gindex = rgb_green[cinfo->in_color_space];
269 register int bindex = rgb_blue[cinfo->in_color_space];
270 register int aindex = alpha_index[cinfo->in_color_space];
271 register int ps = rgb_pixelsize[cinfo->in_color_space];
274 for (col = cinfo->image_width; col > 0; col--) {
275 outptr[bindex] = *inptr++; /* can omit GETJSAMPLE() safely */
276 outptr[gindex] = *inptr++;
277 outptr[rindex] = *inptr++;
278 outptr[aindex] = 0xFF;
282 for (col = cinfo->image_width; col > 0; col--) {
283 outptr[bindex] = *inptr++; /* can omit GETJSAMPLE() safely */
284 outptr[gindex] = *inptr++;
285 outptr[rindex] = *inptr++;
295 METHODDEF(JDIMENSION)
296 get_32bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
297 /* This version is for reading 32-bit pixels */
299 bmp_source_ptr source = (bmp_source_ptr)sinfo;
300 JSAMPARRAY image_ptr;
301 register JSAMPROW inptr, outptr;
302 register JDIMENSION col;
304 if (source->use_inversion_array) {
305 /* Fetch next row from virtual array */
306 source->source_row--;
307 image_ptr = (*cinfo->mem->access_virt_sarray)
308 ((j_common_ptr)cinfo, source->whole_image,
309 source->source_row, (JDIMENSION)1, FALSE);
310 inptr = image_ptr[0];
312 if (!ReadOK(source->pub.input_file, source->iobuffer, source->row_width))
313 ERREXIT(cinfo, JERR_INPUT_EOF);
314 inptr = source->iobuffer;
317 /* Transfer data. Note source values are in BGR order
318 * (even though Microsoft's own documents say the opposite).
320 outptr = source->pub.buffer[0];
321 if (cinfo->in_color_space == JCS_EXT_BGRX ||
322 cinfo->in_color_space == JCS_EXT_BGRA) {
323 MEMCOPY(outptr, inptr, source->row_width);
324 } else if (cinfo->in_color_space == JCS_CMYK) {
325 for (col = cinfo->image_width; col > 0; col--) {
326 /* can omit GETJSAMPLE() safely */
327 JSAMPLE b = *inptr++, g = *inptr++, r = *inptr++;
328 rgb_to_cmyk(r, g, b, outptr, outptr + 1, outptr + 2, outptr + 3);
329 inptr++; /* skip the 4th byte (Alpha channel) */
333 register int rindex = rgb_red[cinfo->in_color_space];
334 register int gindex = rgb_green[cinfo->in_color_space];
335 register int bindex = rgb_blue[cinfo->in_color_space];
336 register int aindex = alpha_index[cinfo->in_color_space];
337 register int ps = rgb_pixelsize[cinfo->in_color_space];
340 for (col = cinfo->image_width; col > 0; col--) {
341 outptr[bindex] = *inptr++; /* can omit GETJSAMPLE() safely */
342 outptr[gindex] = *inptr++;
343 outptr[rindex] = *inptr++;
344 outptr[aindex] = *inptr++;
348 for (col = cinfo->image_width; col > 0; col--) {
349 outptr[bindex] = *inptr++; /* can omit GETJSAMPLE() safely */
350 outptr[gindex] = *inptr++;
351 outptr[rindex] = *inptr++;
352 inptr++; /* skip the 4th byte (Alpha channel) */
363 * This method loads the image into whole_image during the first call on
364 * get_pixel_rows. The get_pixel_rows pointer is then adjusted to call
365 * get_8bit_row, get_24bit_row, or get_32bit_row on subsequent calls.
368 METHODDEF(JDIMENSION)
369 preload_image(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
371 bmp_source_ptr source = (bmp_source_ptr)sinfo;
372 register FILE *infile = source->pub.input_file;
373 register JSAMPROW out_ptr;
374 JSAMPARRAY image_ptr;
376 cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;
378 /* Read the data into a virtual array in input-file row order. */
379 for (row = 0; row < cinfo->image_height; row++) {
380 if (progress != NULL) {
381 progress->pub.pass_counter = (long)row;
382 progress->pub.pass_limit = (long)cinfo->image_height;
383 (*progress->pub.progress_monitor) ((j_common_ptr)cinfo);
385 image_ptr = (*cinfo->mem->access_virt_sarray)
386 ((j_common_ptr)cinfo, source->whole_image, row, (JDIMENSION)1, TRUE);
387 out_ptr = image_ptr[0];
388 if (fread(out_ptr, 1, source->row_width, infile) != source->row_width) {
390 ERREXIT(cinfo, JERR_INPUT_EOF);
392 ERREXIT(cinfo, JERR_FILE_READ);
395 if (progress != NULL)
396 progress->completed_extra_passes++;
398 /* Set up to read from the virtual array in top-to-bottom order */
399 switch (source->bits_per_pixel) {
401 source->pub.get_pixel_rows = get_8bit_row;
404 source->pub.get_pixel_rows = get_24bit_row;
407 source->pub.get_pixel_rows = get_32bit_row;
410 ERREXIT(cinfo, JERR_BMP_BADDEPTH);
412 source->source_row = cinfo->image_height;
414 /* And read the first row */
415 return (*source->pub.get_pixel_rows) (cinfo, sinfo);
420 * Read the file header; return image size and component count.
424 start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
426 bmp_source_ptr source = (bmp_source_ptr)sinfo;
427 U_CHAR bmpfileheader[14];
428 U_CHAR bmpinfoheader[64];
430 #define GET_2B(array, offset) \
431 ((unsigned short)UCH(array[offset]) + \
432 (((unsigned short)UCH(array[offset + 1])) << 8))
433 #define GET_4B(array, offset) \
434 ((unsigned int)UCH(array[offset]) + \
435 (((unsigned int)UCH(array[offset + 1])) << 8) + \
436 (((unsigned int)UCH(array[offset + 2])) << 16) + \
437 (((unsigned int)UCH(array[offset + 3])) << 24))
439 unsigned int bfOffBits;
440 unsigned int headerSize;
443 unsigned short biPlanes;
444 unsigned int biCompression;
445 int biXPelsPerMeter, biYPelsPerMeter;
446 unsigned int biClrUsed = 0;
447 int mapentrysize = 0; /* 0 indicates no colormap */
449 JDIMENSION row_width = 0;
451 /* Read and verify the bitmap file header */
452 if (!ReadOK(source->pub.input_file, bmpfileheader, 14))
453 ERREXIT(cinfo, JERR_INPUT_EOF);
454 if (GET_2B(bmpfileheader, 0) != 0x4D42) /* 'BM' */
455 ERREXIT(cinfo, JERR_BMP_NOT);
456 bfOffBits = GET_4B(bmpfileheader, 10);
457 /* We ignore the remaining fileheader fields */
459 /* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows),
460 * or 64 bytes (OS/2 2.x). Check the first 4 bytes to find out which.
462 if (!ReadOK(source->pub.input_file, bmpinfoheader, 4))
463 ERREXIT(cinfo, JERR_INPUT_EOF);
464 headerSize = GET_4B(bmpinfoheader, 0);
465 if (headerSize < 12 || headerSize > 64)
466 ERREXIT(cinfo, JERR_BMP_BADHEADER);
467 if (!ReadOK(source->pub.input_file, bmpinfoheader + 4, headerSize - 4))
468 ERREXIT(cinfo, JERR_INPUT_EOF);
470 switch (headerSize) {
472 /* Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) */
473 biWidth = (int)GET_2B(bmpinfoheader, 4);
474 biHeight = (int)GET_2B(bmpinfoheader, 6);
475 biPlanes = GET_2B(bmpinfoheader, 8);
476 source->bits_per_pixel = (int)GET_2B(bmpinfoheader, 10);
478 switch (source->bits_per_pixel) {
479 case 8: /* colormapped image */
480 mapentrysize = 3; /* OS/2 uses RGBTRIPLE colormap */
481 TRACEMS2(cinfo, 1, JTRC_BMP_OS2_MAPPED, biWidth, biHeight);
483 case 24: /* RGB image */
484 TRACEMS2(cinfo, 1, JTRC_BMP_OS2, biWidth, biHeight);
487 ERREXIT(cinfo, JERR_BMP_BADDEPTH);
493 /* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */
494 /* or OS/2 2.x header, which has additional fields that we ignore */
495 biWidth = (int)GET_4B(bmpinfoheader, 4);
496 biHeight = (int)GET_4B(bmpinfoheader, 8);
497 biPlanes = GET_2B(bmpinfoheader, 12);
498 source->bits_per_pixel = (int)GET_2B(bmpinfoheader, 14);
499 biCompression = GET_4B(bmpinfoheader, 16);
500 biXPelsPerMeter = (int)GET_4B(bmpinfoheader, 24);
501 biYPelsPerMeter = (int)GET_4B(bmpinfoheader, 28);
502 biClrUsed = GET_4B(bmpinfoheader, 32);
503 /* biSizeImage, biClrImportant fields are ignored */
505 switch (source->bits_per_pixel) {
506 case 8: /* colormapped image */
507 mapentrysize = 4; /* Windows uses RGBQUAD colormap */
508 TRACEMS2(cinfo, 1, JTRC_BMP_MAPPED, biWidth, biHeight);
510 case 24: /* RGB image */
511 TRACEMS2(cinfo, 1, JTRC_BMP, biWidth, biHeight);
513 case 32: /* RGB image + Alpha channel */
514 TRACEMS2(cinfo, 1, JTRC_BMP, biWidth, biHeight);
517 ERREXIT(cinfo, JERR_BMP_BADDEPTH);
520 if (biCompression != 0)
521 ERREXIT(cinfo, JERR_BMP_COMPRESSED);
523 if (biXPelsPerMeter > 0 && biYPelsPerMeter > 0) {
524 /* Set JFIF density parameters from the BMP data */
525 cinfo->X_density = (UINT16)(biXPelsPerMeter / 100); /* 100 cm per meter */
526 cinfo->Y_density = (UINT16)(biYPelsPerMeter / 100);
527 cinfo->density_unit = 2; /* dots/cm */
531 ERREXIT(cinfo, JERR_BMP_BADHEADER);
535 if (biWidth <= 0 || biHeight <= 0)
536 ERREXIT(cinfo, JERR_BMP_EMPTY);
538 ERREXIT(cinfo, JERR_BMP_BADPLANES);
540 /* Compute distance to bitmap data --- will adjust for colormap below */
541 bPad = bfOffBits - (headerSize + 14);
543 /* Read the colormap, if any */
544 if (mapentrysize > 0) {
546 biClrUsed = 256; /* assume it's 256 */
547 else if (biClrUsed > 256)
548 ERREXIT(cinfo, JERR_BMP_BADCMAP);
549 /* Allocate space to store the colormap */
550 source->colormap = (*cinfo->mem->alloc_sarray)
551 ((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)biClrUsed, (JDIMENSION)3);
552 source->cmap_length = (int)biClrUsed;
553 /* and read it from the file */
554 read_colormap(source, (int)biClrUsed, mapentrysize);
555 /* account for size of colormap */
556 bPad -= biClrUsed * mapentrysize;
559 /* Skip any remaining pad bytes */
560 if (bPad < 0) /* incorrect bfOffBits value? */
561 ERREXIT(cinfo, JERR_BMP_BADHEADER);
562 while (--bPad >= 0) {
563 (void)read_byte(source);
566 /* Compute row width in file, including padding to 4-byte boundary */
567 switch (source->bits_per_pixel) {
569 if (cinfo->in_color_space == JCS_UNKNOWN)
570 cinfo->in_color_space = JCS_EXT_RGB;
571 if (IsExtRGB(cinfo->in_color_space))
572 cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
573 else if (cinfo->in_color_space == JCS_GRAYSCALE)
574 cinfo->input_components = 1;
575 else if (cinfo->in_color_space == JCS_CMYK)
576 cinfo->input_components = 4;
578 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
579 row_width = (JDIMENSION)biWidth;
582 if (cinfo->in_color_space == JCS_UNKNOWN)
583 cinfo->in_color_space = JCS_EXT_BGR;
584 if (IsExtRGB(cinfo->in_color_space))
585 cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
586 else if (cinfo->in_color_space == JCS_CMYK)
587 cinfo->input_components = 4;
589 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
590 row_width = (JDIMENSION)(biWidth * 3);
593 if (cinfo->in_color_space == JCS_UNKNOWN)
594 cinfo->in_color_space = JCS_EXT_BGRA;
595 if (IsExtRGB(cinfo->in_color_space))
596 cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
597 else if (cinfo->in_color_space == JCS_CMYK)
598 cinfo->input_components = 4;
600 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
601 row_width = (JDIMENSION)(biWidth * 4);
604 ERREXIT(cinfo, JERR_BMP_BADDEPTH);
606 while ((row_width & 3) != 0) row_width++;
607 source->row_width = row_width;
609 if (source->use_inversion_array) {
610 /* Allocate space for inversion array, prepare for preload pass */
611 source->whole_image = (*cinfo->mem->request_virt_sarray)
612 ((j_common_ptr)cinfo, JPOOL_IMAGE, FALSE,
613 row_width, (JDIMENSION)biHeight, (JDIMENSION)1);
614 source->pub.get_pixel_rows = preload_image;
615 if (cinfo->progress != NULL) {
616 cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;
617 progress->total_extra_passes++; /* count file input as separate pass */
620 source->iobuffer = (U_CHAR *)
621 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, row_width);
622 switch (source->bits_per_pixel) {
624 source->pub.get_pixel_rows = get_8bit_row;
627 source->pub.get_pixel_rows = get_24bit_row;
630 source->pub.get_pixel_rows = get_32bit_row;
633 ERREXIT(cinfo, JERR_BMP_BADDEPTH);
637 /* Ensure that biWidth * cinfo->input_components doesn't exceed the maximum
638 value of the JDIMENSION type. This is only a danger with BMP files, since
639 their width and height fields are 32-bit integers. */
640 if ((unsigned long long)biWidth *
641 (unsigned long long)cinfo->input_components > 0xFFFFFFFFULL)
642 ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
643 /* Allocate one-row buffer for returned data */
644 source->pub.buffer = (*cinfo->mem->alloc_sarray)
645 ((j_common_ptr)cinfo, JPOOL_IMAGE,
646 (JDIMENSION)(biWidth * cinfo->input_components), (JDIMENSION)1);
647 source->pub.buffer_height = 1;
649 cinfo->data_precision = 8;
650 cinfo->image_width = (JDIMENSION)biWidth;
651 cinfo->image_height = (JDIMENSION)biHeight;
656 * Finish up at the end of the file.
660 finish_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
667 * The module selection routine for BMP format input.
670 GLOBAL(cjpeg_source_ptr)
671 jinit_read_bmp(j_compress_ptr cinfo, boolean use_inversion_array)
673 bmp_source_ptr source;
675 /* Create module interface object */
676 source = (bmp_source_ptr)
677 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
678 sizeof(bmp_source_struct));
679 source->cinfo = cinfo; /* make back link for subroutines */
680 /* Fill in method ptrs, except get_pixel_rows which start_input sets */
681 source->pub.start_input = start_input_bmp;
682 source->pub.finish_input = finish_input_bmp;
684 source->use_inversion_array = use_inversion_array;
686 return (cjpeg_source_ptr)source;
689 #endif /* BMP_SUPPORTED */