PsdStatus PsdFile::readImageResources() { if (!mResourcesBlock.mAddress) return PsdStatusNoInit; if (mResourcesBlock.mLength == 0) return PsdStatusOK; const uint8_t *ptr = mResourcesBlock.mAddress, *end = mResourcesBlock.getEndAddress(); if (end > mMapped.get().getEndAddress()) return PsdStatusFileOutOfRange; mResources.reset(new map<uint16_t, shared_ptr<PsdResource> >); uint32_t size; uint16_t id; end -= 8; while (ptr < end && CHECK_FOUR_CHAR(ptr, '8', 'B', 'I', 'M')) { ptr += 4; id = PsdUtils::fetch16(ptr); ptr += 2; string name = PsdUtils::fetchPascalString(ptr); ptr += PAD2(name.size() + 1); size = PsdUtils::fetch32(ptr); ptr += 4; (*mResources)[id] = shared_ptr<PsdResource>(new PsdResource(id, name, ptr, size)); ptr += PAD2(size); LOG_DEBUG("[RES] %u (%s) %u\n", id, name.c_str(), size); } return PsdStatusOK; }
static long doirb(psd_file_t f){ static struct dictentry resource = {0, NULL, "RESOURCE", "dummy", NULL}; char type[4], name[0x100]; int id, namelen; long size; size_t padded_size; struct dictentry *d; fread(type, 1, 4, f); id = get2B(f); namelen = fgetc(f); fread(name, 1, PAD2(1+namelen)-1, f); name[namelen] = 0; size = get4B(f); padded_size = PAD2(size); d = findbyid(id); if((verbose || print_rsrc || resdump) && !xmlout){ printf(" resource '%c%c%c%c' (%5d,\"%s\"):%5ld bytes", type[0],type[1],type[2],type[3], id, name, size); if(d) printf(" [%s]", d->desc); putchar('\n'); } if(d && d->tag){ if(xml){ fprintf(xml, "\t<RESOURCE TYPE='%c%c%c%c' ID='%d'", type[0],type[1],type[2],type[3], id); if(namelen) fprintf(xml, " NAME='%s'", name); } if(d->func){ if(xml) fputs(">\n", xml); entertag(f, 2, size, &resource, d, 1); if(xml) fputs("\t</RESOURCE>\n\n", xml); } else if(xml){ fputs(" /> <!-- not parsed -->\n", xml); } } if(resdump){ char *temp_buf = checkmalloc(padded_size); if(fread(temp_buf, 1, padded_size, f) < padded_size) fatal("did not read expected bytes in image resource\n"); dumphex((unsigned char*)temp_buf, size); putchar('\n'); free(temp_buf); } else fseeko(f, padded_size, SEEK_CUR); // skip resource block data return 4+2+PAD2(1+namelen)+4+padded_size; /* returns total bytes in block */ }
int is_resource(unsigned char *addr, size_t len, size_t offset) { int namelen; long size; if(KEYMATCH(addr + offset, "8BIM")){ offset += 4; // type offset += 2; // id namelen = addr[offset]; offset += PAD2(1+namelen); size = peek4B(addr+offset); offset += 4; offset += PAD2(size); // skip resource block data return offset; // should be offset of next resource } return 0; }