1 // This file is part of Deark.
2 // Copyright (C) 2016 Jason Summers
3 // See the file COPYING for terms of use.
5 // Award BIOS logo formats
7 #include <deark-config.h>
8 #include <deark-private.h>
9 DE_DECLARE_MODULE(de_module_awbm
);
11 typedef struct localctx_struct
{
16 #define EPA_CH 14 // "character" height (width must be 8)
18 static int do_v1_image(deark
*c
, i64 pos
,
19 i64 w_blocks
, i64 h_blocks
, int special
, unsigned int createflags
)
21 de_bitmap
*img
= NULL
;
24 i64 colors_start
=0, bitmap_start
;
30 h
= EPA_CH
* h_blocks
;
31 if(!de_good_image_dimensions(c
, w
, h
)) goto done
;
32 img
= de_bitmap_create(c
, w
, h
, special
?4:3);
35 // The first block is not stored, and is assumed to be blank.
36 // To compensate, pretend the image starts 1 block before it does.
37 // (There's special code later to make the first block blank.)
38 bitmap_start
= pos
- EPA_CH
;
42 bitmap_start
= colors_start
+ w_blocks
*h_blocks
;
45 // Read the bitmap, "character by character"
46 for(j
=0; j
<h_blocks
; j
++) {
47 for(i
=0; i
<w_blocks
; i
++) {
50 // No data (transparent)
51 clr1
= DE_STOCKCOLOR_TRANSPARENT
;
52 clr2
= DE_STOCKCOLOR_TRANSPARENT
;
56 clr1
= DE_MAKE_RGB(0x00,0x00,0xff);
57 clr2
= DE_STOCKCOLOR_BLACK
;
61 // Read the color attributes for this block of pixel
62 b
= de_getbyte(colors_start
+ j
*w_blocks
+ i
);
63 clr1
= de_palette_pc16((int)(b
&0x0f));
64 clr2
= de_palette_pc16((int)((b
&0xf0)>>4));
67 // Read each individual pixel
68 for(j2
=0; j2
<EPA_CH
; j2
++) {
69 for(i2
=0; i2
<8; i2
++) {
70 if(special
&& j
==0 && i
==0) {
74 b
= de_get_bits_symbol(c
->infile
, 1,
75 bitmap_start
+ j
*w_blocks
*EPA_CH
+ i
*EPA_CH
+ j2
, i2
);
77 de_bitmap_setpixel_rgba(img
, i
*8+i2
, j
*EPA_CH
+j2
, b
?clr1
:clr2
);
82 de_bitmap_write_to_file(img
, NULL
, createflags
);
85 de_bitmap_destroy(img
);
89 static void do_v1(deark
*c
, lctx
*d
)
91 i64 w_blocks
, h_blocks
;
94 de_declare_fmt(c
, "Award BIOS logo v1");
96 w_blocks
= (i64
)de_getbyte(0);
97 h_blocks
= (i64
)de_getbyte(1);
98 if(!do_v1_image(c
, 2, w_blocks
, h_blocks
, 0, 0)) goto done
;
100 after_bitmap
= 2 + w_blocks
*h_blocks
+ h_blocks
*EPA_CH
*w_blocks
;
101 if(c
->infile
->len
>= after_bitmap
+70) {
102 // The file usually contains a second image: a small Award logo.
103 do_v1_image(c
, after_bitmap
, 3, 2, 1, DE_CREATEFLAG_IS_AUX
);
109 static int detect_palette_at(deark
*c
, lctx
*d
, i64 pos
, i64 ncolors
)
111 if(pos
+ 4 + 3*ncolors
> c
->infile
->len
) return 0;
112 if(!dbuf_memcmp(c
->infile
, pos
, "RGB ", 4)) return 1;
117 static void do_v2(deark
*c
, lctx
*d
)
119 de_bitmap
*img
= NULL
;
131 i64 ncolors
= 0; // 16 or 256
134 de_zeromem(pal
, sizeof(pal
));
135 d
->w
= de_getu16le(4);
136 d
->h
= de_getu16le(6);
137 de_dbg_dimensions(c
, d
->w
, d
->h
);
138 if(!de_good_image_dimensions(c
, d
->w
, d
->h
)) goto done
;
141 rowspan1
= (d
->w
+7)/8;
143 rowspan
= d
->w
; // Start by guessing 8bpp
144 bitmap_size
= rowspan
* d
->h
;
146 if(detect_palette_at(c
, d
, bitmap_start
+bitmap_size
, 256)) {
148 de_declare_fmt(c
, "Award BIOS logo v2 8-bit");
151 // Doesn't seem to be an 8pp image. Try 4bpp.
152 rowspan
= rowspan1
* 4;
153 bitmap_size
= rowspan
* d
->h
;
154 if(detect_palette_at(c
, d
, bitmap_start
+bitmap_size
, 16)) {
156 de_declare_fmt(c
, "Award BIOS logo v2 4-bit");
161 de_err(c
, "Can't detect image format");
165 // Default to BGR for 16-color images, RGB for 256-color.
171 s
= de_get_ext_option(c
, "awbm:rgb");
172 if(s
) d
->rgb_order
= de_atoi(s
);
174 palette_start
= bitmap_start
+bitmap_size
+4;
177 for(i
=0; i
<ncolors
; i
++) {
178 cr
= de_scale_63_to_255(de_getbyte(palette_start
+i
*3+0));
179 cg
= de_scale_63_to_255(de_getbyte(palette_start
+i
*3+1));
180 cb
= de_scale_63_to_255(de_getbyte(palette_start
+i
*3+2));
182 pal
[i
] = DE_MAKE_RGB(cr
, cg
, cb
);
184 pal
[i
] = DE_MAKE_RGB(cb
, cg
, cr
);
187 img
= de_bitmap_create(c
, d
->w
, d
->h
, 3);
188 for(j
=0; j
<d
->h
; j
++) {
189 for(i
=0; i
<d
->w
; i
++) {
193 b1
= de_get_bits_symbol(c
->infile
, 1, bitmap_start
+ j
*rowspan
+ k
*rowspan1
, i
);
198 b
= de_getbyte(bitmap_start
+ j
*rowspan
+ i
);
200 de_bitmap_setpixel_rgb(img
, i
, j
, pal
[(unsigned int)b
]);
204 de_bitmap_write_to_file(img
, NULL
, 0);
206 de_bitmap_destroy(img
);
209 static void de_run_awbm(deark
*c
, de_module_params
*mparams
)
213 d
= de_malloc(c
, sizeof(lctx
));
215 if(!dbuf_memcmp(c
->infile
, 0, "AWBM", 4)) {
225 static int de_identify_awbm(deark
*c
)
232 if(!de_memcmp(buf
, "AWBM", 4)) return 100;
234 nblocks
= (i64
)buf
[0] * (i64
)buf
[1];
235 if(nblocks
<1 || nblocks
>256) return 0;
236 if(c
->infile
->len
== 2 + nblocks
*15 + 70) {
237 epa_ext
= de_input_file_has_ext(c
, "epa");
238 if(epa_ext
) return 100;
244 static void de_help_awbm(deark
*c
)
246 de_msg(c
, "-opt awbm:rgb=0 : Assume BGR sample order");
247 de_msg(c
, "-opt awbm:rgb=1 : Assume RGB sample order");
250 void de_module_awbm(deark
*c
, struct deark_module_info
*mi
)
253 mi
->desc
= "Award BIOS logo";
254 mi
->run_fn
= de_run_awbm
;
255 mi
->identify_fn
= de_identify_awbm
;
256 mi
->help_fn
= de_help_awbm
;