static int de_identify_woz(deark *c) { if(dbuf_memcmp(c->infile, 0, "WOZ", 3)) return 0; if(dbuf_memcmp(c->infile, 4, "\xff\x0a\x0d\x0a", 4)) return 0; return 100; }
static int de_identify_psf(deark *c) { if(!dbuf_memcmp(c->infile, 0, "\x72\xb5\x4a\x86", 4)) return 100; if(!dbuf_memcmp(c->infile, 0, "\x36\x04", 2)) { // TODO: Better PSFv1 detection. return 65; } return 0; }
static int de_identify_gemraster(deark *c) { i64 ver, x2; i64 nplanes; if(!de_input_file_has_ext(c, "img") && !de_input_file_has_ext(c, "ximg")) { return 0; } ver = de_getu16be(0); if(ver!=1 && ver!=2 && ver!=3) return 0; x2 = de_getu16be(2); if(x2<0x0008 || x2>0x0800) return 0; nplanes = de_getu16be(4); if(!(nplanes>=1 && nplanes<=8) && nplanes!=15 && nplanes!=16 && nplanes!=24 && nplanes!=32) { return 0; } if(ver==1 && x2==0x08) return 70; if(!dbuf_memcmp(c->infile, 16, "XIMG", 4)) { return 100; } return 10; }
static int de_identify_gemmeta(deark *c) { // FIXME: This will not identify all files. if(!dbuf_memcmp(c->infile, 0, "\xff\xff\x18\x00", 4)) return 100; return 0; }
static int has_signature(deark *c) { if(c->infile->len<18+26) return 0; if(!dbuf_memcmp(c->infile, c->infile->len-18, "TRUEVISION-XFILE.\0", 18)) { return 1; } return 0; }
static int de_identify_wad(deark *c) { if(!dbuf_memcmp(c->infile, 1, "WAD", 3)) { u8 b0; b0 = de_getbyte(0); if(b0=='I' || b0=='P') return 80; } return 0; }
static int de_identify_icns(deark *c) { de_int64 fsize; if(dbuf_memcmp(c->infile, 0, "icns", 4)) return 0; fsize = de_getui32be(4); if(fsize == c->infile->len) return 100; return 20; }
static void do_theora_vorbis_after_headers(deark *c, lctx *d, struct stream_info *si) { i64 pos = 0; int saved_indent_level; dbuf *f = NULL; de_dbg_indent_save(c, &saved_indent_level); if(si->stream_state!=0) goto done; if(!si->header_stream) goto done; if(!si->sti) goto done; f = si->header_stream; de_dbg(c, "[decoding %s comment/setup headers, %d bytes]", si->sti->name, (int)si->header_stream->len); de_dbg_indent(c, 1); // Make sure the comment header signature is present. if(si->stream_type==STREAMTYPE_VORBIS) { if(dbuf_memcmp(f, 0, "\x03" "vorbis", 7)) { goto done; } pos += 7; } else if(si->stream_type==STREAMTYPE_THEORA) { if(dbuf_memcmp(f, 0, "\x81" "theora", 7)) { goto done; } pos += 7; } do_vorbis_comment_block(c, d, f, pos); // TODO: "Setup" header done: si->stream_state = 1; dbuf_close(si->header_stream); si->header_stream = NULL; de_dbg_indent_restore(c, saved_indent_level); }
// Caller allocates sdd. It does not need to be initialized. // flags: 0x1 = Print a debug message if signature is found. int de_fmtutil_detect_SAUCE(deark *c, dbuf *f, struct de_SAUCE_detection_data *sdd, unsigned int flags) { de_zeromem(sdd, sizeof(struct de_SAUCE_detection_data)); if(f->len<128) return 0; if(dbuf_memcmp(f, f->len-128, "SAUCE00", 7)) return 0; if(flags & 0x1) { de_dbg(c, "SAUCE metadata, signature at %"I64_FMT, f->len-128); } sdd->has_SAUCE = 1; sdd->data_type = dbuf_getbyte(f, f->len-128+94); sdd->file_type = dbuf_getbyte(f, f->len-128+95); return (int)sdd->has_SAUCE; }
static void do_decode_24bit(deark *c, lctx *d, struct page_ctx *pg) { dbuf *unc_pixels = NULL; struct deark_bitmap *img = NULL; de_int64 i, j; de_byte cr, cg, cb, ca; de_int64 w, h; de_int64 skip; w = pg->type_info->width; h = pg->type_info->height; // TODO: Try to support uncompressed 24-bit images, assuming they exist. // Apparently, some 'it32' icons begin with four extra 0x00 bytes. // Skip over the first four bytes if they are 0x00. // (I don't know the reason for these bytes, but this is the same // logic libicns uses.) skip = 0; if(pg->code4cc.id==0x69743332) { // 'it32' (128x128) if(!dbuf_memcmp(c->infile, pg->image_pos, "\0\0\0\0", 4)) { skip = 4; } } unc_pixels = dbuf_create_membuf(c, w*h*3, 1); do_uncompress_24(c, d, pg, unc_pixels, skip); img = de_bitmap_create(c, w, h, 4); for(j=0; j<pg->type_info->height; j++) { for(i=0; i<pg->type_info->width; i++) { cr = dbuf_getbyte(unc_pixels, j*w + i); cg = dbuf_getbyte(unc_pixels, (h+j)*w + i); cb = dbuf_getbyte(unc_pixels, (2*h+j)*w + i); if(pg->mask_pos) ca = de_getbyte(pg->mask_pos + j*w + i); else ca = 0xff; de_bitmap_setpixel_rgba(img, i, j, DE_MAKE_RGBA(cr,cg,cb,ca)); } } de_bitmap_write_to_file(img, pg->filename_token, 0); de_bitmap_destroy(img); if(unc_pixels) dbuf_close(unc_pixels); }
static void handler_eXIf(deark *c, lctx *d, struct handler_params *hp) { i64 pos = hp->dpos; i64 len = hp->dlen; if(len>=6 && !dbuf_memcmp(c->infile, pos, "Exif\0", 5)) { // Some versions of the PNG-Exif proposal had the Exif data starting with // an "Exif\0\0" identifier, and some files were created in this format. // So we'll support it. de_dbg(c, "[skipping JPEG app ID]"); pos += 6; len -= 6; } if(len<8) return; de_fmtutil_handle_exif(c, pos, len); }
static int de_identify_ogg(deark *c) { i64 pos = 0; if(!c->detection_data.id3.detection_attempted) { de_err(c, "ogg detection requires id3 module"); return 0; } if(c->detection_data.id3.has_id3v2) { pos = (i64)c->detection_data.id3.bytes_at_start; } if(!dbuf_memcmp(c->infile, pos, "OggS", 4)) return 100; return 0; }
static void handle_1_90(deark *c, lctx *d, const struct ds_info *dsi, de_int64 pos, de_int64 len) { const char *csname; d->charset = DE_ENCODING_UNKNOWN; // TODO: Fully interpret this field. if(len>=3 && !dbuf_memcmp(c->infile, pos, "\x1b\x25\x47", 3)) { d->charset = DE_ENCODING_UTF8; } if(d->charset==DE_ENCODING_UTF8) csname="utf-8"; else csname="unknown"; de_dbg(c, "charset: %s\n", csname); }
// Sets d->file_format and d->has_signature static void detect_file_format(deark *c, lctx *d) { int has_igch; u8 img_type; d->has_signature = has_signature(c); de_dbg(c, "has v2 signature: %s", d->has_signature?"yes":"no"); if(d->has_signature) { d->file_format = FMT_TGA; return; } img_type = de_getbyte(2); if(img_type==0) { has_igch = !dbuf_memcmp(c->infile, 20, "IGCH", 4); if(has_igch) { d->file_format = FMT_VST; return; } } d->file_format = FMT_TGA; }
static int de_identify_t64(deark *c) { if(!dbuf_memcmp(c->infile, 0, "C64", 3)) return 80; return 0; }
static int de_identify_ebml(deark *c) { if(!dbuf_memcmp(c->infile, 0, "\x1a\x45\xdf\xa3", 4)) return 100; return 0; }
static int de_identify_rpm(deark *c) { if(!dbuf_memcmp(c->infile, 0, "\xed\xab\xee\xdb", 4)) return 100; return 0; }
static void de_run_gemraster(deark *c, de_module_params *mparams) { i64 ver; i64 ext_word0 = 0; lctx *d = NULL; int need_format_warning = 0; int saved_indent_level; de_dbg_indent_save(c, &saved_indent_level); d = de_malloc(c, sizeof(lctx)); de_dbg(c, "header (base part) at %d", 0); de_dbg_indent(c, 1); ver = de_getu16be(0); de_dbg(c, "version: %d", (int)ver); d->header_size_in_words = de_getu16be(2); d->header_size_in_bytes = d->header_size_in_words*2; de_dbg(c, "header size: %d words (%d bytes)", (int)d->header_size_in_words, (int)d->header_size_in_bytes); d->nplanes = de_getu16be(4); de_dbg(c, "planes: %d", (int)d->nplanes); if(d->header_size_in_words>=11) { d->is_ximg = !dbuf_memcmp(c->infile, 16, "XIMG", 4); } d->patlen = de_getu16be(6); de_dbg(c, "pattern def len: %d", (int)d->patlen); d->pixwidth = de_getu16be(8); d->pixheight = de_getu16be(10); de_dbg(c, "pixel size: %d"DE_CHAR_TIMES"%d microns", (int)d->pixwidth, (int)d->pixheight); d->w = de_getu16be(12); d->h = de_getu16be(14); de_dbg_dimensions(c, d->w, d->h); de_dbg_indent(c, -1); if(d->header_size_in_words>=9) { // This may help to detect the image format. ext_word0 = de_getu16be(16); } if(ver>2) { de_err(c, "This version of GEM Raster (%d) is not supported.", (int)ver); goto done; } if(d->is_ximg) { de_declare_fmt(c, "GEM VDI Bit Image, XIMG extension"); } else if(d->header_size_in_words==25 && d->patlen==2 && ext_word0==0x0080) { de_declare_fmt(c, "GEM VDI Bit Image, Hyperpaint extension"); } else if(d->header_size_in_words==8 && d->nplanes==1) { ; } else if(d->header_size_in_words==8 && (d->nplanes>=2 && d->nplanes<=8)) { need_format_warning = 1; } else if(d->header_size_in_words==9 && (d->nplanes>=1 && d->nplanes<=8)) { need_format_warning = 1; } else { if(d->header_size_in_words==27 && ext_word0==0x5354) { de_declare_fmt(c, "GEM VDI Bit Image, STTT extension"); } de_err(c, "This version of GEM Raster is not supported."); goto done; } if(need_format_warning) { de_warn(c, "This type of GEM Raster image is not very portable, and might " "not be handled correctly."); } if(!de_good_image_dimensions(c, d->w, d->h)) goto done; d->rowspan_per_plane = (d->w+7)/8; d->rowspan_total = d->rowspan_per_plane * d->nplanes; // If we haven't declared the format yet, do so. de_declare_fmt(c, "GEM VDI Bit Image"); if(d->is_ximg) { do_gem_ximg(c, d); } else if(d->header_size_in_words==25) { do_gem_ximg(c, d); } else { do_gem_img(c, d); } done: de_dbg_indent_restore(c, saved_indent_level); de_free(c, d); }