1247 lines
35 KiB
C
1247 lines
35 KiB
C
/*
|
|
|
|
$Log: S:\oiwh\libgfs\gifinfo.c_v $
|
|
*
|
|
* Rev 1.14 14 Dec 1995 17:34:12 RWR
|
|
* Add (read-only) support for compressed 8-bit and 4-bit palettized BMP files
|
|
*
|
|
* Rev 1.13 27 Oct 1995 15:35:18 JAR
|
|
* added the function CheckForThumb to the jfifinfo routine. This is for reading
|
|
* JPG files, the new function will check for the presence of a thumbnail image in
|
|
* the JFIF file, and skip it, then fix up the jpeg header for the jpeg dll to
|
|
* expand properly!
|
|
*
|
|
* Rev 1.12 23 Oct 1995 14:09:42 RWR
|
|
* Use the image offset value from the BMP header (don't assume anything!)
|
|
*
|
|
* Rev 1.11 19 Oct 1995 09:55:52 RWR
|
|
* Remove kludge to support old invalid BMP files (pre-3.7.2-created)
|
|
*
|
|
* Rev 1.10 04 Sep 1995 15:24:50 RWR
|
|
* Check for inverted B/W palette in bmpinfo() routine, set GFS_BILEVEL_0ISWHITE
|
|
*
|
|
* Rev 1.9 28 Aug 1995 14:22:20 RWR
|
|
* Correct processing of "OS2" type BMP file headers
|
|
*
|
|
* Rev 1.8 25 Aug 1995 16:22:08 RWR
|
|
* Correct line width computation to cast to (short) AFTER dividing by 8
|
|
*
|
|
* Rev 1.7 22 Aug 1995 15:55:08 HEIDI
|
|
*
|
|
*
|
|
* In .JPG files (JFIF) the Units may be specified in one of 3 ways:
|
|
* 1) if Units == 01, then resolution is dots per inch
|
|
* 2) if Units == 02, then resolution is dots per centimeter
|
|
* 3) if Units == 00, then there is no resolution, and the measurement is a
|
|
* pixel aspect ratio. Display and file info calls, however want a
|
|
* resolution, so we will return JFIF_DEFAULT_DPI = 200.
|
|
*
|
|
* Rev 1.6 16 Aug 1995 14:54:12 RWR
|
|
* Change PCX/DCX getinfo processing to return UNCOMPRESSED instead of PACKBITS
|
|
*
|
|
* Rev 1.5 08 Aug 1995 13:23:44 RWR
|
|
* Set EINVALID_COMPRESSION error if compressed BMP file (we don't support that)
|
|
*
|
|
* Rev 1.4 24 Jul 1995 16:57:22 JFC
|
|
* Fix typo: replace "pgnum" with "fct->format".
|
|
*
|
|
* Rev 1.3 20 Jul 1995 14:15:48 RWR
|
|
* Fix problem with TGAHEADER structure being force-aligned by the C compiler
|
|
*
|
|
* Rev 1.2 15 May 1995 15:43:58 RWR
|
|
* Roll in dword-alignment fix from GFSE product line
|
|
*
|
|
* Rev 1.1 19 Apr 1995 16:35:08 RWR
|
|
* Make sure WIN32_LEAN_AND_MEAN is defined (explicitly or via GFSINTRN.H)
|
|
* Also surround local include files with quotes instead of angle brackets
|
|
*
|
|
* Rev 1.0 06 Apr 1995 14:02:50 HEIDI
|
|
* Initial entry
|
|
*
|
|
* Rev 1.0 28 Mar 1995 15:53:34 JAR
|
|
* Initial entry
|
|
|
|
*/
|
|
|
|
/* SccsId: @(#)Source gifinfo.c 1.40@(#)
|
|
*
|
|
* (c) Copyright Wang Laboratories, Inc. 1989, 1990, 1991
|
|
* All Rights Reserved
|
|
*
|
|
* GFS: gifinfo() - return the INFO structure
|
|
*
|
|
* UPDATE HISTORY:
|
|
* 08/18/94, kmc, added support for DCX file format.
|
|
* 04/19/93, kmc, fixed pcxinfo function and added PutPcxInfo function.
|
|
* 10/02/91, krs, hacked from wfilegif
|
|
*
|
|
*
|
|
*/
|
|
|
|
/*LINTLIBRARY*/
|
|
#define GFS_CORE
|
|
#ifndef HVS1
|
|
#include "gfsintrn.h"
|
|
#include <stdio.h>
|
|
#include "gfs.h"
|
|
#include "gfct.h"
|
|
#include <errno.h>
|
|
#include <math.h>
|
|
|
|
extern long FAR PASCAL ulseek();
|
|
|
|
#define GIFid1 0x4947
|
|
#define GIFid2 0x3846
|
|
#define GIFid3 0x6137
|
|
|
|
#define ScrColorMap 0x80
|
|
|
|
#define BFT_BITMAP 0x4d42 /* 'BM' hex for start of bmp file...*/
|
|
|
|
#define WIDTHBYTESLONG(i) ((i+31)/32*4) /* ULONG aligned ! */
|
|
#define WIDTHBYTESWORD(i) ((i+15)/16*2) /* WORD aligned ! */
|
|
#define WIDTHBYTESBYTE(i) ((i+7)/8) /* BYTE aligned ! */
|
|
|
|
typedef struct {
|
|
WORD Signat1; /* GI */
|
|
WORD Signat2; /* F8 */
|
|
WORD Signat3; /* 7a */
|
|
WORD ScrWidth; /* "Screen" width in pixels */
|
|
WORD ScrHeight; /* "Screen" height in pixels */
|
|
BYTE ScrBitsPerPixel; /* bits/pixel + other stuff */
|
|
BYTE ScrBackground; /* index of background color */
|
|
BYTE UselessZero; /* useless zero */
|
|
} GIFSCRDESC;
|
|
|
|
#define ImgColorMap 0x80
|
|
#define ImgInterlace 0x40
|
|
|
|
typedef struct {
|
|
WORD ImgLeft; /* pixel offset from left side of screen */
|
|
WORD ImgTop; /* pixel offset from top of screen */
|
|
WORD ImgWidth; /* pixel width of image */
|
|
WORD ImgHeight; /* pixel height of image */
|
|
BYTE ImgBitsPerPixel; /* bits/pixel + other stuff */
|
|
} GIFIMGDESC;
|
|
|
|
typedef struct tagRGB {
|
|
BYTE rgbtRed;
|
|
BYTE rgbtGreen;
|
|
BYTE rgbtBlue;
|
|
} RGB;
|
|
|
|
/* GIF extension structures. */
|
|
typedef struct
|
|
{
|
|
unsigned int left,top,width,depth;
|
|
unsigned char flags;
|
|
} GIFIMAGEBLOCK;
|
|
|
|
typedef struct
|
|
{
|
|
char blocksize;
|
|
char flags;
|
|
unsigned int delay;
|
|
char transparent_colour;
|
|
char terminator;
|
|
} GIFCONTROLBLOCK;
|
|
|
|
typedef struct
|
|
{
|
|
char blocksize;
|
|
unsigned int left,top;
|
|
unsigned int gridwidth,gridheight;
|
|
char cellwidth,cellheight;
|
|
char forecolour,backcolour;
|
|
} GIFPLAINTEXT;
|
|
|
|
typedef struct
|
|
{
|
|
char blocksize;
|
|
char applstring[8];
|
|
char authentication[3];
|
|
} GIFAPPLICATION;
|
|
|
|
// 9510.27 jar prototype for JPG thumbnail stuff
|
|
BOOL CheckForThumb( int fildes, long *pSeekOff);
|
|
|
|
/*************************************************************************
|
|
* gifinfo - get values and put into info struct
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
int FAR PASCAL gifinfo(fct, pgnum, rawbufsz) /*errno_KEY*/
|
|
struct _gfct FAR *fct;
|
|
u_short pgnum;
|
|
u_long FAR *rawbufsz;
|
|
{
|
|
int bitspp;
|
|
short PaletteLength;
|
|
long PalettePos;
|
|
long ImagePos;
|
|
long ImageEnd;
|
|
struct gfsinfo FAR *info;
|
|
GIFSCRDESC scrbuf;
|
|
GIFIMGDESC imgbuf;
|
|
char codesize = 0;
|
|
char interlaced = 0;
|
|
char start = 0;
|
|
unsigned char extension;
|
|
unsigned char n;
|
|
GIFPLAINTEXT pt;
|
|
GIFCONTROLBLOCK cb;
|
|
GIFAPPLICATION ap;
|
|
|
|
info = (struct gfsinfo FAR *) &fct->uinfo;
|
|
|
|
fct->num_pages = 1;
|
|
fct->curr_page = 1;
|
|
|
|
info->version = GFS_VERSION;
|
|
info->type = GFS_MAIN;
|
|
info->horiz_res[0] = 100;
|
|
info->horiz_res[1] = 1;
|
|
info->vert_res[0] = 100;
|
|
info->vert_res[1] = 1;
|
|
info->res_unit = INCH;
|
|
info->origin = 0;
|
|
info->rotation = 0;
|
|
info->reflection = 0;
|
|
info->byte_order = II;
|
|
info->fill_order = HIGHTOLOW;
|
|
info->img_cmpr.type = LZW;
|
|
info->_file.type = GFS_GIF;
|
|
|
|
lseek ( fct->fildes, 0L, 0 );
|
|
|
|
read ( fct->fildes, (char FAR *)&scrbuf, sizeof(scrbuf));
|
|
bitspp = ( scrbuf.ScrBitsPerPixel & 7 ) + 1;
|
|
PaletteLength = (1 << bitspp) * sizeof(RGB);
|
|
if ( scrbuf.ScrBitsPerPixel & ScrColorMap )
|
|
{
|
|
PalettePos = lseek ( fct->fildes, 0L, 1 );
|
|
lseek ( fct->fildes, (long)PaletteLength, 1 );
|
|
}
|
|
|
|
/* Get the image block. Skip any extensions. */
|
|
read(fct->fildes, (char FAR *) &start, sizeof(start));
|
|
if (start == '!') /* We have extensions. Skip them. */
|
|
{
|
|
while (1)
|
|
{
|
|
read(fct->fildes, (char FAR *) &extension, sizeof(extension));
|
|
switch(extension)
|
|
{
|
|
case 0x0001: /* plain text descriptor */
|
|
read(fct->fildes, (char FAR *) &pt, sizeof(GIFPLAINTEXT));
|
|
do
|
|
{
|
|
n = 0;
|
|
read(fct->fildes, (char FAR *) &n, sizeof(n));
|
|
if((n > 0) && (n < 256))
|
|
lseek(fct->fildes, (long) n, FROM_CURRENT);
|
|
} while(n > 0);
|
|
break;
|
|
case 0x00f9: /* graphic control block */
|
|
read(fct->fildes, (char FAR *) &cb, sizeof(GIFCONTROLBLOCK));
|
|
break;
|
|
case 0x00fe: /* comment extension */
|
|
n = 0;
|
|
do
|
|
{
|
|
n = 0;
|
|
read(fct->fildes, (char FAR *) &n, sizeof(n));
|
|
if((n > 0) && (n < 256))
|
|
lseek(fct->fildes, (long) n, FROM_CURRENT);
|
|
} while(n > 0);
|
|
break;
|
|
case 0x00ff: /* GIFAPPLICATION extension */
|
|
read(fct->fildes, (char FAR *) &ap, sizeof(GIFAPPLICATION));
|
|
do
|
|
{
|
|
n = 0;
|
|
read(fct->fildes, (char FAR *) &n, sizeof(n));
|
|
if((n > 0) && (n < 256))
|
|
lseek(fct->fildes, (long) n, FROM_CURRENT);
|
|
} while(n > 0);
|
|
break;
|
|
default: /* something else */
|
|
do
|
|
{
|
|
n = 0;
|
|
read(fct->fildes, (char FAR *) &n, sizeof(n));
|
|
if((n > 0) && (n < 256))
|
|
lseek(fct->fildes, (long) n, FROM_CURRENT);
|
|
} while(n > 0);
|
|
break;
|
|
}
|
|
read(fct->fildes, (char FAR *) &start, sizeof(start));
|
|
if (start == ',')
|
|
break;
|
|
else if (start == '!')
|
|
continue;
|
|
else
|
|
return ((int) -1);
|
|
}
|
|
}
|
|
|
|
if (start == ',')
|
|
read(fct->fildes, (char FAR *)&imgbuf, sizeof(imgbuf));
|
|
else
|
|
return((int) -1);
|
|
|
|
/* Get the initial code size. */
|
|
read(fct->fildes, (char FAR *)&codesize, sizeof(codesize));
|
|
|
|
ImagePos = lseek ( fct->fildes, 0L, 1 );
|
|
if ( imgbuf.ImgBitsPerPixel & ImgColorMap )
|
|
{
|
|
bitspp = ( imgbuf.ImgBitsPerPixel & 7 ) + 1;
|
|
PaletteLength = (1 << bitspp) * sizeof(RGB);
|
|
PalettePos = ImagePos;
|
|
ImagePos += PaletteLength;
|
|
}
|
|
|
|
info->_file.fmt.gif.PaletteLength = PaletteLength;
|
|
info->_file.fmt.gif.PalettePos = PalettePos;
|
|
info->_file.fmt.gif.ImagePos = ImagePos;
|
|
info->_file.fmt.gif.bpp = bitspp;
|
|
info->_file.fmt.gif.CodeSize = (char) codesize;
|
|
info->_file.fmt.gif.Flags = imgbuf.ImgBitsPerPixel;
|
|
|
|
info->horiz_size = imgbuf.ImgWidth;
|
|
info->vert_size = imgbuf.ImgHeight;
|
|
|
|
info->bits_per_sample[0] = bitspp;
|
|
info->samples_per_pix = 1;
|
|
|
|
info->img_clr.img_interp = GFS_PSEUDO;
|
|
info->PSEUDO_MAP.cnt = (long)PaletteLength;
|
|
|
|
ImageEnd = lseek ( fct->fildes, 0L, 2 );
|
|
*rawbufsz = ImageEnd - ImagePos;
|
|
|
|
return( (int) 0 );
|
|
}
|
|
|
|
#define RGB_SIZE 3
|
|
|
|
/* 7/20/95 rwr Must redefine unaligned WORD fields to byte+pad
|
|
in order to avoid C-compiler forced alignment problem
|
|
(the fields are re-cast to WORD in the code) */
|
|
typedef struct _tgaheader
|
|
{
|
|
char identsize;
|
|
char colormaptype;
|
|
char imagetype;
|
|
char colormapstart; /* This is a WORD (but the compiler aligns it!) */
|
|
char filler1;
|
|
char colormaplength; /* This is a WORD (but the compiler aligns it!) */
|
|
char filler2;
|
|
char colormapbits;
|
|
char xstart; /* This is a WORD (but the compiler aligns it!) */
|
|
char filler3;
|
|
char ystart; /* This is a WORD (but the compiler aligns it!) */
|
|
char filler4;
|
|
char width; /* This is a WORD (but the compiler aligns it!) */
|
|
char filler5;
|
|
char depth; /* This is a WORD (but the compiler aligns it!) */
|
|
char filler6;
|
|
char bits;
|
|
char descriptor;
|
|
} TGAHEADER;
|
|
|
|
int FAR PASCAL tgainfo(fct, pgnum, rawbufsz) /*errno_KEY*/
|
|
struct _gfct FAR *fct;
|
|
u_short pgnum;
|
|
u_long FAR *rawbufsz;
|
|
{
|
|
short PaletteLength;
|
|
long PalettePos;
|
|
long EndPalettePos;
|
|
long ImagePos;
|
|
long ImageEnd;
|
|
TGAHEADER tgahead;
|
|
struct gfsinfo FAR *info;
|
|
|
|
info = (struct gfsinfo FAR *) &fct->uinfo;
|
|
|
|
fct->num_pages = 1;
|
|
fct->curr_page = 1;
|
|
|
|
info->version = GFS_VERSION;
|
|
info->type = GFS_MAIN;
|
|
info->horiz_res[0] = 100;
|
|
info->horiz_res[1] = 1;
|
|
info->vert_res[0] = 100;
|
|
info->vert_res[1] = 1;
|
|
info->res_unit = INCH;
|
|
info->origin = 0;
|
|
info->rotation = 0;
|
|
info->reflection = 0;
|
|
info->byte_order = II;
|
|
info->fill_order = HIGHTOLOW;
|
|
info->img_cmpr.type = UNCOMPRESSED;
|
|
info->_file.type = GFS_TGA;
|
|
|
|
lseek(fct->fildes, 0L, 0);
|
|
read(fct->fildes, (char FAR *)&tgahead, sizeof(tgahead));
|
|
lseek(fct->fildes, (long)tgahead.identsize, FROM_CURRENT);
|
|
|
|
if(tgahead.colormaptype)
|
|
{
|
|
PalettePos = lseek(fct->fildes, 0L, FROM_CURRENT);
|
|
switch(tgahead.colormapbits)
|
|
{
|
|
case 24:
|
|
/* 7/20/95 rwr Must cast byte-to-WORD to get around align problem */
|
|
EndPalettePos = lseek(fct->fildes,
|
|
(long) (((*((WORD *)&tgahead.colormaplength)) -
|
|
(*((WORD *)&tgahead.colormapstart))) * RGB_SIZE), FROM_CURRENT);
|
|
break;
|
|
case 15:
|
|
case 16:
|
|
/* 7/20/95 rwr Must cast byte-to-WORD to get around align problem */
|
|
EndPalettePos = lseek(fct->fildes,
|
|
(long) (((*((WORD *)&tgahead.colormaplength)) -
|
|
(*((WORD *)&tgahead.colormapstart))) * sizeof(unsigned short)), FROM_CURRENT);
|
|
break;
|
|
}
|
|
PaletteLength = (short) (EndPalettePos - PalettePos);
|
|
info->img_clr.img_interp = GFS_PSEUDO;
|
|
info->PSEUDO_MAP.cnt = (long) PaletteLength;
|
|
if (tgahead.bits > 8)
|
|
{
|
|
info->bits_per_sample[0] = 8;
|
|
info->bits_per_sample[1] = 8;
|
|
info->bits_per_sample[2] = 8;
|
|
info->samples_per_pix = 3;
|
|
}
|
|
else if (tgahead.bits == 8)
|
|
{
|
|
info->bits_per_sample[0] = 8;
|
|
info->samples_per_pix = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (tgahead.bits > 8)
|
|
{
|
|
info->img_clr.img_interp = GFS_RGB;
|
|
info->bits_per_sample[0] = 8;
|
|
info->bits_per_sample[1] = 8;
|
|
info->bits_per_sample[2] = 8;
|
|
info->samples_per_pix = 3;
|
|
}
|
|
else if (tgahead.bits == 8)
|
|
{
|
|
info->img_clr.img_interp = GFS_PSEUDO;
|
|
info->bits_per_sample[0] = 8;
|
|
info->samples_per_pix = 1;
|
|
info->PSEUDO_MAP.cnt = 768;
|
|
info->img_cmpr.opts.gifNeedPalette = 1;
|
|
}
|
|
else if (tgahead.bits < 8)
|
|
{
|
|
info->img_clr.img_interp = GFS_BILEVEL_0ISWHITE;
|
|
info->bits_per_sample[0] = 1;
|
|
info->samples_per_pix = 1;
|
|
}
|
|
}
|
|
|
|
ImagePos = lseek(fct->fildes, 0L, FROM_CURRENT);
|
|
|
|
info->_file.fmt.tga.imagetype = tgahead.imagetype;
|
|
info->_file.fmt.tga.PaletteLength = PaletteLength;
|
|
info->_file.fmt.tga.PalettePos = (unsigned int) PalettePos;
|
|
info->_file.fmt.tga.colormapbits = tgahead.colormapbits;
|
|
info->_file.fmt.tga.bits = tgahead.bits;
|
|
info->_file.fmt.tga.descriptor = tgahead.descriptor;
|
|
info->_file.fmt.tga.ImagePos = ImagePos;
|
|
|
|
/* 7/20/95 rwr Must cast byte-to-WORD to get around align problem */
|
|
info->horiz_size = *((WORD *)&tgahead.width);
|
|
info->vert_size = *((WORD *)&tgahead.depth);
|
|
|
|
ImageEnd = lseek(fct->fildes, 0L, 2);
|
|
*rawbufsz = ImageEnd - ImagePos;
|
|
|
|
return ((int) 0);
|
|
}
|
|
|
|
//***********************************************************************
|
|
//
|
|
// jfif area
|
|
//
|
|
//***********************************************************************
|
|
typedef struct _jfif
|
|
{
|
|
short soi;
|
|
short appx;
|
|
short length;
|
|
char id[5];
|
|
short ver;
|
|
char units;
|
|
short xres;
|
|
short yres;
|
|
char xthumb;
|
|
char ythumb;
|
|
} JFIF;
|
|
|
|
#define JFIF_SIZE 20
|
|
#define MAX_FRAME_SIZE 773
|
|
#define JFIF_DEFAULT_DPI 200
|
|
|
|
#define JFXX_SIZE 8
|
|
|
|
//***********************************************************************
|
|
//
|
|
// jfifinfo
|
|
//
|
|
//***********************************************************************
|
|
int FAR PASCAL jfifinfo(fct, pgnum, rawbufsz) /*errno_KEY*/
|
|
struct _gfct FAR *fct;
|
|
u_short pgnum;
|
|
u_long FAR *rawbufsz;
|
|
{
|
|
unsigned char abyte;
|
|
unsigned char bbyte;
|
|
int i;
|
|
int components = 0;
|
|
short flength;
|
|
long read_on;
|
|
long num_read;
|
|
long image_pos;
|
|
long image_end;
|
|
long int_format_size;
|
|
JFIF header;
|
|
char FAR *jpeg_buffer;
|
|
struct gfsinfo FAR *info;
|
|
unsigned char buffer[JFIF_SIZE];
|
|
unsigned char fbuffer[MAX_FRAME_SIZE];
|
|
|
|
// 9510.26 jar thumbnail stuff
|
|
BOOL bThumb = FALSE;
|
|
long SeekOff;
|
|
|
|
info = (struct gfsinfo FAR *) &fct->uinfo;
|
|
|
|
fct->num_pages = 1;
|
|
fct->curr_page = 1;
|
|
|
|
info->version = GFS_VERSION;
|
|
info->type = GFS_MAIN;
|
|
info->origin = 0;
|
|
info->rotation = 0;
|
|
info->reflection = 0;
|
|
info->byte_order = II;
|
|
info->fill_order = HIGHTOLOW;
|
|
info->img_cmpr.type = JPEG2;
|
|
info->_file.type = GFS_JFIF;
|
|
|
|
lseek(fct->fildes, 0L, 0);
|
|
read(fct->fildes, (char FAR *) &buffer, sizeof(buffer));
|
|
|
|
header.soi = (buffer[0] << 8) + buffer[1];
|
|
header.appx = (buffer[2] << 8) + buffer[3];
|
|
header.length = (buffer[4] << 8) + buffer[5];
|
|
for (i = 0; i < 5; ++i)
|
|
header.id[i] = buffer[i + 6];
|
|
header.ver = (buffer[11] << 8) + buffer[12];
|
|
header.units = buffer[13];
|
|
header.xres = (buffer[14] << 8) + buffer[15];
|
|
header.yres = (buffer[16] << 8) + buffer[17];
|
|
header.xthumb = buffer[18];
|
|
header.ythumb = buffer[19];
|
|
|
|
info->horiz_res[0] = header.xres;
|
|
info->horiz_res[1] = 1;
|
|
info->vert_res[0] = header.yres;
|
|
info->vert_res[1] = 1;
|
|
|
|
if (header.units == 0)
|
|
{
|
|
info->res_unit = NO_ABSOLUTE_MEASURE;
|
|
/* display and info want a number. It does not matter what it is
|
|
so we will return a default in this case. */
|
|
|
|
info->horiz_res[0] = JFIF_DEFAULT_DPI;
|
|
info->vert_res[0] = JFIF_DEFAULT_DPI;
|
|
}
|
|
else if (header.units == 1)
|
|
info->res_unit = INCH;
|
|
else if (header.units == 2)
|
|
info->res_unit = CENTIMETER;
|
|
|
|
// 9510.26 jar check for that pesky little thumbnail, this will seek the
|
|
// file so that we're at the real data
|
|
bThumb = CheckForThumb( fct->fildes, &SeekOff);
|
|
|
|
/* Look for frame header. We currently only support the baseline DCT
|
|
sequential (0xFFC0) encoding process.
|
|
*/
|
|
read_on = 1;
|
|
while (read_on != 0)
|
|
{
|
|
num_read = (long) read(fct->fildes, (char FAR *)&abyte, sizeof(abyte));
|
|
if (abyte == 0xFF)
|
|
{
|
|
num_read = (long) read(fct->fildes, (char FAR *)&abyte, sizeof(abyte));
|
|
switch (abyte)
|
|
{
|
|
case 0xC0:
|
|
/* We've found the frame header. Get it's length and read
|
|
it in.
|
|
*/
|
|
read(fct->fildes, (char FAR *) &abyte, sizeof(abyte));
|
|
read(fct->fildes, (char FAR *) &bbyte, sizeof(abyte));
|
|
flength = (abyte << 8) + bbyte - 2;
|
|
read(fct->fildes, (char FAR *) &fbuffer, flength);
|
|
|
|
info->horiz_size = (fbuffer[3] << 8) + fbuffer[4];
|
|
info->vert_size = (fbuffer[1] << 8) + fbuffer[2];
|
|
components = fbuffer[5];
|
|
read_on = 0;
|
|
break;
|
|
|
|
case 0xC1:
|
|
case 0xC2:
|
|
case 0xC3:
|
|
case 0xC5:
|
|
case 0xC6:
|
|
case 0xC7:
|
|
case 0xC8:
|
|
case 0xC9:
|
|
case 0xCA:
|
|
case 0xCB:
|
|
case 0xCD:
|
|
case 0xCE:
|
|
case 0xCF:
|
|
/* We've found the frame header, but the encoding process is
|
|
not supported.
|
|
*/
|
|
return ((int) -1);
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (num_read == 0)
|
|
{
|
|
/* We've reached the end of the file. */
|
|
return((int) -1);
|
|
}
|
|
}
|
|
|
|
/* Now search for the start of scan marker (0xFFDA). Once found, use it
|
|
as the start of image data. Copy everything up to it as the interchange
|
|
format header.
|
|
*/
|
|
read_on = 1;
|
|
while (read_on != 0)
|
|
{
|
|
num_read = (long) read(fct->fildes, (char FAR *)&abyte, sizeof(abyte));
|
|
if (abyte == 0xFF)
|
|
{
|
|
num_read = (long) read(fct->fildes, (char FAR *)&abyte, sizeof(abyte));
|
|
if (abyte == 0xDA)
|
|
{
|
|
image_pos = lseek(fct->fildes, 0L, FROM_CURRENT) - 2;
|
|
// 9510.27 jar thumbnail fix up
|
|
//int_format_size = image_pos;
|
|
if ( !bThumb)
|
|
{
|
|
int_format_size = image_pos;
|
|
}
|
|
else
|
|
{
|
|
int_format_size = image_pos - SeekOff + JFIF_SIZE;
|
|
}
|
|
|
|
info->img_cmpr.type = (u_long) JPEG2;
|
|
/* Need to allocate jpeg_info structure for the read if it doesn't
|
|
already exist.
|
|
*/
|
|
if (info->img_cmpr.opts.jpeg_info_ptr == NULL)
|
|
{
|
|
if ((info->img_cmpr.opts.jpeg_info_ptr = (LPJPEG_INFO) calloc(1,
|
|
(int) sizeof(JPEG_INFO))) == (LPJPEG_INFO) NULL)
|
|
{
|
|
errno = (int) ENOMEM;
|
|
fct->last_errno = (int) errno;
|
|
return((int) -1);
|
|
}
|
|
}
|
|
/* Store the start of image data in the JpegRestartInterval.
|
|
It is not needed for JFIF.
|
|
*/
|
|
info->img_cmpr.opts.jpeg_info_ptr->jpeg.JpegRestartInterval =
|
|
(int) image_pos;
|
|
|
|
info->img_cmpr.opts.jpeg_info_ptr->jpeg.JpegInterchangeFormatLength =
|
|
int_format_size;
|
|
info->img_cmpr.opts.jpeg_info_ptr->jpeg.JpegProc = (int) 1;
|
|
info->img_cmpr.opts.jpeg_info_ptr->jpeg.JpegInterchangeFormatOffset = 0;
|
|
info->img_cmpr.opts.jpeg_info_ptr->jpeg_buffer_size = int_format_size;
|
|
|
|
if (info->img_cmpr.opts.jpeg_info_ptr->jpeg_buffer == (char FAR *) NULL)
|
|
info->img_cmpr.opts.jpeg_info_ptr->jpeg_buffer = (char FAR *) calloc(1,
|
|
(int) int_format_size);
|
|
if (info->img_cmpr.opts.jpeg_info_ptr->jpeg_buffer == (char FAR *) NULL)
|
|
{
|
|
errno = (int) ENOMEM;
|
|
fct->last_errno = (int) errno;
|
|
if (info->img_cmpr.opts.jpeg_info_ptr != NULL)
|
|
{
|
|
free((char FAR *) info->img_cmpr.opts.jpeg_info_ptr);
|
|
info->img_cmpr.opts.jpeg_info_ptr = NULL;
|
|
}
|
|
return((int) -1);
|
|
}
|
|
jpeg_buffer = info->img_cmpr.opts.jpeg_info_ptr->jpeg_buffer;
|
|
// 9510.26 jar do the thiung for the thumbnail
|
|
//lseek(fct->fildes, 0L, FROM_BEGINNING);
|
|
//num_read = (long) read(fct->fildes, (char FAR *) jpeg_buffer, (int) int_format_size);
|
|
if ( !bThumb)
|
|
{
|
|
lseek(fct->fildes, 0L, FROM_BEGINNING);
|
|
num_read = (long) read(fct->fildes,
|
|
(char FAR *) jpeg_buffer,
|
|
(int) int_format_size);
|
|
}
|
|
else
|
|
{
|
|
lseek(fct->fildes, 0L, FROM_BEGINNING);
|
|
num_read = (long) read(fct->fildes,
|
|
(char FAR *) jpeg_buffer,
|
|
(int) JFIF_SIZE);
|
|
lseek(fct->fildes, SeekOff, FROM_BEGINNING);
|
|
num_read = (long) read(fct->fildes,
|
|
(char FAR *)(jpeg_buffer+JFIF_SIZE),
|
|
(int) (int_format_size - JFIF_SIZE));
|
|
}
|
|
read_on = 0;
|
|
}
|
|
}
|
|
if (num_read == 0)
|
|
{
|
|
/* We've reached the end of the file. */
|
|
return((int) -1);
|
|
}
|
|
}
|
|
|
|
if (components == 3)
|
|
{
|
|
info->samples_per_pix = 3;
|
|
info->bits_per_sample[0] = 8;
|
|
info->bits_per_sample[1] = 8;
|
|
info->bits_per_sample[2] = 8;
|
|
info->img_clr.img_interp = GFS_RGB;
|
|
}
|
|
else if (components == 1)
|
|
{
|
|
info->samples_per_pix = 1;
|
|
info->bits_per_sample[0] = 8;
|
|
info->img_clr.img_interp = GFS_GRAYSCALE_0ISWHITE;
|
|
}
|
|
info->_file.fmt.tiff.strips_per_image = 1;
|
|
info->_file.fmt.tiff.rows_strip = info->vert_size;
|
|
|
|
image_end = lseek(fct->fildes, 0L, FROM_END);
|
|
*rawbufsz = image_end - image_pos;
|
|
info->_file.fmt.tiff.largest_strip = *rawbufsz;
|
|
|
|
return ((int) 0);
|
|
}
|
|
//***********************************************************************
|
|
//
|
|
// CheckForThumb
|
|
//
|
|
// we need to see if there's a thumbnail
|
|
// if so then
|
|
// set flag true
|
|
// get the offset to the next bunch of data
|
|
// return
|
|
//***********************************************************************
|
|
BOOL CheckForThumb( int fildes, long *pSeekOff)
|
|
{
|
|
BOOL bThumb = FALSE;
|
|
long NumRead;
|
|
unsigned char AByte;
|
|
unsigned char Bytes[JFXX_SIZE];
|
|
|
|
NumRead = (long) read( fildes, (char FAR *)&AByte, sizeof(AByte));
|
|
if (AByte == 0xFF)
|
|
{
|
|
NumRead = (long) read( fildes, (char FAR *)&AByte, sizeof(AByte));
|
|
if (AByte == 0xE0)
|
|
{
|
|
NumRead = (long) read( fildes, (char FAR *)Bytes, JFXX_SIZE);
|
|
if ( Bytes[2] == 'J' &&
|
|
Bytes[3] == 'F' &&
|
|
Bytes[4] == 'X' &&
|
|
Bytes[5] == 'X')
|
|
{
|
|
// we've found the thumbnail
|
|
*pSeekOff = (long)((long)(Bytes[0] << 8) + (long)Bytes[1]);
|
|
*pSeekOff += JFIF_SIZE + 2L;
|
|
lseek( fildes, *pSeekOff, FROM_BEGINNING);
|
|
bThumb = TRUE;
|
|
}
|
|
}
|
|
}
|
|
return bThumb;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
#define InchPerMeter 39
|
|
|
|
int FAR PASCAL bmpinfo(fct, pgnum, rawbufsz) /*errno_KEY*/
|
|
struct _gfct FAR *fct;
|
|
u_short pgnum;
|
|
u_long FAR *rawbufsz;
|
|
{
|
|
short PalLen;
|
|
long PalPos;
|
|
short ImagePos;
|
|
long ImageEnd;
|
|
struct gfsinfo FAR *info;
|
|
int x;
|
|
char BmpType;
|
|
char temp;
|
|
BITMAPFILEHEADER hbuf;
|
|
BITMAPINFOHEADER ibuf;
|
|
BITMAPCOREHEADER cbuf;
|
|
|
|
info = (struct gfsinfo FAR *) &fct->uinfo;
|
|
|
|
fct->num_pages = 1;
|
|
fct->curr_page = 1;
|
|
|
|
info->version = GFS_VERSION;
|
|
info->type = GFS_MAIN;
|
|
info->res_unit = INCH;
|
|
info->origin = 0;
|
|
info->rotation = 0;
|
|
info->reflection = 0;
|
|
info->byte_order = II;
|
|
info->fill_order = HIGHTOLOW;
|
|
info->_file.type = GFS_BMP;
|
|
|
|
lseek ( fct->fildes, 0L, 0 );
|
|
BmpType = BMP_WIN;
|
|
read ( fct->fildes, (LPSTR)&hbuf, sizeof(hbuf) );
|
|
read ( fct->fildes, (LPSTR)&ibuf, sizeof(ibuf) );
|
|
if ( ibuf.biSize == sizeof ( BITMAPCOREHEADER ))
|
|
{
|
|
lseek ( fct->fildes, (long)sizeof ( BITMAPFILEHEADER ), 0 );
|
|
read ( fct->fildes, (LPSTR)&cbuf, sizeof(cbuf));
|
|
ibuf.biSize = cbuf.bcSize;
|
|
ibuf.biWidth = cbuf.bcWidth;
|
|
ibuf.biHeight = cbuf.bcHeight;
|
|
ibuf.biPlanes = cbuf.bcPlanes;
|
|
ibuf.biBitCount = cbuf.bcBitCount;
|
|
ibuf.biCompression = 0;
|
|
ibuf.biSizeImage =
|
|
(((ibuf.biWidth * ibuf.biBitCount + 31) & 0x0003ffe0) / 8)
|
|
* ibuf.biHeight;
|
|
ibuf.biXPelsPerMeter = ibuf.biYPelsPerMeter = 0;
|
|
ibuf.biClrUsed = 0;
|
|
ibuf.biClrImportant = 0;
|
|
BmpType = BMP_OS2;
|
|
}
|
|
|
|
info->_file.fmt.bmp.BmpCmp = (char)ibuf.biCompression;
|
|
// if (ibuf.biCompression != BI_RGB)
|
|
// {
|
|
// errno = (int)EINVALID_COMPRESSION;
|
|
// return((int)-1);
|
|
// }
|
|
info->horiz_size = ibuf.biWidth;
|
|
info->vert_size = ibuf.biHeight;
|
|
|
|
PalLen = 0;
|
|
PalPos = 0;
|
|
ImagePos = sizeof (BITMAPFILEHEADER) + (BmpType == BMP_OS2 ?
|
|
sizeof ( BITMAPCOREHEADER ) : sizeof ( BITMAPINFOHEADER));
|
|
info->samples_per_pix = 1;
|
|
switch ( ibuf.biBitCount )
|
|
{
|
|
case 1:
|
|
if (info->_file.fmt.bmp.BmpCmp != BI_RGB)
|
|
{
|
|
errno = (int)EINVALID_COMPRESSION;
|
|
return((int)-1);
|
|
}
|
|
lseek(fct->fildes,ImagePos,0);
|
|
read (fct->fildes,(LPSTR)&temp,sizeof(temp));
|
|
if (temp != 0)
|
|
info->img_clr.img_interp = GFS_BILEVEL_0ISWHITE;
|
|
else
|
|
info->img_clr.img_interp = GFS_BILEVEL_0ISBLACK;
|
|
info->bits_per_sample[0] = ibuf.biBitCount;
|
|
// 10/23/95 rwr We'll do this right below
|
|
// ImagePos += ( 2 * (BmpType == BMP_OS2 ? sizeof(RGBTRIPLE) : sizeof(RGBQUAD)));
|
|
break;
|
|
case 4:
|
|
if ( (info->_file.fmt.bmp.BmpCmp != BI_RLE4)
|
|
&& (info->_file.fmt.bmp.BmpCmp != BI_RGB) )
|
|
{
|
|
errno = (int)EINVALID_COMPRESSION;
|
|
return((int)-1);
|
|
}
|
|
goto case48;
|
|
case 8:
|
|
if ( (info->_file.fmt.bmp.BmpCmp != BI_RLE8)
|
|
&& (info->_file.fmt.bmp.BmpCmp != BI_RGB) )
|
|
{
|
|
errno = (int)EINVALID_COMPRESSION;
|
|
return((int)-1);
|
|
}
|
|
case48:
|
|
info->img_clr.img_interp = GFS_PSEUDO;
|
|
if ( ibuf.biClrUsed )
|
|
{
|
|
PalLen = (short) ibuf.biClrUsed *
|
|
(BmpType == BMP_OS2 ? sizeof(RGBTRIPLE) : sizeof(RGBQUAD) );
|
|
}
|
|
else
|
|
{
|
|
PalLen = (1 << ibuf.biBitCount) *
|
|
(BmpType == BMP_OS2 ? sizeof(RGBTRIPLE) : sizeof(RGBQUAD) );
|
|
}
|
|
info->bits_per_sample[0] = ibuf.biBitCount;
|
|
info->PSEUDO_MAP.cnt = (long)PalLen;
|
|
PalPos = sizeof (BITMAPFILEHEADER) + (BmpType == BMP_OS2 ?
|
|
sizeof ( BITMAPCOREHEADER ) : sizeof ( BITMAPINFOHEADER));
|
|
// 10/23/95 rwr We'll do this right below
|
|
// ImagePos += PalLen;
|
|
break;
|
|
case 24:
|
|
if (info->_file.fmt.bmp.BmpCmp != BI_RGB)
|
|
{
|
|
errno = (int)EINVALID_COMPRESSION;
|
|
return((int)-1);
|
|
}
|
|
info->img_clr.img_interp = GFS_RGB;
|
|
info->samples_per_pix = 3;
|
|
for ( x = 0; x < 3; x++ )
|
|
info->bits_per_sample[x] = 8;
|
|
break;
|
|
}
|
|
// 10/23/95 rwr Use the supplied offset (there may be junk in between!)
|
|
ImagePos = (short)hbuf.bfOffBits;
|
|
info->horiz_res[0] = ibuf.biXPelsPerMeter/InchPerMeter;
|
|
info->horiz_res[1] = 1;
|
|
info->vert_res[0] = ibuf.biYPelsPerMeter/InchPerMeter;
|
|
info->vert_res[1] = 1;
|
|
info->img_cmpr.type = UNCOMPRESSED;
|
|
|
|
info->_file.fmt.bmp.PaletteLength = PalLen;
|
|
info->_file.fmt.bmp.PalettePos = (short) PalPos;
|
|
info->_file.fmt.bmp.ImagePos = ImagePos;
|
|
|
|
/* What follows is a kludge to support our old invalid output BMPs */
|
|
/* We can recognize them by the incorrectly aligned biWidth values! */
|
|
// 10/19/95 rwr Remove this logic - we can no longer support our old
|
|
// bad BMP files because we have to support everyone else's
|
|
// bad BMP files (i.e. the ones with bad biSizeImage fields)
|
|
// if ((ibuf.biSizeImage != 0) && (ibuf.biHeight != 0))
|
|
// info->_file.fmt.bmp.ByteWidth = /* Maybe Bad Value? */
|
|
// (short)(ibuf.biSizeImage / ibuf.biHeight);
|
|
// else
|
|
info->_file.fmt.bmp.ByteWidth = /* Definitely Good Value */
|
|
(short)(((ibuf.biWidth * ibuf.biBitCount + 31) & 0x0003ffe0) / 8);
|
|
info->_file.fmt.bmp.BmpType = BmpType;
|
|
|
|
/* info->tidbit = NULL; */
|
|
|
|
ImageEnd = lseek ( fct->fildes, 0L, 2 );
|
|
*rawbufsz = ImageEnd - ImagePos;
|
|
|
|
return( (int) 0 );
|
|
}
|
|
|
|
int FAR PASCAL PutBmpInfo ( struct _gfct FAR *fct,
|
|
struct gfsinfo FAR *info )
|
|
{
|
|
BITMAPFILEHEADER hbuf;
|
|
BITMAPINFOHEADER ibuf;
|
|
|
|
hbuf.bfType = BFT_BITMAP;
|
|
|
|
hbuf.bfReserved1 = 0;
|
|
hbuf.bfReserved2 = 0;
|
|
|
|
ibuf.biSize = sizeof(BITMAPINFOHEADER);
|
|
ibuf.biWidth = info->horiz_size;
|
|
ibuf.biHeight = info->vert_size;
|
|
ibuf.biPlanes = 1;
|
|
ibuf.biBitCount = (unsigned short) (info->bits_per_sample[0] * info->samples_per_pix);
|
|
ibuf.biCompression = BI_RGB;
|
|
|
|
/* account for long alignment for biSizeImage */
|
|
|
|
ibuf.biSizeImage = ((((long)ibuf.biWidth * ibuf.biBitCount + 31) & 0x0003ffe0 ) / 8) * ibuf.biHeight;
|
|
|
|
ibuf.biXPelsPerMeter = info->horiz_res[0] / info->horiz_res[1];
|
|
ibuf.biYPelsPerMeter = info->vert_res[0] / info->vert_res[1];
|
|
ibuf.biClrUsed = info->PSEUDO_MAP.cnt / sizeof ( RGBQUAD );
|
|
ibuf.biClrImportant = 0;
|
|
|
|
hbuf.bfOffBits = sizeof(hbuf) + sizeof(ibuf) + info->PSEUDO_MAP.cnt;
|
|
|
|
hbuf.bfSize = hbuf.bfOffBits + ibuf.biSizeImage;
|
|
info->_file.fmt.bmp.ImagePos = (short) hbuf.bfOffBits;
|
|
info->_file.fmt.bmp.WritePos = 0;
|
|
info->_file.fmt.bmp.ByteWidth = (short)
|
|
(((ibuf.biWidth * ibuf.biBitCount + 31) & 0x0003ffe0) / 8);
|
|
|
|
lseek ( fct->fildes, 0L, FROM_BEGINNING );
|
|
write ( fct->fildes, (char FAR *)&hbuf, sizeof ( hbuf ));
|
|
write ( fct->fildes, (char FAR *)&ibuf, sizeof ( ibuf ));
|
|
|
|
/* SCS added only call when there is a palette.... */
|
|
if ((u_int)info->PSEUDO_MAP.cnt )
|
|
write ( fct->fildes, (char FAR *)info->PSEUDO_MAP.ptr,
|
|
(u_int)info->PSEUDO_MAP.cnt );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
struct pnb {
|
|
char d_Manuf;
|
|
char d_Hard;
|
|
char d_Encod;
|
|
|
|
char d_Bitpx;
|
|
short d_X1, d_Y1, d_X2, d_Y2;
|
|
short d_Hres, d_Vres;
|
|
char d_clrma[48];
|
|
char d_Vmode;
|
|
char d_NPlanes;
|
|
short d_Bplin;
|
|
short d_PalType; /* kmc - ignored in Paintbrush IV and IV+ */
|
|
char d_Xtra[10];
|
|
char d_Text[48];
|
|
};
|
|
|
|
|
|
|
|
int FAR PASCAL pcxinfo(fct, pgnum, rawbufsz) /*errno_KEY*/
|
|
struct _gfct FAR *fct;
|
|
u_short pgnum;
|
|
u_long FAR *rawbufsz;
|
|
{
|
|
short PalLen;
|
|
long PalPos;
|
|
long ImagePos;
|
|
long ImageEnd;
|
|
struct gfsinfo FAR *info;
|
|
int x;
|
|
int bitspp;
|
|
struct pnb pcx;
|
|
unsigned long start;
|
|
|
|
info = (struct gfsinfo FAR *) &fct->uinfo;
|
|
|
|
/* fct->num_pages = 1; */
|
|
fct->curr_page = pgnum;
|
|
|
|
info->version = GFS_VERSION; /* kmc 2/93 - changed from 1 */
|
|
info->type = GFS_MAIN;
|
|
info->res_unit = INCH;
|
|
info->origin = 0;
|
|
info->rotation = 0;
|
|
info->reflection = 0;
|
|
info->byte_order = II;
|
|
info->fill_order = HIGHTOLOW;
|
|
|
|
if (fct->format == GFS_PCX)
|
|
{
|
|
info->_file.type = GFS_PCX;
|
|
lseek ( fct->fildes, 0L, 0 );
|
|
read ( fct->fildes, (LPSTR)&pcx, sizeof(pcx) );
|
|
}
|
|
else if (fct->format == GFS_DCX)
|
|
{
|
|
info->_file.type = GFS_DCX;
|
|
start = *(fct->u.dcx.dcx_offsets + pgnum);
|
|
lseek ( fct->fildes, (long)start, 0 );
|
|
read ( fct->fildes, (LPSTR)&pcx, sizeof(pcx) );
|
|
}
|
|
|
|
info->horiz_size = pcx.d_X2 - pcx.d_X1 + 1;
|
|
info->vert_size = pcx.d_Y2 - pcx.d_Y1 + 1;
|
|
|
|
PalLen = 0;
|
|
PalPos = 0;
|
|
|
|
bitspp = pcx.d_Bitpx*pcx.d_NPlanes;
|
|
|
|
if ( bitspp > 1 )
|
|
{
|
|
if ( bitspp < 4 ) bitspp = 4;
|
|
PalLen = (1 << bitspp) * 3;
|
|
}
|
|
|
|
info->samples_per_pix = 1;
|
|
info->bits_per_sample[0] = bitspp;
|
|
if (fct->format == GFS_PCX)
|
|
{
|
|
ImagePos = sizeof ( pcx );
|
|
ImageEnd = lseek ( fct->fildes, 0L, 2 );
|
|
}
|
|
else if ((pgnum + 1) == fct->num_pages) /* DCX */
|
|
{
|
|
ImagePos = start + sizeof ( pcx );
|
|
ImageEnd = lseek ( fct->fildes, 0L, 2 );
|
|
}
|
|
else /* DCX */
|
|
{
|
|
ImagePos = start + sizeof ( pcx );
|
|
ImageEnd = *(fct->u.dcx.dcx_offsets + pgnum + 1);
|
|
}
|
|
|
|
*rawbufsz = ImageEnd - ImagePos;
|
|
|
|
if ( PalLen == sizeof(pcx.d_clrma) )
|
|
{
|
|
PalPos = (long) ((char *)&pcx.d_clrma[0] - (char *)&pcx);
|
|
if ( pcx.d_Hard == 3 ) /* KMC - If 3, then either monochrome of default */
|
|
PalPos = 0; /* palette. Make gfsgtdata return a canned */
|
|
/* palette, cause there ain't one in the file. */
|
|
}
|
|
else
|
|
PalPos = ImageEnd - PalLen;
|
|
|
|
switch ( bitspp )
|
|
{
|
|
case 1:
|
|
info->img_clr.img_interp = GFS_BILEVEL_0ISBLACK;
|
|
break;
|
|
case 4:
|
|
case 8:
|
|
info->img_clr.img_interp = GFS_PSEUDO;
|
|
info->PSEUDO_MAP.cnt = (long)PalLen;
|
|
break;
|
|
case 24:
|
|
info->img_clr.img_interp = GFS_RGB;
|
|
info->samples_per_pix = 3;
|
|
for ( x = 0; x < 3; x++ )
|
|
info->bits_per_sample[x] = 8;
|
|
break;
|
|
}
|
|
info->horiz_res[0] = 100;
|
|
info->horiz_res[1] = 1;
|
|
info->vert_res[0] = 100;
|
|
info->vert_res[1] = 1;
|
|
info->img_cmpr.type = UNCOMPRESSED;
|
|
|
|
info->_file.fmt.pcx.PaletteLength = PalLen;
|
|
info->_file.fmt.pcx.PalettePos = PalPos;
|
|
if (info->_file.type == GFS_PCX)
|
|
info->_file.fmt.pcx.ImagePos = (short) ImagePos;
|
|
else if (info->_file.type == GFS_DCX)
|
|
info->img_cmpr.opts.dcxImagePos = ImagePos;
|
|
info->_file.fmt.pcx.bpl = pcx.d_Bplin * pcx.d_NPlanes;
|
|
info->_file.fmt.pcx.planes = pcx.d_NPlanes;
|
|
|
|
return( (int) 0 );
|
|
}
|
|
|
|
/* KMC - NEW FUNCTION (4/93):
|
|
|
|
FUNCTION: PutPcxInfo
|
|
|
|
DESCRIPTION:
|
|
This function sets up the proper PCX file header info based on the type
|
|
of PCX file you are writing, and writes the header information to the file.
|
|
|
|
INPUT:
|
|
struct _gfct FAR *fct: Pointer to internal fct structure containing file info.
|
|
struct gfsinfo FAR *info: Pointer to gfsinfo structure containing info on image.
|
|
u_short pgnum: Page number if DCX file.
|
|
|
|
OUTPUT:
|
|
Status of the write. 0 returned if successful, -1 if unsuccessful.
|
|
*/
|
|
int FAR PASCAL PutPcxInfo( struct _gfct FAR *fct, struct gfsinfo FAR *info,
|
|
u_short pgnum)
|
|
{
|
|
struct pnb pcxbuf;
|
|
int status;
|
|
u_long bits;
|
|
long filepos;
|
|
long fp;
|
|
long offset[1];
|
|
|
|
bits = (info->bits_per_sample[0])*(info->samples_per_pix);
|
|
memset((char FAR *)&pcxbuf,(int)0,(int)sizeof(pcxbuf));
|
|
pcxbuf.d_Manuf = 0x0a;
|
|
pcxbuf.d_Encod = 1;
|
|
pcxbuf.d_X1 = pcxbuf.d_Y1 = 0;
|
|
pcxbuf.d_X2 = (short) info->horiz_size - 1;
|
|
pcxbuf.d_Y2 = (short) info->vert_size - 1;
|
|
if (bits == 1) { /* black/white image */
|
|
pcxbuf.d_Hard = 2;
|
|
pcxbuf.d_Bitpx = 1;
|
|
pcxbuf.d_NPlanes = 1;
|
|
pcxbuf.d_PalType = 1;
|
|
info->_file.fmt.pcx.bpl = pcxbuf.d_Bplin = (short)
|
|
WIDTHBYTESBYTE(info->horiz_size);
|
|
}
|
|
else if (bits > 1 && bits <= 4) { /* 4 bit palettized image */
|
|
pcxbuf.d_Hard = 2;
|
|
pcxbuf.d_Bitpx = 1;
|
|
pcxbuf.d_NPlanes = (char) bits;
|
|
pcxbuf.d_PalType = 1;
|
|
info->_file.fmt.pcx.bpl = pcxbuf.d_Bplin = (short)
|
|
WIDTHBYTESBYTE(info->horiz_size);
|
|
memcpy((char FAR *)&pcxbuf.d_clrma,(char FAR *)info->PSEUDO_MAP.ptr,48);
|
|
}
|
|
else if (bits > 4 && bits <= 8) { /* 8 bit palettized image */
|
|
pcxbuf.d_PalType = 1;
|
|
pcxbuf.d_Bitpx = 8;
|
|
pcxbuf.d_Hard = 5;
|
|
pcxbuf.d_NPlanes = 1;
|
|
info->_file.fmt.pcx.bpl = pcxbuf.d_Bplin = (short) info->horiz_size;
|
|
}
|
|
else { /* 24 bit image */
|
|
pcxbuf.d_Bitpx = 8;
|
|
pcxbuf.d_Hard = 5;
|
|
pcxbuf.d_NPlanes = 3;
|
|
info->_file.fmt.pcx.bpl = pcxbuf.d_Bplin = (short) info->horiz_size;
|
|
}
|
|
if (fct->format == GFS_DCX)
|
|
{
|
|
filepos = lseek(fct->fildes,0L,FROM_END);
|
|
offset[0] = filepos;
|
|
fp = lseek(fct->fildes,((pgnum+1)*4),FROM_BEGINNING);
|
|
if ((status = write(fct->fildes,(char FAR *)offset,4)) == -1)
|
|
{
|
|
fct->last_errno = errno;
|
|
return(-1);
|
|
}
|
|
lseek(fct->fildes,filepos,FROM_BEGINNING);
|
|
info->img_cmpr.opts.dcxImagePos = filepos + 128;
|
|
}
|
|
else if (fct->format == GFS_PCX)
|
|
{
|
|
info->_file.fmt.pcx.ImagePos = 128;
|
|
lseek(fct->fildes,0L,FROM_BEGINNING);
|
|
}
|
|
if ((status = write(fct->fildes,(char FAR *)&pcxbuf,sizeof(pcxbuf))) == -1)
|
|
{
|
|
fct->last_errno = errno;
|
|
return(-1);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
#endif
|