Exemple #1
0
unsigned scan(unsigned char *addr, size_t len, int psd_version, struct layer_info *li)
{
	unsigned char *p = addr, *q;
	size_t i;
	int j, k;
	unsigned n = 0, ps_ptr_bytes = 2 << psd_version;
	struct dictentry *de;

	for(i = 0; i < len;)
	{
		if(KEYMATCH((char*)p+i, "8BIM")){
			i += 4;

			// found possible layer signature
			// check next 4 bytes for a known blend mode
			for(de = bmdict; de->key; ++de)
				if(!memcmp(de->key, (char*)p+i, 4)){
					// found a possible layer blendmode signature
					// try to guess number of channels
					for(j = 1; j < 64; ++j){
						q = p + i - 4 - j*(ps_ptr_bytes + 2) - 2;
						if(peek2B(q) == j){
							long t = peek4B(q-16), l = peek4B(q-12), b = peek4B(q-8), r = peek4B(q-4);
							// sanity check bounding box
							if(b >= t && r >= l){
								// sanity check channel ids
								for(k = 0; k < j; ++k){
									int chid = peek2B(q + 2 + k*(ps_ptr_bytes + 2));
									if(chid < -2 || chid >= j)
										break; // smells bad, give up
								}
								if(k == j){
									// channel ids were ok. could still be a valid guess...
									++n;
									if(li){
										li->filepos = q - p - 16;
										++li;
									}
									else
										VERBOSE("scavenge @ %8td : key: %c%c%c%c  could be %d channel layer: t = %ld, l = %ld, b = %ld, r = %ld\n",
											   q - p - 16,
											   de->key[0], de->key[1], de->key[2], de->key[3],
											   j,
											   t, l, b, r);
									break;
								}
							}
						}
					}

					break;
				}
		}else
			++i;
	}
	return n;
}
Exemple #2
0
static void displayinfo(int level, unsigned char data[]){
	static const char *kind[] = {"ALPHACOLORSELECTED", "ALPHACOLORMASKED", "SPOTCHANNEL"};
	const char *indent = tabs(level);

	if(xml){
		fprintf(xml, "%s<%s>\n", indent, kind[data[12]]);
		colorspace(level+1, peek2B(data), data+2);
		fprintf(xml, "\t%s<OPACITY>%d</OPACITY>\n", indent, peek2B(data+10));
		// kind values seem to be:
		// 0 = alpha channel, colour indicates selected areas
		// 1 = alpha channel, colour indicates masked areas
		// 2 = spot colour channel
		//fprintf(xml, "\t%s<KIND>%d</KIND>\n", indent, data[12]);
		fprintf(xml, "%s</%s>\n", indent, kind[data[12]]);
	}
}
Exemple #3
0
void scan_merged(unsigned char *addr, size_t len, struct psd_header *h)
{
	size_t i, j = 0;
	unsigned ps_ptr_bytes = 2 << h->version;

	h->lmistart = h->lmilen = 0;

	// first search for a valid image resource block (these precede layer/mask info)
	for(i = 0; i < len;)
	{
		j = is_resource(addr, len, i);
		if(j && j < len-4){
			VERBOSE("scavenge: possible resource id=%d @ %lu\n", peek2B(addr+i+4), (unsigned long)i);
			i = j; // found an apparently valid resource; skip over it

			// is it followed by another resource?
			if(memcmp("8BIM", addr+j, 4))
				break; // no - stop looking
		}else
			++i;
	}

	if(!j)
		alwayswarn("Did not find any plausible image resources; probably cannot locate merged image data.\n");

	for(i = j; i < len; ++i)
	{
		psd_bytes_t lmilen = h->version == 2 ? peek8B(addr+i) : peek4B(addr+i),
				  layerlen = h->version == 2 ? peek8B(addr+i+ps_ptr_bytes) : peek4B(addr+i+ps_ptr_bytes);
		if(lmilen > 0 && (i+lmilen) < len && layerlen == 0)
		{
			// sanity check compression type
			int comptype = peek2Bu(addr + i + lmilen);
			if(comptype == 0 || comptype == 1)
			{
				h->lmistart = i+ps_ptr_bytes;
				h->lmilen = lmilen;
				VERBOSE("scavenge: possible empty LMI @ %lld\n", h->lmistart);
				UNQUIET(
"May be able to recover merged image if you can provide correct values\n\
for --mergedrows, --mergedcols, --mergedchan, --depth and --mode.\n");
				break; // take first one
			}
		}