1 // This file is part of Deark.
2 // Copyright (C) 2016 Jason Summers
3 // See the file COPYING for terms of use.
5 // Alpha Microsystems BMP
7 #include <deark-config.h>
8 #include <deark-private.h>
9 #include <deark-fmtutil.h>
10 DE_DECLARE_MODULE(de_module_alphabmp
);
12 typedef struct localctx_struct
{
16 unsigned int has_palette
;
17 unsigned int palette_is_hls
;
23 static int do_read_palette(deark
*c
, lctx
*d
, i64 pos
, i64
*pal_nbytes
)
25 de_dbg(c
, "palette at %d", (int)pos
);
28 d
->num_pal_entries
= de_getu16le(pos
) + 1;
29 de_dbg(c
, "number of palette colors: %d", (int)d
->num_pal_entries
);
31 *pal_nbytes
= 2 + d
->num_pal_entries
* 6;
33 *pal_nbytes
= 2 + d
->num_pal_entries
* 3;
34 if(d
->palette_is_hls
) goto done
;
36 de_read_palette_rgb(c
->infile
, pos
+2, d
->num_pal_entries
, 3, d
->pal
, 256, 0);
42 static void do_bitmap(deark
*c
, lctx
*d
, dbuf
*unc_pixels
)
48 de_bitmap
*img
= NULL
;
51 bits_per_row
= de_pad_to_n(d
->npwidth
* d
->bpp
, 8);
52 rowspan
= bits_per_row
/8;
53 d
->pdwidth
= bits_per_row
/ d
->bpp
;
55 img
= de_bitmap_create2(c
, d
->npwidth
, d
->pdwidth
, d
->h
, 3);
57 for(j
=0; j
<d
->h
; j
++) {
58 for(i
=0; i
<d
->pdwidth
; i
++) {
60 b
= de_get_bits_symbol(unc_pixels
, d
->bpp
, j
*rowspan
, i
);
61 clr
= d
->pal
[(unsigned int)b
];
64 clr
= dbuf_getRGB(unc_pixels
, j
*rowspan
+ i
*3, 0);
66 de_bitmap_setpixel_rgb(img
, i
, j
, clr
);
70 de_bitmap_write_to_file(img
, NULL
, 0);
72 de_bitmap_destroy(img
);
75 static int do_uncompress_image(deark
*c
, lctx
*d
, i64 pos1
, dbuf
*unc_pixels
)
77 i64 bytes_in_this_line
;
80 struct de_dfilter_ctx
*dfctx
= NULL
;
81 struct de_dfilter_out_params dcmpro
;
82 struct de_dfilter_results dres
;
84 de_dbg(c
, "decompressing bitmap");
86 // Each line is compressed independently, using PackBits.
87 de_dfilter_init_objects(c
, NULL
, &dcmpro
, &dres
);
88 dcmpro
.f
= unc_pixels
;
89 dfctx
= de_dfilter_create(c
, dfilter_packbits_codec
, NULL
, &dcmpro
, &dres
);
91 for(j
=0; j
<d
->h
; j
++) {
92 bytes_in_this_line
= de_getu16le(pos
);
94 de_dfilter_addslice(dfctx
, c
->infile
, pos
, bytes_in_this_line
);
95 de_dfilter_command(dfctx
, DE_DFILTER_COMMAND_SOFTRESET
, 0);
96 pos
+= bytes_in_this_line
;
99 de_dfilter_finish(dfctx
);
101 de_err(c
, "%s", de_dfilter_get_errmsg(c
, &dres
));
105 de_dbg(c
, "decompressed %d bytes to %d bytes", (int)(pos
-pos1
),
106 (int)unc_pixels
->len
);
108 de_dfilter_destroy(dfctx
);
112 static void de_run_alphabmp(deark
*c
, de_module_params
*mparams
)
118 dbuf
*unc_pixels
= NULL
;
119 int saved_indent_level
;
121 de_dbg_indent_save(c
, &saved_indent_level
);
123 d
= de_malloc(c
, sizeof(lctx
));
124 de_declare_fmt(c
, "Alpha Microsystems BMP");
128 de_dbg(c
, "bitmap image definition block at %d", (int)pos
);
131 d
->npwidth
= de_getu16le(pos
);
132 d
->h
= de_getu16le(pos
+2);
133 de_dbg_dimensions(c
, d
->npwidth
, d
->h
);
134 if(!de_good_image_dimensions(c
, d
->npwidth
, d
->h
)) goto done
;
136 d
->bpp
= de_getu16le(pos
+4);
137 de_dbg(c
, "bits/pixel: %d", (int)d
->bpp
);
139 flags
= (unsigned int)de_getu16le(pos
+6);
140 d
->has_palette
= flags
& 0x01;
141 d
->palette_is_hls
= (flags
>>1) & 0x01;
142 de_dbg(c
, "has-palette: %d", (int)d
->has_palette
);
144 de_dbg(c
, "palette-is-HLS: %d", (int)d
->palette_is_hls
);
146 d
->compression
= de_getu16le(pos
+8);
147 de_dbg(c
, "compression: %d", (int)d
->compression
);
148 de_dbg_indent(c
, -1);
153 if(d
->palette_is_hls
&& d
->bpp
<=8) {
154 de_err(c
, "HLS palettes are not supported");
157 if(!do_read_palette(c
, d
, pos
, &palsize
)) goto done
;
161 de_err(c
, "Paletted images without an embedded palette are not supported");
165 de_dbg(c
, "bitmap at %d", (int)pos
);
169 unc_pixels
= dbuf_create_membuf(c
, 32768, 0);
170 if(!do_uncompress_image(c
, d
, pos
, unc_pixels
)) goto done
;
173 unc_pixels
= dbuf_open_input_subfile(c
->infile
, pos
, c
->infile
->len
- pos
);
176 if(d
->bpp
!=1 && d
->bpp
!=4 && d
->bpp
!=8 && d
->bpp
!=24) {
177 de_err(c
, "%d bits/pixel is not supported", (int)d
->bpp
);
181 do_bitmap(c
, d
, unc_pixels
);
182 de_dbg_indent(c
, -1);
185 de_dbg_indent_restore(c
, saved_indent_level
);
186 dbuf_close(unc_pixels
);
190 static int de_identify_alphabmp(deark
*c
)
194 if(!de_input_file_has_ext(c
, "bmp")) return 0;
196 flg
= de_getu16le(0);
197 if(flg
==0xffff || flg
==0xfffe) {
203 void de_module_alphabmp(deark
*c
, struct deark_module_info
*mi
)
206 mi
->desc
= "Alpha Microsystems BMP";
207 mi
->run_fn
= de_run_alphabmp
;
208 mi
->identify_fn
= de_identify_alphabmp
;