bmp: Minor refactoring
[deark.git] / modules / bmp.c
blobb5504b205368b03b75b6ab9117b4c8e9c081ee76
1 // This file is part of Deark.
2 // Copyright (C) 2016 Jason Summers
3 // See the file COPYING for terms of use.
5 // Windows BMP image
7 #include <deark-config.h>
8 #include <deark-private.h>
9 #include <deark-fmtutil.h>
10 DE_DECLARE_MODULE(de_module_bmp);
11 DE_DECLARE_MODULE(de_module_picjpeg);
12 DE_DECLARE_MODULE(de_module_dib);
13 DE_DECLARE_MODULE(de_module_ddb);
14 DE_DECLARE_MODULE(de_module_jigsaw_wk);
16 #define FILEHEADER_SIZE 14
18 #define CODE_LINK 0x4c494e4bU
19 #define CODE_MBED 0x4d424544U
21 struct bitfieldsinfo {
22 u32 mask;
23 UI shift;
24 double scale; // Amount to multiply the sample value by, to scale it to [0..255]
27 typedef struct localctx_bmp {
28 #define DE_BMPVER_OS2V1 1 // OS2v1 or Windows v2
29 #define DE_BMPVER_OS2V2 2
30 #define DE_BMPVER_WINV345 3 // Windows v3+
31 #define DE_BMPVER_64BIT 10
32 int version;
33 u8 want_returned_img;
34 de_finfo *fi;
35 de_bitmap *img; // Image to be written by the main function
36 UI createflags;
37 i64 fsize; // The "file size" field in the file header
38 i64 bits_offset; // The bfOffBits field in the file header
39 i64 infohdrsize;
40 i64 bitcount;
41 u32 compression_field;
42 i64 size_image; // biSizeImage
43 i64 width, pdwidth, height;
44 int top_down;
45 i64 pal_entries; // Actual number stored in file. 0 means no palette.
46 i64 pal_pos;
47 i64 bytes_per_pal_entry;
48 int pal_is_grayscale;
50 #define BF_NONE 0 // Bitfields are not applicable
51 #define BF_DEFAULT 1 // Use the default bitfields for this bit depth
52 #define BF_SEGMENT 2 // Use the bitfields segment in the file
53 #define BF_IN_HEADER 3 // Use the bitfields fields in the infoheader
54 int bitfields_type;
55 i64 bitfields_segment_len; // Used if bitfields_type==BF_SEGMENT
57 i64 xpelspermeter, ypelspermeter;
59 #define CMPR_NONE 0
60 #define CMPR_RLE4 11
61 #define CMPR_RLE8 12
62 #define CMPR_RLE24 13
63 #define CMPR_JPEG 14
64 #define CMPR_PNG 15
65 #define CMPR_HUFFMAN1D 16
66 int compression_type;
68 struct de_fourcc cstype4cc;
69 i64 profile_offset_raw;
70 i64 profile_offset;
71 i64 profile_size;
73 i64 rowspan;
74 struct bitfieldsinfo bitfield[4];
75 de_color pal[256];
76 } lctx;
78 ///// RLE decompressor
80 struct rle_dcmpr_ctx {
81 u8 disallow_delta;
82 i64 unit_size;
83 // width_in_units: E.g. if RLE4, the number of 4-bit units. Normally equal
84 // to the width in pixels, except that we sometimes allow the bitcount and
85 // compression to be mismatched.
86 i64 width_in_units;
87 i64 height;
88 i64 dst_rowspan;
89 dbuf *inf;
90 i64 inf_startpos;
91 i64 inf_endpos;
92 dbuf *unc_pixels;
93 de_bitmap *mask; // optional
95 i64 xpos, ypos;
96 UI num_pending_bits;
97 u8 pending_bits;
98 u8 delta_used;
99 u8 errflag;
102 static void rle_to_bytes_flush(deark *c, struct rle_dcmpr_ctx *rc)
104 if(rc->num_pending_bits) {
105 dbuf_writebyte(rc->unc_pixels, rc->pending_bits);
107 rc->pending_bits = 0;
108 rc->num_pending_bits = 0;
111 // Updates rc->xpos.
112 // mflag: Also write to the mask, if present.
113 static void rle_to_bytes_append_unit4(deark *c, struct rle_dcmpr_ctx *rc, u8 n, u8 mflag)
115 if(rc->num_pending_bits) { // presumably = 4
116 rc->pending_bits |= n;
117 rc->num_pending_bits += 4;
118 rle_to_bytes_flush(c, rc);
120 else { // presumably num_pending_bits = 0
121 rc->pending_bits = n<<4;
122 rc->num_pending_bits += 4;
125 if(mflag && rc->mask) {
126 de_bitmap_setpixel_gray(rc->mask, rc->xpos, rc->ypos, 0xff);
128 rc->xpos++;
131 static void rle_to_bytes_append_unit8(deark *c, struct rle_dcmpr_ctx *rc, u8 n, u8 mflag)
133 dbuf_writebyte(rc->unc_pixels, n);
134 if(mflag && rc->mask) {
135 de_bitmap_setpixel_gray(rc->mask, rc->xpos, rc->ypos, 0xff);
137 rc->xpos++;
140 static void rle_to_bytes_append_unit24(deark *c, struct rle_dcmpr_ctx *rc,
141 u8 cr, u8 cg, u8 cb, u8 mflag)
143 dbuf_writebyte(rc->unc_pixels, cb);
144 dbuf_writebyte(rc->unc_pixels, cg);
145 dbuf_writebyte(rc->unc_pixels, cr);
146 if(mflag && rc->mask) {
147 de_bitmap_setpixel_gray(rc->mask, rc->xpos, rc->ypos, 0xff);
149 rc->xpos++;
152 static void rle_to_bytes_on_eol(deark *c, struct rle_dcmpr_ctx *rc, i64 nlines_complete)
154 rle_to_bytes_flush(c, rc);
155 dbuf_truncate(rc->unc_pixels, nlines_complete*rc->dst_rowspan);
158 // Decompress an RLE-compressed image to the equivalent noncompressed format.
159 // Decompressing BMP RLE directly to pixels would be easier, but there are some
160 // benefits to doing it this way.
162 // Caller allocs and initializes rc.
163 // Caller allocs and frees unc_pixels and mask.
164 static void decompress_rle_to_bytes(deark *c, struct rle_dcmpr_ctx *rc)
166 i64 pos = rc->inf_startpos;
168 while(1) {
169 i64 num_bytes_to_read;
170 i64 num_units_to_decode;
171 i64 num_units_decoded;
172 i64 k;
173 u8 b1, b2;
174 u8 b;
175 u8 pix1, pix2;
176 u8 cg, cr, cb;
178 if(pos >= rc->inf_endpos) {
179 goto done;
181 if(rc->ypos >= rc->height) {
182 goto done;
184 if(rc->ypos==(rc->height-1) && (rc->xpos>=rc->width_in_units)) {
185 goto done;
188 // Read the next two bytes from the input file.
189 b1 = dbuf_getbyte_p(rc->inf, &pos);
190 b2 = dbuf_getbyte_p(rc->inf, &pos);
191 if(b1==0 && b2==0) { // End of line
192 rc->xpos = 0;
193 rc->ypos++;
194 rle_to_bytes_on_eol(c, rc, rc->ypos);
196 else if(b1==0 && b2==1) { // End of bitmap
197 goto done;
199 else if(b1==0 && b2==2) { // Delta
200 i64 newxpos, newypos;
202 rc->delta_used = 1;
203 if(rc->disallow_delta) {
204 rc->errflag = 1;
205 goto done;
208 b = dbuf_getbyte_p(rc->inf, &pos);
209 newxpos = rc->xpos + (i64)b;
210 b = dbuf_getbyte_p(rc->inf, &pos);
211 newypos = rc->ypos + (i64)b;
213 if(newxpos>rc->width_in_units) {
214 newxpos = rc->width_in_units;
216 if(newypos>=rc->height) goto done;
218 while(rc->ypos<newypos) {
219 rc->ypos++;
220 rc->xpos = 0;
221 rle_to_bytes_on_eol(c, rc, rc->ypos);
223 while(rc->xpos<newxpos) {
224 if(rc->unit_size==4) {
225 rle_to_bytes_append_unit4(c, rc, 0, 0);
227 else if(rc->unit_size==24) {
228 rle_to_bytes_append_unit24(c, rc, 0, 0, 0, 0);
230 else {
231 rle_to_bytes_append_unit8(c, rc, 0, 0);
235 else if(b1==0) { // b2 noncompressed pixels
236 if(rc->unit_size==4) { // b2 noncompressed pixels (4-bit units) follow
237 num_units_to_decode = (i64)b2;
238 num_bytes_to_read = ((num_units_to_decode+3)/4)*2;
239 num_units_decoded = 0;
240 for(k=0; k<num_bytes_to_read; k++) {
241 UI q;
243 b = dbuf_getbyte_p(rc->inf, &pos);
244 for(q=0; (q<2) && (num_units_decoded<num_units_to_decode); q++) {
245 if(q==0) pix1 = b>>4;
246 else pix1 = b&0x0f;
247 rle_to_bytes_append_unit4(c, rc, pix1, 1);
248 num_units_decoded++;
252 else if(rc->unit_size==24) {
253 num_units_to_decode = (i64)b2;
254 for(k=0; k<num_units_to_decode; k++) {
255 cb = dbuf_getbyte_p(rc->inf, &pos);
256 cg = dbuf_getbyte_p(rc->inf, &pos);
257 cr = dbuf_getbyte_p(rc->inf, &pos);
258 rle_to_bytes_append_unit24(c, rc, cr, cg, cb, 1);
260 if(num_units_to_decode % 2) {
261 pos++;
264 else { // b2 noncompressed pixels (8-bit units) follow
265 num_units_to_decode = (i64)b2;
266 num_bytes_to_read = de_pad_to_2(num_units_to_decode);
267 num_units_decoded = 0;
269 for(k=0; k<num_bytes_to_read; k++) {
270 b = dbuf_getbyte_p(rc->inf, &pos);
271 if(num_units_decoded<num_units_to_decode) {
272 rle_to_bytes_append_unit8(c, rc, b, 1);
273 num_units_decoded++;
278 else { // Compressed pixels - b1 pixels
279 num_units_to_decode = (i64)b1;
280 if(rc->unit_size==4) { // b1 pixels alternating between the colors in b2
281 pix1 = b2>>4;
282 pix2 = b2&0x0f;
283 for(k=0; k<num_units_to_decode; k++) {
284 rle_to_bytes_append_unit4(c, rc, (k%2)?pix2:pix1, 1);
287 else if(rc->unit_size==24) {
288 cg = dbuf_getbyte_p(rc->inf, &pos);
289 cr = dbuf_getbyte_p(rc->inf, &pos);
290 for(k=0; k<num_units_to_decode; k++) {
291 rle_to_bytes_append_unit24(c, rc, cr, cg, b2, 1);
294 else { // 8: b1 pixels of color b2
295 for(k=0; k<num_units_to_decode; k++) {
296 rle_to_bytes_append_unit8(c, rc, b2, 1);
302 done:
303 rle_to_bytes_on_eol(c, rc, rc->height);
304 dbuf_flush(rc->unc_pixels);
305 if(rc->errflag) {
306 de_err(c, "Decompression failed");
309 ///// End of RLE decompressor
311 static i64 get_bits_size(deark *c, lctx *d)
313 if(d->size_image>0 && d->bits_offset+d->size_image <= c->infile->len) {
314 return d->size_image;
316 return c->infile->len - d->bits_offset;
319 // Sets d->version, and certain header fields.
320 static int detect_bmp_version(deark *c, lctx *d)
322 i64 pos;
324 pos = 0;
325 d->fsize = de_getu32le(pos+2);
327 pos += FILEHEADER_SIZE;
328 d->infohdrsize = de_getu32le(pos);
330 if(d->infohdrsize<=12) {
331 d->bitcount = de_getu16le(pos+10);
333 else {
334 d->bitcount = de_getu16le(pos+14);
337 if(d->infohdrsize==12) {
338 d->version = DE_BMPVER_OS2V1;
339 return 1;
341 if(d->infohdrsize<16) {
342 return 0;
345 if(d->infohdrsize>=20) {
346 d->compression_field = (u32)de_getu32le(pos+16);
349 // We're only trying to support the most basic 64-bit BMP images.
350 if(d->bitcount==64 && d->infohdrsize==40 && d->compression_field==0) {
351 d->version = DE_BMPVER_64BIT;
352 return 1;
355 if(d->infohdrsize>=16 && d->infohdrsize<=64) {
356 if(d->fsize==FILEHEADER_SIZE+d->infohdrsize) {
357 d->version = DE_BMPVER_OS2V2;
358 return 1;
361 if((d->compression_field==3 && d->bitcount==1) ||
362 (d->compression_field==4 && d->bitcount==24))
364 d->version = DE_BMPVER_OS2V2;
365 return 1;
368 if(d->infohdrsize!=40 && d->infohdrsize!=52 && d->infohdrsize!=56) {
369 d->version = DE_BMPVER_OS2V2;
370 return 1;
374 d->version = DE_BMPVER_WINV345;
375 return 1;
378 static int read_fileheader(deark *c, lctx *d, i64 pos)
380 de_dbg(c, "file header at %"I64_FMT, pos);
381 de_dbg_indent(c, 1);
382 de_dbg(c, "bfSize: %"I64_FMT, d->fsize);
383 d->bits_offset = de_getu32le(pos+10);
384 de_dbg(c, "bfOffBits: %"I64_FMT, d->bits_offset);
385 de_dbg_indent(c, -1);
386 return 1;
389 // Calculate .shift and .scale
390 static void update_bitfields_info(deark *c, lctx *d)
392 i64 k;
393 u32 tmpmask;
395 for(k=0; k<4; k++) {
396 tmpmask = d->bitfield[k].mask;
397 if(tmpmask==0) continue;
398 while((tmpmask & 0x1) == 0) {
399 d->bitfield[k].shift++;
400 tmpmask >>= 1;
402 d->bitfield[k].scale = 255.0 / (double)tmpmask;
406 static void do_read_bitfields(deark *c, lctx *d, i64 pos, i64 len)
408 i64 k;
410 if(len>16) len=16;
411 for(k=0; 4*k<len; k++) {
412 d->bitfield[k].mask = (u32)de_getu32le(pos+4*k);
413 de_dbg(c, "mask[%d]: 0x%08x", (int)k, (UI)d->bitfield[k].mask);
415 update_bitfields_info(c, d);
418 static void set_default_bitfields(deark *c, lctx *d)
420 if(d->bitcount==16) {
421 d->bitfield[0].mask = 0x000007c00U;
422 d->bitfield[1].mask = 0x0000003e0U;
423 d->bitfield[2].mask = 0x00000001fU;
424 update_bitfields_info(c, d);
426 else if(d->bitcount==32) {
427 d->bitfield[0].mask = 0x00ff0000U;
428 d->bitfield[1].mask = 0x0000ff00U;
429 d->bitfield[2].mask = 0x000000ffU;
430 update_bitfields_info(c, d);
434 static void get_cstype_descr_dbgstr(struct de_fourcc *cstype4cc, char *s_dbgstr, size_t s_len)
436 // The ID might be a FOURCC, or not.
437 if(cstype4cc->id>0xffffU) {
438 de_snprintf(s_dbgstr, s_len, "0x%08x ('%s')", (UI)cstype4cc->id,
439 cstype4cc->id_dbgstr);
441 else {
442 const char *name = "?";
443 switch(cstype4cc->id) {
444 case 0: name = "LCS_CALIBRATED_RGB"; break;
446 de_snprintf(s_dbgstr, s_len, "%u (%s)", (UI)cstype4cc->id, name);
450 // Read any version of BITMAPINFOHEADER.
452 // Note: Some of this BMP parsing code is duplicated in the
453 // de_fmtutil_get_bmpinfo() library function. The BMP module's needs are
454 // not quite aligned with what that function is intended for, and it
455 // would be too messy to try to add the necessary features to it.
456 static int read_infoheader(deark *c, lctx *d, i64 pos)
458 i64 height_raw;
459 i64 clr_used_raw;
460 int bitcount_ok = 0;
461 int cmpr_ok = 0;
462 int retval = 0;
463 i64 nplanes;
465 de_dbg(c, "info header at %"I64_FMT, pos);
466 de_dbg_indent(c, 1);
467 de_dbg(c, "info header size: %"I64_FMT, d->infohdrsize);
469 if(d->version==DE_BMPVER_OS2V1) {
470 d->width = de_getu16le(pos+4);
471 d->height = de_getu16le(pos+6);
472 nplanes = de_getu16le(pos+8);
474 else {
475 d->width = de_geti32le(pos+4);
476 height_raw = de_geti32le(pos+8);
477 if(height_raw<0) {
478 d->top_down = 1;
479 d->height = -height_raw;
481 else {
482 d->height = height_raw;
484 nplanes = de_getu16le(pos+12);
486 d->pdwidth = d->width; // Default "padded width"
487 de_dbg_dimensions(c, d->width, d->height);
488 if(d->top_down) {
489 de_dbg(c, "orientation: top-down");
491 else {
492 d->createflags |= DE_CREATEFLAG_FLIP_IMAGE;
495 de_dbg(c, "planes: %d", (int)nplanes);
497 // Already read, in detect_bmp_version()
498 de_dbg(c, "bits/pixel: %d", (int)d->bitcount);
500 // FIXME? The conditional test for 64 may lead to misleading error messages
501 // (but I'm afraid something might break without it).
502 if(d->bitcount==0 || d->bitcount==1 || d->bitcount==2 || d->bitcount==4 ||
503 d->bitcount==8 || d->bitcount==16 || d->bitcount==24 || d->bitcount==32 ||
504 (d->bitcount==64 && d->version==DE_BMPVER_64BIT))
506 bitcount_ok = 1;
509 if(d->version==DE_BMPVER_OS2V1) {
510 d->bytes_per_pal_entry = 3;
512 else {
513 char cmprname[80];
514 // d->compression_field was already read, in detect_bmp_version()
515 fmtutil_get_bmp_compression_name(d->compression_field, cmprname, sizeof(cmprname),
516 (d->version==DE_BMPVER_OS2V2));
517 de_dbg(c, "compression (etc.): %u (%s)", (UI)d->compression_field, cmprname);
518 d->bytes_per_pal_entry = 4;
521 d->compression_type = CMPR_NONE; // Temporary default
523 switch(d->compression_field) {
524 case 0: // BI_RGB
525 if(d->bitcount==16 || d->bitcount==32) {
526 d->bitfields_type = BF_DEFAULT;
528 d->compression_type = CMPR_NONE;
529 cmpr_ok = 1;
530 break;
531 case 1: // BI_RLE8
532 d->compression_type=CMPR_RLE8;
533 cmpr_ok = 1;
534 break;
535 case 2: // BI_RLE4
536 d->compression_type=CMPR_RLE4;
537 cmpr_ok = 1;
538 break;
539 case 3: // BI_BITFIELDS or Huffman_1D
540 if(d->version==DE_BMPVER_OS2V2) {
541 if(d->bitcount==1) {
542 d->compression_type=CMPR_HUFFMAN1D;
543 cmpr_ok = 1;
546 else if(d->bitcount==16 || d->bitcount==32) {
547 d->compression_type = CMPR_NONE;
548 cmpr_ok = 1;
549 if(d->infohdrsize>=52) {
550 d->bitfields_type = BF_IN_HEADER;
552 else {
553 d->bitfields_type = BF_SEGMENT;
554 d->bitfields_segment_len = 12;
557 break;
558 case 4: // BI_JPEG or RLE24
559 if(d->version==DE_BMPVER_OS2V2) {
560 if(d->bitcount==24) {
561 d->compression_type=CMPR_RLE24;
562 cmpr_ok = 1;
565 else {
566 d->compression_type=CMPR_JPEG;
567 cmpr_ok = 1;
569 break;
570 case 5: // BI_PNG
571 d->compression_type=CMPR_PNG;
572 cmpr_ok = 1;
573 break;
574 case 6: // BI_ALPHABITFIELDS
575 if(d->bitcount==16 || d->bitcount==32) {
576 d->compression_type = CMPR_NONE;
577 cmpr_ok = 1;
578 if(d->infohdrsize>=56) {
579 d->bitfields_type = BF_IN_HEADER;
581 else {
582 d->bitfields_type = BF_SEGMENT;
583 d->bitfields_segment_len = 16;
586 break;
589 if(d->infohdrsize>=24) {
590 d->size_image = de_getu32le(pos+20);
591 de_dbg(c, "biSizeImage: %"I64_FMT, d->size_image);
594 if(d->infohdrsize>=32) {
595 d->xpelspermeter = de_geti32le(pos+24);
596 d->ypelspermeter = de_geti32le(pos+28);
597 de_dbg(c, "density: %d"DE_CHAR_TIMES"%d pixels/meter", (int)d->xpelspermeter, (int)d->ypelspermeter);
598 if(d->xpelspermeter>0 && d->ypelspermeter>0) {
599 d->fi->density.code = DE_DENSITY_DPI;
600 d->fi->density.xdens = (double)d->xpelspermeter * 0.0254;
601 d->fi->density.ydens = (double)d->ypelspermeter * 0.0254;
605 if(d->infohdrsize>=36)
606 clr_used_raw = de_getu32le(pos+32);
607 else
608 clr_used_raw = 0;
610 if(d->bitcount>=1 && d->bitcount<=8 && clr_used_raw==0) {
611 d->pal_entries = ((i64)1)<<d->bitcount;
613 else {
614 d->pal_entries = clr_used_raw;
616 de_dbg(c, "number of palette colors: %d", (int)d->pal_entries);
618 // Note that after 40 bytes, WINV345 and OS2V2 header fields are different,
619 // so we have to pay more attention to the version.
621 if(d->bitfields_type==BF_IN_HEADER) {
622 do_read_bitfields(c, d, pos+40, d->infohdrsize>=56 ? 16 : 12);
625 if(d->bitfields_type==BF_DEFAULT) {
626 set_default_bitfields(c, d);
629 if(d->version==DE_BMPVER_WINV345 && d->infohdrsize>=108) {
630 char cstype_descr_dbgstr[80];
631 dbuf_read_fourcc(c->infile, pos+56, &d->cstype4cc, 4, DE_4CCFLAG_REVERSED);
632 get_cstype_descr_dbgstr(&d->cstype4cc, cstype_descr_dbgstr, sizeof(cstype_descr_dbgstr));
633 de_dbg(c, "CSType: %s", cstype_descr_dbgstr);
636 if(d->version==DE_BMPVER_WINV345 && d->infohdrsize>=124) {
637 u32 intent;
638 intent = (u32)de_getu32le(pos+108);
639 de_dbg(c, "intent: %u", (UI)intent);
642 if(d->version==DE_BMPVER_WINV345 && d->infohdrsize>=124 &&
643 (d->cstype4cc.id==CODE_MBED || d->cstype4cc.id==CODE_LINK))
645 d->profile_offset_raw = de_getu32le(pos+112);
646 de_dbg(c, "profile offset: %d+%"I64_FMT, (int)FILEHEADER_SIZE,
647 d->profile_offset_raw);
648 d->profile_size = de_getu32le(pos+116);
649 de_dbg(c, "profile size: %"I64_FMT, d->profile_size);
652 if(!bitcount_ok) {
653 de_err(c, "Bad or unsupported bits/pixel: %d", (int)d->bitcount);
654 goto done;
656 if(!cmpr_ok) {
657 de_err(c, "Unsupported compression type: %u", (UI)d->compression_field);
658 goto done;
660 if(!de_good_image_dimensions(c, d->width, d->height)) {
661 goto done;
664 retval = 1;
665 done:
666 de_dbg_indent(c, -1);
667 return retval;
670 static void do_read_linked_profile(deark *c, lctx *d)
672 de_ucstring *fname = NULL;
674 de_dbg(c, "linked profile filename at %"I64_FMT, d->profile_offset);
675 fname = ucstring_create(c);
676 dbuf_read_to_ucstring_n(c->infile, d->profile_offset,
677 d->profile_size, DE_DBG_MAX_STRLEN, fname,
678 DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_WINDOWS1252);
679 de_dbg_indent(c, 1);
680 de_dbg(c, "profile filename: \"%s\"", ucstring_getpsz(fname));
681 de_dbg_indent(c, -1);
682 ucstring_destroy(fname);
685 static void do_read_embedded_profile(deark *c, lctx *d)
687 de_dbg(c, "embedded profile at %"I64_FMT", size=%"I64_FMT, d->profile_offset,
688 d->profile_size);
689 de_dbg_indent(c, 1);
690 dbuf_create_file_from_slice(c->infile, d->profile_offset, d->profile_size, "icc",
691 NULL, DE_CREATEFLAG_IS_AUX);
692 de_dbg_indent(c, -1);
695 static void do_read_profile(deark *c, lctx *d)
697 if(d->want_returned_img) return;
698 if(d->version!=DE_BMPVER_WINV345) return;
699 if(d->infohdrsize<124) return;
700 if(d->profile_offset_raw==0 || d->profile_size==0) return;
701 d->profile_offset = FILEHEADER_SIZE + d->profile_offset_raw;
702 if(d->profile_offset+d->profile_size > c->infile->len) return;
703 if(d->cstype4cc.id==CODE_LINK) {
704 do_read_linked_profile(c, d);
706 else if(d->cstype4cc.id==CODE_MBED) {
707 do_read_embedded_profile(c, d);
711 // Some OS/2v2 files exist with bad (3-bytes/color) palettes.
712 // Try to detect them.
713 static void do_os2v2_bad_palette(deark *c, lctx *d)
715 i64 pal_space_avail;
716 i64 pal_bytes_if_3bpc;
717 i64 pal_bytes_if_4bpc;
718 int nonzero_rsvd;
719 int i;
721 if(d->version!=DE_BMPVER_OS2V2) return;
722 if(d->pal_entries<1) return;
724 pal_space_avail = d->bits_offset - d->pal_pos;
725 pal_bytes_if_4bpc = 4*d->pal_entries;
726 pal_bytes_if_3bpc = 3*d->pal_entries;
728 if(pal_space_avail>=pal_bytes_if_4bpc) return;
729 if(pal_space_avail<pal_bytes_if_3bpc || pal_space_avail>(pal_bytes_if_3bpc+1)) return;
731 // Look for nonzero 'reserved' bytes
732 nonzero_rsvd = 0;
733 for(i=0; i<pal_bytes_if_3bpc; i+=4) {
734 if(de_getbyte(d->pal_pos + i + 3) != 0) {
735 nonzero_rsvd = 1;
736 break;
739 if(!nonzero_rsvd) return;
741 de_warn(c, "Assuming palette has 3 bytes per entry, instead of 4");
742 d->bytes_per_pal_entry = 3;
745 static void do_read_palette(deark *c, lctx *d)
747 i64 pal_size_in_bytes;
749 if(d->pal_entries<1) return;
751 pal_size_in_bytes = d->pal_entries*d->bytes_per_pal_entry;
752 if(d->pal_pos+pal_size_in_bytes > d->bits_offset) {
753 de_warn(c, "Palette at %"I64_FMT" (size %"I64_FMT") overlaps bitmap at %"I64_FMT,
754 d->pal_pos, pal_size_in_bytes, d->bits_offset);
755 if(d->version==DE_BMPVER_OS2V2) {
756 do_os2v2_bad_palette(c, d);
760 de_dbg(c, "color table at %"I64_FMT", %"I64_FMT" entries", d->pal_pos, d->pal_entries);
762 de_dbg_indent(c, 1);
763 de_read_palette_rgb(c->infile, d->pal_pos, d->pal_entries, d->bytes_per_pal_entry,
764 d->pal, 256, DE_GETRGBFLAG_BGR);
766 d->pal_is_grayscale = de_is_grayscale_palette(d->pal, d->pal_entries);
767 de_dbg_indent(c, -1);
770 // A wrapper for de_bitmap_create()
771 static de_bitmap *bmp_bitmap_create(deark *c, lctx *d, int bypp)
773 de_bitmap *img;
775 img = de_bitmap_create2(c, d->width, d->pdwidth, d->height, bypp);
776 return img;
779 static void do_image_paletted(deark *c, lctx *d, dbuf *bits, i64 bits_offset, u8 want_trns)
781 int bypp;
783 if(d->pal_is_grayscale) bypp = 1;
784 else bypp = 3;
785 if(want_trns) bypp++;
787 d->img = bmp_bitmap_create(c, d, bypp);
788 de_convert_image_paletted(bits, bits_offset,
789 d->bitcount, d->rowspan, d->pal, d->img, 0);
792 static void do_image_24bit(deark *c, lctx *d, dbuf *bits, i64 bits_offset, u8 want_trns)
794 i64 i, j;
795 u32 clr;
796 int bypp;
798 if(want_trns) bypp = 4;
799 else bypp = 3;
801 d->img = bmp_bitmap_create(c, d, bypp);
802 for(j=0; j<d->height; j++) {
803 i64 rowpos = bits_offset + j*d->rowspan;
804 i64 pos_in_this_row = 0;
805 u8 cbuf[3];
807 for(i=0; i<d->pdwidth; i++) {
808 dbuf_read(bits, cbuf, rowpos + pos_in_this_row, 3);
809 if(pos_in_this_row+3 > d->rowspan) {
810 // If -padpix was used, a partial pixel at the end of the row is
811 // possible. Happens when width == 1 or 2 (mod 4).
812 // To handle that, zero out the byte(s) that we shouldn't have read.
813 cbuf[2] = 0;
814 if(pos_in_this_row+2 > d->rowspan) {
815 cbuf[1] = 0;
818 clr = DE_MAKE_RGB(cbuf[2], cbuf[1], cbuf[0]);
819 de_bitmap_setpixel_rgb(d->img, i, j, clr);
820 pos_in_this_row += 3;
825 static void do_image_16_32bit(deark *c, lctx *d, dbuf *bits, i64 bits_offset)
827 i64 i, j;
828 int has_transparency;
829 u32 v;
830 i64 k;
831 u8 sm[4];
833 if(d->bitfields_type==BF_SEGMENT) {
834 has_transparency = (d->bitfields_segment_len>=16 && d->bitfield[3].mask!=0);
836 else if(d->bitfields_type==BF_IN_HEADER) {
837 has_transparency = (d->bitfield[3].mask!=0);
839 else {
840 has_transparency = 0;
843 d->img = bmp_bitmap_create(c, d, has_transparency?4:3);
844 for(j=0; j<d->height; j++) {
845 for(i=0; i<d->pdwidth; i++) {
846 if(d->bitcount==16) {
847 v = (u32)dbuf_getu16le(bits, bits_offset + j*d->rowspan + 2*i);
849 else {
850 v = (u32)dbuf_getu32le(bits, bits_offset + j*d->rowspan + 4*i);
853 for(k=0; k<4; k++) {
854 if(d->bitfield[k].mask!=0) {
855 sm[k] = (u8)(0.5 + d->bitfield[k].scale * (double)((v&d->bitfield[k].mask) >> d->bitfield[k].shift));
857 else {
858 if(k==3)
859 sm[k] = 255; // Default alpha sample = opaque
860 else
861 sm[k] = 0; // Default other samples = 0
864 de_bitmap_setpixel_rgba(d->img, i, j, DE_MAKE_RGBA(sm[0], sm[1], sm[2], sm[3]));
869 static void do_image_64bit(deark *c, lctx *d, dbuf *bits, i64 bits_offset)
871 de_bitmap *imghi = NULL;
872 de_bitmap *imglo = NULL;
873 i64 i, j;
874 size_t k;
875 u8 range_flag = 0;
876 u8 sm_hi[4];
877 u8 sm_lo[4];
878 int sm16[4];
880 if(d->want_returned_img) return; // Not supported for this image type
881 imghi = bmp_bitmap_create(c, d, 4);
882 imglo = bmp_bitmap_create(c, d, 4);
883 for(j=0; j<d->height; j++) {
884 i64 pos;
886 pos = bits_offset + j*d->rowspan;
887 for(i=0; i<d->pdwidth; i++) {
888 sm16[2] = (int)dbuf_geti16le_p(bits, &pos);
889 sm16[1] = (int)dbuf_geti16le_p(bits, &pos);
890 sm16[0] = (int)dbuf_geti16le_p(bits, &pos);
891 sm16[3] = (int)dbuf_geti16le_p(bits, &pos);
893 // This is a signed "fixed point" format.
894 // Full sample range is -32768 to 32767 (= -4.0 to +3.999);
895 // 0 is the normal min brightness ("black" or transparent), and
896 // 8192 is the normal max brightness ("white" or opaque).
897 // Colorspace is, apparently, linear.
898 for(k=0; k<4; k++) {
899 if(sm16[k]<0 || sm16[k]>8192) {
900 range_flag = 1;
902 de_scale_n_to_16bit(8192, sm16[k], &sm_hi[k], &sm_lo[k]);
904 de_bitmap_setpixel_rgba(imghi, i, j, DE_MAKE_RGBA(sm_hi[0], sm_hi[1], sm_hi[2], sm_hi[3]));
905 de_bitmap_setpixel_rgba(imglo, i, j, DE_MAKE_RGBA(sm_lo[0], sm_lo[1], sm_lo[2], sm_lo[3]));
909 if(range_flag) {
910 de_warn(c, "Image has samples outside the normal range");
912 d->fi->linear_colorpace = 1;
913 d->createflags |= DE_CREATEFLAG_OPT_IMAGE;
914 de_bitmap16_write_to_file_finfo(imghi, imglo, d->fi, d->createflags);
915 de_bitmap_destroy(imghi);
916 de_bitmap_destroy(imglo);
919 static void do_image_rle(deark *c, lctx *d, dbuf *bits, i64 bits_offset)
921 struct rle_dcmpr_ctx *rc = NULL;
922 u8 use_mask = 0;
923 u8 is_standard = 0;
925 rc = de_malloc(c, sizeof(struct rle_dcmpr_ctx));
927 switch(d->compression_type) {
928 case CMPR_RLE4: rc->unit_size = 4; break;
929 case CMPR_RLE8: rc->unit_size = 8; break;
930 case CMPR_RLE24: rc->unit_size = 24; break;
931 default:
932 goto done;
935 if(rc->unit_size == d->bitcount) {
936 is_standard = 1;
939 if(is_standard) {
940 use_mask = 1;
941 rc->mask = de_bitmap_create(c, d->width, d->height, 1);
943 else {
944 rc->disallow_delta = 1;
947 rc->width_in_units = de_pad_to_n(d->bitcount*d->width, rc->unit_size)/rc->unit_size;
948 rc->height = d->height;
949 rc->dst_rowspan = d->rowspan;
950 rc->inf = bits;
951 rc->inf_startpos = bits_offset;
952 rc->inf_endpos = bits->len;
953 rc->unc_pixels = dbuf_create_membuf(c, rc->height*rc->dst_rowspan, 0x1);
954 dbuf_enable_wbuffer(rc->unc_pixels);
956 decompress_rle_to_bytes(c, rc);
957 if(rc->errflag) goto done;
959 if(!is_standard) {
960 // For example, the nonstandard "Monochrome RLE" format supported by
961 // the DOS software GDS, by Photodex.
962 de_warn(c, "Nonstandard image type. Might not be decoded correctly.");
965 if(d->bitcount<=8) {
966 do_image_paletted(c, d, rc->unc_pixels, 0, use_mask);
968 else {
969 do_image_24bit(c, d, rc->unc_pixels, 0, use_mask);
972 if(rc->mask) {
973 de_bitmap_apply_mask(d->img, rc->mask, 0);
976 done:
977 if(rc) {
978 dbuf_close(rc->unc_pixels);
979 de_bitmap_destroy(rc->mask);
980 de_free(c, rc);
984 static void do_image_huffman1d(deark *c, lctx *d)
986 dbuf *unc_pixels = NULL;
987 struct de_dfilter_in_params dcmpri;
988 struct de_dfilter_out_params dcmpro;
989 struct de_dfilter_results dres;
990 struct de_fax34_params fax34params;
992 // Caution: These settings might be wrong. I need more information about this format.
993 de_zeromem(&fax34params, sizeof(struct de_fax34_params));
994 fax34params.image_width = d->width;
995 fax34params.image_height = d->height;
996 fax34params.out_rowspan = d->rowspan;
997 fax34params.tiff_cmpr_meth = 3;
998 fax34params.t4options = 0;
999 fax34params.is_lsb = (u8)de_get_ext_option_bool(c, "bmp:huffmanlsb", 0);
1001 unc_pixels = dbuf_create_membuf(c, d->rowspan*d->height, 0x1);
1003 de_dfilter_init_objects(c, &dcmpri, &dcmpro, &dres);
1004 dcmpri.f = c->infile;
1005 dcmpri.pos = d->bits_offset;
1006 dcmpri.len = get_bits_size(c, d);
1007 dcmpro.f = unc_pixels;
1008 dcmpro.len_known = 1;
1009 dcmpro.expected_len = d->rowspan*d->height;
1011 fmtutil_fax34_codectype1(c, &dcmpri, &dcmpro, &dres,
1012 (void*)&fax34params);
1014 do_image_paletted(c, d, unc_pixels, 0, 0);
1016 dbuf_close(unc_pixels);
1019 static void extract_embedded_image(deark *c, lctx *d, const char *ext)
1021 i64 nbytes;
1023 if(d->want_returned_img) return;
1025 nbytes = get_bits_size(c, d);
1026 if(nbytes<1) return;
1028 dbuf_create_file_from_slice(c->infile, d->bits_offset, nbytes, ext, NULL, 0);
1031 static void do_image(deark *c, lctx *d)
1033 de_dbg(c, "bitmap at %"I64_FMT, d->bits_offset);
1035 if(d->bits_offset >= c->infile->len) {
1036 de_err(c, "Bad bits-offset field");
1037 goto done;
1040 d->rowspan = ((d->bitcount*d->width +31)/32)*4;
1041 if(d->compression_type==CMPR_NONE && !d->want_returned_img) {
1042 if(c->padpix && d->bitcount==24) {
1043 // The 24-bit decoder can handle partial pixels.
1044 d->pdwidth = (d->rowspan+2)/3;
1046 else if(d->bitcount>=1 && d->bitcount<=24) {
1047 // By default, ignore a partial-pixel's worth of padding.
1048 // bits-per-row / bits-per-pixel
1049 d->pdwidth = (d->rowspan*8) / d->bitcount;
1053 if(d->bitcount>=1 && d->bitcount<=8 && d->compression_type==CMPR_NONE) {
1054 do_image_paletted(c, d, c->infile, d->bits_offset, 0);
1056 else if(d->bitcount==24 && d->compression_type==CMPR_NONE) {
1057 do_image_24bit(c, d, c->infile, d->bits_offset, 0);
1059 else if((d->bitcount==16 || d->bitcount==32) && d->compression_type==CMPR_NONE) {
1060 do_image_16_32bit(c, d, c->infile, d->bits_offset);
1062 else if((d->compression_type==CMPR_RLE4 && (d->bitcount==1 || d->bitcount==4)) ||
1063 (d->compression_type==CMPR_RLE8 && d->bitcount==8) ||
1064 (d->compression_type==CMPR_RLE24 && d->bitcount==24))
1066 do_image_rle(c, d, c->infile, d->bits_offset);
1068 else if(d->version==DE_BMPVER_64BIT) {
1069 do_image_64bit(c, d, c->infile, d->bits_offset);
1071 else if(d->compression_type==CMPR_HUFFMAN1D && d->bitcount==1) {
1072 do_image_huffman1d(c, d);
1074 else if(d->compression_type==CMPR_JPEG) {
1075 extract_embedded_image(c, d, "jpg");
1077 else if(d->compression_type==CMPR_PNG) {
1078 extract_embedded_image(c, d, "png");
1080 else {
1081 de_err(c, "This type of BMP image is not supported");
1082 goto done;
1085 if(d->img && !d->want_returned_img) {
1086 d->createflags |= DE_CREATEFLAG_OPT_IMAGE;
1087 de_bitmap_write_to_file_finfo(d->img, d->fi, d->createflags);
1090 done:
1094 static void de_run_bmp(deark *c, de_module_params *mparams)
1096 lctx *d = NULL;
1097 i64 pos;
1099 d = de_malloc(c, sizeof(lctx));
1101 if(mparams) {
1102 // if in_params.flags & 0x2, then the parent module wants the decoded
1103 // image to be returned, instead of written to a file.
1104 // in_params.obj1 points to an fmtutil_bmp_mparams_indata struct,
1105 // allocated by the caller, that will be filled in by the bmp module.
1106 // [It's acknowledged that out_params seems more appropriate for data
1107 // going from the child to the parent. But I don't think it's right
1108 // for the parent to put stuff in out_params, and I want the parent
1109 // to both allocate and free the container struct. Some rethinking of this
1110 // data passing system is probably in order.]
1111 if(mparams->in_params.flags & 0x02) {
1112 d->want_returned_img = 1;
1116 d->fi = de_finfo_create(c);
1118 if(dbuf_memcmp(c->infile, 0, "BM", 2)) {
1119 de_err(c, "Not a BMP file.");
1120 goto done;
1123 if(!detect_bmp_version(c, d)) {
1124 de_err(c, "Unidentified BMP version.");
1125 goto done;
1128 switch(d->version) {
1129 case DE_BMPVER_OS2V1:
1130 if(d->fsize==26) {
1131 de_declare_fmt(c, "BMP, OS/2 v1");
1133 else {
1134 de_declare_fmt(c, "BMP, OS/2 v1 or Windows v2");
1136 break;
1137 case DE_BMPVER_OS2V2: de_declare_fmt(c, "BMP, OS/2 v2"); break;
1138 case DE_BMPVER_WINV345:
1139 switch(d->infohdrsize) {
1140 case 40: de_declare_fmt(c, "BMP, Windows v3"); break;
1141 case 108: de_declare_fmt(c, "BMP, Windows v4"); break;
1142 case 124: de_declare_fmt(c, "BMP, Windows v5"); break;
1143 default: de_declare_fmt(c, "BMP, Windows v3+");
1145 break;
1146 case DE_BMPVER_64BIT:
1147 de_declare_fmt(c, "BMP, 64-bit");
1148 break;
1151 pos = 0;
1152 if(!read_fileheader(c, d, pos)) goto done;
1153 pos += FILEHEADER_SIZE;
1154 if(!read_infoheader(c, d, pos)) goto done;
1155 pos += d->infohdrsize;
1156 if(d->bitfields_type==BF_SEGMENT) {
1157 de_dbg(c, "bitfields segment at %"I64_FMT", len=%"I64_FMT, pos, d->bitfields_segment_len);
1158 if(pos+d->bitfields_segment_len > d->bits_offset) {
1159 de_warn(c, "BITFIELDS segment at %"I64_FMT" (size %"I64_FMT") overlaps bitmap at %"I64_FMT,
1160 pos, d->bitfields_segment_len, d->bits_offset);
1162 de_dbg_indent(c, 1);
1163 do_read_bitfields(c, d, pos, d->bitfields_segment_len);
1164 de_dbg_indent(c, -1);
1165 pos += d->bitfields_segment_len;
1167 d->pal_pos = pos;
1168 do_read_palette(c, d);
1169 do_image(c, d);
1170 do_read_profile(c, d);
1172 if(d->want_returned_img && mparams && mparams->in_params.obj1) {
1173 struct fmtutil_bmp_mparams_indata *idata =
1174 (struct fmtutil_bmp_mparams_indata*)mparams->in_params.obj1;
1175 idata->img = d->img;
1176 d->img = NULL;
1177 idata->fi = d->fi;
1178 d->fi = NULL;
1179 idata->createflags = d->createflags;
1182 done:
1183 if(d) {
1184 de_bitmap_destroy(d->img);
1185 de_finfo_destroy(c, d->fi);
1186 de_free(c, d);
1190 // Note that this function must work together with de_identify_vbm().
1191 static int de_identify_bmp(deark *c)
1193 i64 fsize;
1194 i64 bits_offset;
1195 i64 infohdrsize;
1196 u32 compression_field = 0;
1197 int bmp_ext;
1198 u8 buf[6];
1200 de_read(buf, 0, sizeof(buf));
1201 if(de_memcmp(buf, "BM", 2)) {
1202 return 0;
1205 bmp_ext = de_input_file_has_ext(c, "bmp");
1206 fsize = de_getu32le_direct(&buf[2]);
1207 bits_offset = de_getu32le(10);
1208 infohdrsize = de_getu32le(14);
1209 if(infohdrsize>=20) {
1210 compression_field = (u32)de_getu32le(14+16);
1211 // Don't detect KQP format as BMP
1212 if(infohdrsize==68 && compression_field==0x4745504aU) return 0;
1215 if(infohdrsize<12) return 0;
1216 if(infohdrsize>256) return 0;
1217 if(bits_offset>=c->infile->len) return 0;
1218 if(bits_offset<14+infohdrsize) return 0;
1219 if(fsize==c->infile->len && bmp_ext) return 100;
1220 if(buf[2]==0xcb) {
1221 // Possible VBM file.
1222 // Windows BMP files are highly unlikely to start with 'B' 'M' \xcb,
1223 // because that would imply the file is an odd number of bytes in size,
1224 // which is legal but silly.
1225 if(bmp_ext) return 90;
1226 return 5;
1229 if(bmp_ext) return 100;
1230 if(infohdrsize==12 || infohdrsize==40 || infohdrsize==108 ||
1231 infohdrsize==124)
1233 return 100;
1235 return 90;
1238 void de_module_bmp(deark *c, struct deark_module_info *mi)
1240 mi->id = "bmp";
1241 mi->desc = "BMP (Windows or OS/2 bitmap)";
1242 mi->run_fn = de_run_bmp;
1243 mi->identify_fn = de_identify_bmp;
1246 // **************************************************************************
1247 // Pegasus JPEG (PIC JPEG)
1248 // Konica KQP
1249 // **************************************************************************
1251 // This is a JPEG parser that does only what's needed for Pegasus JPEG conversion.
1253 struct de_scan_jpeg_data_ctx {
1254 // Positions are absolute, and start with the start of the marker.
1255 // Lengths are the total length of the segment.
1256 u8 error_flag;
1257 u8 found_sos;
1258 u8 found_dht;
1259 u8 found_dqt;
1260 u8 found_sof;
1261 u8 found_jfif;
1262 u8 found_pic;
1263 u8 found_8bim;
1264 i64 soi_pos;
1265 i64 sos_pos;
1266 i64 sof_pos;
1267 i64 jfif_pos;
1268 i64 pic_pos;
1269 i64 pic_len;
1270 i64 _8bim_pos;
1271 i64 _8bim_len;
1274 // Caller initializes scan_jpeg_data_ctx.
1275 static void de_scan_jpeg_data(deark *c, dbuf *f, i64 pos1, i64 len,
1276 struct de_scan_jpeg_data_ctx *sd)
1278 i64 pos = pos1;
1279 i64 endpos = pos1+len;
1281 while(1) {
1282 i64 seg_startpos;
1283 i64 seg_len;
1284 u8 b1;
1286 if(pos+4 > endpos) goto done;
1287 seg_startpos = pos;
1288 if(dbuf_getbyte_p(f, &pos) != 0xff) {
1289 sd->error_flag = 1;
1290 goto done;
1293 b1 = dbuf_getbyte_p(f, &pos);
1294 if(b1==0 || b1==0xff) {
1295 sd->error_flag = 1;
1296 goto done;
1299 if(seg_startpos==pos1) { // Expecting SOI
1300 if(b1!=0xd8) goto done;
1301 sd->soi_pos = seg_startpos;
1302 continue;
1305 if(b1==0xd9) { // EOI
1306 goto done;
1309 // (Not expecting any other bare markers)
1311 seg_len = 2 + dbuf_getu16be_p(f, &pos);
1313 switch(b1) {
1314 case 0xc4: // DHT
1315 sd->found_dht = 1;
1316 break;
1317 case 0xda: // SOS
1318 sd->found_sos = 1;
1319 sd->sos_pos = seg_startpos;
1320 goto done; // we don't scan past SOS
1321 case 0xdb: // DQT
1322 sd->found_dqt = 1;
1323 break;
1324 case 0xe0: // APP0
1325 if(seg_len>=11 && !sd->found_jfif) {
1326 if(!dbuf_memcmp(f, seg_startpos+4, "JFIF\0", 5)) {
1327 sd->found_jfif = 1;
1328 sd->jfif_pos = seg_startpos;
1331 break;
1332 case 0xe1: // APP1
1333 if(seg_len>=11 && !sd->found_pic) {
1334 if(!dbuf_memcmp(f, seg_startpos+4, "PIC\0", 4)) {
1335 sd->found_pic = 1;
1336 sd->pic_pos = seg_startpos;
1337 sd->pic_len = seg_len;
1340 break;
1341 case 0xe2: // APP2
1342 if(seg_len>8 && !sd->found_8bim) {
1343 if(!dbuf_memcmp(f, seg_startpos+4, "8BIM", 4)) {
1344 sd->found_8bim = 1;
1345 sd->_8bim_pos = seg_startpos;
1346 sd->_8bim_len = seg_len;
1349 break;
1350 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1351 case 0xc5: case 0xc6: case 0xc7:
1352 case 0xc9: case 0xca: case 0xcb:
1353 case 0xcd: case 0xce: case 0xcf:
1354 sd->found_sof = 1;
1355 sd->sof_pos = seg_startpos;
1356 break;
1359 pos = seg_startpos + seg_len;
1362 done:
1366 static void picjpeg_scale_qtable(u8 tbl[64], UI setting)
1368 size_t i;
1370 for(i=0; i<64; i++) {
1371 UI x;
1373 x = tbl[i];
1374 // The denominator 32 might not be exactly right, but assuming this is
1375 // the right idea, it's not too far off.
1376 x = (x * setting)/32;
1377 if(x>255) x = 255;
1378 else if(x<1) x = 1;
1379 tbl[i] = x;
1383 static void de_run_picjpeg(deark *c, de_module_params *mparams)
1385 i64 bits_offset;
1386 i64 jpeg_data_len;
1387 UI lum_setting;
1388 UI chr_setting;
1389 int need_errmsg = 0;
1390 i64 srcpos;
1391 dbuf *outf = NULL;
1392 i64 i;
1393 u32 hdr[7];
1394 struct de_bmpinfo bi;
1395 struct de_scan_jpeg_data_ctx sd;
1397 de_declare_fmt(c, "Pegasus JPEG or KQP");
1399 (void)fmtutil_get_bmpinfo(c, c->infile, &bi, 0, c->infile->len,
1400 DE_BMPINFO_HAS_FILEHEADER|DE_BMPINFO_CMPR_IS_4CC|DE_BMPINFO_NOERR);
1401 // TODO?: Read the palette (for dbg info)
1403 bits_offset = de_getu32le(10);
1404 jpeg_data_len = c->infile->len - bits_offset;
1405 if(jpeg_data_len<2) {
1406 need_errmsg = 1;
1407 goto done;
1410 // Extended BMP header fields
1411 for(i=0; i<7; i++) {
1412 hdr[i] = (u32)de_getu32le(54+4*i);
1413 de_dbg(c, "bmp ext hdr[%u]: %u", (UI)i, (UI)hdr[i]);
1416 // Validate the extra BMP fields.
1417 // Not sure what all these are.
1418 // [5] & [6] are related to sampling factors.
1419 if(hdr[0]!=44 || hdr[1]!=24 || hdr[2]!=0 || hdr[3]!=2 ||
1420 hdr[4]!=8)
1422 need_errmsg = 1;
1423 goto done;
1426 de_zeromem(&sd, sizeof(struct de_scan_jpeg_data_ctx));
1427 de_scan_jpeg_data(c, c->infile, bits_offset, c->infile->len-bits_offset, &sd);
1428 if(sd.error_flag) {
1429 need_errmsg = 1;
1430 goto done;
1432 if(!sd.found_pic || !sd.found_sof || !sd.found_sos) {
1433 need_errmsg = 1;
1434 goto done;
1436 if(sd.pic_pos >= sd.sof_pos) {
1437 need_errmsg = 1;
1438 goto done;
1441 // Read from "PIC" segment.
1442 lum_setting = (UI)de_getbyte(sd.pic_pos+9);
1443 chr_setting = (UI)de_getbyte(sd.pic_pos+10);
1444 de_dbg(c, "luminance: %u", lum_setting);
1445 de_dbg(c, "chrominance: %u", chr_setting);
1447 de_dbg(c, "has DHT: %u", (UI)sd.found_dht);
1449 outf = dbuf_create_output_file(c, "jpg", NULL, 0);
1451 srcpos = sd.soi_pos;
1452 dbuf_copy(c->infile, srcpos, 2, outf);
1453 srcpos += 2;
1455 if(sd.found_jfif && sd.jfif_pos==srcpos) {
1456 // Copy everything before the JFIF version number
1457 dbuf_copy(c->infile, srcpos, 9, outf);
1458 // Sometimes the JFIF version number is wrong, so we correct it.
1459 dbuf_writebyte(outf, 1);
1460 dbuf_writebyte(outf, 2);
1461 srcpos += 11;
1464 // Copy everything up to the PIC segment
1465 dbuf_copy(c->infile, srcpos, sd.pic_pos-srcpos, outf);
1467 srcpos = sd.pic_pos + sd.pic_len; // Skip the PIC segment
1469 // Convert the Photoshop Resources segment to a more standard format
1470 if(sd.found_8bim && sd._8bim_pos>=srcpos && sd._8bim_pos<sd.sof_pos) {
1471 // Copy everything up to 8BIM
1472 dbuf_copy(c->infile, srcpos, sd._8bim_pos-srcpos, outf);
1474 dbuf_writeu16be(outf, 0xffed);
1475 dbuf_writeu16be(outf, 2 + 14 + (sd._8bim_len-4));
1476 dbuf_write(outf, (const u8*)"Photoshop 3.0\0", 14);
1477 dbuf_copy(c->infile, sd._8bim_pos+4, sd._8bim_len-4, outf);
1478 srcpos = sd._8bim_pos + sd._8bim_len;
1481 // Copy everything up to SOF
1482 dbuf_copy(c->infile, srcpos, sd.sof_pos-srcpos, outf);
1483 srcpos = sd.sof_pos;
1485 // Insert DQT segments
1486 if(!sd.found_dqt) {
1487 u8 tmptbl[64];
1489 dbuf_write(outf, (const u8*)"\xff\xdb\x00\x43\x00", 5);
1490 fmtutil_get_std_jpeg_qtable(0, tmptbl);
1491 picjpeg_scale_qtable(tmptbl, lum_setting);
1492 dbuf_write(outf, tmptbl, 64);
1494 dbuf_write(outf, (const u8*)"\xff\xdb\x00\x43\x01", 5);
1495 fmtutil_get_std_jpeg_qtable(1, tmptbl);
1496 picjpeg_scale_qtable(tmptbl, chr_setting);
1497 dbuf_write(outf, tmptbl, 64);
1500 // Copy everything up to SOS
1501 dbuf_copy(c->infile, srcpos, sd.sos_pos-srcpos, outf);
1502 srcpos = sd.sos_pos;
1504 // Insert DHT segment
1505 if(!sd.found_dht) {
1506 dbuf_write(outf, (const u8*)"\xff\xc4\x01\xa2\x00", 5);
1507 fmtutil_write_std_jpeg_dht(outf, 0);
1508 dbuf_writebyte(outf, 0x10);
1509 fmtutil_write_std_jpeg_dht(outf, 1);
1510 dbuf_writebyte(outf, 0x01);
1511 fmtutil_write_std_jpeg_dht(outf, 2);
1512 dbuf_writebyte(outf, 0x11);
1513 fmtutil_write_std_jpeg_dht(outf, 3);
1516 // Copy the rest of the file
1517 dbuf_copy(c->infile, srcpos, c->infile->len-srcpos, outf);
1519 done:
1520 if(need_errmsg) {
1521 de_err(c, "Can't convert this Pegasus JPEG file");
1523 dbuf_close(outf);
1526 static int de_identify_picjpeg(deark *c)
1528 if(dbuf_memcmp(c->infile, 0, (const void*)"BM", 2)) return 0;
1529 if(de_getu32le(14) != 68) return 0;
1530 if((UI)de_getu32le(30) != 0x4745504aU) return 0;
1531 return 100;
1534 void de_module_picjpeg(deark *c, struct deark_module_info *mi)
1536 mi->id = "picjpeg";
1537 mi->desc = "Pegasus JPEG, and KQP";
1538 mi->run_fn = de_run_picjpeg;
1539 mi->identify_fn = de_identify_picjpeg;
1540 mi->id_alias[0] = "kqp";
1543 // **************************************************************************
1544 // Raw DIB
1545 // **************************************************************************
1547 static void de_run_dib(deark *c, de_module_params *mparams)
1549 struct de_bmpinfo bi;
1550 UI createflags = 0;
1551 dbuf *outf = NULL;
1552 int implicit_size = 0;
1553 i64 dib_len;
1554 const char *ext = "bmp";
1555 de_finfo *fi_to_use = NULL;
1557 if(mparams) {
1558 // If flags&0x01, try to calculate the proper file size, instead of trusting
1559 // the length of the input file.
1560 if(mparams->in_params.flags & 0x01) implicit_size = 1;
1562 if(mparams->in_params.flags & 0x80) ext = "preview.bmp";
1564 fi_to_use = mparams->in_params.fi;
1567 if(de_havemodcode(c, mparams, 'X')) {
1568 createflags |= DE_CREATEFLAG_IS_AUX;
1571 if(!fmtutil_get_bmpinfo(c, c->infile, &bi, 0, c->infile->len, 0)) {
1572 de_err(c, "Invalid DIB, or not a DIB file");
1573 goto done;
1576 if(implicit_size) {
1577 dib_len = bi.total_size;
1578 if(dib_len > c->infile->len) {
1579 dib_len = c->infile->len;
1582 else {
1583 dib_len = c->infile->len;
1586 outf = dbuf_create_output_file(c, ext, fi_to_use, createflags);
1588 de_dbg(c, "writing a BMP FILEHEADER");
1589 fmtutil_generate_bmpfileheader(c, outf, &bi, 14+dib_len);
1591 de_dbg(c, "copying DIB file");
1592 dbuf_copy(c->infile, 0, dib_len, outf);
1594 done:
1595 dbuf_close(outf);
1598 static int de_identify_dib(deark *c)
1600 i64 n;
1602 n = de_getu32le(0); // biSize
1603 if(n!=40) return 0;
1604 n = de_getu16le(12); // biPlanes
1605 if(n!=1) return 0;
1606 n = de_getu16le(14); // biBitCount
1607 if(n==1 || n==4 || n==8 || n==16 || n==24 || n==32) return 15;
1608 return 0;
1611 // BMP file without a file header.
1612 // This module constructs a BMP file header.
1613 void de_module_dib(deark *c, struct deark_module_info *mi)
1615 mi->id = "dib";
1616 mi->desc = "DIB (raw Windows bitmap)";
1617 mi->run_fn = de_run_dib;
1618 mi->identify_fn = de_identify_dib;
1621 // **************************************************************************
1622 // DDB / "BMP v1"
1623 // **************************************************************************
1625 struct ddbctx_struct {
1626 i64 bmWidthBytes;
1627 UI createflags;
1628 u8 cdr_adjdim_flag;
1629 de_finfo *fi;
1630 u8 have_custom_pal;
1631 de_color pal[256];
1634 static void ddb_convert_pal4planar(deark *c, struct ddbctx_struct *d,
1635 i64 fpos, de_bitmap *img)
1637 const i64 nplanes = 4;
1638 i64 rowspan;
1639 de_color pal16[16];
1641 rowspan = d->bmWidthBytes * nplanes;
1643 // The usual order seems to be
1644 // row0_plane0x1, row0_plane0x2, row0_plane0x4, row0_plane0x8,
1645 // row1_plane0x1, row1_plane0x2, row1_plane0x4, row1_plane0x8,
1646 // ...
1647 // But I have seen another, and I see no way to detect/support it.
1649 de_copy_std_palette(DE_PALID_WIN16, 0, 0, pal16, 16, 0);
1650 de_convert_image_paletted_planar(c->infile, fpos, nplanes, rowspan,
1651 d->bmWidthBytes, pal16, img, 0x2);
1654 static void ddb_convert_pal8(deark *c, struct ddbctx_struct *d,
1655 i64 fpos, de_bitmap *img)
1657 i64 i, j;
1658 size_t k;
1659 int badcolorflag = 0;
1661 de_copy_std_palette(DE_PALID_WIN16, 1, 0, &d->pal[0], 8, 0);
1662 de_copy_std_palette(DE_PALID_WIN16, 1, 8, &d->pal[248], 8, 0);
1664 if(!d->have_custom_pal) {
1665 for(k=16; k<248; k++) {
1666 d->pal[k] = DE_MAKE_RGB(254, (u8)k ,254); // Just an arbitrary color
1670 for(j=0; j<img->height; j++) {
1671 for(i=0; i<img->width; i++) {
1672 UI palent;
1673 de_color clr;
1675 palent = de_getbyte(fpos+j*d->bmWidthBytes+i);
1676 if(!d->have_custom_pal && palent>=8 && palent<248) {
1677 badcolorflag = 1;
1679 clr = d->pal[(UI)palent];
1681 de_bitmap_setpixel_rgb(img, i, j, clr);
1684 if(badcolorflag) {
1685 de_warn(c, "Image uses nonportable colors");
1689 static void ddb_convert_32bit(deark *c, struct ddbctx_struct *d,
1690 i64 fpos, de_bitmap *img)
1692 de_convert_image_rgb(c->infile, fpos, d->bmWidthBytes, 4, img, DE_GETRGBFLAG_BGR);
1695 static void do_ddb_bitmap(deark *c, struct ddbctx_struct *d, i64 pos1)
1697 i64 pos = pos1;
1698 UI bmType;
1699 i64 bmWidth, bmHeight;
1700 i64 pdwidth;
1701 i64 bmPlanes;
1702 i64 bmBitsPixel;
1703 i64 src_realbitsperpixel;
1704 de_bitmap *img = NULL;
1706 bmType = (UI)de_getu16le_p(&pos);
1707 de_dbg(c, "bmType: %u", bmType);
1709 bmWidth = de_getu16le_p(&pos);
1710 bmHeight = de_getu16le_p(&pos);
1711 de_dbg_dimensions(c, bmWidth, bmHeight);
1713 d->bmWidthBytes = de_getu16le_p(&pos);
1714 de_dbg(c, "bytes/row: %d", (int)d->bmWidthBytes);
1716 bmPlanes = (i64)de_getbyte_p(&pos);
1717 de_dbg(c, "planes: %d", (int)bmPlanes);
1719 bmBitsPixel = (i64)de_getbyte_p(&pos);
1720 de_dbg(c, "bmBitsPixel: %d", (int)bmBitsPixel);
1722 pos += 4; // Placeholder for a pointer?
1724 if((bmBitsPixel==1 && bmPlanes==1) ||
1725 (bmBitsPixel==1 && bmPlanes==4) ||
1726 (bmBitsPixel==8 && bmPlanes==1) ||
1727 (bmBitsPixel==32 && bmPlanes==1))
1731 else {
1732 de_err(c, "This type of DDB bitmap is not supported "
1733 "(bmBitsPixel=%d, planes=%d)", (int)bmBitsPixel, (int)bmPlanes);
1734 goto done;
1737 de_dbg(c, "pixels at %"I64_FMT, pos);
1739 src_realbitsperpixel = bmBitsPixel * bmPlanes;
1741 if(d->cdr_adjdim_flag && src_realbitsperpixel==1 &&
1742 bmWidth==bmHeight && (bmWidth==90 || bmWidth==128))
1744 // See comments in the cdr_wl module about "adjdim".
1745 bmWidth--;
1746 bmHeight--;
1747 de_dbg(c, "adjusted dimensions: %"I64_FMT DE_CHAR_TIMES"%"I64_FMT,
1748 bmWidth, bmHeight);
1751 if(!de_good_image_dimensions(c, bmWidth, bmHeight)) goto done;
1753 pdwidth = (d->bmWidthBytes*8) / bmBitsPixel;
1754 img = de_bitmap_create2(c, bmWidth, pdwidth, bmHeight, (src_realbitsperpixel==1)?1:3);
1756 if(bmBitsPixel==1 && bmPlanes==1) {
1757 de_convert_image_bilevel(c->infile, pos, d->bmWidthBytes, img, 0);
1759 else if(bmBitsPixel==1 && bmPlanes==4) {
1760 ddb_convert_pal4planar(c, d, pos, img);
1762 else if(bmBitsPixel==8 && bmPlanes==1) {
1763 ddb_convert_pal8(c, d, pos, img);
1765 else if(bmBitsPixel==32 && bmPlanes==1) {
1766 ddb_convert_32bit(c, d, pos, img);
1769 de_bitmap_write_to_file_finfo(img, d->fi, DE_CREATEFLAG_OPT_IMAGE | d->createflags);
1771 done:
1772 de_bitmap_destroy(img);
1775 static void de_run_ddb(deark *c, de_module_params *mparams)
1777 int has_filetype = 1;
1778 struct ddbctx_struct *d = NULL;
1779 i64 pos = 0;
1781 d = de_malloc(c, sizeof(struct ddbctx_struct));
1782 d->createflags = 0;
1784 if(de_havemodcode(c, mparams, 'N')) {
1785 has_filetype = 0;
1787 if(de_havemodcode(c, mparams, 'X')) {
1788 d->createflags |= DE_CREATEFLAG_IS_AUX;
1790 if(!c->padpix) {
1791 d->cdr_adjdim_flag = (u8)de_havemodcode(c, mparams, 'C');
1793 if(mparams) {
1794 if(mparams->in_params.fi) {
1795 d->fi = mparams->in_params.fi;
1797 // If not NULL, obj1 points to the palette to use (must be de_color[256]).
1798 if(mparams->in_params.obj1) {
1799 d->have_custom_pal = 1;
1800 de_memcpy(d->pal, mparams->in_params.obj1, 256*sizeof(de_color));
1804 if(has_filetype) {
1805 UI file_type;
1806 file_type = (UI)de_getu16le_p(&pos);
1807 de_dbg(c, "file type: 0x%04x", file_type);
1810 do_ddb_bitmap(c, d, pos);
1812 de_free(c, d);
1815 void de_module_ddb(deark *c, struct deark_module_info *mi)
1817 mi->id = "ddb";
1818 mi->desc = "Windows DDB bitmap";
1819 mi->run_fn = de_run_ddb;
1820 mi->identify_fn = NULL;
1821 mi->flags |= DE_MODFLAG_HIDDEN;
1824 // **************************************************************************
1825 // Jigsaw .jig
1826 // Windows 3.x program by Walter A. Kuhn
1827 // (JIGSAW20.ZIP, JIGPUZ00.ZIP, ...)
1828 // **************************************************************************
1830 static int looks_like_bmp_bytes(const u8 *buf, i64 len, UI flags)
1832 int ret;
1834 if(len<30) return 0;
1835 ret = de_memmatch(buf, (const u8*)"BM????\x00\x00\x00\x00??\x00\x00"
1836 "?\x00\x00\x00????????\x01\x00?\x00", 30, '?', 0);
1837 return ret;
1840 static void de_run_jigsaw_wk(deark *c, de_module_params *mparams)
1842 i64 fsize;
1843 dbuf *outf = NULL;
1845 fsize = de_getu32le(2);
1846 if(fsize>c->infile->len) goto done;
1848 outf = dbuf_create_output_file(c, "bmp", NULL, 0);
1849 dbuf_write(outf, (const u8*)"BM", 2);
1850 dbuf_copy(c->infile, 2, fsize-2, outf);
1852 done:
1853 dbuf_close(outf);
1856 static int de_identify_jigsaw_wk(deark *c)
1858 i64 fsize;
1859 int ret;
1860 u8 buf[32];
1862 if(dbuf_memcmp(c->infile, 0, "JG", 2)) {
1863 return 0;
1866 fsize = de_getu32le(2);
1867 if(fsize>c->infile->len) return 0;
1869 de_read(buf, 0, sizeof(buf));
1870 buf[0] = 'B';
1871 buf[1] = 'M';
1872 ret = looks_like_bmp_bytes(buf, sizeof(buf), 0);
1873 if(ret) {
1874 return 95;
1877 return 0;
1880 void de_module_jigsaw_wk(deark *c, struct deark_module_info *mi)
1882 mi->id = "jigsaw_wk";
1883 mi->desc = "Jigsaw .jig";
1884 mi->run_fn = de_run_jigsaw_wk;
1885 mi->identify_fn = de_identify_jigsaw_wk;