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