210 lines
5.1 KiB
C
210 lines
5.1 KiB
C
/* @(#) im_desc_hd: Copies vips file header to an IMAGE descriptor.
|
|
* @(#)
|
|
* @(#) int
|
|
* @(#) im__read_header_bytes( IMAGE *im, unsigned char *from )
|
|
* @(#)
|
|
* @(#) int
|
|
* @(#) im__write_header_bytes( IMAGE *im, unsigned char *to )
|
|
* @(#)
|
|
* @(#) Returns 0 on success and -1 on error
|
|
*
|
|
* Copyright: Nicos Dessipris
|
|
* Written on: 13/02/1990
|
|
* Modified on : 22/2/92 v6.3 Kirk Martinez
|
|
* 17/11/94 JC
|
|
* - read compression fields too
|
|
* 28/10/98 JC
|
|
* - byteswap stuff added
|
|
* 21/8/02 JC
|
|
* - oops, was truncating float
|
|
* 22/8/05
|
|
* - slightly less stupid
|
|
* 30/12/06
|
|
* - use gunit32/16 for 2 and 4 byte quantities
|
|
* 12/1/07
|
|
* - override bbits in the file ... it's now deprecated
|
|
* 7/3/08
|
|
* - write MAGIC correctly on sparc/powerpc machines
|
|
*/
|
|
|
|
/*
|
|
|
|
This file is part of VIPS.
|
|
|
|
VIPS is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
|
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif /*HAVE_CONFIG_H*/
|
|
#include <vips/intl.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <vips/vips.h>
|
|
|
|
#ifdef WITH_DMALLOC
|
|
#include <dmalloc.h>
|
|
#endif /*WITH_DMALLOC*/
|
|
|
|
/* Read short/int/float LSB and MSB first.
|
|
*/
|
|
void
|
|
im__read_4byte( int msb_first, unsigned char *to, unsigned char **from )
|
|
{
|
|
unsigned char *p = *from;
|
|
int out;
|
|
|
|
if( msb_first )
|
|
out = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
|
|
else
|
|
out = p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
|
|
|
|
*from += 4;
|
|
*((guint32 *) to) = out;
|
|
}
|
|
|
|
void
|
|
im__read_2byte( int msb_first, unsigned char *to, unsigned char **from )
|
|
{
|
|
int out;
|
|
unsigned char *p = *from;
|
|
|
|
if( msb_first )
|
|
out = p[0] << 8 | p[1];
|
|
else
|
|
out = p[1] << 8 | p[0];
|
|
|
|
*from += 2;
|
|
*((guint16 *) to) = out;
|
|
}
|
|
|
|
/* We always write in native byte order.
|
|
*/
|
|
void
|
|
im__write_4byte( unsigned char **to, unsigned char *from )
|
|
{
|
|
*((guint32 *) *to) = *((guint32 *) from);
|
|
*to += 4;
|
|
}
|
|
|
|
void
|
|
im__write_2byte( unsigned char **to, unsigned char *from )
|
|
{
|
|
*((guint16 *) *to) = *((guint16 *) from);
|
|
*to += 2;
|
|
}
|
|
|
|
/* offset, read, write functions.
|
|
*/
|
|
typedef struct _FieldIO {
|
|
glong offset;
|
|
void (*read)( int msb_first, unsigned char *to, unsigned char **from );
|
|
void (*write)( unsigned char **to, unsigned char *from );
|
|
} FieldIO;
|
|
|
|
static FieldIO fields[] = {
|
|
{ G_STRUCT_OFFSET( IMAGE, Xsize ),
|
|
im__read_4byte, im__write_4byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, Ysize ),
|
|
im__read_4byte, im__write_4byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, Bands ),
|
|
im__read_4byte, im__write_4byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, Bbits ),
|
|
im__read_4byte, im__write_4byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, BandFmt ),
|
|
im__read_4byte, im__write_4byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, Coding ),
|
|
im__read_4byte, im__write_4byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, Type ),
|
|
im__read_4byte, im__write_4byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, Xres ),
|
|
im__read_4byte, im__write_4byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, Yres ),
|
|
im__read_4byte, im__write_4byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, Length ),
|
|
im__read_4byte, im__write_4byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, Compression ),
|
|
im__read_2byte, im__write_2byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, Level ),
|
|
im__read_2byte, im__write_2byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, Xoffset ),
|
|
im__read_4byte, im__write_4byte },
|
|
{ G_STRUCT_OFFSET( IMAGE, Yoffset ),
|
|
im__read_4byte, im__write_4byte }
|
|
};
|
|
|
|
int
|
|
im__read_header_bytes( IMAGE *im, unsigned char *from )
|
|
{
|
|
int msb_first;
|
|
int i;
|
|
|
|
im__read_4byte( 1, (unsigned char *) &im->magic, &from );
|
|
if( im->magic != IM_MAGIC_INTEL && im->magic != IM_MAGIC_SPARC ) {
|
|
im_error( "im_open", _( "\"%s\" is not a VIPS image" ),
|
|
im->filename );
|
|
return( -1 );
|
|
}
|
|
msb_first = im->magic == IM_MAGIC_SPARC;
|
|
|
|
for( i = 0; i < IM_NUMBER( fields ); i++ )
|
|
fields[i].read( msb_first,
|
|
&G_STRUCT_MEMBER( unsigned char, im, fields[i].offset ),
|
|
&from );
|
|
|
|
/* Set this ourselves ... bbits is deprecated in the file format.
|
|
*/
|
|
im->Bbits = im_bits_of_fmt( im->BandFmt );
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
int
|
|
im__write_header_bytes( IMAGE *im, unsigned char *to )
|
|
{
|
|
guint32 magic;
|
|
int i;
|
|
unsigned char *q;
|
|
|
|
/* Always write the magic number MSB first.
|
|
*/
|
|
magic = im_amiMSBfirst() ? IM_MAGIC_SPARC : IM_MAGIC_INTEL;
|
|
to[0] = magic >> 24;
|
|
to[1] = magic >> 16;
|
|
to[2] = magic >> 8;
|
|
to[3] = magic;
|
|
q = to + 4;
|
|
|
|
for( i = 0; i < IM_NUMBER( fields ); i++ )
|
|
fields[i].write( &q,
|
|
&G_STRUCT_MEMBER( unsigned char, im,
|
|
fields[i].offset ) );
|
|
|
|
/* Pad spares with zeros.
|
|
*/
|
|
while( q - to < im->sizeof_header )
|
|
*q++ = 0;
|
|
|
|
return( 0 );
|
|
}
|