static void do_psf1_header(deark *c, lctx *d) { de_int64 pos = 0; de_dbg(c, "PFXv1 header at %d\n", (int)pos); de_dbg_indent(c, 1); d->headersize = 4; d->mode = de_getbyte(2); de_dbg(c, "mode: 0x%02x\n", (unsigned int)d->mode); de_dbg_indent(c, 1); d->num_glyphs = (d->mode & 0x01) ? 512 : 256; de_dbg(c, "number of glyphs: %d\n", (int)d->num_glyphs); d->has_unicode_table = (d->mode & 0x02) ? 1 : 0; de_dbg(c, "has Unicode table: %s\n", d->has_unicode_table?"yes":"no"); de_dbg_indent(c, -1); d->bytes_per_glyph = (de_int64)de_getbyte(3); d->glyph_height = d->bytes_per_glyph; d->glyph_width = 8; de_dbg(c, "glyph dimensions: %dx%d\n", (int)d->glyph_width, (int)d->glyph_height); de_dbg_indent(c, -1); }
static int do_image(deark *c, lctx *d, struct page_ctx *pg, de_int64 pos1) { int retval = 0; de_dbg(c, "image data at %d\n", (int)pos1); de_dbg_indent(c, 1); if(!de_good_image_dimensions(c, pg->width, pg->height)) goto done; switch(pg->fmt) { case FMT_PBM_ASCII: if(!do_image_pbm_ascii(c, d, pg, pos1)) goto done; break; case FMT_PGM_ASCII: case FMT_PPM_ASCII: if(!do_image_pgm_ppm_ascii(c, d, pg, pos1)) goto done; break; case FMT_PBM_BINARY: if(!do_image_pbm_binary(c, d, pg, pos1)) goto done; break; case FMT_PGM_BINARY: case FMT_PPM_BINARY: if(!do_image_pgm_ppm_binary(c, d, pg, pos1)) goto done; break; default: de_err(c, "Unsupported PNM format\n"); goto done; } retval = 1; done: de_dbg_indent(c, -1); return retval; }
static void do_dir_entry(deark *c, lctx *d, de_int64 entry_num, de_int64 pos) { de_byte filetype_c64s; de_byte filetype; filetype_c64s = de_getbyte(pos); if(filetype_c64s==0) { de_dbg2(c, "unused entry #%d at %d\n", (int)entry_num, (int)pos); return; } de_dbg(c, "entry #%d at %d\n", (int)entry_num, (int)pos); de_dbg_indent(c, 1); filetype = de_getbyte(pos+1); de_dbg(c, "c64s filetype=%d, filetype=0x%02x\n", (int)filetype_c64s, (int)filetype); if(filetype==0x00) { de_err(c, "Unsupported file type (0x%02x)\n", (int)filetype); } else { do_extract_file(c, d, pos, filetype_c64s, filetype); } de_dbg_indent(c, -1); }
static void do_psf2_header(deark *c, lctx *d) { de_int64 pos = 0; de_dbg(c, "PFXv2 header at %d\n", (int)pos); de_dbg_indent(c, 1); d->psf2_version = (de_uint32)de_getui32le(pos+4); de_dbg(c, "PSFv2 version number: %d\n", (int)d->psf2_version); if(d->psf2_version!=0) { de_warn(c, "Unknown PSFv2 version number: %d\n", (int)d->psf2_version); } d->headersize = de_getui32le(pos+8); de_dbg(c, "header size: %d\n", (int)d->headersize); d->flags = (de_uint32)de_getui32le(pos+12); de_dbg(c, "flags: 0x%08x\n", (unsigned int)d->flags); de_dbg_indent(c, 1); d->has_unicode_table = (d->flags & 0x01) ? 1 : 0; de_dbg(c, "has Unicode table: %s\n", d->has_unicode_table?"yes":"no"); de_dbg_indent(c, -1); d->num_glyphs = de_getui32le(pos+16); de_dbg(c, "number of glyphs: %d\n", (int)d->num_glyphs); d->bytes_per_glyph = de_getui32le(pos+20); de_dbg(c, "bytes per glyph: %d\n", (int)d->bytes_per_glyph); d->glyph_height = de_getui32le(pos+24); d->glyph_width = de_getui32le(pos+28); de_dbg(c, "glyph dimensions: %dx%d\n", (int)d->glyph_width, (int)d->glyph_height); de_dbg_indent(c, -1); }
static void do_read_developer_area(deark *c, lctx *d, i64 pos) { i64 num_tags; i64 i; i64 tag_id, tag_data_pos, tag_data_size; de_dbg(c, "developer area at %d", (int)pos); if(pos > c->infile->len - 2) { de_warn(c, "Bad developer area offset: %u", (unsigned int)pos); return; } de_dbg_indent(c, 1); num_tags = de_getu16le(pos); de_dbg(c, "number of tags: %d", (int)num_tags); for(i=0; i<num_tags; i++) { if(i>=200) break; tag_id = de_getu16le(pos + 2 + 10*i); tag_data_pos = de_getu32le(pos + 2 + 10*i + 2); tag_data_size = de_getu32le(pos + 2 + 10*i + 6); de_dbg(c, "tag #%d: id=%d, pos=%d, size=%d", (int)i, (int)tag_id, (int)tag_data_pos, (int)tag_data_size); if(tag_id==20) { // Tag 20 seems to contain Photoshop resources, though this is unconfirmed. de_dbg_indent(c, 1); // TODO: We could retrieve the pixel density settings from the Photoshop data, // but it's not clear whether they are ever useful. de_fmtutil_handle_photoshop_rsrc(c, c->infile, tag_data_pos, tag_data_size, 0x0); de_dbg_indent(c, -1); } } de_dbg_indent(c, -1); }
static int read_pnm_header(deark *c, lctx *d, struct page_ctx *pg, de_int64 pos1) { char tokenbuf[100]; int retval = 0; de_dbg(c, "header at %d\n", (int)pos1); de_dbg_indent(c, 1); de_dbg(c, "format: %s\n", pg->fmt_name); pg->hdr_parse_pos = pos1+2; // Skip "P?" if(!read_next_token(c, d, pg, tokenbuf, sizeof(tokenbuf))) goto done; pg->width = de_atoi64(tokenbuf); if(!read_next_token(c, d, pg, tokenbuf, sizeof(tokenbuf))) goto done; pg->height = de_atoi64(tokenbuf); de_dbg(c, "dimensions: %dx%d\n", (int)pg->width, (int)pg->height); if(fmt_is_pbm(pg->fmt)) { pg->maxval = 1; } else { if(!read_next_token(c, d, pg, tokenbuf, sizeof(tokenbuf))) goto done; pg->maxval = de_atoi64(tokenbuf); de_dbg(c, "maxval: %d\n", (int)pg->maxval); if(pg->maxval<1 || pg->maxval>65535) { de_err(c, "Invalid maxval: %d\n", (int)pg->maxval); goto done; } } retval = 1; done: de_dbg_indent(c, -1); return retval; }
static void do_read_embedded_profile(deark *c, lctx *d) { de_dbg(c, "embedded profile at %d, size=%d\n", (int)d->profile_offset, (int)d->profile_size); de_dbg_indent(c, 1); dbuf_create_file_from_slice(c->infile, d->profile_offset, d->profile_size, "icc", NULL, DE_CREATEFLAG_IS_AUX); de_dbg_indent(c, -1); }
static void do_psf1_unicode_table(deark *c, lctx *d, struct de_bitmap_font *font) { de_int64 cur_idx; de_int64 pos; int got_cp; int found_fffe; de_int32 n; de_dbg(c, "Unicode table at %d\n", (int)d->unicode_table_pos); de_dbg_indent(c, 1); pos = d->unicode_table_pos; cur_idx = 0; got_cp = 0; // Have we set the codepoint for glyph[cur_idx]? found_fffe = 0; while(1) { if(cur_idx >= d->num_glyphs) break; if(pos+1 >= c->infile->len) break; n = (de_int32)de_getui16le(pos); pos+=2; if(n==0xffff) { if(!got_cp) { de_warn(c, "Missing codepoint for char #%d\n", (int)cur_idx); } cur_idx++; got_cp = 0; found_fffe = 0; continue; } else if(n==0xfffe) { found_fffe = 1; } if(found_fffe) { // Anything after 0xfffe is a multi-codepoint character, which we // don't support. continue; } if(!got_cp) { de_dbg2(c, "char[%d] = U+%04x\n", (int)cur_idx, (unsigned int)n); font->char_array[cur_idx].codepoint_unicode = n; got_cp = 1; continue; } // This is an "extra" codepoint for the current glyph. do_extra_codepoint(c, d, font, cur_idx, n); } font->has_unicode_codepoints = 1; font->prefer_unicode = 1; de_dbg_indent(c, -1); }
static int read_fileheader(deark *c, lctx *d, de_int64 pos) { de_dbg(c, "file header at %d\n", (int)pos); de_dbg_indent(c, 1); de_dbg(c, "bfSize: %d\n", (int)d->fsize); d->bits_offset = de_getui32le(pos+10); de_dbg(c, "bfOffBits: %d\n", (int)d->bits_offset); de_dbg_indent(c, -1); return 1; }
static int do_header(deark *c, lctx *d, i64 pos) { de_dbg(c, "header at %d", (int)pos); de_dbg_indent(c, 1); d->nlumps = de_getu32le(pos+4); de_dbg(c, "#lumps: %d", (int)d->nlumps); d->dir_pos = de_getu32le(pos+8); de_dbg(c, "dir pos: %d", (int)d->dir_pos); de_dbg_indent(c, -1); return 1; }
// Returns 0 if we should stop reading the file. static int do_record(deark *c, lctx *d, de_int64 pos, de_int64 *bytesused) { int retval = 0; struct opcode_data op; de_int64 ptsin_size_bytes; de_int64 intin_size_bytes; de_int64 data_size_bytes; const struct opcode_info *opinfo; const char *opcode_name; *bytesused = 0; de_memset(&op, 0, sizeof(struct opcode_data)); de_dbg(c, "record at %d\n", (int)pos); de_dbg_indent(c, 1); op.opcode = de_getui16le(pos); op.ptsin_count = de_getui16le(pos+2); op.intin_count = de_getui16le(pos+4); op.func_id = de_getui16le(pos+6); ptsin_size_bytes = 4*op.ptsin_count; intin_size_bytes = 2*op.intin_count; data_size_bytes = ptsin_size_bytes + intin_size_bytes; op.ptsin_pos = pos + 8; op.intin_pos = pos + 8 + ptsin_size_bytes; opinfo = find_opcode_info(op.opcode); if(opinfo && opinfo->name) opcode_name = opinfo->name; else opcode_name = "?"; de_dbg(c, "opcode=%d (%s), func_id=%d, #pts=%d, #int=%d (dlen=%d)\n", (int)op.opcode, opcode_name, (int)op.func_id, (int)op.ptsin_count, (int)op.intin_count, (int)data_size_bytes); *bytesused = 8 + data_size_bytes; if(opinfo && opinfo->fn) { opinfo->fn(c, d, &op); } if(op.opcode==65535) { goto done; } retval = 1; done: de_dbg_indent(c, -1); return retval; }
static int read_pam_header(deark *c, lctx *d, struct page_ctx *pg, de_int64 pos1) { int ret; de_int64 pos = pos1; int retval = 0; char linebuf[200]; char token1buf[200]; //char token2buf[200]; de_dbg(c, "header at %d\n", (int)pos1); de_dbg_indent(c, 1); de_err(c, "PAM format not supported\n"); goto done; pos += 3; // Skip "P7\n" while(1) { de_int64 content_len; de_int64 total_len; de_int64 curpos; //ret = dbuf_find_line(c->infile, pos, // &content_len, &total_len); ret = read_pam_header_line(c, d, pg, pos, &content_len, &total_len, linebuf, sizeof(linebuf)); if(!ret) { de_err(c, "Invalid PAM header\n"); break; } if(content_len>0 && (de_getbyte(pos)=='#')) { // comment line pos += total_len; continue; } curpos = 0; if(!read_next_pam_token(c, d, pg, linebuf, token1buf, sizeof(token1buf), &curpos)) goto done; if(!de_strcmp(token1buf,"ENDHDR")) { break; } pos += total_len; continue; } retval = 1; done: de_dbg_indent(c, -1); return retval; }
static void do_para_info(deark *c, lctx *d) { i64 i; if(d->pnPara_npages<1) return; de_dbg(c, "paragraph info at %d, len=%d page(s)", (int)d->pnPara_offs, (int)d->pnPara_npages); de_dbg_indent(c, 1); for(i=0; i<d->pnPara_npages; i++) { do_para_info_page(c, d, d->pnPara_offs + 128*i); } de_dbg_indent(c, -1); }
static void do_read_linked_profile(deark *c, lctx *d) { de_ucstring *fname = NULL; de_dbg(c, "linked profile filename at %d\n", (int)d->profile_offset); fname = ucstring_create(c); dbuf_read_to_ucstring_n(c->infile, d->profile_offset, d->profile_size, 300, fname, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_WINDOWS1252); de_dbg_indent(c, 1); de_dbg(c, "profile filename: \"%s\"\n", ucstring_get_printable_sz(fname)); de_dbg_indent(c, -1); ucstring_destroy(fname); }
// This .vst (TrueVista) decoder is based on guesswork, on the limited information // in the TGA spec, and on the behavior of XnView. It may not be correct. static int do_read_vst_headers(deark *c, lctx *d) { int retval = 0; de_dbg(c, "header at %d", 0); de_dbg_indent(c, 1); d->id_field_len = (i64)de_getbyte(0); if(d->id_field_len==0) { // ??? XnView seems to do something like this. d->id_field_len=18; } d->cmpr_type = TGA_CMPR_NONE; d->cmpr_name = "none"; d->main_image.width = de_getu16le(12); d->main_image.height = de_getu16le(14); de_dbg_dimensions(c, d->main_image.width, d->main_image.height); d->pixel_depth = (i64)de_getbyte(16); de_dbg(c, "pixel depth: %d", (int)d->pixel_depth); if(d->pixel_depth==8) { d->color_map_type = 1; d->color_type = TGA_CLRTYPE_PALETTE; d->clrtype_name = "palette"; } else { d->color_type = TGA_CLRTYPE_TRUECOLOR; d->clrtype_name = "truecolor"; } if(d->color_type==TGA_CLRTYPE_PALETTE) { d->cmap_start = 0; d->cmap_length = 256; d->cmap_depth = 24; } do_read_image_descriptor(c, d); de_dbg_indent(c, -1); if(!de_good_image_dimensions(c, d->main_image.width, d->main_image.height)) goto done; retval = 1; done: return retval; }
static void read_palette_ximg(deark *c, lctx *d) { i64 pal_entries_in_file; i64 pal_entries_to_read; i64 i; i64 cr1, cg1, cb1; u8 cr, cg, cb; int range_warned = 0; char tmps[64]; pal_entries_in_file = (d->header_size_in_bytes-22)/3; if(pal_entries_in_file<1) return; if(d->nplanes<=8) pal_entries_to_read = (i64)(1<<((unsigned int)d->nplanes)); else pal_entries_to_read = 0; if(pal_entries_to_read>pal_entries_in_file) pal_entries_to_read = pal_entries_in_file; if(pal_entries_to_read>256) pal_entries_to_read = 256; if(pal_entries_in_file<1) return; de_dbg(c, "palette at %d", 22); de_dbg_indent(c, 1); for(i=0; i<pal_entries_to_read; i++) { cr1 = de_getu16be(22 + 6*i); cg1 = de_getu16be(22 + 6*i + 2); cb1 = de_getu16be(22 + 6*i + 4); cr = de_scale_1000_to_255(cr1); cg = de_scale_1000_to_255(cg1); cb = de_scale_1000_to_255(cb1); d->pal[i] = DE_MAKE_RGB(cr, cg, cb); de_snprintf(tmps, sizeof(tmps), "(%4d,%4d,%4d) "DE_CHAR_RIGHTARROW" ", (int)cr1, (int)cg1, (int)cb1); de_dbg_pal_entry2(c, (int)i, d->pal[i], tmps, NULL, NULL); // TODO: Maybe some out-of-range colors have special meaning? if(!range_warned && (cr1>1000 || cg1>1000 || cb1>1000)) { de_warn(c, "Bad palette color #%d: is (%d,%d,%d), max=(1000,1000,1000).", (int)i, (int)cr1, (int)cg1, (int)cb1); range_warned=1; } } de_dbg_indent(c, -1); }
static void do_paragraph(deark *c, lctx *d, struct para_info *pinfo) { if(pinfo->papflags&0x10) { de_dbg(c, "picture at %d, len=%d", (int)pinfo->thisparapos, (int)pinfo->thisparalen); de_dbg_indent(c, 1); do_picture(c, d, pinfo); de_dbg_indent(c, -1); } else { de_dbg(c, "text paragraph at %d, len=%d", (int)pinfo->thisparapos, (int)pinfo->thisparalen); do_text_paragraph(c, d, pinfo); } }
static int do_directory(deark *c, lctx *d, i64 pos) { i64 k; de_dbg(c, "directory at %d", (int)pos); de_dbg_indent(c, 1); if(pos<0 || pos>=c->infile->len) goto done; if(d->nlumps<1 || d->nlumps>10000) goto done; for(k=0; k<d->nlumps; k++) { if(pos+16*k > c->infile->len-16) break; do_lump_entry(c, d, k, pos+16*k); } done: de_dbg_indent(c, -1); return 1; }
static int do_read_palette(deark *c, lctx *d, i64 pos, i64 *pal_nbytes) { de_dbg(c, "palette at %d", (int)pos); de_dbg_indent(c, 1); d->num_pal_entries = de_getu16le(pos) + 1; de_dbg(c, "number of palette colors: %d", (int)d->num_pal_entries); if(d->palette_is_hls) *pal_nbytes = 2 + d->num_pal_entries * 6; else *pal_nbytes = 2 + d->num_pal_entries * 3; if(d->palette_is_hls) goto done; de_read_palette_rgb(c->infile, pos+2, d->num_pal_entries, 3, d->pal, 256, 0); done: de_dbg_indent(c, -1); return 1; }
// pos1 points to the ole_id field (should be 0x00000501). // Returns nonzero if there may be additional renditions. static int do_picture_ole_rendition(deark *c, lctx *d, struct para_info *pinfo, unsigned int objectType, int rendition_idx, i64 pos1, i64 *bytes_consumed) { unsigned int ole_id; unsigned int objectType2; int retval = 0; de_dbg(c, "OLE rendition[%d] at %d", rendition_idx, (int)pos1); de_dbg_indent(c, 1); ole_id = (unsigned int)de_getu32le(pos1); de_dbg(c, "ole id: 0x%08x", ole_id); if(ole_id!=0x00000501U) { de_err(c, "Unexpected ole_id: 0x%08x", ole_id); goto done; } objectType2 = (unsigned int)de_getu32le(pos1+4); de_dbg(c, "type: %u", objectType2); if(objectType==1) { if(objectType2==3) { do_picture_ole_static_rendition(c, d, pinfo, rendition_idx, pos1, bytes_consumed); } } else if(objectType==2) { if(objectType2==0) { goto done; } else if(objectType2==2) { do_picture_ole_embedded_rendition(c, d, pinfo, rendition_idx, pos1, bytes_consumed); retval = 1; } else if(objectType2==5) { // replacement do_picture_ole_static_rendition(c, d, pinfo, rendition_idx, pos1, bytes_consumed); } } done: de_dbg_indent(c, -1); return retval; }
static int do_picture_ole_static_rendition(deark *c, lctx *d, struct para_info *pinfo, int rendition_idx, i64 pos1, i64 *bytes_consumed) { i64 pos = pos1; i64 stringlen; struct de_stringreaderdata *srd_typename = NULL; pos += 4; // 0x00000501 pos += 4; // "type" (probably already read by caller) stringlen = de_getu32le_p(&pos); srd_typename = dbuf_read_string(c->infile, pos, stringlen, 260, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII); de_dbg(c, "typename: \"%s\"", ucstring_getpsz(srd_typename->str)); pos += stringlen; if(!de_strcmp(srd_typename->sz, "DIB")) { pos += 12; de_dbg_indent(c, 1); de_run_module_by_id_on_slice(c, "dib", NULL, c->infile, pos, pinfo->thisparapos+pinfo->thisparalen-pos); de_dbg_indent(c, -1); } else if(!de_strcmp(srd_typename->sz, "METAFILEPICT")) { i64 dlen; pos += 8; // ?? dlen = de_getu32le_p(&pos); de_dbg(c, "metafile size: %d", (int)dlen); // Includes "mfp", apparently pos += 8; // "mfp" struct dbuf_create_file_from_slice(c->infile, pos, dlen-8, "wmf", NULL, 0); } else if(!de_strcmp(srd_typename->sz, "BITMAP")) { do_static_bitmap(c, d, pinfo, pos); } else { de_warn(c, "Static OLE picture type \"%s\" is not supported", ucstring_getpsz(srd_typename->str)); } de_destroy_stringreaderdata(c, srd_typename); return 0; }
static int do_lead_section(deark *c, lctx *d) { int retval = 0; de_dbg(c, "lead section at %d", 0); de_dbg_indent(c, 1); d->ver_major = de_getbyte(4); d->ver_minor = de_getbyte(5); de_dbg(c, "RPM format version: %d.%d", (int)d->ver_major, (int)d->ver_minor); if(d->ver_major < 3) { de_err(c, "Unsupported RPM version (%d.%d)", (int)d->ver_major, (int)d->ver_minor); goto done; } retval = 1; done: de_dbg_indent(c, -1); return retval; }
static void de_run_woz(deark *c, de_module_params *mparams) { lctx *d = NULL; struct de_iffctx *ictx = NULL; u32 crc; i64 pos = 0; // WOZ has a 12-byte header, then sequence of chunks that are basically the // same format as RIFF. d = de_malloc(c, sizeof(lctx)); ictx = de_malloc(c, sizeof(struct de_iffctx)); ictx->userdata = (void*)d; ictx->preprocess_chunk_fn = my_preprocess_woz_chunk_fn; ictx->handle_chunk_fn = my_woz_chunk_handler; ictx->f = c->infile; ictx->is_le = 1; ictx->reversed_4cc = 0; if(ictx->f->len<12) goto done; de_dbg(c, "header at %d", (int)pos); de_dbg_indent(c, 1); pos += 3; // "WOZ" part of signature d->wozver = dbuf_getbyte_p(ictx->f, &pos); de_dbg(c, "format version: '%c'", de_byte_to_printable_char(d->wozver)); if(d->wozver<'1' || d->wozver>'2') { de_err(c, "Unsupported WOZ format version"); goto done; } pos += 4; // rest of signature crc = (u32)dbuf_getu32le_p(ictx->f, &pos); de_dbg(c, "crc: 0x%08x", (unsigned int)crc); de_dbg_indent(c, -1); de_fmtutil_read_iff_format(c, ictx, pos, ictx->f->len-pos); done: de_free(c, ictx); de_free(c, d); }
static void do_read_image_descriptor(deark *c, lctx *d) { d->image_descriptor = de_getbyte(17); de_dbg(c, "descriptor: 0x%02x", (unsigned int)d->image_descriptor); de_dbg_indent(c, 1); d->num_attribute_bits = (i64)(d->image_descriptor & 0x0f); de_dbg(c, "number of %s bits: %d", d->file_format==FMT_VST?"alpha channel":"attribute", (int)d->num_attribute_bits); d->right_to_left = (d->image_descriptor>>4)&0x01; d->top_down = (d->image_descriptor>>5)&0x01; de_dbg(c, "right-to-left flag: %d", (int)d->right_to_left); de_dbg(c, "top-down flag: %d", (int)d->top_down); d->interleave_mode = d->image_descriptor >> 6; if(d->interleave_mode != 0) { de_dbg(c, "interleaving: %d", (int)d->interleave_mode); } de_dbg_indent(c, -1); }
static void do_read_footer(deark *c, lctx *d) { i64 footerpos; i64 ext_offset, dev_offset; footerpos = c->infile->len - 26; de_dbg(c, "v2 footer at %d", (int)footerpos); de_dbg_indent(c, 1); ext_offset = de_getu32le(footerpos); de_dbg(c, "extension area offset: %d", (int)ext_offset); dev_offset = de_getu32le(footerpos+4); de_dbg(c, "developer area offset: %d", (int)dev_offset); de_dbg_indent(c, -1); if(ext_offset!=0) { do_read_extension_area(c, d, ext_offset); } if(dev_offset!=0) { do_read_developer_area(c, d, dev_offset); } }
static int do_header(deark *c, lctx *d, i64 pos) { de_dbg(c, "header at %d", (int)pos); de_dbg_indent(c, 1); d->fcMac = de_getu32le(pos+7*2); de_dbg(c, "fcMac: %d", (int)d->fcMac); d->pnChar = (d->fcMac + 127) / 128; d->pnChar_offs = d->pnChar * 128; de_dbg(c, "pnChar: page %d (offset %d)", (int)d->pnChar, (int)d->pnChar_offs); d->pnPara = de_getu16le(pos+9*2); d->pnPara_offs = d->pnPara * 128; de_dbg(c, "pnPara: page %d (offset %d)", (int)d->pnPara, (int)d->pnPara_offs); d->pnFntb = de_getu16le(pos+10*2); de_dbg(c, "pnFntb: page %d", (int)d->pnFntb); d->pnSep = de_getu16le(pos+11*2); de_dbg(c, "pnSep: page %d", (int)d->pnSep); d->pnSetb = de_getu16le(pos+12*2); de_dbg(c, "pnSetb: page %d", (int)d->pnSetb); d->pnPgtb = de_getu16le(pos+13*2); de_dbg(c, "pnPgtb: page %d", (int)d->pnPgtb); d->pnFfntb = de_getu16le(pos+14*2); de_dbg(c, "pnFfntb: page %d", (int)d->pnFfntb); d->pnMac = de_getu16le(pos+48*2); de_dbg(c, "pnMac: %d pages", (int)d->pnMac); d->pnPara_npages = d->pnFntb - d->pnPara; de_dbg_indent(c, -1); return 1; }
static void do_decode_thumbnail(deark *c, lctx *d) { dbuf *unc_pixels = NULL; i64 hdrsize = 2; de_dbg(c, "thumbnail image at %d", (int)d->thumbnail_offset); de_dbg_indent(c, 1); // The thumbnail image is supposed to use the same format as the main image, // except without compression. (And the dimensions are obviously different.) // Presumably this means the origin, palette, etc. will be the same. // But based on the few TGA thumbnails we've seen, nobody reads the spec, and // it's anybody's guess what format the thumbnail will use. // TGA 2.0 spec says the dimensions are one *byte* each. d->thumbnail_image.width = (i64)de_getbyte(d->thumbnail_offset); d->thumbnail_image.height = (i64)de_getbyte(d->thumbnail_offset+1); de_dbg(c, "thumbnail dimensions: %d"DE_CHAR_TIMES"%d", (int)d->thumbnail_image.width, (int)d->thumbnail_image.height); if(d->thumbnail_image.width!=0 && d->thumbnail_image.height==0) { de_warn(c, "Thumbnail image height is 0. Assuming the file incorrectly uses " "16-bit thumbnail dimensions, instead of 8."); d->thumbnail_image.width = de_getu16le(d->thumbnail_offset); d->thumbnail_image.height = de_getu16le(d->thumbnail_offset+2); de_dbg(c, "revised thumbnail dimensions: %d"DE_CHAR_TIMES"%d", (int)d->thumbnail_image.width, (int)d->thumbnail_image.height); hdrsize = 4; } if(!de_good_image_dimensions(c, d->thumbnail_image.width, d->thumbnail_image.height)) goto done; d->thumbnail_image.img_size_in_bytes = d->thumbnail_image.height * d->thumbnail_image.width * d->bytes_per_pixel; unc_pixels = dbuf_open_input_subfile(c->infile, d->thumbnail_offset+hdrsize, d->thumbnail_image.img_size_in_bytes); do_decode_image(c, d, &d->thumbnail_image, unc_pixels, "thumb", DE_CREATEFLAG_IS_AUX); done: dbuf_close(unc_pixels); de_dbg_indent(c, -1); }
static void run_ogg_internal(deark *c, lctx *d) { i64 pos; i64 ogg_end; struct de_id3info id3i; d->always_hexdump = de_get_ext_option(c, "ogg:hexdump")?1:0; d->streamtable = de_inthashtable_create(c); de_fmtutil_handle_id3(c, c->infile, &id3i, 0); pos = id3i.main_start; ogg_end = id3i.main_end; while(1) { u32 sig; int ret; i64 bytes_consumed = 0; if(pos >= ogg_end) break; sig = (u32)de_getu32be(pos); if(sig!=0x04f676753U) { de_err(c, "Ogg page signature not found at %"I64_FMT, pos); break; } de_dbg(c, "page at %"I64_FMT, pos); de_dbg_indent(c, 1); ret = do_ogg_page(c, d, pos, &bytes_consumed); de_dbg_indent(c, -1); if(!ret || bytes_consumed<=4) break; pos += bytes_consumed; d->total_page_count++; } if(!d->format_declared) declare_ogg_format(c, d); de_dbg(c, "number of bitstreams: %d", (int)d->bitstream_count); }
static void do_lump_entry(deark *c, lctx *d, i64 lump_idx, i64 pos) { i64 lump_pos; i64 lump_size; struct de_stringreaderdata *srd = NULL; de_dbg(c, "lump[%d] dir entry at %d", (int)lump_idx, (int)pos); de_dbg_indent(c, 1); lump_pos = de_getu32le(pos); de_dbg(c, "data pos: %d", (int)lump_pos); lump_size = de_getu32le(pos+4); de_dbg(c, "data size: %d", (int)lump_size); // dbuf_read_string is used (instead of dbuf_read_to_ucstring) because // the names have special meanings, so someday we might want to run // comparisons against them. But currently we don't do that. srd = dbuf_read_string(c->infile, pos+8, 8, 8, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII); de_dbg(c, "name: \"%s\"", ucstring_getpsz_d(srd->str)); do_lump_extract(c, d, lump_pos, lump_size, srd); de_dbg_indent(c, -1); de_destroy_stringreaderdata(c, srd); }
static void do_read_palette(deark *c, lctx *d) { de_int64 pal_size_in_bytes; if(d->pal_entries<1) return; pal_size_in_bytes = d->pal_entries*d->bytes_per_pal_entry; if(d->pal_pos+pal_size_in_bytes > d->bits_offset) { de_warn(c, "Palette at %d (size %d) overlaps bitmap at %d\n", (int)d->pal_pos, (int)pal_size_in_bytes, (int)d->bits_offset); if(d->version==DE_BMPVER_OS2V2) { do_os2v2_bad_palette(c, d); } } de_dbg(c, "color table at %d, %d entries\n", (int)d->pal_pos, (int)d->pal_entries); de_dbg_indent(c, 1); de_read_palette_rgb(c->infile, d->pal_pos, d->pal_entries, d->bytes_per_pal_entry, d->pal, 256, DE_GETRGBFLAG_BGR); d->pal_is_grayscale = de_is_grayscale_palette(d->pal, d->pal_entries); de_dbg_indent(c, -1); }