~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to source/Irrlicht/jpeglib/rdbmp.c

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

Show diffs side-by-side

added added

removed removed

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