rdbmp.c
Go to the documentation of this file.
1 /*
2  * rdbmp.c
3  *
4  * Copyright (C) 1994-1996, Thomas G. Lane.
5  * This file is part of the Independent JPEG Group's software.
6  * For conditions of distribution and use, see the accompanying README file.
7  *
8  * This file contains routines to read input images in Microsoft "BMP"
9  * format (MS Windows 3.x, OS/2 1.x, and OS/2 2.x flavors).
10  * Currently, only 8-bit and 24-bit images are supported, not 1-bit or
11  * 4-bit (feeding such low-depth images into JPEG would be silly anyway).
12  * Also, we don't support RLE-compressed files.
13  *
14  * These routines may need modification for non-Unix environments or
15  * specialized applications. As they stand, they assume input from
16  * an ordinary stdio stream. They further assume that reading begins
17  * at the start of the file; start_input may need work if the
18  * user interface has already read some data (e.g., to determine that
19  * the file is indeed BMP format).
20  *
21  * This code contributed by James Arthur Boucher.
22  */
23 
24 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
25 
26 #ifdef BMP_SUPPORTED
27 
28 
29 /* Macros to deal with unsigned chars as efficiently as compiler allows */
30 
31 #ifdef HAVE_UNSIGNED_CHAR
32 typedef unsigned char U_CHAR;
33 #define UCH(x) ((int) (x))
34 #else /* !HAVE_UNSIGNED_CHAR */
35 #ifdef CHAR_IS_UNSIGNED
36 typedef char U_CHAR;
37 #define UCH(x) ((int) (x))
38 #else
39 typedef char U_CHAR;
40 #define UCH(x) ((int) (x) & 0xFF)
41 #endif
42 #endif /* HAVE_UNSIGNED_CHAR */
43 
44 
45 #define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len)))
46 
47 
48 /* Private version of data source object */
49 
51 
52 typedef struct _bmp_source_struct {
53  struct cjpeg_source_struct pub; /* public fields */
54 
55  j_compress_ptr cinfo; /* back link saves passing separate parm */
56 
57  JSAMPARRAY colormap; /* BMP colormap (converted to my format) */
58 
59  jvirt_sarray_ptr whole_image; /* Needed to reverse row order */
60  JDIMENSION source_row; /* Current source row number */
61  JDIMENSION row_width; /* Physical width of scanlines in file */
62 
63  int bits_per_pixel; /* remembers 8- or 24-bit format */
65 
66 
67 LOCAL(int)
68 read_byte (bmp_source_ptr sinfo)
69 /* Read next byte from BMP file */
70 {
71  register FILE *infile = sinfo->pub.input_file;
72  register int c;
73 
74  if ((c = getc(infile)) == EOF)
75  ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
76  return c;
77 }
78 
79 
80 LOCAL(void)
81 read_colormap (bmp_source_ptr sinfo, int cmaplen, int mapentrysize)
82 /* Read the colormap from a BMP file */
83 {
84  int i;
85 
86  switch (mapentrysize) {
87  case 3:
88  /* BGR format (occurs in OS/2 files) */
89  for (i = 0; i < cmaplen; i++) {
90  sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo);
91  sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo);
92  sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo);
93  }
94  break;
95  case 4:
96  /* BGR0 format (occurs in MS Windows files) */
97  for (i = 0; i < cmaplen; i++) {
98  sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo);
99  sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo);
100  sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo);
101  (void) read_byte(sinfo);
102  }
103  break;
104  default:
105  ERREXIT(sinfo->cinfo, JERR_BMP_BADCMAP);
106  break;
107  }
108 }
109 
110 
111 /*
112  * Read one row of pixels.
113  * The image has been read into the whole_image array, but is otherwise
114  * unprocessed. We must read it out in top-to-bottom row order, and if
115  * it is an 8-bit image, we must expand colormapped pixels to 24bit format.
116  */
117 
120 /* This version is for reading 8-bit colormap indexes */
121 {
122  bmp_source_ptr source = (bmp_source_ptr) sinfo;
123  register JSAMPARRAY colormap = source->colormap;
124  JSAMPARRAY image_ptr;
125  register int t;
126  register JSAMPROW inptr, outptr;
127  register JDIMENSION col;
128 
129  /* Fetch next row from virtual array */
130  source->source_row--;
131  image_ptr = (*cinfo->mem->access_virt_sarray)
132  ((j_common_ptr) cinfo, source->whole_image,
133  source->source_row, (JDIMENSION) 1, FALSE);
134 
135  /* Expand the colormap indexes to real data */
136  inptr = image_ptr[0];
137  outptr = source->pub.buffer[0];
138  for (col = cinfo->image_width; col > 0; col--) {
139  t = GETJSAMPLE(*inptr++);
140  *outptr++ = colormap[0][t]; /* can omit GETJSAMPLE() safely */
141  *outptr++ = colormap[1][t];
142  *outptr++ = colormap[2][t];
143  }
144 
145  return 1;
146 }
147 
148 
151 /* This version is for reading 24-bit pixels */
152 {
153  bmp_source_ptr source = (bmp_source_ptr) sinfo;
154  JSAMPARRAY image_ptr;
155  register JSAMPROW inptr, outptr;
156  register JDIMENSION col;
157 
158  /* Fetch next row from virtual array */
159  source->source_row--;
160  image_ptr = (*cinfo->mem->access_virt_sarray)
161  ((j_common_ptr) cinfo, source->whole_image,
162  source->source_row, (JDIMENSION) 1, FALSE);
163 
164  /* Transfer data. Note source values are in BGR order
165  * (even though Microsoft's own documents say the opposite).
166  */
167  inptr = image_ptr[0];
168  outptr = source->pub.buffer[0];
169  for (col = cinfo->image_width; col > 0; col--) {
170  outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */
171  outptr[1] = *inptr++;
172  outptr[0] = *inptr++;
173  outptr += 3;
174  }
175 
176  return 1;
177 }
178 
179 
180 /*
181  * This method loads the image into whole_image during the first call on
182  * get_pixel_rows. The get_pixel_rows pointer is then adjusted to call
183  * get_8bit_row or get_24bit_row on subsequent calls.
184  */
185 
188 {
189  bmp_source_ptr source = (bmp_source_ptr) sinfo;
190  register FILE *infile = source->pub.input_file;
191  register int c;
192  register JSAMPROW out_ptr;
193  JSAMPARRAY image_ptr;
194  JDIMENSION row, col;
196 
197  /* Read the data into a virtual array in input-file row order. */
198  for (row = 0; row < cinfo->image_height; row++) {
199  if (progress != NULL) {
200  progress->pub.pass_counter = (long) row;
201  progress->pub.pass_limit = (long) cinfo->image_height;
202  (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
203  }
204  image_ptr = (*cinfo->mem->access_virt_sarray)
205  ((j_common_ptr) cinfo, source->whole_image,
206  row, (JDIMENSION) 1, TRUE);
207  out_ptr = image_ptr[0];
208  for (col = source->row_width; col > 0; col--) {
209  /* inline copy of read_byte() for speed */
210  if ((c = getc(infile)) == EOF)
211  ERREXIT(cinfo, JERR_INPUT_EOF);
212  *out_ptr++ = (JSAMPLE) c;
213  }
214  }
215  if (progress != NULL)
216  progress->completed_extra_passes++;
217 
218  /* Set up to read from the virtual array in top-to-bottom order */
219  switch (source->bits_per_pixel) {
220  case 8:
221  source->pub.get_pixel_rows = get_8bit_row;
222  break;
223  case 24:
224  source->pub.get_pixel_rows = get_24bit_row;
225  break;
226  default:
227  ERREXIT(cinfo, JERR_BMP_BADDEPTH);
228  }
229  source->source_row = cinfo->image_height;
230 
231  /* And read the first row */
232  return (*source->pub.get_pixel_rows) (cinfo, sinfo);
233 }
234 
235 
236 /*
237  * Read the file header; return image size and component count.
238  */
239 
240 METHODDEF(void)
242 {
243  bmp_source_ptr source = (bmp_source_ptr) sinfo;
244  U_CHAR bmpfileheader[14];
245  U_CHAR bmpinfoheader[64];
246 #define GET_2B(array,offset) ((unsigned int) UCH(array[offset]) + \
247  (((unsigned int) UCH(array[offset+1])) << 8))
248 #define GET_4B(array,offset) ((INT32) UCH(array[offset]) + \
249  (((INT32) UCH(array[offset+1])) << 8) + \
250  (((INT32) UCH(array[offset+2])) << 16) + \
251  (((INT32) UCH(array[offset+3])) << 24))
252  INT32 bfOffBits;
253  INT32 headerSize;
254  INT32 biWidth = 0; /* initialize to avoid compiler warning */
255  INT32 biHeight = 0;
256  unsigned int biPlanes;
257  INT32 biCompression;
258  INT32 biXPelsPerMeter,biYPelsPerMeter;
259  INT32 biClrUsed = 0;
260  int mapentrysize = 0; /* 0 indicates no colormap */
261  INT32 bPad;
263 
264  /* Read and verify the bitmap file header */
265  if (! ReadOK(source->pub.input_file, bmpfileheader, 14))
266  ERREXIT(cinfo, JERR_INPUT_EOF);
267  if (GET_2B(bmpfileheader,0) != 0x4D42) /* 'BM' */
268  ERREXIT(cinfo, JERR_BMP_NOT);
269  bfOffBits = (INT32) GET_4B(bmpfileheader,10);
270  /* We ignore the remaining fileheader fields */
271 
272  /* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows),
273  * or 64 bytes (OS/2 2.x). Check the first 4 bytes to find out which.
274  */
275  if (! ReadOK(source->pub.input_file, bmpinfoheader, 4))
276  ERREXIT(cinfo, JERR_INPUT_EOF);
277  headerSize = (INT32) GET_4B(bmpinfoheader,0);
278  if (headerSize < 12 || headerSize > 64)
279  ERREXIT(cinfo, JERR_BMP_BADHEADER);
280  if (! ReadOK(source->pub.input_file, bmpinfoheader+4, headerSize-4))
281  ERREXIT(cinfo, JERR_INPUT_EOF);
282 
283  switch ((int) headerSize) {
284  case 12:
285  /* Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) */
286  biWidth = (INT32) GET_2B(bmpinfoheader,4);
287  biHeight = (INT32) GET_2B(bmpinfoheader,6);
288  biPlanes = GET_2B(bmpinfoheader,8);
289  source->bits_per_pixel = (int) GET_2B(bmpinfoheader,10);
290 
291  switch (source->bits_per_pixel) {
292  case 8: /* colormapped image */
293  mapentrysize = 3; /* OS/2 uses RGBTRIPLE colormap */
294  TRACEMS2(cinfo, 1, JTRC_BMP_OS2_MAPPED, (int) biWidth, (int) biHeight);
295  break;
296  case 24: /* RGB image */
297  TRACEMS2(cinfo, 1, JTRC_BMP_OS2, (int) biWidth, (int) biHeight);
298  break;
299  default:
300  ERREXIT(cinfo, JERR_BMP_BADDEPTH);
301  break;
302  }
303  if (biPlanes != 1)
304  ERREXIT(cinfo, JERR_BMP_BADPLANES);
305  break;
306  case 40:
307  case 64:
308  /* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */
309  /* or OS/2 2.x header, which has additional fields that we ignore */
310  biWidth = GET_4B(bmpinfoheader,4);
311  biHeight = GET_4B(bmpinfoheader,8);
312  biPlanes = GET_2B(bmpinfoheader,12);
313  source->bits_per_pixel = (int) GET_2B(bmpinfoheader,14);
314  biCompression = GET_4B(bmpinfoheader,16);
315  biXPelsPerMeter = GET_4B(bmpinfoheader,24);
316  biYPelsPerMeter = GET_4B(bmpinfoheader,28);
317  biClrUsed = GET_4B(bmpinfoheader,32);
318  /* biSizeImage, biClrImportant fields are ignored */
319 
320  switch (source->bits_per_pixel) {
321  case 8: /* colormapped image */
322  mapentrysize = 4; /* Windows uses RGBQUAD colormap */
323  TRACEMS2(cinfo, 1, JTRC_BMP_MAPPED, (int) biWidth, (int) biHeight);
324  break;
325  case 24: /* RGB image */
326  TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight);
327  break;
328  default:
329  ERREXIT(cinfo, JERR_BMP_BADDEPTH);
330  break;
331  }
332  if (biPlanes != 1)
333  ERREXIT(cinfo, JERR_BMP_BADPLANES);
334  if (biCompression != 0)
335  ERREXIT(cinfo, JERR_BMP_COMPRESSED);
336 
337  if (biXPelsPerMeter > 0 && biYPelsPerMeter > 0) {
338  /* Set JFIF density parameters from the BMP data */
339  cinfo->X_density = (UINT16) (biXPelsPerMeter/100); /* 100 cm per meter */
340  cinfo->Y_density = (UINT16) (biYPelsPerMeter/100);
341  cinfo->density_unit = 2; /* dots/cm */
342  }
343  break;
344  default:
345  ERREXIT(cinfo, JERR_BMP_BADHEADER);
346  break;
347  }
348 
349  /* Compute distance to bitmap data --- will adjust for colormap below */
350  bPad = bfOffBits - (headerSize + 14);
351 
352  /* Read the colormap, if any */
353  if (mapentrysize > 0) {
354  if (biClrUsed <= 0)
355  biClrUsed = 256; /* assume it's 256 */
356  else if (biClrUsed > 256)
357  ERREXIT(cinfo, JERR_BMP_BADCMAP);
358  /* Allocate space to store the colormap */
359  source->colormap = (*cinfo->mem->alloc_sarray)
361  (JDIMENSION) biClrUsed, (JDIMENSION) 3);
362  /* and read it from the file */
363  read_colormap(source, (int) biClrUsed, mapentrysize);
364  /* account for size of colormap */
365  bPad -= biClrUsed * mapentrysize;
366  }
367 
368  /* Skip any remaining pad bytes */
369  if (bPad < 0) /* incorrect bfOffBits value? */
370  ERREXIT(cinfo, JERR_BMP_BADHEADER);
371  while (--bPad >= 0) {
372  (void) read_byte(source);
373  }
374 
375  /* Compute row width in file, including padding to 4-byte boundary */
376  if (source->bits_per_pixel == 24)
377  row_width = (JDIMENSION) (biWidth * 3);
378  else
379  row_width = (JDIMENSION) biWidth;
380  while ((row_width & 3) != 0) row_width++;
381  source->row_width = row_width;
382 
383  /* Allocate space for inversion array, prepare for preload pass */
384  source->whole_image = (*cinfo->mem->request_virt_sarray)
386  row_width, (JDIMENSION) biHeight, (JDIMENSION) 1);
387  source->pub.get_pixel_rows = preload_image;
388  if (cinfo->progress != NULL) {
389  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
390  progress->total_extra_passes++; /* count file input as separate pass */
391  }
392 
393  /* Allocate one-row buffer for returned data */
394  source->pub.buffer = (*cinfo->mem->alloc_sarray)
396  (JDIMENSION) (biWidth * 3), (JDIMENSION) 1);
397  source->pub.buffer_height = 1;
398 
400  cinfo->input_components = 3;
401  cinfo->data_precision = 8;
402  cinfo->image_width = (JDIMENSION) biWidth;
403  cinfo->image_height = (JDIMENSION) biHeight;
404 }
405 
406 
407 /*
408  * Finish up at the end of the file.
409  */
410 
411 METHODDEF(void)
413 {
414  /* no work */
415 }
416 
417 
418 /*
419  * The module selection routine for BMP format input.
420  */
421 
424 {
425  bmp_source_ptr source;
426 
427  /* Create module interface object */
428  source = (bmp_source_ptr)
429  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
431  source->cinfo = cinfo; /* make back link for subroutines */
432  /* Fill in method ptrs, except get_pixel_rows which start_input sets */
433  source->pub.start_input = start_input_bmp;
434  source->pub.finish_input = finish_input_bmp;
435 
436  return (cjpeg_source_ptr) source;
437 }
438 
439 #endif /* BMP_SUPPORTED */
int c
Definition: autoplay.py:16
char JSAMPLE
Definition: jmorecfg.h:64
struct _bmp_source_struct * bmp_source_ptr
Definition: rdbmp.c:50
JSAMPLE FAR * JSAMPROW
Definition: jpeglib.h:66
#define FALSE
Definition: OPC_IceHook.h:9
j_compress_ptr cinfo
Definition: rdbmp.c:55
struct jpeg_common_struct * j_common_ptr
Definition: jpeglib.h:261
JDIMENSION image_height
Definition: jpeglib.h:280
start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
Definition: rdbmp.c:241
JDIMENSION row_width
Definition: rdbmp.c:61
#define GETJSAMPLE(value)
Definition: jmorecfg.h:68
#define ERREXIT(cinfo, code)
Definition: jerror.h:205
#define TRACEMS2(cinfo, lvl, code, p1, p2)
Definition: jerror.h:259
#define TRUE
Definition: OPC_IceHook.h:13
#define SIZEOF(object)
Definition: jinclude.h:80
long INT32
Definition: jmorecfg.h:161
JDIMENSION buffer_height
Definition: cdjpeg.h:37
jinit_read_bmp(j_compress_ptr cinfo)
Definition: rdbmp.c:423
#define GET_2B(array, offset)
read_byte(bmp_source_ptr sinfo)
Definition: rdbmp.c:68
#define for
png_uint_32 i
Definition: png.h:2735
finish_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
Definition: rdbmp.c:412
J_COLOR_SPACE in_color_space
Definition: jpeglib.h:282
JSAMPARRAY colormap
Definition: rdbmp.c:57
#define JPOOL_IMAGE
Definition: jpeglib.h:749
jvirt_sarray_ptr whole_image
Definition: rdbmp.c:59
int total_extra_passes
Definition: cdjpeg.h:84
#define LOCAL(type)
Definition: jmorecfg.h:186
int bits_per_pixel
Definition: rdbmp.c:63
typedef void(PNGAPI *png_error_ptr) PNGARG((png_structp
t
png_bytepp row
Definition: png.h:1759
JDIMENSION source_row
Definition: rdbmp.c:60
JSAMPARRAY buffer
Definition: cdjpeg.h:36
struct jpeg_progress_mgr pub
Definition: cdjpeg.h:82
unsigned int UINT16
Definition: jmorecfg.h:149
struct _bmp_source_struct bmp_source_struct
JSAMPROW * JSAMPARRAY
Definition: jpeglib.h:67
typedef int
Definition: png.h:1113
#define GLOBAL(type)
Definition: jmorecfg.h:188
FILE * input_file
Definition: cdjpeg.h:34
get_24bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
Definition: rdbmp.c:150
#define METHODDEF(type)
Definition: jmorecfg.h:184
FILE * infile
Definition: cdjpeg.h:141
int completed_extra_passes
Definition: cdjpeg.h:83
read_colormap(bmp_source_ptr sinfo, int cmaplen, int mapentrysize)
Definition: rdbmp.c:81
cd_progress_ptr progress
Definition: cdjpeg.h:147
#define ReadOK(file, buffer, len)
Definition: rdbmp.c:45
unsigned int JDIMENSION
Definition: jmorecfg.h:171
struct cdjpeg_progress_mgr * cd_progress_ptr
Definition: cdjpeg.h:89
preload_image(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
Definition: rdbmp.c:187
struct cjpeg_source_struct pub
Definition: rdbmp.c:53
unsigned char U_CHAR
Definition: rdbmp.c:32
get_8bit_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
Definition: rdbmp.c:119
#define GET_4B(array, offset)
JDIMENSION image_width
Definition: jpeglib.h:279


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Sat May 8 2021 02:42:40