2001 lines
70 KiB
C
2001 lines
70 KiB
C
/*
|
|
$Log: S:\oiwh\filing\fiostrip.c_v $
|
|
*
|
|
* Rev 1.22 19 Jan 1996 11:24:38 RWR
|
|
* Add logic to keep track of (and free) oicom400.dll module (Load/FreeLibrary)
|
|
*
|
|
* Rev 1.21 20 Oct 1995 17:51:10 RWR
|
|
* Move GetCompRowsPerStrip() function from oicom400.dll to oifil400.dll
|
|
* (also requires constants to be moved from comex.h & oicomex.c to engfile.h)
|
|
*
|
|
* Rev 1.20 19 Sep 1995 18:05:00 RWR
|
|
* Modify NEWCMPEX conditionals for separate builds of compress & expand stuff
|
|
*
|
|
* Rev 1.19 13 Sep 1995 17:14:56 RWR
|
|
* Preliminary checkin of conditional code supporting new compress/expand calls
|
|
*
|
|
* Rev 1.18 08 Sep 1995 09:20:16 JAR
|
|
* we were inverting the AWD data when writing, which we should NEVER do,
|
|
* so it is now removed and we write out the data as we get it from caller
|
|
*
|
|
* Rev 1.17 06 Sep 1995 09:29:28 JAR
|
|
* added code to mask extra bits when writing an AWD file
|
|
*
|
|
* Rev 1.16 04 Sep 1995 15:17:10 RWR
|
|
* Add bInvert flag to FlipBuffer() for BMP inverted B&W image
|
|
*
|
|
* Rev 1.15 29 Aug 1995 09:57:18 JAR
|
|
* this is the code for supporting write of awd
|
|
*
|
|
* Rev 1.14 25 Aug 1995 16:19:20 RWR
|
|
* Correct computation of line width to cast to (short) AFTER division by 8
|
|
*
|
|
* Rev 1.13 08 Aug 1995 14:18:14 JAR
|
|
* support for IMGFileGetInfo for the AWD stuff, the public interface calls these
|
|
* items LastInfo instead of AWDInfo, in case we use them for files other than AWD
|
|
*
|
|
* Rev 1.12 11 Jul 1995 15:17:52 HEIDI
|
|
*
|
|
* took out bogus assignment of FileDes to FileId
|
|
*
|
|
* Rev 1.11 11 Jul 1995 12:14:00 HEIDI
|
|
*
|
|
* fixed some renamed file id fields
|
|
*
|
|
* Rev 1.10 11 Jul 1995 09:53:48 HEIDI
|
|
*
|
|
* Set the following variable
|
|
*
|
|
* jpeg_info.FileId = pdata->FileDes;
|
|
*
|
|
* because later in OIComex, the value is needed for the new filing functions.
|
|
*
|
|
* Rev 1.9 10 Jul 1995 11:03:42 JAR
|
|
* Intermediate check in for awd support, some of the items are commented out until
|
|
* this support is added in the GFS dll.
|
|
*
|
|
* Rev 1.8 23 Jun 1995 10:40:06 RWR
|
|
* Change "wiisfio2.h" include file to "filing.h"
|
|
*
|
|
* Rev 1.7 22 May 1995 18:35:30 RWR
|
|
* More changes to account for admin.h->oiadm.h and new LIB file location
|
|
*
|
|
* Rev 1.6 16 May 1995 11:33:22 RWR
|
|
* Replace hardcoded DLL names with entries from (new) dllnames.h header file
|
|
*
|
|
* Rev 1.5 15 May 1995 15:45:24 RWR
|
|
* Change dword-alignment mask value from ffe0 to 3ffe0, consistent w/LIBGFS
|
|
*
|
|
* Rev 1.4 09 May 1995 13:21:50 RWR
|
|
* #include file modifications to match changes to oiadm.h/admin.h/privapis.h
|
|
*
|
|
* Rev 1.3 28 Apr 1995 17:58:44 RWR
|
|
* Define common routine to load OICOM400 (LoadOICOMEX) to simplify debugging
|
|
*
|
|
* Rev 1.2 27 Apr 1995 00:09:34 RWR
|
|
* Change all "oicomex" references to "oicom400" to match new Win32 DLL name
|
|
*
|
|
* Rev 1.1 14 Apr 1995 01:26:04 JAR
|
|
* made it compile
|
|
*
|
|
* Rev 1.0 06 Apr 1995 08:50:14 RWR
|
|
* Initial entry
|
|
*
|
|
* Rev 1.6 28 Mar 1995 11:16:10 RWR
|
|
* Corrected computation of scanline length for BMP images
|
|
*
|
|
* Rev 1.5 21 Mar 1995 17:57:30 RWR
|
|
* Comment out FIO_FLAG_ENCRYPT references (several)
|
|
*
|
|
* Rev 1.4 09 Mar 1995 15:37:08 RWR
|
|
* Eliminate use of temporary static copies of LP_FIO_DATA structure variables
|
|
*
|
|
* Rev 1.3 31 Oct 1994 10:26:12 KMC
|
|
* In PrepareForJpegRead, set dwSize = ...jpeg_info_ptr->jpeg_buffer_size rather
|
|
* that ...jpeg_info_ptr->jpeg.JpegInterchangeFormatLength.
|
|
*
|
|
* Rev 1.2 02 Sep 1994 14:53:16 KMC
|
|
* Intermediate chkin of changes for multi-page TIFF writing.
|
|
*/
|
|
|
|
/******************************************************************************
|
|
PC-WIIS File Input/Output routines
|
|
|
|
This module contains all the entry points for WRITE.
|
|
|
|
13-apr-90 steve sherman split out from fiowrite.c for smaller code seg.
|
|
29-oct-91 krs plopped in bmpwrite
|
|
27-jan-92 jar saved the universe of JPEGness...
|
|
4-feb-92 jar added some flag business for more efficient JPEG buffering
|
|
16-jun-93 jar/kmc, added routines for new Wang JPEG.
|
|
24-jun-93 kmc, added a check of GFS version # for Xing JPEG files. Return
|
|
an error message if encounter one.
|
|
22-jul-93 kmc, do not return error for Xing JPEGS. Jpeg DLL can now read them.
|
|
08-sep-93 kmc, Pack JPEG subsample, quality values in GfsInfo grp3 field
|
|
in PrepareForJpegWrite.
|
|
09-sep-93 kmc, commented out call to wgfsgtdata to get gfs version # in
|
|
PrepareForJpegRead..
|
|
14-sep-93 kmc, commented out references to parts of new jpeg structure in
|
|
gfs.h that were commented out for this release (3.6).
|
|
24-mar-95 rwr, corrected computation of DestWidth in WriteBMP() routine,
|
|
which was miscalculating & causing rounding error
|
|
*******************************************************************************/
|
|
|
|
#include "abridge.h"
|
|
#include <windows.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include "wic.h"
|
|
#include "oifile.h"
|
|
#include "oierror.h"
|
|
#include "oicmp.h"
|
|
#include "filing.h"
|
|
#include "dllnames.h"
|
|
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
// 9508.30 rwr these are new for "wincmpex" replacement processing
|
|
int WCCompressOpen (LPCXDATA);
|
|
int WCCompressData (LPCXDATA);
|
|
int WCCompressClose (LPCXDATA);
|
|
int WCExpandOpen (LPCXDATA);
|
|
int WCExpandData (LPCXDATA);
|
|
#endif
|
|
|
|
// 9504.12 jar added conditional
|
|
#ifndef MSWINDOWS
|
|
#define MSWINDOWS
|
|
#endif
|
|
|
|
#include "wgfs.h"
|
|
#include "oicomex.h"
|
|
#include "oidisp.h"
|
|
#include "oiadm.h" // kmc (3.6) - for new subsample defines, SUB_...
|
|
|
|
//#include "monit.h"
|
|
|
|
/* jar -- new jpeg stuff */
|
|
|
|
#define JPEG_BASELINE 1
|
|
#define JPEG_QTABLE_LENGTH 64
|
|
|
|
#define JPEG_ERR_NOSTARTSCAN 999
|
|
#define JPEG_ERR_NOQTABLE 998
|
|
#define JPEG_NOMEMORY 997
|
|
#define JPEG_NOTYET 996
|
|
|
|
#define LPQTABLE _QTABLE FAR *
|
|
#define LPDCTABLE _DCTABLE FAR *
|
|
#define LPACTABLE _ACTABLE FAR *
|
|
|
|
/* prototypes */
|
|
UINT PrepareForJpegWrite( lp_INFO, LP_COM_CALL_SPEC, UINT);
|
|
UINT PrepareForJpegRead( HWND, lp_INFO, LP_EXP_CALL_SPEC);
|
|
|
|
/* private to this (jpeg stuff) module */
|
|
UINT FindRestartAndQStuff( LPUINT, LPQTABLE, LPSTR, UINT, UINT);
|
|
UINT DoQTableStuff( LPQTABLE, LPSTR, UINT, UINT);
|
|
UINT FindHuffman( LPDCTABLE, LPACTABLE, LPSTR, UINT, UINT);
|
|
UINT BufCopy( LPSTR, LPSTR, UINT);
|
|
|
|
/* jar -- end of new jpeg stuff */
|
|
|
|
WORD WriteStrips (HWND, LPCXDATA, LP_FIO_DATA, LPSTR, LPINT, BOOL);
|
|
WORD WriteNoStrips (HWND, LPCXDATA, LP_FIO_DATA, LPSTR, LPINT, BOOL);
|
|
HANDLE LoadOICOMEX(void);
|
|
|
|
// mask table for the awd junk
|
|
BYTE MaskTable[] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
|
|
|
|
// other stuff
|
|
extern HANDLE hOicomex;
|
|
|
|
/*************************************************************************/
|
|
//***************************************************************************
|
|
//
|
|
// WriteStrips
|
|
//
|
|
//***************************************************************************
|
|
WORD WriteStrips (hWnd, lpcxdata, pdata, buffer_address,
|
|
this_many_lines, done)
|
|
HWND hWnd;
|
|
LPCXDATA lpcxdata;
|
|
LP_FIO_DATA pdata;
|
|
LPSTR buffer_address;
|
|
LPINT this_many_lines;
|
|
BOOL done;
|
|
{
|
|
|
|
WORD status = 0;
|
|
int total_lines;
|
|
int TotalLineCnt = 0;
|
|
int CmpLineCnt = 0;
|
|
LPSTR lpCompressData;
|
|
int numofbytes;
|
|
char localdone;
|
|
int byteswritten = 0;
|
|
int errcode = 0;
|
|
FIO_INFORMATION file_info;
|
|
FIO_INFO_CGBW color_info;
|
|
COMP_CALL_SPEC jpeg_info;
|
|
LPSTR lpbyte_align_buf;
|
|
LPSTR lpcaller_buf;
|
|
FARPROC lpFuncOICompress;
|
|
HANDLE hModule=0;
|
|
lp_INFO lpGFSInfo=0;
|
|
BOOL UseLZW = FALSE;
|
|
BOOL JpegDone = 0;
|
|
unsigned int pgnum;
|
|
|
|
/* stuff we need to patch up the JPEG universe */
|
|
int JPEGLinesInStrip = 0;
|
|
int RealLinesInStrip = 0;
|
|
int BufferAmount = 0;
|
|
LPSTR lpCallerBuff = NULL;
|
|
BOOL ALittleExtra = FALSE;
|
|
|
|
/* Now lock and roll compression buffer */
|
|
if (!(lpCompressData = (LPSTR) GlobalLock ( pdata->hCompressBuf )))
|
|
{
|
|
return (FIO_GLOBAL_LOCK_FAILED);
|
|
}
|
|
|
|
total_lines = *this_many_lines;
|
|
|
|
// Set up correct page number to use for the write.
|
|
if ((pdata->page_opts == FIO_INSERT_PAGE) ||
|
|
(pdata->page_opts == FIO_OVERWRITE_PAGE))
|
|
{
|
|
pgnum = pdata->pgcnt + 1; // Need to append to file first,
|
|
}
|
|
else // then adjust page index later.
|
|
{
|
|
pgnum = pdata->pgnum;
|
|
}
|
|
|
|
if ((lpcxdata->CompressType & FIO_LZW ) == FIO_LZW)
|
|
{
|
|
UseLZW = TRUE;
|
|
}
|
|
|
|
// See if we have to swapbgr data to rgb data for tiff write.......
|
|
// Do it inplace so we do not have to allocate another buffer....
|
|
if (pdata->image_type == ITYPE_BGR24)
|
|
{
|
|
SwapRGB ( buffer_address, lpcxdata->BufferByteWidth,
|
|
lpcxdata->BufferByteWidth, *this_many_lines);
|
|
}
|
|
|
|
/** Loop Until we have compressed all the data buffer given to us **/
|
|
if ((lpcxdata->CompressType & FIO_TYPES_MASK) != FIO_TJPEG)
|
|
{
|
|
while (( total_lines > 0) && (!status))
|
|
{
|
|
/*
|
|
*** NOTE: pdata->Strip_index contains the number of Lines that
|
|
were written in the last incomplete strip.
|
|
*/
|
|
lpcxdata->Status = 0;
|
|
|
|
if(!(pdata->Strip_index ))
|
|
{
|
|
if (UseLZW)
|
|
{
|
|
lpcxdata->BufferFlags = 8;
|
|
}
|
|
else
|
|
{
|
|
lpcxdata->BufferFlags = 0;
|
|
}
|
|
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
if (!WCCompressOpen(lpcxdata))
|
|
#else
|
|
if (!CompressOpen(lpcxdata))
|
|
#endif
|
|
{
|
|
status = FIO_GLOBAL_ALLOC_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((unsigned int)(total_lines + pdata->Strip_index) >= pdata->strip_lines)
|
|
{ /* we have enough data to complete a strip */
|
|
CmpLineCnt = pdata->strip_lines- pdata->Strip_index;
|
|
localdone = STRIP_DONE;
|
|
pdata->Strip_index = 0;
|
|
}
|
|
else /* we don't have enough data to complete a strip */
|
|
{
|
|
localdone = 0;
|
|
CmpLineCnt = total_lines;
|
|
pdata->Strip_index += total_lines;
|
|
}
|
|
|
|
/* Begin Data Compression */
|
|
lpcxdata->ExpandLines = CmpLineCnt;
|
|
lpcxdata->CompressBytes = (int) pdata->CmpBuffersize;
|
|
lpcxdata->lpExpandData = buffer_address +
|
|
(TotalLineCnt * lpcxdata->BufferByteWidth);
|
|
lpcxdata->lpCompressData = lpCompressData;
|
|
|
|
TotalLineCnt += CmpLineCnt;
|
|
total_lines -= CmpLineCnt;
|
|
|
|
lpcxdata->Status = 0;
|
|
|
|
if ((done) && (total_lines <= 0)) /* Test for last strip EOF */
|
|
{
|
|
localdone = IMAGE_DONE | STRIP_DONE;
|
|
}
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
numofbytes = WCCompressData(lpcxdata);
|
|
#else
|
|
numofbytes = CompressData(lpcxdata);
|
|
#endif
|
|
/*
|
|
** scs. 3-20-90 This Write is here for compression buffer overflow.
|
|
** Negative Compression is quite common for dither patterns.
|
|
*/
|
|
while ((lpcxdata->Status == c_erro) && (!status)) /* output buffer filled */
|
|
{
|
|
if (numofbytes > 0)
|
|
{
|
|
// if (pdata->fio_flags & FIO_FLAG_ENCRYPT)
|
|
// encrypt(lpcxdata->lpCompressData,(long) numofbytes);
|
|
if ((byteswritten = (int)wgfswrite( hWnd, pdata->filedes,
|
|
lpcxdata->lpCompressData,
|
|
(unsigned long) numofbytes,
|
|
(unsigned short)pgnum,
|
|
0, &errcode)) < 0)
|
|
{
|
|
total_lines = 0;
|
|
status = errcode;
|
|
}
|
|
}
|
|
lpcxdata->CompressBytes = (int) pdata->CmpBuffersize;
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
numofbytes = WCCompressData(lpcxdata);
|
|
#else
|
|
numofbytes = CompressData(lpcxdata);
|
|
#endif
|
|
}
|
|
|
|
if (lpcxdata->Status == c_errx) /* if Expansion error exit */
|
|
{
|
|
total_lines = 0;
|
|
status = FIO_EXPAND_COMPRESS_ERROR;
|
|
}
|
|
|
|
if ( (localdone & STRIP_DONE) &&
|
|
((numofbytes > 0) || (lpcxdata->Status == c_erri) || UseLZW) )
|
|
{
|
|
int SaveFlag = localdone;
|
|
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
numofbytes = WCCompressClose(lpcxdata);
|
|
#else
|
|
numofbytes = CompressClose(lpcxdata);
|
|
#endif
|
|
/* WGFS network or local */
|
|
if (lpcxdata->Status == c_erro) // yes, we have overflow..
|
|
{
|
|
localdone = 0; // we are not done the strip...
|
|
}
|
|
// if (pdata->fio_flags & FIO_FLAG_ENCRYPT)
|
|
// encrypt(lpcxdata->lpCompressData,(long) numofbytes);
|
|
if ((byteswritten = (int)wgfswrite( hWnd, pdata->filedes,
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
lpcxdata->lpDspBuffer,
|
|
#else
|
|
lpcxdata->lpCompressData,
|
|
#endif
|
|
(unsigned long) numofbytes,
|
|
(unsigned short)pgnum,
|
|
localdone, &errcode)) < 0)
|
|
{
|
|
total_lines = 0;
|
|
status = errcode;
|
|
}
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
VirtualFree(lpcxdata->lpDspBuffer,0,MEM_RELEASE);
|
|
#endif
|
|
if (byteswritten != numofbytes)
|
|
{
|
|
status = FIO_WRITE_ERROR;
|
|
}
|
|
|
|
// New stuff to handle overflow on compressclose for lzw compression...
|
|
localdone = SaveFlag; // restore the strip flag.
|
|
|
|
if ((lpcxdata->Status == c_erro) && (!status) && (UseLZW))
|
|
{
|
|
lpcxdata->ExpandLines = 0;
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
numofbytes = WCCompressClose(lpcxdata);
|
|
#else
|
|
numofbytes = CompressClose(lpcxdata);
|
|
#endif
|
|
if (numofbytes > 0)
|
|
{
|
|
// if (pdata->fio_flags & FIO_FLAG_ENCRYPT)
|
|
// encrypt(lpcxdata->lpCompressData,(long) numofbytes);
|
|
if ((byteswritten = (int)wgfswrite( hWnd, pdata->filedes,
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
lpcxdata->lpDspBuffer,
|
|
#else
|
|
lpcxdata->lpCompressData,
|
|
#endif
|
|
(unsigned long) numofbytes,
|
|
(unsigned short)pgnum,
|
|
localdone, &errcode)) < 0)
|
|
{
|
|
total_lines = 0;
|
|
status = errcode;
|
|
}
|
|
}
|
|
|
|
if (byteswritten != numofbytes)
|
|
{
|
|
status = FIO_WRITE_ERROR;
|
|
}
|
|
}
|
|
|
|
/***
|
|
* -- Note on second strip in tiff file compression type 3
|
|
* -- pre-eols end and we must remove bit setting in compression type.
|
|
***/
|
|
}
|
|
}
|
|
}
|
|
else /***** Write Out JPEG Comp data. First check OICOMPEX.DLL is loaded.. *****/
|
|
{
|
|
if (!(pdata->hJPEGBufComp))
|
|
{
|
|
status = NOMEMORY;
|
|
goto exit2;
|
|
}
|
|
|
|
jpeg_info.wiisfio.in_ptr = GlobalLock(pdata->hJPEGBufComp);
|
|
jpeg_info.wiisfio.out_ptr = lpCompressData;
|
|
jpeg_info.wiisfio.bytes_used = &numofbytes;
|
|
|
|
/* clear done flag -- we'll set it later if appropriate - jar */
|
|
jpeg_info.wiisfio.done_flag = 0;
|
|
|
|
/* get the handle from the property list - jar */
|
|
jpeg_info.wiisfio.lpUniqueHandle = &(pdata->hJPEG_OIComp);
|
|
|
|
lpcaller_buf = buffer_address;
|
|
|
|
if (!(lpGFSInfo = (lp_INFO) GlobalLock ( pdata->hGFS_info )))
|
|
{
|
|
status = FIO_GLOBAL_LOCK_FAILED;
|
|
goto exit2;
|
|
}
|
|
|
|
while (( total_lines > 0) && (!status))
|
|
{
|
|
/*
|
|
*** NOTE: pdata->Strip_index contains the number of Lines that were written
|
|
in the last incomplete strip.
|
|
*/
|
|
|
|
lpbyte_align_buf = jpeg_info.wiisfio.in_ptr +
|
|
(pdata->Strip_index * pdata->JPEG_byte_widthComp);
|
|
|
|
if ( ((unsigned int)(total_lines + pdata->Strip_index) >= pdata->strip_lines) ||
|
|
( done == TRUE ))
|
|
{ /* we have enough data to complete a strip */
|
|
CmpLineCnt = pdata->strip_lines- pdata->Strip_index;
|
|
|
|
/* we must account for rear-end case - jar */
|
|
if ( done)
|
|
{
|
|
if ((unsigned int)(total_lines + pdata->Strip_index) <= pdata->strip_lines)
|
|
{
|
|
/* ha ha I like the curly braces tabbed in - jar */
|
|
CmpLineCnt = total_lines;
|
|
RealLinesInStrip = total_lines + pdata->Strip_index;
|
|
|
|
/* JPEG dll requires multiple of 8 for lines so as Captain
|
|
Picard would say -- make it so! - jar */
|
|
|
|
JPEGLinesInStrip = ((RealLinesInStrip + 7)/8)*8;
|
|
|
|
/* also, save the last line of real input data for
|
|
buffering - jar */
|
|
|
|
lpCallerBuff = lpcaller_buf;
|
|
lpCallerBuff += ((CmpLineCnt-1) * lpcxdata->BufferByteWidth);
|
|
}
|
|
else
|
|
{
|
|
/* we've got a little left over to take care of */
|
|
ALittleExtra = TRUE;
|
|
}
|
|
}
|
|
localdone = STRIP_DONE;
|
|
pdata->Strip_index = 0;
|
|
farbmcopy(lpcaller_buf, lpbyte_align_buf,
|
|
(unsigned int) lpcxdata->BufferByteWidth,
|
|
(unsigned int) pdata->JPEG_byte_widthComp,
|
|
min ((UINT)lpcxdata->BufferByteWidth, (UINT)pdata->JPEG_byte_widthComp),
|
|
(unsigned int) CmpLineCnt);
|
|
|
|
// Update pointer offset of intermediate byte aligned buffer....
|
|
lpbyte_align_buf += (CmpLineCnt * pdata->JPEG_byte_widthComp);
|
|
// Update pointer offset of users input buffer...
|
|
lpcaller_buf += (CmpLineCnt * lpcxdata->BufferByteWidth);
|
|
}
|
|
else /* we don't have enough data to complete a strip */
|
|
/* so we just copy it to my intermediate buffer */
|
|
{
|
|
localdone = 0;
|
|
CmpLineCnt = total_lines;
|
|
pdata->Strip_index += total_lines;
|
|
farbmcopy(lpcaller_buf, lpbyte_align_buf,
|
|
(unsigned int) lpcxdata->BufferByteWidth,
|
|
(unsigned int) pdata->JPEG_byte_widthComp,
|
|
min ((UINT)lpcxdata->BufferByteWidth, (UINT)pdata->JPEG_byte_widthComp),
|
|
(unsigned int) CmpLineCnt);
|
|
goto exit2;
|
|
}
|
|
|
|
TotalLineCnt += CmpLineCnt;
|
|
total_lines -= CmpLineCnt;
|
|
|
|
lpcxdata->Status = 0;
|
|
|
|
if ((done) && (total_lines <= 0)) /* Test for last strip EOF */
|
|
{
|
|
localdone = IMAGE_DONE | STRIP_DONE;
|
|
|
|
/* set the jpeg dll done flag too - jar */
|
|
/* cannot set done flag on last strip since it does not compress it scs */
|
|
/* we have to set it on a separate call. scs */
|
|
|
|
JpegDone = 1;
|
|
|
|
/* okay bullwinkle, we're done for real, let's make sure we've got
|
|
a good bunch o'data to give to those crazy JPEG dudes - jar */
|
|
BufferAmount = JPEGLinesInStrip - RealLinesInStrip;
|
|
if ( BufferAmount)
|
|
{
|
|
while ( BufferAmount--)
|
|
{
|
|
/* we gots to align this dude and we got only that last
|
|
line from the input data so we gotta do it this way
|
|
- jar */
|
|
farbmcopy( lpCallerBuff, lpbyte_align_buf,
|
|
(unsigned int) lpcxdata->BufferByteWidth,
|
|
(unsigned int) pdata->JPEG_byte_widthComp,
|
|
min ((UINT)lpcxdata->BufferByteWidth, (UINT)pdata->JPEG_byte_widthComp),
|
|
(unsigned int)1);
|
|
lpbyte_align_buf += pdata->JPEG_byte_widthComp;
|
|
}
|
|
}
|
|
} /* end of the dung test - jar */
|
|
|
|
// Get Address of OICompress.. Since Wiisfio1 Should not link with it....
|
|
if (!(hModule))
|
|
{
|
|
if (hModule = hOicomex)
|
|
{
|
|
if (!(lpFuncOICompress = GetProcAddress(hModule, "OICompress")))
|
|
{
|
|
status = FIO_SPAWN_HANDLER_ERROR;
|
|
goto exit2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 9504.13 jar return is 0/1 baby!
|
|
//if ((hModule = LoadOICOMEX()) >= 32)
|
|
if (hModule = LoadOICOMEX())
|
|
{
|
|
hOicomex = hModule;
|
|
if (!(lpFuncOICompress = GetProcAddress(hModule, "OICompress")))
|
|
{
|
|
status = FIO_SPAWN_HANDLER_ERROR;
|
|
goto exit2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = FIO_SPAWN_HANDLER_ERROR;
|
|
goto exit2;
|
|
}
|
|
}
|
|
}
|
|
|
|
file_info.rows_strip = pdata->strip_lines;
|
|
|
|
/* wait a cotton pickin minute --
|
|
make this work for the last strip - jar */
|
|
if ( (done) && ( !ALittleExtra))
|
|
{
|
|
file_info.rows_strip = JPEGLinesInStrip;
|
|
}
|
|
else if ((JpegDone) && (ALittleExtra)) // scs needed to add this test..
|
|
{
|
|
file_info.rows_strip = JPEGLinesInStrip;
|
|
}
|
|
|
|
file_info.file_type = FIO_TIF;
|
|
file_info.page_count = 1;
|
|
file_info.page_number = 1;
|
|
file_info.horizontal_pixels = (unsigned int) lpGFSInfo->horiz_size;
|
|
file_info.vertical_pixels = (unsigned int) lpGFSInfo->vert_size;
|
|
file_info.bits_per_sample = (unsigned int) lpGFSInfo->bits_per_sample[0];
|
|
file_info.samples_per_pix = (unsigned int) lpGFSInfo->samples_per_pix;
|
|
file_info.compression_type = FIO_TJPEG;
|
|
file_info.strips_per_image = pdata->strip_lines;
|
|
file_info.filename = NULL;
|
|
|
|
color_info.palette_entries = 0;
|
|
color_info.lppalette_table= NULL;
|
|
color_info.compress_type = FIO_TJPEG;
|
|
//color_info.compress_info1= (UINT)lpGFSInfo->img_cmpr.opts.grp3;
|
|
if ( lpGFSInfo->img_cmpr.type == JPEG)
|
|
{
|
|
color_info.compress_info1 = (UINT)lpGFSInfo->img_cmpr.opts.grp3;
|
|
}
|
|
else /* this is new style man */
|
|
{
|
|
/* we must get the jpeg_info_ptr back since gfs may have zapped it */
|
|
if ( lpGFSInfo->img_cmpr.opts.jpeg_info_ptr == NULL)
|
|
{
|
|
GlobalUnlock( pdata->hJpegInfoForGFS);
|
|
lpGFSInfo->img_cmpr.opts.jpeg_info_ptr =
|
|
(LPJPEG_INFO)GlobalLock( pdata->hJpegInfoForGFS);
|
|
}
|
|
color_info.compress_info1=
|
|
(UINT)lpGFSInfo->img_cmpr.opts.jpeg_info_ptr->jpegbits;
|
|
}
|
|
color_info.image_type = pdata->image_type;
|
|
|
|
// if (!(status = OICompress(WIISFIO, hWnd, &(pdata->hJPEG_OI), &jpeg_info, &file_info, &color_info)))
|
|
|
|
if (!(status = (int) (*lpFuncOICompress)((BYTE)WIISFIO,
|
|
(HWND)hWnd,
|
|
(LP_COM_CALL_SPEC) &jpeg_info,
|
|
(LP_FIO_INFORMATION) &file_info,
|
|
(LP_FIO_INFO_CGBW) &(color_info)
|
|
)))
|
|
{
|
|
/* the brave new world of jpeg -- jar */
|
|
// if (pdata->fio_flags & FIO_FLAG_ENCRYPT)
|
|
// encrypt(lpCompressData,(long) numofbytes);
|
|
if ((byteswritten = (int)wgfswrite( hWnd, pdata->filedes, lpCompressData,
|
|
(unsigned long) numofbytes,
|
|
(unsigned short)pgnum, localdone,
|
|
&errcode)) < 0)
|
|
{
|
|
total_lines = 0;
|
|
status = errcode;
|
|
}
|
|
if (JpegDone) // we have to call jpeg one more time to free its buffers.
|
|
{
|
|
jpeg_info.wiisfio.done_flag = 1;
|
|
|
|
(*lpFuncOICompress)((BYTE)WIISFIO,
|
|
(HWND) hWnd,
|
|
(LP_COM_CALL_SPEC) &jpeg_info,
|
|
(LP_FIO_INFORMATION) &file_info,
|
|
(LP_FIO_INFO_CGBW) &(color_info));
|
|
|
|
/* null it out so gfs doesn't try to free it */
|
|
lpGFSInfo->img_cmpr.opts.jpeg_info_ptr == NULL;
|
|
GlobalUnlock( pdata->hJpegInfoForGFS);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = FIO_EXPAND_COMPRESS_ERROR;
|
|
}
|
|
|
|
} // end of while loop on total_lines > 0
|
|
|
|
#ifdef XXXX
|
|
|
|
while (( total_lines > 0) && (!status))
|
|
{
|
|
/*
|
|
*** NOTE: pdata->Strip_index contains the number of Lines that were written
|
|
in the last incomplete strip.
|
|
*/
|
|
lpcxdata->Status = 0;
|
|
if(!(pdata->Strip_index ))
|
|
{
|
|
if ((lpcxdata->CompressType & FIO_LZW ) == FIO_LZW)
|
|
{
|
|
lpcxdata->BufferFlags = 8;
|
|
}
|
|
else
|
|
{
|
|
lpcxdata->BufferFlags = 0;
|
|
}
|
|
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
if (!WCCompressOpen(lpcxdata))
|
|
#else
|
|
if (!CompressOpen(lpcxdata))
|
|
#endif
|
|
{
|
|
status = FIO_GLOBAL_ALLOC_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
if ((total_lines + pdata->Strip_index) >= pdata->strip_lines)
|
|
{ /* we have enough data to complete a strip */
|
|
CmpLineCnt = pdata->strip_lines- pdata->Strip_index;
|
|
localdone = STRIP_DONE;
|
|
pdata->Strip_index = 0;
|
|
}
|
|
else /* we donut have enough data to complete a strip */
|
|
{
|
|
localdone = 0;
|
|
CmpLineCnt = total_lines;
|
|
pdata->Strip_index += total_lines;
|
|
}
|
|
|
|
/* Begin Data Compression */
|
|
lpcxdata->ExpandLines = CmpLineCnt;
|
|
lpcxdata->CompressBytes = (int) pdata->CmpBuffersize;
|
|
lpcxdata->lpExpandData = buffer_address +
|
|
(TotalLineCnt * lpcxdata->BufferByteWidth);
|
|
lpcxdata->lpCompressData = lpCompressData;
|
|
|
|
TotalLineCnt += CmpLineCnt;
|
|
total_lines -= CmpLineCnt;
|
|
|
|
lpcxdata->Status = 0;
|
|
|
|
if ((done) && (total_lines <= 0)) /* Test for last strip EOF */
|
|
{
|
|
localdone = IMAGE_DONE | STRIP_DONE;
|
|
}
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
numofbytes = WCCompressData(lpcxdata);
|
|
#else
|
|
numofbytes = CompressData(lpcxdata);
|
|
#endif
|
|
/*
|
|
** scs. 3-20-90 This Write is here for compression buffer overflow.
|
|
** Negative Compression is quite common for dither patterns.
|
|
*/
|
|
|
|
while ((lpcxdata->Status == c_erro) && (!status)) /* output buffer filled */
|
|
{
|
|
if (numofbytes > 0)
|
|
{
|
|
// if (pdata->fio_flags & FIO_FLAG_ENCRYPT)
|
|
// encrypt(lpcxdata->lpCompressData,(long) numofbytes);
|
|
if ((byteswritten = (int)wgfswrite( hWnd, pdata->filedes,
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
lpcxdata->lpDspBuffer,
|
|
#else
|
|
lpcxdata->lpCompressData,
|
|
#endif
|
|
(unsigned long) numofbytes,
|
|
pgnum, 0, &errcode)) < 0)
|
|
{
|
|
total_lines = 0;
|
|
status = errcode;
|
|
}
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
VirtualFree(lpDspBuffer,0,MEM_RELEASE);
|
|
#endif
|
|
}
|
|
lpcxdata->CompressBytes = (int) pdata->CmpBuffersize;
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
numofbytes = WCCompressData(lpcxdata);
|
|
#else
|
|
numofbytes = CompressData(lpcxdata);
|
|
#endif
|
|
} // end of while loop
|
|
|
|
if (lpcxdata->Status == c_errx) /* if Expansion error exit */
|
|
{
|
|
total_lines = 0;
|
|
status = FIO_EXPAND_COMPRESS_ERROR;
|
|
}
|
|
|
|
if ((localdone & STRIP_DONE) && (numofbytes > 0))
|
|
{
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
numofbytes = WCCompressClose(lpcxdata);
|
|
#else
|
|
numofbytes = CompressClose(lpcxdata);
|
|
#endif
|
|
/* WGFS network or local */
|
|
// if (pdata->fio_flags & FIO_FLAG_ENCRYPT)
|
|
// encrypt(lpcxdata->lpCompressData,(long) numofbytes);
|
|
if ((byteswritten = (int)wgfswrite( hWnd, pdata->filedes,
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
lpcxdata->lpDspBuffer,
|
|
#else
|
|
lpcxdata->lpCompressData,
|
|
#endif
|
|
(unsigned long) numofbytes,
|
|
pgnum, localdone, &errcode)) < 0)
|
|
{
|
|
total_lines = 0;
|
|
status = errcode;
|
|
}
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
VirtualFree(lpcxdata->lpDspBuffer,0,MEM_RELEASE);
|
|
#endif
|
|
if (byteswritten != numofbytes)
|
|
{
|
|
status = FIO_WRITE_ERROR;
|
|
}
|
|
}
|
|
}
|
|
#endif // end of ifdef XXXX
|
|
|
|
exit2:
|
|
if (pdata->hJPEGBufComp)
|
|
{
|
|
GlobalUnlock(pdata->hJPEGBufComp);
|
|
}
|
|
}
|
|
|
|
if (lpGFSInfo)
|
|
{
|
|
GlobalUnlock (pdata->hGFS_info);
|
|
}
|
|
|
|
// See if we have had to swap bytes if so then swap them back
|
|
// Do it inplace so we do not have to allocate another buffer....
|
|
if (pdata->image_type == ITYPE_BGR24)
|
|
{
|
|
SwapRGB ( buffer_address, lpcxdata->BufferByteWidth,
|
|
lpcxdata->BufferByteWidth, *this_many_lines);
|
|
}
|
|
|
|
GlobalUnlock ( pdata->hCompressBuf );
|
|
return (status);
|
|
}
|
|
|
|
WORD WriteBmp( HWND hWnd, LPCXDATA lpcxdata, LP_FIO_DATA pdata,
|
|
LPSTR lpSrc, LPINT this_many_lines, BOOL done );
|
|
|
|
/* New, function prototype for writeing PCX files. */
|
|
WORD WritePcx( HWND hWnd, LPCXDATA lpcxdata, LP_FIO_DATA pdata,
|
|
LPSTR lpSrc, LPINT this_many_lines, BOOL done );
|
|
|
|
// 9507.07 jar AWD prototype
|
|
int WriteAWD( HWND hWnd, LPCXDATA lpcxdata, LP_FIO_DATA pdata,
|
|
unsigned int pgnum, LPSTR lpSrc, LPINT this_many_lines,
|
|
BOOL done );
|
|
|
|
/*************************************************************************/
|
|
//***************************************************************************
|
|
//
|
|
// WriteNoStrips
|
|
//
|
|
//***************************************************************************
|
|
WORD WriteNoStrips ( HWND hWnd, LPCXDATA lpcxdata,
|
|
LP_FIO_DATA pdata, LPSTR lpSrc, LPINT this_many_lines, BOOL done )
|
|
{
|
|
WORD status = 0;
|
|
int CmpLineCnt;
|
|
LPSTR lpCompressData;
|
|
int numofbytes;
|
|
char localdone = 0;
|
|
int byteswritten =0;
|
|
int errcode = 0;
|
|
unsigned int pgnum;
|
|
|
|
if ( pdata->file_type == FIO_BMP )
|
|
{
|
|
return WriteBmp( hWnd, lpcxdata, pdata, lpSrc, this_many_lines, done );
|
|
}
|
|
|
|
/* New, for writing PCX files. */
|
|
if ( (pdata->file_type == FIO_PCX) || (pdata->file_type == FIO_DCX) )
|
|
{
|
|
return WritePcx( hWnd, lpcxdata, pdata, lpSrc, this_many_lines, done );
|
|
}
|
|
|
|
if (*this_many_lines == 0)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
// Set up correct page number to use for the write.
|
|
if ((pdata->page_opts == FIO_INSERT_PAGE) ||
|
|
(pdata->page_opts == FIO_OVERWRITE_PAGE))
|
|
{
|
|
pgnum = pdata->pgcnt + 1; // Need to append to file first,
|
|
}
|
|
else
|
|
{ // then adjust page index later.
|
|
pgnum = pdata->pgnum;
|
|
}
|
|
// 9506.29 jar AWD: we will have to support the manner in which looks like
|
|
// other FILING.DLL formats. This means we will fake out
|
|
// pdata->Strip_index, pdata->strip_lines
|
|
if (pdata->file_type == FIO_AWD)
|
|
{
|
|
// 9508.02 JAR for now we just return, this is because
|
|
// an AWD write consists of merely putting
|
|
// out some flags and rotation/scale data, which
|
|
// we accomplish via gfsputi
|
|
return (WORD)WriteAWD( hWnd, lpcxdata, pdata, pgnum, lpSrc,
|
|
this_many_lines, done );
|
|
// 9507.10 JAR return the oop's we didn't do it error
|
|
//return (FIO_ERROR + 0xff);
|
|
}
|
|
|
|
/* Now lock compression buffer */
|
|
if (!(lpCompressData = (LPSTR) GlobalLock ( pdata->hCompressBuf )))
|
|
{
|
|
return (FIO_GLOBAL_LOCK_FAILED);
|
|
}
|
|
|
|
// See if we have to swapbgr data to rgb data for tiff write.......
|
|
// Do it inplace so we do not have to allocate another buffer....
|
|
if (pdata->image_type == ITYPE_BGR24)
|
|
{
|
|
SwapRGB ( lpSrc, lpcxdata->BufferByteWidth,
|
|
lpcxdata->BufferByteWidth, *this_many_lines);
|
|
}
|
|
|
|
|
|
CmpLineCnt = *this_many_lines;
|
|
if (pdata->start_byte == 0)
|
|
{
|
|
pdata->start_byte = 1;
|
|
lpcxdata->ExpandLines = CmpLineCnt;
|
|
lpcxdata->CompressBytes = (int) pdata->CmpBuffersize;
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
if (!WCCompressOpen(lpcxdata)) // Only Start One Open Compression
|
|
#else
|
|
if (!CompressOpen(lpcxdata)) // Only Start One Open Compression
|
|
#endif
|
|
{
|
|
status = FIO_GLOBAL_ALLOC_FAILED;
|
|
}
|
|
}
|
|
lpcxdata->lpExpandData = lpSrc;
|
|
if ((!status))
|
|
{
|
|
/* Begin Data Compression */
|
|
lpcxdata->ExpandLines = CmpLineCnt;
|
|
lpcxdata->CompressBytes = (int) pdata->CmpBuffersize;
|
|
lpcxdata->lpCompressData = lpCompressData;
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
numofbytes = WCCompressData(lpcxdata);
|
|
#else
|
|
numofbytes = CompressData(lpcxdata);
|
|
#endif
|
|
/*
|
|
** scs. 3-20-90 This Write is here for compression buffer overflow.
|
|
** Negative Compression is quite common for dither patterns.
|
|
*/
|
|
while ((lpcxdata->Status == c_erro) && (!status)) /* output buffer filled */
|
|
{
|
|
if (numofbytes > 0)
|
|
{
|
|
// if (pdata->fio_flags & FIO_FLAG_ENCRYPT)
|
|
// encrypt(lpCompressData,(long) numofbytes);
|
|
if ((byteswritten = (int)wgfswrite( hWnd, pdata->filedes,
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
lpcxdata->lpDspBuffer,
|
|
#else
|
|
lpCompressData,
|
|
#endif
|
|
(unsigned long) numofbytes,
|
|
(unsigned short)pgnum,
|
|
(char)0, &errcode)) < 0)
|
|
{
|
|
status = errcode;
|
|
}
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
VirtualFree(lpcxdata->lpDspBuffer,0,MEM_RELEASE);
|
|
#endif
|
|
}
|
|
lpcxdata->CompressBytes = (int) pdata->CmpBuffersize;
|
|
lpcxdata->lpCompressData = lpCompressData;
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
numofbytes = WCCompressData(lpcxdata);
|
|
#else
|
|
numofbytes = CompressData(lpcxdata);
|
|
#endif
|
|
}
|
|
|
|
if (done)
|
|
{
|
|
lpcxdata->ExpandLines = 0;
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
numofbytes = WCCompressClose(lpcxdata);
|
|
#else
|
|
numofbytes = CompressClose(lpcxdata);
|
|
#endif
|
|
localdone = IMAGE_DONE | STRIP_DONE;
|
|
}
|
|
|
|
if (done)
|
|
{
|
|
if (numofbytes > 0)
|
|
{
|
|
/* WGFS network or local */
|
|
// if (pdata->fio_flags & FIO_FLAG_ENCRYPT)
|
|
// encrypt(lpCompressData,(long) numofbytes);
|
|
if ((byteswritten = (int)wgfswrite( hWnd, pdata->filedes,
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
lpcxdata->lpDspBuffer,
|
|
#else
|
|
lpCompressData,
|
|
#endif
|
|
(unsigned long) numofbytes,
|
|
(unsigned short)pgnum,
|
|
localdone, &errcode)) < 0)
|
|
{
|
|
status = errcode;
|
|
}
|
|
#if ((NEWCMPEX == 'W') || (NEWCMPEX == 'A'))
|
|
VirtualFree(lpcxdata->lpDspBuffer,0,MEM_RELEASE);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
status = FIO_WRITE_ERROR;
|
|
}
|
|
|
|
if (byteswritten != numofbytes)
|
|
{
|
|
status = FIO_WRITE_ERROR;
|
|
}
|
|
}
|
|
|
|
if (lpcxdata->Status == c_errx) /* if Expansion error exit */
|
|
{
|
|
status = FIO_EXPAND_COMPRESS_ERROR;
|
|
}
|
|
}
|
|
|
|
// See if we have had to swap bytes if so then swap them back
|
|
// Do it inplace so we do not have to allocate another buffer....
|
|
if (pdata->image_type == ITYPE_BGR24)
|
|
{
|
|
SwapRGB ( lpSrc, lpcxdata->BufferByteWidth,
|
|
lpcxdata->BufferByteWidth, *this_many_lines);
|
|
}
|
|
|
|
GlobalUnlock ( pdata->hCompressBuf );
|
|
|
|
return (status);
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SwapRGB
|
|
//
|
|
//***************************************************************************
|
|
void pascal SwapRGB ( LPSTR lpDest, int DestWidth, int ConvertWidth, int Lines )
|
|
{
|
|
LPSTR lptmp;
|
|
LPSTR lptmp2;
|
|
char val2;
|
|
unsigned int rgbwidth, y;
|
|
int x;
|
|
|
|
lptmp2 = lpDest;
|
|
rgbwidth = ConvertWidth / 3;
|
|
for (x=0; x < Lines; x++)
|
|
{
|
|
lptmp = lptmp2;
|
|
for (y=0; y < rgbwidth; y++)
|
|
{
|
|
val2 = *lptmp;
|
|
*lptmp = *(lptmp + 2);
|
|
*(lptmp + 2) = val2;
|
|
lptmp += 3;
|
|
}
|
|
lptmp2 += DestWidth;
|
|
}
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// WriteBmp
|
|
//
|
|
//***************************************************************************
|
|
WORD WriteBmp( HWND hWnd, LPCXDATA lpcxdata, LP_FIO_DATA pdata,
|
|
LPSTR lpSrc, LPINT lpLines, BOOL done )
|
|
{
|
|
WORD status = 0;
|
|
LPSTR lpDest;
|
|
int byteswritten = 0;
|
|
int errcode = 0;
|
|
lp_INFO lpGFSInfo;
|
|
short Lines;
|
|
short BufferLines;
|
|
short BufferBytes;
|
|
short DestWidth;
|
|
short SrcWidth;
|
|
|
|
lpGFSInfo = (lp_INFO)GlobalLock ( pdata->hGFS_info );
|
|
|
|
if ( *lpLines == 0 )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (!(lpDest = (LPSTR) GlobalLock ( pdata->hCompressBuf )))
|
|
{
|
|
return (FIO_GLOBAL_LOCK_FAILED);
|
|
}
|
|
|
|
Lines = *lpLines;
|
|
DestWidth = (short)(((((long) lpGFSInfo->horiz_size *
|
|
(lpGFSInfo->bits_per_sample[0] * lpGFSInfo->samples_per_pix)) + 31 )
|
|
& 0x0003ffe0) / 8);
|
|
SrcWidth = lpcxdata->BufferByteWidth;
|
|
|
|
// monit2("DestWidth me %d gfs %d\n", DestWidth,
|
|
// lpGFSInfo->_file.fmt.bmp.ByteWidth );
|
|
|
|
if ( !pdata->start_byte )
|
|
{
|
|
// use ImagePos to tell GFS where to put the buffer
|
|
lpGFSInfo->_file.fmt.bmp.WritePos = 0;
|
|
pdata->start_byte = 1;
|
|
}
|
|
|
|
while ( Lines )
|
|
{
|
|
BufferLines = min ( Lines, (short)pdata->CmpBuffersize / DestWidth );
|
|
BufferBytes = DestWidth * BufferLines;
|
|
|
|
FlipBuffer ( lpDest, lpSrc, DestWidth, SrcWidth, BufferLines, FALSE );
|
|
// See if we have to swap rgb data to bgr data for bmp write.......
|
|
if (pdata->image_type == ITYPE_RGB24)
|
|
{
|
|
SwapRGB ( lpDest, DestWidth, SrcWidth, BufferLines );
|
|
}
|
|
|
|
// monit2("Writing %d Lines From %X\n", BufferLines, lpSrc );
|
|
|
|
if ((byteswritten = (int)wgfswrite( hWnd, pdata->filedes, lpDest,
|
|
(unsigned long) BufferBytes,
|
|
(unsigned short)pdata->pgnum,
|
|
0, &errcode)) < 0)
|
|
{
|
|
status = errcode;
|
|
}
|
|
lpGFSInfo->_file.fmt.bmp.WritePos += BufferLines;
|
|
Lines -= BufferLines;
|
|
lpSrc += SrcWidth * BufferLines;
|
|
}
|
|
GlobalUnlock ( pdata->hCompressBuf );
|
|
GlobalUnlock ( pdata->hGFS_info );
|
|
|
|
return (status);
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// WriteAWD
|
|
//
|
|
//***************************************************************************
|
|
int WriteAWD( HWND hWnd, LPCXDATA lpcxdata, LP_FIO_DATA pdata,
|
|
unsigned int pgnum, LPSTR lpSrc, LPINT lpLines,
|
|
BOOL done )
|
|
{
|
|
|
|
int Status = 0;
|
|
int BytesWritten = 0;
|
|
int errcode = 0;
|
|
lp_INFO lpGFSInfo;
|
|
int BufferBytes;
|
|
int QuantumUnit;
|
|
int GrandTotal;
|
|
int DestWidth;
|
|
|
|
int DestWidthRound;
|
|
int TempLines;
|
|
LPSTR lpSrcTemp = NULL;
|
|
LPSTR lpTemp = NULL;
|
|
LPSTR lpOurBufferTemp = NULL;
|
|
BYTE BogusBits;
|
|
int ByteMaskBits;
|
|
BYTE ByteMask;
|
|
int WholeBytesToFill;
|
|
int i;
|
|
int j;
|
|
|
|
lpGFSInfo = (lp_INFO)GlobalLock ( pdata->hGFS_info );
|
|
|
|
if ( *lpLines == 0 )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//DestWidth = lpGFSInfo->_file.fmt.pcx.bpl;
|
|
DestWidth = ((lpGFSInfo->horiz_size + 7)/8);
|
|
DestWidthRound = ((lpGFSInfo->horiz_size + 31)/32)*4;
|
|
|
|
// 9509.06 jar Not only do we need to account for the 32bit boundedness,
|
|
// but we also need to mask extra bits at the end of a line if
|
|
// the pixel width of the image is NOT on an 8bit boundary.
|
|
|
|
|
|
//if ( DestWidthRound > DestWidth)
|
|
if ( ( DestWidthRound > DestWidth) ||
|
|
( (unsigned int)(DestWidth*8) > (unsigned int)lpGFSInfo->horiz_size))
|
|
{
|
|
// this means we have a buffer of data that is not aligned by 4 bytes, so we
|
|
// have to take our input buffer, align it by putting it into the correct buffer
|
|
BufferBytes = DestWidthRound * (*lpLines);
|
|
if ( pdata->hAwdBuffer == 0)
|
|
{
|
|
pdata->hAwdBuffer = GlobalAlloc( GMEM_ZEROINIT, (DWORD)BufferBytes);
|
|
if ( pdata->hAwdBuffer)
|
|
{
|
|
pdata->lpAwdBuffer = GlobalLock( pdata->hAwdBuffer);
|
|
}
|
|
}
|
|
|
|
if ( pdata->lpAwdBuffer)
|
|
{
|
|
// copy from input to this one!
|
|
TempLines = *lpLines;
|
|
lpSrcTemp =lpSrc;
|
|
lpOurBufferTemp = pdata->lpAwdBuffer;
|
|
|
|
// determine if we must mask some bits
|
|
BogusBits = (BYTE)((DestWidthRound*8) - lpGFSInfo->horiz_size);
|
|
ByteMaskBits = BogusBits - ( ( BogusBits/8)*8);
|
|
ByteMask = MaskTable[ByteMaskBits];
|
|
WholeBytesToFill = ( BogusBits/8);
|
|
|
|
while( TempLines--)
|
|
{
|
|
memcpy( lpOurBufferTemp, lpSrcTemp, DestWidth);
|
|
lpSrcTemp += DestWidth;
|
|
|
|
// apply byte mask
|
|
*(lpOurBufferTemp + ( DestWidth - 1)) |= ByteMask;
|
|
i = 0;
|
|
j = WholeBytesToFill;
|
|
|
|
// fill in the whole byte chunks
|
|
while( j--)
|
|
{
|
|
*(lpOurBufferTemp + ( DestWidth + i++)) = (BYTE)(0xff);
|
|
}
|
|
|
|
lpOurBufferTemp += DestWidthRound;
|
|
} // end of the while loop over lines
|
|
lpSrc =pdata->lpAwdBuffer;
|
|
} // end of if lpAwdBuffer valid
|
|
else
|
|
{
|
|
Status = FIO_GLOBAL_ALLOC_FAILED;
|
|
}
|
|
} // end of if double buffering needed
|
|
else
|
|
{
|
|
BufferBytes = DestWidth * (*lpLines);
|
|
}
|
|
|
|
if ( !Status)
|
|
{
|
|
if ( !pdata->start_byte )
|
|
{
|
|
pdata->start_byte = 1;
|
|
}
|
|
|
|
// we cannot write more than 64*1024 bytes at a time
|
|
if ( BufferBytes <= ( 64*1024))
|
|
{
|
|
if ((BytesWritten = (int)wgfswrite( hWnd, pdata->filedes, lpSrc,
|
|
(unsigned long) BufferBytes,
|
|
(unsigned short)pgnum,
|
|
(char)done, &errcode)) < 0)
|
|
{
|
|
Status = errcode;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// we must loop til done!
|
|
QuantumUnit = min ( BufferBytes, ( 64*1024));
|
|
GrandTotal = BufferBytes;
|
|
lpTemp = lpSrc;
|
|
|
|
while ( ( GrandTotal > 0) && ( !Status))
|
|
{
|
|
if ((BytesWritten = (int)wgfswrite( hWnd, pdata->filedes, lpTemp,
|
|
(unsigned long) QuantumUnit,
|
|
(unsigned short)pgnum,
|
|
(char)done, &errcode)) < 0)
|
|
{
|
|
Status = errcode;
|
|
break;
|
|
}
|
|
GrandTotal -= min( GrandTotal, BytesWritten);
|
|
if ( GrandTotal > 0)
|
|
{
|
|
lpTemp += BytesWritten;
|
|
}
|
|
}
|
|
}
|
|
} // end of if status ok
|
|
|
|
// we need to check to see if this is the last buffer we're writing, if so then
|
|
// we must call gfswrite once more, this time with 0 bytes!
|
|
if ( pdata->lines == 0 || done)
|
|
{
|
|
if ((BytesWritten = (int)wgfswrite( hWnd, pdata->filedes, lpTemp,
|
|
(unsigned long) 0L,
|
|
(unsigned short)pgnum,
|
|
(char)done, &errcode)) < 0)
|
|
{
|
|
Status = errcode;
|
|
}
|
|
|
|
// clean up the memory
|
|
if ( pdata->hAwdBuffer)
|
|
{
|
|
pdata->lpAwdBuffer = NULL;
|
|
GlobalUnlock( pdata->hAwdBuffer);
|
|
GlobalFree( pdata->hAwdBuffer);
|
|
pdata->hAwdBuffer = 0;
|
|
}
|
|
}
|
|
|
|
GlobalUnlock ( pdata->hGFS_info );
|
|
return(Status);
|
|
}
|
|
/* jar -- new jpeg stuff */
|
|
|
|
/****************************************************************************
|
|
* *
|
|
* PrepareForJpegWrite this will take care of JPEG info when we are *
|
|
* writing a JPEG file *
|
|
* *
|
|
* history *
|
|
* *
|
|
* 3-may-93 jar created *
|
|
* *
|
|
****************************************************************************/
|
|
UINT PrepareForJpegWrite( lp_INFO lpGfsInfo, LP_COM_CALL_SPEC lpCallSpec,
|
|
UINT Components)
|
|
{
|
|
UINT TheError = 0;
|
|
long horiz_sub_sample,
|
|
vert_sub_sample = 1; /* For now, vertical is always 1 */
|
|
|
|
if ( lpCallSpec->wiisfio.JpegData.uJpegHeaderSwitch != JPEGNADA)
|
|
{
|
|
/* we're writing JPEG -- write out process -- baseline */
|
|
|
|
/* KMC - write out subsample, luminance, chrominance values
|
|
(luminance, chrominance are same as quality) to the
|
|
lpGfsInfo...grp3 field (1st 2 bytes) in the format
|
|
documented in the API Programmer's Guide Vol. 2. for the
|
|
IMGFileReadOpenCgbw API. Note, luminance and chrominance
|
|
are equal (both are stored as lum_comp_factor in lp_CallSpec
|
|
structure). Note, the 2nd (leftmost) two bytes of the grp3
|
|
field contain the vertical subsample value for the YCbCr
|
|
SubSampling tag. It is hardcoded here as 1, and shouldn't
|
|
change.
|
|
*/
|
|
horiz_sub_sample = lpCallSpec->wiisfio.sub_sample;
|
|
switch (horiz_sub_sample)
|
|
{
|
|
case SUB_HI_COMP: // subsample = 4
|
|
horiz_sub_sample = LO_RES;
|
|
break;
|
|
case SUB_MD_COMP: // subsample = 2
|
|
horiz_sub_sample = MD_RES;
|
|
break;
|
|
case SUB_LO_COMP: // subsample = 1
|
|
horiz_sub_sample = HI_RES;
|
|
break;
|
|
}
|
|
horiz_sub_sample <<= 14;
|
|
vert_sub_sample <<= 16; // KMC, put vertical subsample into leftmost 2 bytes.
|
|
lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpegbits = 0;
|
|
lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpegbits = ((lpCallSpec->wiisfio.lum_comp_factor) << 7);
|
|
lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpegbits |= lpCallSpec->wiisfio.lum_comp_factor;
|
|
lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpegbits |= (horiz_sub_sample | vert_sub_sample);
|
|
|
|
//lpGfsInfo->img_cmpr.jpeg.JpegProc = JPEG_BASELINE;
|
|
lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg.JpegProc = JPEG_BASELINE;
|
|
|
|
//lpGfsInfo->img_cmpr.jpeg.JpegInterchangeFormatLength =
|
|
// lpCallSpec->wiisfio.JpegData.JpegInter.dwJpegInterchangeSize;
|
|
lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg.JpegInterchangeFormatLength =
|
|
lpCallSpec->wiisfio.JpegData.JpegInter.dwJpegInterchangeSize;
|
|
|
|
|
|
lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg_buffer_size =
|
|
lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg.JpegInterchangeFormatLength;
|
|
|
|
lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg_buffer =
|
|
(char FAR *)lpCallSpec->wiisfio.JpegData.JpegInter.lpJpegInterchange;
|
|
|
|
/* now the restart interval, quantization tables and huffman tables */
|
|
TheError = FindRestartAndQStuff(
|
|
(LPUINT)&(lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg.JpegRestartInterval),
|
|
(LPQTABLE)&(lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg.JpegQTable),
|
|
(LPSTR)lpCallSpec->wiisfio.JpegData.JpegInter.lpJpegInterchange,
|
|
(UINT)lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg_buffer_size,
|
|
Components);
|
|
|
|
if ( !TheError)
|
|
{
|
|
FindHuffman( (LPDCTABLE)&(lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg.JpegDCTable),
|
|
(LPACTABLE)&(lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg.JpegACTable),
|
|
(LPSTR)lpCallSpec->wiisfio.JpegData.JpegInter.lpJpegInterchange,
|
|
(UINT)lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg_buffer_size,
|
|
Components);
|
|
/* KMC - not supported for this release:
|
|
lpGfsInfo->img_cmpr.jpeg.JpegQTable.nComponents = Components;
|
|
lpGfsInfo->img_cmpr.jpeg.JpegDCTable.nComponents = Components;
|
|
lpGfsInfo->img_cmpr.jpeg.JpegACTable.nComponents = Components;
|
|
*/
|
|
}
|
|
}
|
|
return TheError;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* *
|
|
* FindRestartAndQStuff search the JPEG Header for the restart marker *
|
|
* and the quantization tables and put into the *
|
|
* GFS info structure *
|
|
* *
|
|
* history *
|
|
* *
|
|
* 3-may-93 jar created *
|
|
* *
|
|
****************************************************************************/
|
|
UINT FindRestartAndQStuff( LPUINT lpRestartInterval, LPQTABLE lpQTable,
|
|
LPSTR lpJpeg, UINT uSizeJpeg, UINT Components)
|
|
{
|
|
UINT TheError = 0;
|
|
WORD MarkerLength = 0;
|
|
BOOL bRestart = FALSE;
|
|
BOOL bQ[3] = { FALSE, FALSE, FALSE};
|
|
UINT Amount = 0;
|
|
UINT Offset = 0;
|
|
UINT QCount = 0;
|
|
BYTE FFvar = 0xff;
|
|
BYTE DDvar = 0xdd;
|
|
BYTE DBvar = 0xdb;
|
|
|
|
*lpRestartInterval = 0;
|
|
|
|
if ( Components == 1)
|
|
bQ[1] = bQ[2] = TRUE;
|
|
|
|
while (( uSizeJpeg--) || (bRestart && bQ ))
|
|
{
|
|
Offset++;
|
|
if ( (BYTE)(*lpJpeg++) == FFvar)
|
|
{
|
|
Offset++;
|
|
uSizeJpeg--;
|
|
if (( !bRestart) && ( (BYTE)(*lpJpeg) == DDvar))
|
|
{
|
|
lpJpeg++;
|
|
/* restart interval stuff */
|
|
MarkerLength = ((int)(*lpJpeg++) & 0x00ff) << 8;
|
|
MarkerLength = ((int)(*lpJpeg++) & 0x00ff) + MarkerLength;
|
|
|
|
*lpRestartInterval = ((int)(*lpJpeg++) & 0x00ff) << 8;
|
|
*lpRestartInterval = ((int)(*lpJpeg++) & 0x00ff) +
|
|
*lpRestartInterval;
|
|
uSizeJpeg -= 4;
|
|
Offset += 4;
|
|
bRestart = TRUE;
|
|
}
|
|
else if ( (!bQ[0] || !bQ[1] || !bQ[2]) &&
|
|
( (BYTE)(*lpJpeg) == DBvar))
|
|
{
|
|
lpJpeg++;
|
|
/* quantization table stuff */
|
|
Amount = DoQTableStuff( lpQTable, lpJpeg, Offset, QCount);
|
|
uSizeJpeg -= Amount;
|
|
lpJpeg += Amount;
|
|
Offset += Amount;
|
|
bQ[QCount++] = TRUE;
|
|
}
|
|
else
|
|
lpJpeg++;
|
|
} /* end of if 0xff */
|
|
} /* end of while */
|
|
|
|
/* it's okay if there's no restart interval specified */
|
|
if ( !bQ[0] || !bQ[1] || !bQ[2])
|
|
{
|
|
if ( bQ[0] && bQ[1] && !bQ[2])
|
|
{
|
|
/* we've got to duplicate entry 1 into entry 2 */
|
|
lpQTable->nNumOffsets = Components;
|
|
lpQTable->QOffset.OffsetList[2] = lpQTable->QOffset.OffsetList[1];
|
|
}
|
|
else
|
|
TheError = JPEG_ERR_NOQTABLE;
|
|
}
|
|
|
|
return TheError;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* *
|
|
* DoQTableStuff pull out the quantization table info *
|
|
* *
|
|
* history *
|
|
* *
|
|
* 3-may-93 jar created *
|
|
* *
|
|
****************************************************************************/
|
|
UINT DoQTableStuff( LPQTABLE lpQTable, LPSTR lpJpeg, UINT Offset,
|
|
UINT ThisOffset)
|
|
{
|
|
UINT Amount = 0;
|
|
UINT MarkerLength = 0;
|
|
BYTE Precision = 0;
|
|
BYTE Id = 0;
|
|
BOOL Done = FALSE;
|
|
int Index;
|
|
BYTE PrecisionID = 0;
|
|
|
|
/* KMC - not supported for this release:
|
|
lpQTable->nLength = JPEG_QTABLE_LENGTH;
|
|
*/
|
|
MarkerLength = ((int)(*lpJpeg++) & 0x00ff) << 8;
|
|
MarkerLength = ((int)(*lpJpeg++) & 0x00ff) + MarkerLength;
|
|
Amount += 2;
|
|
Offset += 2;
|
|
|
|
/* KMC - not supported for this release. Do what follows instead.
|
|
lpQTable->cPrecisionID = *lpJpeg++;
|
|
Precision = (lpQTable->cPrecisionID & 0xf0) >> 4;
|
|
Id = lpQTable->cPrecisionID & 0x0f;
|
|
Do this instead:
|
|
*/
|
|
PrecisionID = *lpJpeg++;
|
|
Precision = (PrecisionID & 0xf0) >> 4;
|
|
Id = PrecisionID & 0x0f;
|
|
|
|
lpQTable->nNumOffsets = ThisOffset;
|
|
Index = ThisOffset;
|
|
Offset++;
|
|
while (!Done)
|
|
{
|
|
lpQTable->nNumOffsets++;
|
|
lpQTable->QOffset.OffsetList[Index++] = Offset;
|
|
MarkerLength -= ( Amount + 1 + ( QTABLE_ELEMENTS * ( Precision + 1)));
|
|
if ( MarkerLength <= 0)
|
|
Done = TRUE;
|
|
else
|
|
{
|
|
Offset += 1 + ( QTABLE_ELEMENTS * ( Precision + 1));
|
|
Amount += 1 + ( QTABLE_ELEMENTS * ( Precision + 1));
|
|
}
|
|
} /* end of while */
|
|
|
|
Amount += 1 + ( QTABLE_ELEMENTS * ( Precision + 1));
|
|
return Amount;
|
|
}
|
|
/****************************************************************************
|
|
* *
|
|
* FindHuffman find the huffman tables and put into the GFS info *
|
|
* structure *
|
|
* *
|
|
* history *
|
|
* *
|
|
* 3-may-93 jar created *
|
|
* *
|
|
****************************************************************************/
|
|
UINT FindHuffman( LPDCTABLE lpDCTable, LPACTABLE lpACTable,
|
|
LPSTR lpJpeg, UINT uSizeJpeg, UINT Components)
|
|
{
|
|
UINT TheError = 0;
|
|
UINT Offset = 0;
|
|
UINT i;
|
|
UINT IndexDC = 0;
|
|
UINT IndexAC = 0;
|
|
UINT Class = 0;
|
|
UINT ID = 0;
|
|
BOOL bDCDone[3] = {FALSE,FALSE,FALSE};
|
|
BOOL bACDone[3] = {FALSE,FALSE,FALSE};
|
|
UINT Sum;
|
|
UINT MarkerLength = 0;
|
|
BYTE FFvar = 0xff;
|
|
BYTE C4var = 0xc4;
|
|
|
|
if ( Components == 1)
|
|
bDCDone[1] = bDCDone[2] = bACDone[1] = bACDone[2] = TRUE;
|
|
|
|
while ( uSizeJpeg--)
|
|
{
|
|
Offset++;
|
|
if ( (BYTE)(*lpJpeg++) == FFvar)
|
|
{
|
|
Offset++;
|
|
uSizeJpeg--;
|
|
if ( (BYTE)(*lpJpeg++) == C4var)
|
|
{
|
|
while ( !( bDCDone[0] && bDCDone[1] && bDCDone[2] &&
|
|
bACDone[0] && bACDone[1] && bACDone[2] ))
|
|
{
|
|
if ((BYTE)(*lpJpeg) == FFvar)
|
|
{
|
|
*lpJpeg++;
|
|
*lpJpeg++;
|
|
Offset+=2;
|
|
}
|
|
MarkerLength = ((int)(*lpJpeg++) & 0x00ff) << 8;
|
|
MarkerLength = ((int)(*lpJpeg++) & 0x00ff) + MarkerLength;
|
|
Class = (*lpJpeg & 0xf0) >> 4;
|
|
ID = *lpJpeg++ & 0x0f;
|
|
Offset += 3;
|
|
|
|
if ( Class == 0) /* => DC TABLE */
|
|
{
|
|
lpDCTable->DcOffset.OffsetList[IndexDC++] = Offset;
|
|
lpDCTable->nNumOffsets++;
|
|
|
|
Sum = 0;
|
|
for ( i = 0; i < CODE_LENGTH; i++)
|
|
Sum += ((int)(*lpJpeg++) & 0x00ff);
|
|
|
|
Offset += CODE_LENGTH + Sum;
|
|
MarkerLength -= CODE_LENGTH + Sum + 1 + 2;
|
|
if ( MarkerLength <= 0)
|
|
{
|
|
bDCDone[IndexDC - 1] = TRUE;
|
|
if ( IndexDC == 2)
|
|
{
|
|
lpDCTable->DcOffset.OffsetList[IndexDC] =
|
|
lpDCTable->DcOffset.OffsetList[IndexDC-1];
|
|
|
|
lpDCTable->nNumOffsets++;
|
|
IndexDC++;
|
|
bDCDone[2] = TRUE;
|
|
}
|
|
|
|
if (!( bACDone[0] && bACDone[1] && bACDone[2]))
|
|
lpJpeg += Sum;
|
|
}
|
|
else
|
|
lpJpeg += Sum;
|
|
} /* end of the DC TABLE case */
|
|
else
|
|
{
|
|
/* this is AC Table case */
|
|
lpACTable->AcOffset.OffsetList[IndexAC++] = Offset;
|
|
lpACTable->nNumOffsets++;
|
|
|
|
Sum = 0;
|
|
|
|
for ( i = 0; i < CODE_LENGTH; i++)
|
|
Sum += ((int)(*lpJpeg++) & 0x00ff);
|
|
|
|
Offset += CODE_LENGTH + Sum;
|
|
MarkerLength -= CODE_LENGTH + Sum + 1 + 2;
|
|
if ( MarkerLength <= 0)
|
|
{
|
|
bACDone[IndexAC - 1] = TRUE;
|
|
if ( IndexAC == 2)
|
|
{
|
|
lpACTable->AcOffset.OffsetList[IndexAC] =
|
|
lpACTable->AcOffset.OffsetList[IndexAC-1];
|
|
|
|
lpACTable->nNumOffsets++;
|
|
IndexAC++;
|
|
bACDone[2] = TRUE;
|
|
}
|
|
|
|
if (!( bDCDone[0] && bDCDone[1] && bDCDone[2]))
|
|
lpJpeg += Sum;
|
|
}
|
|
else
|
|
lpJpeg += Sum;
|
|
} /* end of the AC TABLE case */
|
|
} /* end of while not done loop */
|
|
break;
|
|
} /* end of huffman table area */
|
|
} /* end of marker if */
|
|
} /* end of while loop over jpeg header */
|
|
|
|
return TheError;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* *
|
|
* BufCopy copy data between buffers *
|
|
* *
|
|
* history *
|
|
* *
|
|
* 3-may-93 jar created *
|
|
* *
|
|
****************************************************************************/
|
|
UINT BufCopy( LPSTR lpDst, LPSTR lpSrc, UINT uAmount)
|
|
{
|
|
UINT Copied = 0;
|
|
|
|
while( uAmount--)
|
|
{
|
|
*lpDst++ = *lpSrc++;
|
|
Copied++;
|
|
}
|
|
return Copied;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* *
|
|
* PrepareForJpegRead this will take care of JPEG info when we are *
|
|
* reading a JPEG file *
|
|
* *
|
|
* history *
|
|
* *
|
|
* 3-may-93 jar created *
|
|
* *
|
|
****************************************************************************/
|
|
UINT PrepareForJpegRead( HWND hWnd, lp_INFO lpGfsInfo, LP_EXP_CALL_SPEC lpCallSpec)
|
|
{
|
|
UINT TheError = 0;
|
|
DWORD dwSize;
|
|
HANDLE hTemp;
|
|
// hdl_tidbits = NULL;
|
|
LPSTR lpTemp;
|
|
// UINT Components;
|
|
// char *gfs_string = "Oi/GFS, writer";
|
|
// int gfs_string_size = 14;
|
|
// int ver_index, version_cmp;
|
|
// char gfs_version[5];
|
|
// char jpeg_ver[] = "5.01";
|
|
// int errcode = 0;
|
|
// int OldJpeg = FALSE;
|
|
|
|
/* Allocate space for software tag ascii data. */
|
|
/* KMC - (3.6) don't do this now. It isn't needed and is causing */
|
|
/* problems on the server side. Will have to fix when */
|
|
/* constructing the JPEG header is supported. */
|
|
/*
|
|
if(!(hdl_tidbits = (HANDLE) GlobalAlloc( GHND |
|
|
GMEM_NOT_BANKED, (DWORD) (lpGfsInfo->TB_SOFTWARE.cnt))))
|
|
{
|
|
TheError = FIO_GLOBAL_ALLOC_FAILED;
|
|
}
|
|
lpGfsInfo->TB_SOFTWARE.ptr = (char FAR *) GlobalLock(hdl_tidbits);
|
|
if (lpGfsInfo->TB_SOFTWARE.ptr == (LPSTR) NULL)
|
|
{
|
|
GlobalFree(hdl_tidbits);
|
|
hdl_tidbits = 0;
|
|
TheError = FIO_GLOBAL_ALLOC_FAILED;
|
|
}
|
|
*/
|
|
/* Get software tag ascii data (gfs version number) */
|
|
/*
|
|
if ((wgfsgtdata( hWnd, Infiledes, lpGfsInfo, &errcode)) <= -1)
|
|
{
|
|
TheError = errcode;
|
|
}
|
|
*/
|
|
/* Check gfs version number for old JPEG files which are obselete. */
|
|
/*
|
|
if (!TheError)
|
|
if (_fstrncmp((char FAR *)gfs_string,
|
|
lpGfsInfo->TB_SOFTWARE.ptr,
|
|
(size_t)gfs_string_size) == 0);
|
|
{
|
|
for (ver_index = 0; ver_index < 4; ++ver_index)
|
|
gfs_version[ver_index] = lpGfsInfo->TB_SOFTWARE.ptr[20+ver_index];
|
|
gfs_version[ver_index] = '\0';
|
|
version_cmp = lstrcmp(gfs_version,jpeg_ver);
|
|
if (version_cmp < 0)
|
|
OldJpeg = TRUE;
|
|
}
|
|
if (hdl_tidbits)
|
|
{
|
|
GlobalUnlock(hdl_tidbits);
|
|
GlobalFree(hdl_tidbits);
|
|
}
|
|
*/
|
|
if (!TheError)
|
|
{
|
|
if ( lpGfsInfo->img_cmpr.type == JPEG2)
|
|
{
|
|
dwSize = lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg_buffer_size;
|
|
if ( dwSize > 0)
|
|
{
|
|
/* we've got a jpeg header */
|
|
lpCallSpec->wiisfio.JpegData.uJpegHeaderSwitch = JPEGHEADER;
|
|
lpCallSpec->wiisfio.JpegData.JpegInter.dwJpegInterchangeSize = dwSize;
|
|
hTemp = GlobalAlloc( GMEM_ZEROINIT, dwSize);
|
|
if ( hTemp)
|
|
{
|
|
lpTemp = GlobalLock( hTemp);
|
|
if ( lpTemp)
|
|
{
|
|
BufCopy(lpTemp, (LPSTR)(lpGfsInfo->img_cmpr.opts.jpeg_info_ptr->jpeg_buffer),(UINT)dwSize);
|
|
lpCallSpec->wiisfio.JpegData.JpegInter.hJpegInterchange = hTemp;
|
|
lpCallSpec->wiisfio.JpegData.JpegInter.lpJpegInterchange = lpTemp;
|
|
}
|
|
else
|
|
TheError = JPEG_NOMEMORY;
|
|
}
|
|
else
|
|
TheError = JPEG_NOMEMORY;
|
|
} /* end of if on size */
|
|
else
|
|
{
|
|
/* oh no! we've got to construct a jpeg header */
|
|
/* the possibility of this happening is very, very, very slight */
|
|
/* lpCallSpec->wiisfio.JpegData.uJpegHeaderSwitch = JPEGTABLE; */
|
|
|
|
/* first the restart interval */
|
|
/*
|
|
lpCallSpec->wiisfio.JpegData.JpegTables.restart_marker =
|
|
lpGfsInfo->img_cmpr.jpeg.JpegRestartInterval;
|
|
*/
|
|
/* q-table */
|
|
/* Components = lpGfsInfo->img_cmpr.jpeg.JpegQTable.nComponents; */
|
|
/*
|
|
for ( Index = 0; Index < Components; Index++)
|
|
{
|
|
lpCallSpec->wiisfio.JpegData.JpegTables.length_q[Index] =
|
|
lpGfsInfo->img_cmpr.jpeg.JpegQTable.nLength + 1;
|
|
|
|
lpCallSpec->wiisfio.JpegData.JpegTables.qtables[Index] = ...;
|
|
}
|
|
*/
|
|
/* we must also take care of dc and ac tables ... */
|
|
/* TheError = JPEG_NOTYET; */
|
|
} /* end of trying to construct our header */
|
|
} /* end of JPEG2 if test */
|
|
else if ( lpGfsInfo->img_cmpr.type == JPEG)
|
|
{
|
|
lpCallSpec->wiisfio.JpegData.uJpegHeaderSwitch = 0;
|
|
lpCallSpec->wiisfio.JpegData.JpegInter.dwJpegInterchangeSize = 0;
|
|
lpCallSpec->wiisfio.JpegData.JpegInter.hJpegInterchange = 0;
|
|
lpCallSpec->wiisfio.JpegData.JpegInter.lpJpegInterchange = 0;
|
|
}
|
|
} /* end of error thing */
|
|
return TheError;
|
|
}
|
|
|
|
/* NEW FUNCTION: (3.7)
|
|
|
|
FUNCTION: WritePcx
|
|
|
|
DESCRIPTION:
|
|
The following function is responsible for passing on data to be written
|
|
out as a PCX file through wgfswrite.
|
|
|
|
INPUT:
|
|
HWND hWnd: Handle to calling window.
|
|
LPCXDATA lpcxdata: Contains info about the data.
|
|
LP_FIO_DATA pdata: Contains more info about data (including GFS info).
|
|
LPSTR lpSrc: Pointer to actual data to be written out.
|
|
LPINT lpLines: Pointer to # of data lines to be written.
|
|
BOOL done: FALSE if more writes to follow. TRUE if last write.
|
|
|
|
OUTPUT:
|
|
Status of the write. Errorcode returned if unsuccessful.
|
|
*/
|
|
|
|
WORD WritePcx( HWND hWnd, LPCXDATA lpcxdata, LP_FIO_DATA pdata,
|
|
LPSTR lpSrc, LPINT lpLines, BOOL done )
|
|
{
|
|
WORD status = 0;
|
|
int byteswritten = 0;
|
|
int errcode = 0;
|
|
lp_INFO lpGFSInfo;
|
|
short Lines;
|
|
short BufferLines;
|
|
short BufferBytes;
|
|
short DestWidth;
|
|
short SrcWidth;
|
|
|
|
lpGFSInfo = (lp_INFO)GlobalLock ( pdata->hGFS_info );
|
|
if ( *lpLines == 0 )
|
|
return 0;
|
|
Lines = *lpLines;
|
|
DestWidth = lpGFSInfo->_file.fmt.pcx.bpl;
|
|
SrcWidth = lpcxdata->BufferByteWidth;
|
|
|
|
if ( !pdata->start_byte ) /* if this is first write */
|
|
pdata->start_byte = 1;
|
|
|
|
BufferLines = Lines;
|
|
BufferBytes = DestWidth * BufferLines;
|
|
|
|
if ((byteswritten = (int)wgfswrite( hWnd, pdata->filedes, lpSrc,
|
|
(unsigned long) BufferBytes, (unsigned short)pdata->pgnum,
|
|
(char)done, &errcode)) < 0)
|
|
{
|
|
status = errcode;
|
|
}
|
|
GlobalUnlock ( pdata->hGFS_info );
|
|
return(status);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* *
|
|
* GetCompRowsPerStrip *
|
|
* *
|
|
****************************************************************************/
|
|
int FAR PASCAL GetCompRowsPerStrip (ImHeight, ImWidth, Itype, CompressType,
|
|
lpRowsPerStrip)
|
|
UINT ImHeight;
|
|
UINT ImWidth;
|
|
int Itype;
|
|
UINT CompressType;
|
|
LPUINT lpRowsPerStrip;
|
|
{
|
|
UINT widthinbytes;
|
|
int error = WANG_CAN_DO_IT;
|
|
|
|
/* lock data segment */
|
|
|
|
switch (Itype)
|
|
{
|
|
case ITYPE_BI_LEVEL :
|
|
widthinbytes = (ImWidth + 7) >> 3;
|
|
break;
|
|
|
|
case ITYPE_PAL4 :
|
|
case ITYPE_GRAY4 :
|
|
widthinbytes = (ImWidth + 1) >> 1;
|
|
break;
|
|
|
|
case ITYPE_GRAY8 :
|
|
case ITYPE_PAL8 :
|
|
widthinbytes = ImWidth;
|
|
break;
|
|
|
|
case ITYPE_RGB24 :
|
|
case ITYPE_BGR24 :
|
|
widthinbytes = ImWidth * 3;
|
|
break;
|
|
|
|
case ITYPE_NONE :
|
|
default :
|
|
*lpRowsPerStrip = 0;
|
|
error = OICOMEXIMAGETYPEERROR;
|
|
goto LASERDATA;
|
|
}
|
|
|
|
switch (CompressType&0x00FF)
|
|
{
|
|
case FIO_OD :
|
|
case FIO_1D :
|
|
case FIO_2D :
|
|
case FIO_PACKED :
|
|
case FIO_LZW :
|
|
*lpRowsPerStrip = (UINT)(WIISFIO_MAX_BUFF_SIZE / widthinbytes);
|
|
break;
|
|
|
|
case FIO_TJPEG :
|
|
// *lpRowsPerStrip = (JPEG_BUFF_SIZE / widthinbytes);
|
|
*lpRowsPerStrip = (UINT)(WANG_SIZE / widthinbytes);
|
|
*lpRowsPerStrip = (*lpRowsPerStrip >> 3) << 3;/* round dwn to nearest 8*/
|
|
/* check & set minimum for JPEG */
|
|
if (*lpRowsPerStrip == 0) *lpRowsPerStrip = JPEG_REQUIRES_8_PIXELS;
|
|
break;
|
|
|
|
case FIO_WAVELET :
|
|
case FIO_FRACTAL :
|
|
case FIO_DPCM :
|
|
default :
|
|
*lpRowsPerStrip = 0;
|
|
error = OICOMEXUNSUPPORTED;
|
|
break;
|
|
}
|
|
LASERDATA :
|
|
return (error);
|
|
}
|