1 // This file is part of Deark.
2 // Copyright (C) 2016 Jason Summers
3 // See the file COPYING for terms of use.
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
{
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
35 de_bitmap
*img
; // Image to be written by the main function
37 i64 fsize
; // The "file size" field in the file header
38 i64 bits_offset
; // The bfOffBits field in the file header
41 u32 compression_field
;
42 i64 size_image
; // biSizeImage
43 i64 width
, pdwidth
, height
;
45 i64 pal_entries
; // Actual number stored in file. 0 means no palette.
47 i64 bytes_per_pal_entry
;
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
55 i64 bitfields_segment_len
; // Used if bitfields_type==BF_SEGMENT
57 i64 xpelspermeter
, ypelspermeter
;
65 #define CMPR_HUFFMAN1D 16
68 struct de_fourcc cstype4cc
;
69 i64 profile_offset_raw
;
74 struct bitfieldsinfo bitfield
[4];
78 ///// RLE decompressor
80 struct rle_dcmpr_ctx
{
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.
93 de_bitmap
*mask
; // optional
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;
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);
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);
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);
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
;
169 i64 num_bytes_to_read
;
170 i64 num_units_to_decode
;
171 i64 num_units_decoded
;
178 if(pos
>= rc
->inf_endpos
) {
181 if(rc
->ypos
>= rc
->height
) {
184 if(rc
->ypos
==(rc
->height
-1) && (rc
->xpos
>=rc
->width_in_units
)) {
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
194 rle_to_bytes_on_eol(c
, rc
, rc
->ypos
);
196 else if(b1
==0 && b2
==1) { // End of bitmap
199 else if(b1
==0 && b2
==2) { // Delta
200 i64 newxpos
, newypos
;
203 if(rc
->disallow_delta
) {
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
) {
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);
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
++) {
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;
247 rle_to_bytes_append_unit4(c
, rc
, pix1
, 1);
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) {
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);
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
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);
303 rle_to_bytes_on_eol(c
, rc
, rc
->height
);
304 dbuf_flush(rc
->unc_pixels
);
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
)
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);
334 d
->bitcount
= de_getu16le(pos
+14);
337 if(d
->infohdrsize
==12) {
338 d
->version
= DE_BMPVER_OS2V1
;
341 if(d
->infohdrsize
<16) {
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
;
355 if(d
->infohdrsize
>=16 && d
->infohdrsize
<=64) {
356 if(d
->fsize
==FILEHEADER_SIZE
+d
->infohdrsize
) {
357 d
->version
= DE_BMPVER_OS2V2
;
361 if((d
->compression_field
==3 && d
->bitcount
==1) ||
362 (d
->compression_field
==4 && d
->bitcount
==24))
364 d
->version
= DE_BMPVER_OS2V2
;
368 if(d
->infohdrsize
!=40 && d
->infohdrsize
!=52 && d
->infohdrsize
!=56) {
369 d
->version
= DE_BMPVER_OS2V2
;
374 d
->version
= DE_BMPVER_WINV345
;
378 static int read_fileheader(deark
*c
, lctx
*d
, i64 pos
)
380 de_dbg(c
, "file header at %"I64_FMT
, pos
);
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);
389 // Calculate .shift and .scale
390 static void update_bitfields_info(deark
*c
, lctx
*d
)
396 tmpmask
= d
->bitfield
[k
].mask
;
397 if(tmpmask
==0) continue;
398 while((tmpmask
& 0x1) == 0) {
399 d
->bitfield
[k
].shift
++;
402 d
->bitfield
[k
].scale
= 255.0 / (double)tmpmask
;
406 static void do_read_bitfields(deark
*c
, lctx
*d
, i64 pos
, i64 len
)
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
);
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
)
465 de_dbg(c
, "info header at %"I64_FMT
, pos
);
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);
475 d
->width
= de_geti32le(pos
+4);
476 height_raw
= de_geti32le(pos
+8);
479 d
->height
= -height_raw
;
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
);
489 de_dbg(c
, "orientation: top-down");
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
))
509 if(d
->version
==DE_BMPVER_OS2V1
) {
510 d
->bytes_per_pal_entry
= 3;
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
) {
525 if(d
->bitcount
==16 || d
->bitcount
==32) {
526 d
->bitfields_type
= BF_DEFAULT
;
528 d
->compression_type
= CMPR_NONE
;
532 d
->compression_type
=CMPR_RLE8
;
536 d
->compression_type
=CMPR_RLE4
;
539 case 3: // BI_BITFIELDS or Huffman_1D
540 if(d
->version
==DE_BMPVER_OS2V2
) {
542 d
->compression_type
=CMPR_HUFFMAN1D
;
546 else if(d
->bitcount
==16 || d
->bitcount
==32) {
547 d
->compression_type
= CMPR_NONE
;
549 if(d
->infohdrsize
>=52) {
550 d
->bitfields_type
= BF_IN_HEADER
;
553 d
->bitfields_type
= BF_SEGMENT
;
554 d
->bitfields_segment_len
= 12;
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
;
566 d
->compression_type
=CMPR_JPEG
;
571 d
->compression_type
=CMPR_PNG
;
574 case 6: // BI_ALPHABITFIELDS
575 if(d
->bitcount
==16 || d
->bitcount
==32) {
576 d
->compression_type
= CMPR_NONE
;
578 if(d
->infohdrsize
>=56) {
579 d
->bitfields_type
= BF_IN_HEADER
;
582 d
->bitfields_type
= BF_SEGMENT
;
583 d
->bitfields_segment_len
= 16;
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);
610 if(d
->bitcount
>=1 && d
->bitcount
<=8 && clr_used_raw
==0) {
611 d
->pal_entries
= ((i64
)1)<<d
->bitcount
;
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) {
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
);
653 de_err(c
, "Bad or unsupported bits/pixel: %d", (int)d
->bitcount
);
657 de_err(c
, "Unsupported compression type: %u", (UI
)d
->compression_field
);
660 if(!de_good_image_dimensions(c
, d
->width
, d
->height
)) {
666 de_dbg_indent(c
, -1);
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
);
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
,
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
)
716 i64 pal_bytes_if_3bpc
;
717 i64 pal_bytes_if_4bpc
;
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
733 for(i
=0; i
<pal_bytes_if_3bpc
; i
+=4) {
734 if(de_getbyte(d
->pal_pos
+ i
+ 3) != 0) {
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
);
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
)
775 img
= de_bitmap_create2(c
, d
->width
, d
->pdwidth
, d
->height
, bypp
);
779 static void do_image_paletted(deark
*c
, lctx
*d
, dbuf
*bits
, i64 bits_offset
, u8 want_trns
)
783 if(d
->pal_is_grayscale
) bypp
= 1;
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
)
798 if(want_trns
) bypp
= 4;
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;
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.
814 if(pos_in_this_row
+2 > d
->rowspan
) {
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
)
828 int has_transparency
;
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);
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
);
850 v
= (u32
)dbuf_getu32le(bits
, bits_offset
+ j
*d
->rowspan
+ 4*i
);
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
));
859 sm
[k
] = 255; // Default alpha sample = opaque
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
;
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
++) {
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.
899 if(sm16
[k
]<0 || sm16
[k
]>8192) {
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]));
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
;
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;
935 if(rc
->unit_size
== d
->bitcount
) {
941 rc
->mask
= de_bitmap_create(c
, d
->width
, d
->height
, 1);
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
;
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
;
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.");
966 do_image_paletted(c
, d
, rc
->unc_pixels
, 0, use_mask
);
969 do_image_24bit(c
, d
, rc
->unc_pixels
, 0, use_mask
);
973 de_bitmap_apply_mask(d
->img
, rc
->mask
, 0);
978 dbuf_close(rc
->unc_pixels
);
979 de_bitmap_destroy(rc
->mask
);
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
)
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");
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");
1081 de_err(c
, "This type of BMP image is not supported");
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
);
1094 static void de_run_bmp(deark
*c
, de_module_params
*mparams
)
1099 d
= de_malloc(c
, sizeof(lctx
));
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.");
1123 if(!detect_bmp_version(c
, d
)) {
1124 de_err(c
, "Unidentified BMP version.");
1128 switch(d
->version
) {
1129 case DE_BMPVER_OS2V1
:
1131 de_declare_fmt(c
, "BMP, OS/2 v1");
1134 de_declare_fmt(c
, "BMP, OS/2 v1 or Windows v2");
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+");
1146 case DE_BMPVER_64BIT
:
1147 de_declare_fmt(c
, "BMP, 64-bit");
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
;
1168 do_read_palette(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
;
1179 idata
->createflags
= d
->createflags
;
1184 de_bitmap_destroy(d
->img
);
1185 de_finfo_destroy(c
, d
->fi
);
1190 // Note that this function must work together with de_identify_vbm().
1191 static int de_identify_bmp(deark
*c
)
1196 u32 compression_field
= 0;
1200 de_read(buf
, 0, sizeof(buf
));
1201 if(de_memcmp(buf
, "BM", 2)) {
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;
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;
1229 if(bmp_ext
) return 100;
1230 if(infohdrsize
==12 || infohdrsize
==40 || infohdrsize
==108 ||
1238 void de_module_bmp(deark
*c
, struct deark_module_info
*mi
)
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)
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.
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
)
1279 i64 endpos
= pos1
+len
;
1286 if(pos
+4 > endpos
) goto done
;
1288 if(dbuf_getbyte_p(f
, &pos
) != 0xff) {
1293 b1
= dbuf_getbyte_p(f
, &pos
);
1294 if(b1
==0 || b1
==0xff) {
1299 if(seg_startpos
==pos1
) { // Expecting SOI
1300 if(b1
!=0xd8) goto done
;
1301 sd
->soi_pos
= seg_startpos
;
1305 if(b1
==0xd9) { // EOI
1309 // (Not expecting any other bare markers)
1311 seg_len
= 2 + dbuf_getu16be_p(f
, &pos
);
1319 sd
->sos_pos
= seg_startpos
;
1320 goto done
; // we don't scan past SOS
1325 if(seg_len
>=11 && !sd
->found_jfif
) {
1326 if(!dbuf_memcmp(f
, seg_startpos
+4, "JFIF\0", 5)) {
1328 sd
->jfif_pos
= seg_startpos
;
1333 if(seg_len
>=11 && !sd
->found_pic
) {
1334 if(!dbuf_memcmp(f
, seg_startpos
+4, "PIC\0", 4)) {
1336 sd
->pic_pos
= seg_startpos
;
1337 sd
->pic_len
= seg_len
;
1342 if(seg_len
>8 && !sd
->found_8bim
) {
1343 if(!dbuf_memcmp(f
, seg_startpos
+4, "8BIM", 4)) {
1345 sd
->_8bim_pos
= seg_startpos
;
1346 sd
->_8bim_len
= seg_len
;
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:
1355 sd
->sof_pos
= seg_startpos
;
1359 pos
= seg_startpos
+ seg_len
;
1366 static void picjpeg_scale_qtable(u8 tbl
[64], UI setting
)
1370 for(i
=0; i
<64; 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;
1383 static void de_run_picjpeg(deark
*c
, de_module_params
*mparams
)
1389 int need_errmsg
= 0;
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) {
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 ||
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
);
1432 if(!sd
.found_pic
|| !sd
.found_sof
|| !sd
.found_sos
) {
1436 if(sd
.pic_pos
>= sd
.sof_pos
) {
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
);
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);
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
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
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
);
1521 de_err(c
, "Can't convert this Pegasus JPEG file");
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;
1534 void de_module_picjpeg(deark
*c
, struct deark_module_info
*mi
)
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 // **************************************************************************
1545 // **************************************************************************
1547 static void de_run_dib(deark
*c
, de_module_params
*mparams
)
1549 struct de_bmpinfo bi
;
1552 int implicit_size
= 0;
1554 const char *ext
= "bmp";
1555 de_finfo
*fi_to_use
= NULL
;
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");
1577 dib_len
= bi
.total_size
;
1578 if(dib_len
> c
->infile
->len
) {
1579 dib_len
= c
->infile
->len
;
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
);
1598 static int de_identify_dib(deark
*c
)
1602 n
= de_getu32le(0); // biSize
1604 n
= de_getu16le(12); // biPlanes
1606 n
= de_getu16le(14); // biBitCount
1607 if(n
==1 || n
==4 || n
==8 || n
==16 || n
==24 || n
==32) return 15;
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
)
1616 mi
->desc
= "DIB (raw Windows bitmap)";
1617 mi
->run_fn
= de_run_dib
;
1618 mi
->identify_fn
= de_identify_dib
;
1621 // **************************************************************************
1623 // **************************************************************************
1625 struct ddbctx_struct
{
1634 static void ddb_convert_pal4planar(deark
*c
, struct ddbctx_struct
*d
,
1635 i64 fpos
, de_bitmap
*img
)
1637 const i64 nplanes
= 4;
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,
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
)
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
++) {
1675 palent
= de_getbyte(fpos
+j
*d
->bmWidthBytes
+i
);
1676 if(!d
->have_custom_pal
&& palent
>=8 && palent
<248) {
1679 clr
= d
->pal
[(UI
)palent
];
1681 de_bitmap_setpixel_rgb(img
, i
, j
, clr
);
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
)
1699 i64 bmWidth
, bmHeight
;
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))
1732 de_err(c
, "This type of DDB bitmap is not supported "
1733 "(bmBitsPixel=%d, planes=%d)", (int)bmBitsPixel
, (int)bmPlanes
);
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".
1747 de_dbg(c
, "adjusted dimensions: %"I64_FMT DE_CHAR_TIMES
"%"I64_FMT
,
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
);
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
;
1781 d
= de_malloc(c
, sizeof(struct ddbctx_struct
));
1784 if(de_havemodcode(c
, mparams
, 'N')) {
1787 if(de_havemodcode(c
, mparams
, 'X')) {
1788 d
->createflags
|= DE_CREATEFLAG_IS_AUX
;
1791 d
->cdr_adjdim_flag
= (u8
)de_havemodcode(c
, mparams
, 'C');
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
));
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
);
1815 void de_module_ddb(deark
*c
, struct deark_module_info
*mi
)
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 // **************************************************************************
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
)
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);
1840 static void de_run_jigsaw_wk(deark
*c
, de_module_params
*mparams
)
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
);
1856 static int de_identify_jigsaw_wk(deark
*c
)
1862 if(dbuf_memcmp(c
->infile
, 0, "JG", 2)) {
1866 fsize
= de_getu32le(2);
1867 if(fsize
>c
->infile
->len
) return 0;
1869 de_read(buf
, 0, sizeof(buf
));
1872 ret
= looks_like_bmp_bytes(buf
, sizeof(buf
), 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
;