Exemplo n.º 1
0
int BDATreader::createTOC() {
    int res,laststate,n;
    long lastpos,p;
    datablockinfo db,saveddb;

    if(hasTOC) deleteTOC();
    if(state>0) {
        laststate=state;
        lastpos=pos;
        saveddb=lastinfo;
        state=1;pos=8;
        FileSeek(f,pos,SEEK_SET);
        res=getnextblockinfo(db);
        while(res==0) {
            TOCN++;
            res=skipblock();
            if(res==0) res=getnextblockinfo(db);
        }
        if(TOCN>0) {
            hasTOC=true;
            TOCpos=new long[TOCN];
            TOCID=new unsigned int[TOCN];
            TOCnames=new string[TOCN];
            state=1;p=pos=8;
            FileSeek(f,pos,SEEK_SET);
            res=getnextblockinfo(db);
            n=0;
            while(res==0) {
                res=skipblock();
                TOCpos[n]=p;
                TOCID[n]=lastinfo.ID;
                TOCnames[n]=lastinfo.name;
                p=pos;
                if(res==0) res=getnextblockinfo(db);
                n++;
            }
        }
        state=laststate;
        pos=lastpos;
        lastinfo=saveddb;
        FileSeek(f,pos,SEEK_SET);
    }
    else return -1;
    return 0;
};
Exemplo n.º 2
0
int BDATreader::printlist() {
    int res,laststate,n;
    long lastpos;
    string tname;
    datablockinfo db,saveddb;
    if(state>0) {
        laststate=state;
        lastpos=pos;
        saveddb=lastinfo;
        state=1;pos=8;
        FileSeek(f,pos,SEEK_SET);
        res=getnextblockinfo(db);
        printf("BDAT binary data file information:\n - name %s\n - size: %ld\n",filename.c_str(),size);
        n=1;
        while(res==0) {
            printf(" - data block %d\n   - name: %s\n   - ID: %d\n   - type: (%08X) ",n,lastinfo.name.c_str(),lastinfo.ID,lastinfo.type);
            switch (lastinfo.type) {
                case DT_bit:tname="bits";break;
                case DT_byte:tname="byte";break;
                case DT_ubyte:tname="unsigned byte";break;
                case DT_word:tname="word/2-byte integer";break;
                case DT_uword:tname="unsigned word/2-byte integer";break;
                case DT_int:tname="int/4-byte integer";break;
                case DT_uint:tname="unsigned int/4-byte integer";break;
                case DT_long:tname="long int/8-byte integer";break;
                case DT_ulong:tname="unsigned long int/8-byte integer";break;
                case DT_single:tname="float/4-byte floating point number";break;
                case DT_double:tname="double/8-byte floating point number";break;
                case DT_quad:tname="quad/16-byte floating point number";break;
                case DT_csingle:tname="complex float/two 4-byte floating point numbers";break;
                case DT_cdouble:tname="complex double/two 8-byte floating point numbers";break;
                case DT_cquad:tname="complex quad/two 16-byte floating point number";break;
                case DT_user:tname="user defined format";break;
                default:tname="unknown";break;
            }
            printf("%s\n   - records: %d\n   - record size: %d bytes\n   - data size: %d bytes\n",tname.c_str(),lastinfo.records,lastinfo.recordsize,lastinfo.records*lastinfo.recordsize);
            res=skipblock();
            if(res==0) res=getnextblockinfo(db);
            n++;
        }
        state=laststate;
        pos=lastpos;
        lastinfo=saveddb;
        FileSeek(f,pos,SEEK_SET);
    }
    else return -1; //file needs to be open
    return 0;
};
Exemplo n.º 3
0
void readlayerinfo(psd_file_t f, struct psd_header *h, int i)
{
	psd_bytes_t extralen, extrastart;
	int j, chid, namelen;
	char *chidstr, tmp[10];
	struct layer_info *li = h->linfo + i;

	// process layer record
	li->top = get4B(f);
	li->left = get4B(f);
	li->bottom = get4B(f);
	li->right = get4B(f);
	li->channels = get2Bu(f);

	VERBOSE("\n");
	UNQUIET("  layer %d: (%4d,%4d,%4d,%4d), %d channels (%4d rows x %4d cols)\n",
			i, li->top, li->left, li->bottom, li->right, li->channels,
			li->bottom-li->top, li->right-li->left);

	if( li->bottom < li->top || li->right < li->left
	 || li->channels > 64 ) // sanity check
	{
		alwayswarn("### something's not right about that, trying to skip layer.\n");
		fseeko(f, 6*li->channels+12, SEEK_CUR);
		skipblock(f, "layer info: extra data");
		li->chan = NULL;
		li->chindex = NULL;
		li->nameno = li->name = li->unicode_name = NULL;
	}
	else
	{
		li->chan = checkmalloc(li->channels*sizeof(struct channel_info));
		li->chindex = checkmalloc((li->channels+3)*sizeof(int));
		li->chindex += 3; // so we can index array from [-3] (hackish)

		for(j = -3; j < li->channels; ++j)
			li->chindex[j] = -1;

		// fetch info on each of the layer's channels

		for(j = 0; j < li->channels; ++j){
			li->chan[j].id = chid = get2B(f);
			li->chan[j].length = GETPSDBYTES(f);
			li->chan[j].rawpos = 0;
			li->chan[j].rowpos = NULL;
			li->chan[j].unzipdata = NULL;

			if(chid >= -3 && chid < li->channels)
				li->chindex[chid] = j;
			else
				warn_msg("unexpected channel id %d", chid);

			switch(chid){
			case UMASK_CHAN_ID: chidstr = " (user layer mask)"; break;
			case LMASK_CHAN_ID: chidstr = " (layer mask)"; break;
			case TRANS_CHAN_ID: chidstr = " (transparency mask)"; break;
			default:
				if(h->mode != SCAVENGE_MODE && chid < (int)strlen(channelsuffixes[h->mode]))
					sprintf(chidstr = tmp, " (%c)", channelsuffixes[h->mode][chid]); // it's a mode-ish channel
				else
					chidstr = ""; // don't know
			}
			VERBOSE("    channel %2d: " LL_L("%7lld","%7ld") " bytes, id=%2d %s\n",
					j, li->chan[j].length, chid, chidstr);
		}

		fread(li->blend.sig, 1, 4, f);
		fread(li->blend.key, 1, 4, f);
		li->blend.opacity = fgetc(f);
		li->blend.clipping = fgetc(f);
		li->blend.flags = fgetc(f);
		fgetc(f); // padding

		// process layer's 'extra data' section

		extralen = get4B(f);
		extrastart = ftello(f);
		VERBOSE("  (extra data: " LL_L("%lld","%ld") " bytes @ "
				LL_L("%lld","%ld") ")\n", extralen, extrastart);

		// fetch layer mask data
		li->mask.size = get4B(f);
		if(li->mask.size >= 20){
			off_t skip = li->mask.size;
			VERBOSE("  (has layer mask)\n");
			li->mask.top = get4B(f);
			li->mask.left = get4B(f);
			li->mask.bottom = get4B(f);
			li->mask.right = get4B(f);
			li->mask.default_colour = fgetc(f);
			li->mask.flags = fgetc(f);
			skip -= 18;
			if(li->mask.size >= 36){
				VERBOSE("  (has user layer mask)\n");
				li->mask.real_flags = fgetc(f);
				li->mask.real_default_colour = fgetc(f);
				li->mask.real_top = get4B(f);
				li->mask.real_left = get4B(f);
				li->mask.real_bottom = get4B(f);
				li->mask.real_right = get4B(f);
				skip -= 18;
			}
			fseeko(f, skip, SEEK_CUR); // skip remainder
		}else
			VERBOSE("  (no layer mask)\n");

		skipblock(f, "layer blending ranges");

		// layer name
		li->nameno = checkmalloc(16);
		sprintf(li->nameno, "layer%d", i+1);
		namelen = fgetc(f);
		li->name = checkmalloc(PAD4(namelen+1));
		fread(li->name, 1, PAD4(namelen+1)-1, f);
		li->name[namelen] = 0;
		if(namelen)
			UNQUIET("    name: \"%s\"\n", li->name);

		// process layer's 'additional info'

		li->additionalpos = ftello(f);
		li->additionallen = extrastart + extralen - li->additionalpos;

		// leave file positioned after extra data
		fseeko(f, extrastart + extralen, SEEK_SET);
	}
}
Exemplo n.º 4
0
int dopsd(psd_file_t f, char *psdpath, struct psd_header *h){
	int result = 0;

	// file header
	fread(h->sig, 1, 4, f);
	h->version = get2Bu(f);
	get4B(f); get2B(f); // reserved[6];
	h->channels = get2Bu(f);
	h->rows = get4B(f);
	h->cols = get4B(f);
	h->depth = get2Bu(f);
	h->mode = get2Bu(f);

	if(!feof(f) && KEYMATCH(h->sig, "8BPS")){
		if(h->version == 1
#ifdef PSBSUPPORT
		   || h->version == 2
#endif
		){
			openfiles(psdpath, h);

			if(listfile) fprintf(listfile, "-- PSD file: %s\n", psdpath);
			if(xml){
				fputs("<PSD FILE='", xml);
				fputsxml(psdpath, xml);
				fprintf(xml, "' VERSION='%u' CHANNELS='%u' ROWS='%u' COLUMNS='%u' DEPTH='%u' MODE='%u'",
						h->version, h->channels, h->rows, h->cols, h->depth, h->mode);
				if(h->mode >= 0 && h->mode < 16)
					fprintf(xml, " MODENAME='%s'", mode_names[h->mode]);
				fputs(">\n", xml);
			}
			UNQUIET("  PS%c (version %u), %u channels, %u rows x %u cols, %u bit %s\n",
					h->version == 1 ? 'D' : 'B', h->version, h->channels, h->rows, h->cols, h->depth,
					h->mode >= 0 && h->mode < 16 ? mode_names[h->mode] : "???");

			if(h->channels <= 0 || h->channels > 64 || h->rows <= 0
			   || h->cols <= 0 || h->depth <= 0 || h->depth > 32 || h->mode < 0)
			{
				alwayswarn("### something isn't right about that header, giving up now.\n");
			}
			else{
				h->colormodepos = ftello(f);
				if(h->mode == ModeDuotone)
					duotone_data(f, 1);
				else
					skipblock(f, "color mode data");

				h->resourcepos = ftello(f);
				if(rsrc || resdump)
					doimageresources(f);
				else
					skipblock(f, "image resources");

				dolayermaskinfo(f, h);

				h->layerdatapos = ftello(f);
				VERBOSE("## layer data begins @ " LL_L("%lld","%ld") "\n", h->layerdatapos);

				result = 1;
			}
		}else
			alwayswarn("# \"%s\": version %d not supported\n", psdpath, h->version);
	}else
		alwayswarn("# \"%s\": couldn't read header, or is not a PSD/PSB\n", psdpath);

	if(!result)
		alwayswarn("# Try --scavenge (and related options) to see if any layer data can be found.\n");

	return result;
}