Пример #1
0
int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer){
    IFFResourceMap *Map;
    bytestream b;
    unsigned i;

    if(ChunkInfo->Size < 20)
        return 0;
    set_bytestream(&b, Buffer, ChunkInfo->Size);
    ChunkInfo->FormattedData = calloc(1, sizeof(IFFResourceMap));
    if(ChunkInfo->FormattedData == NULL)
        return 0;

    Map = ChunkInfo->FormattedData;
    Map->Reserved = read_uint32(&b);
    Map->Version = read_uint32(&b);
    memcpy(Map->MagicNumber, b.Buffer, 4);
    skipbytes(&b, 4);
    Map->IFFSize = read_uint32(&b);
    Map->TypeCount = read_uint32(&b);
    if(Map->Reserved != 0 || Map->Version > 1)
        return 0;

    Map->ResourceTypes = calloc(Map->TypeCount, sizeof(IFFResourceType));
    if(Map->ResourceTypes == NULL)
        return 0;

    for(i=0; i<Map->TypeCount; i++){
        IFFResourceType * Type = &Map->ResourceTypes[i];
        unsigned j;
        if(b.Size < 8) return 0;

        memcpy(Type->Type, b.Buffer, 4);
        skipbytes(&b, 4);
        Type->ResourceCount = read_uint32(&b);
        Type->Resources = calloc(Type->ResourceCount, sizeof(IFFResource));
        if(Type->Resources == NULL)
            return 0;

        for(j=0; j<Type->ResourceCount; j++){
            IFFResource * Resource = &Type->Resources[j];
            if(b.Size < ((Map->Version == 0) ? 9 : 11)) return 0;
            Resource->Offset = read_uint32(&b);
            Resource->ChunkID = (Map->Version == 0) ? read_uint16(&b) : read_uint32(&b);
            Resource->Flags = read_uint16(&b);

            if(Map->Version == 0){
                if(!read_c_string(&b, &Resource->Label))
                    return 0;
            }else{
                if(!read_pascal_string(&b, &Resource->Label))
                    return 0;
            }
        }
    }
    return 1;
}
Пример #2
0
int iff_parse_tmpl(IFFChunk * ChunkInfo, const uint8_t * Buffer){
    IFFTemplate *Template;
    bytestream b;
    const uint8_t * ptr = Buffer;
    unsigned Size = ChunkInfo->Size;
    unsigned FieldCount;
    unsigned i;
    if(Size == 0) return 1;

    /* Walk through a first-pass to find the total field count */
    for(FieldCount=0; Size; FieldCount++){
        unsigned length = *ptr;
        if(Size < 5 || length > Size-5)
            return 0;
        ptr += length+5; Size -= length+5;
    }

    ChunkInfo->FormattedData = calloc(1, sizeof(IFFTemplate));
    if(ChunkInfo->FormattedData == NULL)
        return 0;

    Template = ChunkInfo->FormattedData;
    Template->FieldCount = FieldCount;
    Template->Fields = calloc(FieldCount, sizeof(IFFTemplateField));
    if(Template->Fields == NULL)
        return 0;

    set_bytestream(&b, Buffer, ChunkInfo->Size);

    for(i=0; i<FieldCount; i++){
        IFFTemplateField * Field = &Template->Fields[i];
        if(!read_pascal_string(&b, &Field->Name))
            return 0;

        memcpy(Field->Type, b.Buffer, 4);
        skipbytes(&b, 4);
    }

    return 1;
}
Пример #3
0
Flex *flexReadBegin( char *filename, unsigned int *failID, int *failpos )
{
   FILE *fp = NULL;
   Flex *flex;
   Frame *frame = NULL;
   Layer *layer = NULL;
   unsigned int id, formsize, type, cksize;
   int rlen, nframes = 0, nlayers = 0;

   /* open the file */

   fp = fopen( filename, "rb" );
   if ( !fp ) return NULL;

   /* read the first 12 bytes */

   set_flen( 0 );
   id       = getU4( fp );
   formsize = getU4( fp );
   type     = getU4( fp );
   if ( 12 != get_flen() ) {
      fclose( fp );
      return NULL;
   }

   /* is this a flex image? */

   if ( id != ID_FORM ) {
      fclose( fp );
      if ( failpos ) *failpos = 12;
      return NULL;
   }

   if ( type != ID_FPBM ) {
      fclose( fp );
      if ( failpos ) *failpos = 12;
      return NULL;
   }

   /* allocate a Flex */

   flex = calloc( 1, sizeof( Flex ));
   if ( !flex ) goto Fail;

   /* get the first chunk header */

   id = getU4( fp );
   cksize = getU4( fp );
   if ( 0 > get_flen() ) goto Fail;

   /* process chunks as they're encountered */

   while ( 1 ) {
      set_flen( 0 );

      switch ( id )
      {
         case ID_FPHD:
			if(cksize==28) // Older file version
			{
				flex->hdr.width           = getI2( fp );
				flex->hdr.height          = getI2( fp );
			}
			else // cksize==32
			{
				flex->hdr.width           = getI4( fp );
				flex->hdr.height          = getI4( fp );
			}
			flex->hdr.numLayers       = getI2( fp );
			flex->hdr.numFrames       = getI2( fp );
			flex->hdr.numBuffers      = getI2( fp );
			flex->hdr.flags           = getI2( fp );
			flex->hdr.srcLayerDepth   = getI2( fp );
			skipbytes( fp, 2 );
			flex->hdr.pixelAspect     = getF4( fp );
			flex->hdr.pixelWidth      = getF4( fp );
			flex->hdr.framesPerSecond = getF4( fp );
			frame = calloc( flex->hdr.numFrames, sizeof( Frame ));
			if ( !frame ) goto Fail;
			flex->frame = frame;
			break;

         case ID_FLEX:
            if ( !frame ) goto Fail;
            if ( nframes >= flex->hdr.numFrames ) goto Fail;
            nlayers = getI2( fp );
            layer = calloc( nlayers, sizeof( Layer ));
            if ( !layer ) goto Fail;
            frame[ nframes ].layer = layer;
            frame[ nframes ].hdr.numLayers = nlayers;
            nlayers = 0;
            ++nframes;
            break;

         case ID_LYHD:
            if ( !layer ) goto Fail;
            if ( nlayers >= frame[ nframes - 1 ].hdr.numLayers ) goto Fail;
            layer[ nlayers ].w               = flex->hdr.width;
            layer[ nlayers ].h               = flex->hdr.height;
            layer[ nlayers ].hdr.flags       = getI2( fp );
            layer[ nlayers ].hdr.layerType   = getI2( fp );
            layer[ nlayers ].hdr.layerDepth  = getI2( fp );
            layer[ nlayers ].hdr.compression = getI2( fp );
            layer[ nlayers ].hdr.blackPoint  = getF4( fp );
            layer[ nlayers ].hdr.whitePoint  = getF4( fp );
            layer[ nlayers ].hdr.gamma       = getF4( fp );
            break;

         case ID_LAYR:
            if ( !layer ) goto Fail;
            layer[ nlayers ].offset = ftell( fp );
            layer[ nlayers ].size   = cksize;
            ++nlayers;
            break;

         default:
            break;
      }

      /* error while reading current subchunk? */

      rlen = get_flen();
      if ( rlen < 0 || rlen > cksize ) goto Fail;

      /* skip unread parts of the current subchunk */

      cksize += cksize & 1;
      if ( rlen < cksize )
         fseek( fp, cksize - rlen, SEEK_CUR );

      /* end of the file? */

      if ( formsize <= ftell( fp ) - 8 ) break;

      /* get the next chunk header */

      set_flen( 0 );
      id = getU4( fp );
      cksize = getU4( fp );
      if ( 8 != get_flen() ) goto Fail;
   }

   flex->fp = fp;
   return flex;

Fail:
   if ( failID ) *failID = id;
   if ( fp ) {
      if ( failpos ) *failpos = ftell( fp );
      fclose( fp );
   }
   flexFree( flex );
   return NULL;
}
Пример #4
0
int
main(int argc, char **argv)
{
    int y;
    FBIO *fbp;
    int xout, yout, n, m, xstart, xskip;

    if (!get_args(argc, argv)) {
	(void)fputs(usage, stderr);
	bu_exit(1, NULL);
    }

    /* autosize input? */
    if (fileinput && autosize) {
	size_t w, h;
	if (fb_common_file_size(&w, &h, file_name, 3)) {
	    file_width = w;
	    file_height = h;
	} else {
	    fprintf(stderr, "pix-fb: unable to autosize\n");
	}
    }

    /* If screen size was not set, track the file size */
    if (scr_width == 0)
	scr_width = file_width;
    if (scr_height == 0)
	scr_height = file_height;

    if ((fbp = fb_open(framebuffer, scr_width, scr_height)) == NULL) {
	bu_exit(12, NULL);
    }

    /* Get the screen size we were given */
    scr_width = fb_getwidth(fbp);
    scr_height = fb_getheight(fbp);

    /* compute number of pixels to be output to screen */
    if (scr_xoff < 0) {
	xout = scr_width + scr_xoff;
	xskip = (-scr_xoff);
	xstart = 0;
    } else {
	xout = scr_width - scr_xoff;
	xskip = 0;
	xstart = scr_xoff;
    }

    if (xout < 0)
	bu_exit(0, NULL);			/* off screen */
    if ((size_t)xout > (file_width-file_xoff))
	xout = (file_width-file_xoff);
    scanpix = xout;				/* # pixels on scanline */

    if (inverse)
	scr_yoff = (-scr_yoff);

    yout = scr_height - scr_yoff;
    if (yout < 0)
	bu_exit(0, NULL);			/* off screen */
    if ((size_t)yout > (file_height-file_yoff))
	yout = (file_height-file_yoff);

    /* Only in the simplest case use multi-line writes */
    if (!one_line_only
	&& multiple_lines > 0
	&& !inverse
	&& !zoom
	&& (size_t)xout == file_width
	&& file_width <= (size_t)scr_width)
    {
	scanpix *= multiple_lines;
    }

    scanbytes = scanpix * sizeof(RGBpixel);
    if ((scanline = (unsigned char *)malloc(scanbytes)) == RGBPIXEL_NULL) {
	fprintf(stderr,
		"pix-fb:  malloc(%d) failure for scanline buffer\n",
		scanbytes);
	bu_exit(2, NULL);
    }

    if (clear) {
	fb_clear(fbp, PIXEL_NULL);
    }
    if (zoom) {
	/* Zoom in, and center the display.  Use square zoom. */
	int zoomit;
	zoomit = scr_width/xout;
	if (scr_height/yout < zoomit) zoomit = scr_height/yout;
	if (inverse) {
	    fb_view(fbp,
		    scr_xoff+xout/2, scr_height-1-(scr_yoff+yout/2),
		    zoomit, zoomit);
	} else {
	    fb_view(fbp,
		    scr_xoff+xout/2, scr_yoff+yout/2,
		    zoomit, zoomit);
	}
    }

    if (file_yoff != 0) skipbytes(infd, (off_t)file_yoff*(off_t)file_width*sizeof(RGBpixel));

    if (multiple_lines) {
	/* Bottom to top with multi-line reads & writes */
	unsigned long height;
	for (y = scr_yoff; y < scr_yoff + yout; y += multiple_lines) {
	    n = bu_mread(infd, (char *)scanline, scanbytes);
	    if (n <= 0) break;
	    height = multiple_lines;
	    if (n != scanbytes) {
		height = (n/sizeof(RGBpixel)+xout-1)/xout;
		if (height <= 0) break;
	    }
	    /* Don't over-write */
	    if ((size_t)(y + height) > (size_t)(scr_yoff + yout))
		height = scr_yoff + yout - y;
	    if (height <= 0) break;
	    m = fb_writerect(fbp, scr_xoff, y,
			     file_width, height,
			     scanline);
	    if ((size_t)m != file_width*height) {
		fprintf(stderr,
			"pix-fb: fb_writerect(x=%d, y=%d, w=%lu, h=%lu) failure, ret=%d, s/b=%d\n",
			scr_xoff, y,
			(unsigned long)file_width, height, m, scanbytes);
	    }
	}
    } else if (!inverse) {
	/* Normal way -- bottom to top */
	for (y = scr_yoff; y < scr_yoff + yout; y++) {
	    if (y < 0 || y > scr_height) {
		skipbytes(infd, (off_t)file_width*sizeof(RGBpixel));
		continue;
	    }
	    if (file_xoff+xskip != 0)
		skipbytes(infd, (off_t)(file_xoff+xskip)*sizeof(RGBpixel));
	    n = bu_mread(infd, (char *)scanline, scanbytes);
	    if (n <= 0) break;
	    m = fb_write(fbp, xstart, y, scanline, xout);
	    if (m != xout) {
		fprintf(stderr,
			"pix-fb: fb_write(x=%d, y=%d, npix=%d) ret=%d, s/b=%d\n",
			scr_xoff, y, xout,
			m, xout);
	    }
	    /* slop at the end of the line? */
	    if ((size_t)file_xoff+xskip+scanpix < file_width)
		skipbytes(infd, (off_t)(file_width-file_xoff-xskip-scanpix)*sizeof(RGBpixel));
	}
    } else {
	/* Inverse -- top to bottom */
	for (y = scr_height-1-scr_yoff; y >= scr_height-scr_yoff-yout; y--) {
	    if (y < 0 || y >= scr_height) {
		skipbytes(infd, (off_t)file_width*sizeof(RGBpixel));
		continue;
	    }
	    if (file_xoff+xskip != 0)
		skipbytes(infd, (off_t)(file_xoff+xskip)*sizeof(RGBpixel));
	    n = bu_mread(infd, (char *)scanline, scanbytes);
	    if (n <= 0) break;
	    m = fb_write(fbp, xstart, y, scanline, xout);
	    if (m != xout) {
		fprintf(stderr,
			"pix-fb: fb_write(x=%d, y=%d, npix=%d) ret=%d, s/b=%d\n",
			scr_xoff, y, xout,
			m, xout);
	    }
	    /* slop at the end of the line? */
	    if ((size_t)file_xoff+xskip+scanpix < file_width)
		skipbytes(infd, (off_t)(file_width-file_xoff-xskip-scanpix)*sizeof(RGBpixel));
	}
    }
    sleep(pause_sec);
    if (fb_close(fbp) < 0) {
	fprintf(stderr, "pix-fb: Warning: fb_close() error\n");
    }

    return 0;
}