1f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 2f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * rdbmp.c 3f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 43395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org * This file was part of the Independent JPEG Group's software: 5f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Copyright (C) 1994-1996, Thomas G. Lane. 69862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * Modified 2009-2010 by Guido Vollbeding. 73395bcc26e390d2960d15020d4a4d27ae0c122fenoel@chromium.org * libjpeg-turbo Modifications: 89862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * Modified 2011 by Siarhei Siamashka. 9f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * For conditions of distribution and use, see the accompanying README file. 10f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 11f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This file contains routines to read input images in Microsoft "BMP" 12f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * format (MS Windows 3.x, OS/2 1.x, and OS/2 2.x flavors). 13f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Currently, only 8-bit and 24-bit images are supported, not 1-bit or 14f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 4-bit (feeding such low-depth images into JPEG would be silly anyway). 15f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Also, we don't support RLE-compressed files. 16f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 17f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * These routines may need modification for non-Unix environments or 18f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * specialized applications. As they stand, they assume input from 19f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * an ordinary stdio stream. They further assume that reading begins 20f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * at the start of the file; start_input may need work if the 21f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * user interface has already read some data (e.g., to determine that 22f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * the file is indeed BMP format). 23f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 24f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This code contributed by James Arthur Boucher. 25f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 26f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 27f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ 28f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 29f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef BMP_SUPPORTED 30f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 31f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 32f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Macros to deal with unsigned chars as efficiently as compiler allows */ 33f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 34f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef HAVE_UNSIGNED_CHAR 35f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtypedef unsigned char U_CHAR; 36f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#define UCH(x) ((int) (x)) 37f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#else /* !HAVE_UNSIGNED_CHAR */ 38f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef CHAR_IS_UNSIGNED 39f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtypedef char U_CHAR; 40f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#define UCH(x) ((int) (x)) 41f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#else 42f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtypedef char U_CHAR; 43f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#define UCH(x) ((int) (x) & 0xFF) 44f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 45f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif /* HAVE_UNSIGNED_CHAR */ 46f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 47f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 48f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len))) 49f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 50f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 51f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Private version of data source object */ 52f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 53f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtypedef struct _bmp_source_struct * bmp_source_ptr; 54f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 55f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgtypedef struct _bmp_source_struct { 56f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org struct cjpeg_source_struct pub; /* public fields */ 57f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 58f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org j_compress_ptr cinfo; /* back link saves passing separate parm */ 59f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 60f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JSAMPARRAY colormap; /* BMP colormap (converted to my format) */ 61f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 62f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org jvirt_sarray_ptr whole_image; /* Needed to reverse row order */ 63f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JDIMENSION source_row; /* Current source row number */ 64f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JDIMENSION row_width; /* Physical width of scanlines in file */ 65f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 66f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org int bits_per_pixel; /* remembers 8- or 24-bit format */ 67f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} bmp_source_struct; 68f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 69f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 70f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgLOCAL(int) 71f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgread_byte (bmp_source_ptr sinfo) 72f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Read next byte from BMP file */ 73f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 74f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org register FILE *infile = sinfo->pub.input_file; 75f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org register int c; 76f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 77f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if ((c = getc(infile)) == EOF) 78f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(sinfo->cinfo, JERR_INPUT_EOF); 79f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return c; 80f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 81f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 82f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 83f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgLOCAL(void) 84f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgread_colormap (bmp_source_ptr sinfo, int cmaplen, int mapentrysize) 85f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* Read the colormap from a BMP file */ 86f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 87f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org int i; 88f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 89f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org switch (mapentrysize) { 90f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case 3: 91f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* BGR format (occurs in OS/2 files) */ 92f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org for (i = 0; i < cmaplen; i++) { 93f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo); 94f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo); 95f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo); 96f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 97f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 98f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case 4: 99f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* BGR0 format (occurs in MS Windows files) */ 100f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org for (i = 0; i < cmaplen; i++) { 101f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo); 102f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo); 103f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo); 104f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (void) read_byte(sinfo); 105f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 106f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 107f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org default: 108f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(sinfo->cinfo, JERR_BMP_BADCMAP); 109f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 110f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 111f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 112f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 113f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 114f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 115f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Read one row of pixels. 116f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * The image has been read into the whole_image array, but is otherwise 117f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * unprocessed. We must read it out in top-to-bottom row order, and if 118f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * it is an 8-bit image, we must expand colormapped pixels to 24bit format. 119f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 120f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 121f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgMETHODDEF(JDIMENSION) 122f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgget_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 123f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* This version is for reading 8-bit colormap indexes */ 124f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 125f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org bmp_source_ptr source = (bmp_source_ptr) sinfo; 126f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org register JSAMPARRAY colormap = source->colormap; 127f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JSAMPARRAY image_ptr; 128f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org register int t; 129f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org register JSAMPROW inptr, outptr; 130f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org register JDIMENSION col; 131f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 132f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Fetch next row from virtual array */ 133f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->source_row--; 134f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org image_ptr = (*cinfo->mem->access_virt_sarray) 135f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, source->whole_image, 136f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->source_row, (JDIMENSION) 1, FALSE); 137f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 138f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Expand the colormap indexes to real data */ 139f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org inptr = image_ptr[0]; 140f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org outptr = source->pub.buffer[0]; 141f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org for (col = cinfo->image_width; col > 0; col--) { 142f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org t = GETJSAMPLE(*inptr++); 143f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *outptr++ = colormap[0][t]; /* can omit GETJSAMPLE() safely */ 144f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *outptr++ = colormap[1][t]; 145f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org *outptr++ = colormap[2][t]; 146f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 147f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 148f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return 1; 149f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 150f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 151f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 152f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgMETHODDEF(JDIMENSION) 153f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgget_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 154f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* This version is for reading 24-bit pixels */ 155f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 156f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org bmp_source_ptr source = (bmp_source_ptr) sinfo; 157f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JSAMPARRAY image_ptr; 158f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org register JSAMPROW inptr, outptr; 159f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org register JDIMENSION col; 160f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 161f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Fetch next row from virtual array */ 162f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->source_row--; 163f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org image_ptr = (*cinfo->mem->access_virt_sarray) 164f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, source->whole_image, 165f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->source_row, (JDIMENSION) 1, FALSE); 166f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 167f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Transfer data. Note source values are in BGR order 168f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * (even though Microsoft's own documents say the opposite). 169f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 170f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org inptr = image_ptr[0]; 171f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org outptr = source->pub.buffer[0]; 172f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org for (col = cinfo->image_width; col > 0; col--) { 173f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */ 174f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org outptr[1] = *inptr++; 175f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org outptr[0] = *inptr++; 176f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org outptr += 3; 177f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 178f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 179f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return 1; 180f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 181f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 182f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 1839862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgMETHODDEF(JDIMENSION) 1849862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.orgget_32bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 1859862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org/* This version is for reading 32-bit pixels */ 1869862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org{ 1879862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org bmp_source_ptr source = (bmp_source_ptr) sinfo; 1889862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org JSAMPARRAY image_ptr; 1899862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org register JSAMPROW inptr, outptr; 1909862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org register JDIMENSION col; 1919862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org 1929862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org /* Fetch next row from virtual array */ 1939862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org source->source_row--; 1949862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org image_ptr = (*cinfo->mem->access_virt_sarray) 1959862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org ((j_common_ptr) cinfo, source->whole_image, 1969862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org source->source_row, (JDIMENSION) 1, FALSE); 1979862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org /* Transfer data. Note source values are in BGR order 1989862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * (even though Microsoft's own documents say the opposite). 1999862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org */ 2009862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org inptr = image_ptr[0]; 2019862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org outptr = source->pub.buffer[0]; 2029862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org for (col = cinfo->image_width; col > 0; col--) { 2039862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */ 2049862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org outptr[1] = *inptr++; 2059862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org outptr[0] = *inptr++; 2069862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org inptr++; /* skip the 4th byte (Alpha channel) */ 2079862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org outptr += 3; 2089862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org } 2099862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org 2109862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org return 1; 2119862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org} 2129862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org 2139862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org 214f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 215f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This method loads the image into whole_image during the first call on 216f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * get_pixel_rows. The get_pixel_rows pointer is then adjusted to call 2179862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org * get_8bit_row, get_24bit_row, or get_32bit_row on subsequent calls. 218f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 219f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 220f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgMETHODDEF(JDIMENSION) 221f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgpreload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 222f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 223f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org bmp_source_ptr source = (bmp_source_ptr) sinfo; 224f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org register FILE *infile = source->pub.input_file; 225f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org register JSAMPROW out_ptr; 226f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JSAMPARRAY image_ptr; 2279862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org JDIMENSION row; 228f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; 229f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 230f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Read the data into a virtual array in input-file row order. */ 231f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org for (row = 0; row < cinfo->image_height; row++) { 232f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (progress != NULL) { 233f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->pub.pass_counter = (long) row; 234f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->pub.pass_limit = (long) cinfo->image_height; 235f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); 236f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 237f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org image_ptr = (*cinfo->mem->access_virt_sarray) 238f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, source->whole_image, 239f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org row, (JDIMENSION) 1, TRUE); 240f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org out_ptr = image_ptr[0]; 2419862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org if (fread(out_ptr, 1, source->row_width, infile) != source->row_width) { 2429862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org if (feof(infile)) 2439862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org ERREXIT(cinfo, JERR_INPUT_EOF); 2449862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org else 2459862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org ERREXIT(cinfo, JERR_FILE_READ); 246f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 247f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 248f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (progress != NULL) 249f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->completed_extra_passes++; 250f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 251f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Set up to read from the virtual array in top-to-bottom order */ 252f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org switch (source->bits_per_pixel) { 253f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case 8: 254f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.get_pixel_rows = get_8bit_row; 255f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 256f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case 24: 257f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.get_pixel_rows = get_24bit_row; 258f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 2599862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org case 32: 2609862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org source->pub.get_pixel_rows = get_32bit_row; 2619862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org break; 262f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org default: 263f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_BMP_BADDEPTH); 264f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 265f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->source_row = cinfo->image_height; 266f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 267f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* And read the first row */ 268f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return (*source->pub.get_pixel_rows) (cinfo, sinfo); 269f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 270f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 271f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 272f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 273f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Read the file header; return image size and component count. 274f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 275f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 276f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgMETHODDEF(void) 277f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgstart_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 278f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 279f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org bmp_source_ptr source = (bmp_source_ptr) sinfo; 280f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org U_CHAR bmpfileheader[14]; 281f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org U_CHAR bmpinfoheader[64]; 282f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#define GET_2B(array,offset) ((unsigned int) UCH(array[offset]) + \ 283f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (((unsigned int) UCH(array[offset+1])) << 8)) 284f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#define GET_4B(array,offset) ((INT32) UCH(array[offset]) + \ 285f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (((INT32) UCH(array[offset+1])) << 8) + \ 286f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (((INT32) UCH(array[offset+2])) << 16) + \ 287f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (((INT32) UCH(array[offset+3])) << 24)) 288f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org INT32 bfOffBits; 289f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org INT32 headerSize; 2909862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org INT32 biWidth; 2919862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org INT32 biHeight; 292f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org unsigned int biPlanes; 293f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org INT32 biCompression; 294f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org INT32 biXPelsPerMeter,biYPelsPerMeter; 295f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org INT32 biClrUsed = 0; 296f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org int mapentrysize = 0; /* 0 indicates no colormap */ 297f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org INT32 bPad; 298f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org JDIMENSION row_width; 299f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 300f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Read and verify the bitmap file header */ 301f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (! ReadOK(source->pub.input_file, bmpfileheader, 14)) 302f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_INPUT_EOF); 303f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (GET_2B(bmpfileheader,0) != 0x4D42) /* 'BM' */ 304f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_BMP_NOT); 305f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org bfOffBits = (INT32) GET_4B(bmpfileheader,10); 306f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* We ignore the remaining fileheader fields */ 307f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 308f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows), 309f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * or 64 bytes (OS/2 2.x). Check the first 4 bytes to find out which. 310f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 311f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (! ReadOK(source->pub.input_file, bmpinfoheader, 4)) 312f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_INPUT_EOF); 313f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org headerSize = (INT32) GET_4B(bmpinfoheader,0); 314f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (headerSize < 12 || headerSize > 64) 315f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_BMP_BADHEADER); 316f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (! ReadOK(source->pub.input_file, bmpinfoheader+4, headerSize-4)) 317f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_INPUT_EOF); 318f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 319f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org switch ((int) headerSize) { 320f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case 12: 321f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) */ 322f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org biWidth = (INT32) GET_2B(bmpinfoheader,4); 323f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org biHeight = (INT32) GET_2B(bmpinfoheader,6); 324f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org biPlanes = GET_2B(bmpinfoheader,8); 325f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->bits_per_pixel = (int) GET_2B(bmpinfoheader,10); 326f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 327f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org switch (source->bits_per_pixel) { 328f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case 8: /* colormapped image */ 329f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org mapentrysize = 3; /* OS/2 uses RGBTRIPLE colormap */ 330f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org TRACEMS2(cinfo, 1, JTRC_BMP_OS2_MAPPED, (int) biWidth, (int) biHeight); 331f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 332f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case 24: /* RGB image */ 333f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org TRACEMS2(cinfo, 1, JTRC_BMP_OS2, (int) biWidth, (int) biHeight); 334f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 335f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org default: 336f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_BMP_BADDEPTH); 337f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 338f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 339f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 340f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case 40: 341f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case 64: 342f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */ 343f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* or OS/2 2.x header, which has additional fields that we ignore */ 344f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org biWidth = GET_4B(bmpinfoheader,4); 345f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org biHeight = GET_4B(bmpinfoheader,8); 346f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org biPlanes = GET_2B(bmpinfoheader,12); 347f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->bits_per_pixel = (int) GET_2B(bmpinfoheader,14); 348f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org biCompression = GET_4B(bmpinfoheader,16); 349f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org biXPelsPerMeter = GET_4B(bmpinfoheader,24); 350f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org biYPelsPerMeter = GET_4B(bmpinfoheader,28); 351f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org biClrUsed = GET_4B(bmpinfoheader,32); 352f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* biSizeImage, biClrImportant fields are ignored */ 353f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 354f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org switch (source->bits_per_pixel) { 355f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case 8: /* colormapped image */ 356f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org mapentrysize = 4; /* Windows uses RGBQUAD colormap */ 357f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org TRACEMS2(cinfo, 1, JTRC_BMP_MAPPED, (int) biWidth, (int) biHeight); 358f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 359f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org case 24: /* RGB image */ 360f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight); 361f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 3629862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org case 32: /* RGB image + Alpha channel */ 3639862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight); 3649862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org break; 365f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org default: 366f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_BMP_BADDEPTH); 367f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 368f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 369f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (biCompression != 0) 370f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_BMP_COMPRESSED); 371f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 372f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (biXPelsPerMeter > 0 && biYPelsPerMeter > 0) { 373f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Set JFIF density parameters from the BMP data */ 374f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->X_density = (UINT16) (biXPelsPerMeter/100); /* 100 cm per meter */ 375f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->Y_density = (UINT16) (biYPelsPerMeter/100); 376f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->density_unit = 2; /* dots/cm */ 377f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 378f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org break; 379f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org default: 380f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_BMP_BADHEADER); 3819862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org return; 382f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 383f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 3849862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org if (biWidth <= 0 || biHeight <= 0) 3859862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org ERREXIT(cinfo, JERR_BMP_EMPTY); 3869862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org if (biPlanes != 1) 3879862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org ERREXIT(cinfo, JERR_BMP_BADPLANES); 3889862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org 389f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Compute distance to bitmap data --- will adjust for colormap below */ 390f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org bPad = bfOffBits - (headerSize + 14); 391f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 392f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Read the colormap, if any */ 393f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (mapentrysize > 0) { 394f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (biClrUsed <= 0) 395f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org biClrUsed = 256; /* assume it's 256 */ 396f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org else if (biClrUsed > 256) 397f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_BMP_BADCMAP); 398f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Allocate space to store the colormap */ 399f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->colormap = (*cinfo->mem->alloc_sarray) 400f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, JPOOL_IMAGE, 401f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (JDIMENSION) biClrUsed, (JDIMENSION) 3); 402f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* and read it from the file */ 403f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org read_colormap(source, (int) biClrUsed, mapentrysize); 404f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* account for size of colormap */ 405f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org bPad -= biClrUsed * mapentrysize; 406f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 407f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 408f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Skip any remaining pad bytes */ 409f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (bPad < 0) /* incorrect bfOffBits value? */ 410f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ERREXIT(cinfo, JERR_BMP_BADHEADER); 411f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org while (--bPad >= 0) { 412f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (void) read_byte(source); 413f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 414f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 415f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Compute row width in file, including padding to 4-byte boundary */ 416f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (source->bits_per_pixel == 24) 417f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org row_width = (JDIMENSION) (biWidth * 3); 4189862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org else if (source->bits_per_pixel == 32) 4199862697206250265c6bb37a4186b0a411c78de3bhbono@chromium.org row_width = (JDIMENSION) (biWidth * 4); 420f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org else 421f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org row_width = (JDIMENSION) biWidth; 422f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org while ((row_width & 3) != 0) row_width++; 423f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->row_width = row_width; 424f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 425f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Allocate space for inversion array, prepare for preload pass */ 426f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->whole_image = (*cinfo->mem->request_virt_sarray) 427f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, 428f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org row_width, (JDIMENSION) biHeight, (JDIMENSION) 1); 429f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.get_pixel_rows = preload_image; 430f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (cinfo->progress != NULL) { 431f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; 432f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->total_extra_passes++; /* count file input as separate pass */ 433f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 434f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 435f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Allocate one-row buffer for returned data */ 436f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.buffer = (*cinfo->mem->alloc_sarray) 437f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ((j_common_ptr) cinfo, JPOOL_IMAGE, 438f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (JDIMENSION) (biWidth * 3), (JDIMENSION) 1); 439f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.buffer_height = 1; 440f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 441f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->in_color_space = JCS_RGB; 442f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->input_components = 3; 443f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->data_precision = 8; 444f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->image_width = (JDIMENSION) biWidth; 445f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->image_height = (JDIMENSION) biHeight; 446f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 447f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 448f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 449f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 450f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Finish up at the end of the file. 451f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 452f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 453f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgMETHODDEF(void) 454f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgfinish_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) 455f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 456f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* no work */ 457f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 458f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 459f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 460f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 461f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * The module selection routine for BMP format input. 462f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 463f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 464f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(cjpeg_source_ptr) 465f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgjinit_read_bmp (j_compress_ptr cinfo) 466f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 467f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org bmp_source_ptr source; 468f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 469f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Create module interface object */ 470f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source = (bmp_source_ptr) 471f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 472f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org SIZEOF(bmp_source_struct)); 473f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->cinfo = cinfo; /* make back link for subroutines */ 474f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Fill in method ptrs, except get_pixel_rows which start_input sets */ 475f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.start_input = start_input_bmp; 476f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org source->pub.finish_input = finish_input_bmp; 477f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 478f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return (cjpeg_source_ptr) source; 479f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 480f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 481f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif /* BMP_SUPPORTED */ 482