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_bpg
);
12 typedef struct localctx_struct
{
20 u8 extension_present_flag
;
22 u8 limited_range_flag
;
25 i64 extension_data_len
;
29 static i64
get_ue7(deark
*c
, i64
*pos
)
35 // TODO: Better error handling
41 // A quick hack to prevent 64-bit integer overflow.
42 // 5 bytes are enough for 35 bits, and none of the fields in
43 // BPG v0.9.4.1 require more than 32.
45 val
= (val
<<7)|(b
&0x7f);
54 static void do_exif(deark
*c
, lctx
*d
, i64 pos1
, i64 len1
)
61 de_read(buf
, pos1
, 3);
62 if(buf
[0]==0 && (buf
[1]=='M' || buf
[1]=='I') && buf
[2]==buf
[1]) {
63 de_warn(c
, "Ignoring initial NUL byte in Exif data (libbpg bug?)");
67 fmtutil_handle_exif(c
, pos
, len
);
70 static void do_extensions(deark
*c
, lctx
*d
, i64 pos
)
76 endpos
= pos
+ d
->extension_data_len
;
79 tag
= get_ue7(c
, &pos
);
80 payload_len
= get_ue7(c
, &pos
);
81 if(pos
+payload_len
>endpos
) break;
85 do_exif(c
, d
, pos
, payload_len
);
87 case 2: // ICC profile
88 dbuf_create_file_from_slice(c
->infile
, pos
, payload_len
, "icc", NULL
, DE_CREATEFLAG_IS_AUX
);
91 dbuf_create_file_from_slice(c
->infile
, pos
, payload_len
, "xmp", NULL
, DE_CREATEFLAG_IS_AUX
);
94 dbuf_create_file_from_slice(c
->infile
, pos
, payload_len
, "thumb.bpg", NULL
, DE_CREATEFLAG_IS_AUX
);
97 de_dbg(c
, "unrecognized extension type: %d", (int)tag
);
104 static void do_hevc_file(deark
*c
, lctx
*d
)
112 d
->pixel_format
= b
>>5;
113 d
->alpha_flag
= (b
>>4)&0x01;
114 d
->bit_depth
= (i64
)(b
&0x0f) +8;
115 de_dbg(c
, "pixel format: %d", (int)d
->pixel_format
);
116 de_dbg(c
, "alpha flag: %d", (int)d
->alpha_flag
);
117 de_dbg(c
, "bit depth: %d", (int)d
->bit_depth
);
121 d
->color_space
= b
>>4;
122 d
->extension_present_flag
= (b
>>3)&0x01;
123 d
->alpha2_flag
= (b
>>2)&0x01;
124 d
->limited_range_flag
= (b
>>1)&0x01;
125 de_dbg(c
, "color_space: %d", (int)d
->color_space
);
126 de_dbg(c
, "extension_present_flag: %d", (int)d
->extension_present_flag
);
127 de_dbg(c
, "alpha2_flag: %d", (int)d
->alpha2_flag
);
128 de_dbg(c
, "limited_range_flag: %d", (int)d
->limited_range_flag
);
130 d
->width
= get_ue7(c
, &pos
);
131 d
->height
= get_ue7(c
, &pos
);
132 de_dbg_dimensions(c
, d
->width
, d
->height
);
135 d
->picture_data_len
= get_ue7(c
, &pos
);
136 de_dbg(c
, "picture_data_len: %d%s", (int)d
->picture_data_len
,
137 (d
->picture_data_len
==0)?" (= to EOF)":"");
139 if(d
->extension_present_flag
) {
140 d
->extension_data_len
= get_ue7(c
, &pos
);
141 de_dbg(c
, "extension data len: %d", (int)d
->extension_data_len
);
144 if(d
->extension_present_flag
) {
145 do_extensions(c
, d
, pos
);
146 pos
+= d
->extension_data_len
;
149 de_dbg(c
, "hevc_header_and_data begins at %d", (int)pos
);
152 static void de_run_bpg(deark
*c
, de_module_params
*mparams
)
156 d
= de_malloc(c
, sizeof(lctx
));
163 static int de_identify_bpg(deark
*c
)
165 if(!dbuf_memcmp(c
->infile
, 0, "\x42\x50\x47\xfb", 4)) {
171 void de_module_bpg(deark
*c
, struct deark_module_info
*mi
)
174 mi
->desc
= "BPG (Better Portable Graphics)";
175 mi
->desc2
= "resources only";
176 mi
->run_fn
= de_run_bpg
;
177 mi
->identify_fn
= de_identify_bpg
;