Beispiel #1
0
static BOOL DLL_CALLCONV
Validate(FreeImageIO *io, fi_handle handle) {
	DWORD type = 0;

	// read chunk type
	io->read_proc(&type, 4, 1, handle);
#ifndef FREEIMAGE_BIGENDIAN
	SwapLong(&type);
#endif

	if(type != ID_FORM)
		return FALSE;
		
	// skip 4 bytes
	io->read_proc(&type, 4, 1, handle);

	// read chunk type
	io->read_proc(&type, 4, 1, handle);
#ifndef FREEIMAGE_BIGENDIAN
	SwapLong(&type);
#endif

	// File format : ID_PBM = Packed Bitmap, ID_ILBM = Interleaved Bitmap
	return (type == ID_ILBM) || (type == ID_PBM);
}
Beispiel #2
0
//
// R_LoadVoxelResource
//
// Loads a .vox-format voxel model into an rvoxelmodel_t structure.
//
rvoxelmodel_t *R_LoadVoxelResource(int lumpnum)
{
   rvoxelmodel_t *model = NULL;
   byte *buffer = NULL, *rover = NULL;
   int lumplen  = W_LumpLength(lumpnum);
   int xsize, ysize, zsize, voxsize;
   int i;

   // minimum size test
   if(lumplen < 12)
      return NULL;

   // cache the lump
   rover = buffer = (byte *)(wGlobalDir.cacheLumpNum(lumpnum, PU_STATIC));

   // get sizes
   xsize = SwapLong(*(int32_t *)rover);
   rover += 4;
   ysize = SwapLong(*(int32_t *)rover);
   rover += 4;
   zsize = SwapLong(*(int32_t *)rover);
   rover += 4;

   voxsize = xsize*ysize*zsize;

   // true size test
   if(lumplen < 12 + voxsize + 768)
   {
      Z_ChangeTag(buffer, PU_CACHE);
      return NULL;
   }

   // create the model and its voxel buffer
   model         = (rvoxelmodel_t *)(Z_Calloc(1,       sizeof(rvoxelmodel_t), PU_RENDERER, NULL));
   model->voxels =          (byte *)(Z_Calloc(voxsize, sizeof(byte),          PU_RENDERER, NULL));

   model->xsize = xsize;
   model->ysize = ysize;
   model->zsize = zsize;

   // get voxel data
   memcpy(model->voxels, rover, voxsize);
   rover += voxsize;

   // get original palette data
   memcpy(model->palette, rover, 768);

   // transform palette data into 0-255 range
   // TODO: verify color component order
   for(i = 0; i < 768; i++)
      model->palette[i] <<= 2;

   // TODO: run V_FindBestColor to create translated palette?

   // done with lump
   Z_ChangeTag(buffer, PU_CACHE);

   return model;
}
Beispiel #3
0
static void
SwapFileHeader(BITMAPFILEHEADER *header) {
	SwapShort(&header->bfType);
  	SwapLong(&header->bfSize);
  	SwapShort(&header->bfReserved1);
  	SwapShort(&header->bfReserved2);
	SwapLong(&header->bfOffBits);
}
Beispiel #4
0
static void 
SwapHeader(SGIHeader *header) {
	SwapShort(&header->magic);
	SwapShort(&header->dimension);
	SwapShort(&header->xsize);
	SwapShort(&header->ysize);
	SwapShort(&header->zsize);
	SwapLong((DWORD*)&header->pixmin);
	SwapLong((DWORD*)&header->pixmax);
	SwapLong((DWORD*)&header->colormap);
}
Beispiel #5
0
static void F_DrawPatchCol(int x, patch_t* patch, int col)
{
  const column_t* column =
    (const column_t*)((byte*) patch + SwapLong(patch->columnofs[col]));

  // step through the posts in a column
  if (hires)
    while (column->topdelta != 0xff)
    {
      byte* desttop = screens[0] + x * 2;
      const byte* source = (byte*) column + 3;
      byte* dest = desttop + column->topdelta * SCREENWIDTH * 4;
      int count = column->length;
      for (; count--; dest += SCREENWIDTH * 4)
        dest[0] = dest[SCREENWIDTH * 2] = dest[1] = dest[SCREENWIDTH * 2 + 1] =
                                            *source++;
      column = (column_t*)(source + 1);
    }
  else
    while (column->topdelta != 0xff)
    {
      byte* desttop = screens[0] + x;
      const byte* source = (byte*) column + 3;
      byte* dest = desttop + column->topdelta * SCREENWIDTH;
      int count = column->length;
      for (; count--; dest += SCREENWIDTH)
        * dest = *source++;
      column = (column_t*)(source + 1);
    }
}
Beispiel #6
0
static void
SwapCoreHeader(BITMAPCOREHEADER *header) {
	SwapLong(&header->bcSize);
	SwapShort(&header->bcWidth);
	SwapShort(&header->bcHeight);
	SwapShort(&header->bcPlanes);
	SwapShort(&header->bcBitCnt);
}
Beispiel #7
0
static void
SwapOS21XHeader(BITMAPINFOOS2_1X_HEADER *header) {
	SwapLong(&header->biSize);
	SwapShort(&header->biWidth);
	SwapShort(&header->biHeight);
	SwapShort(&header->biPlanes);
	SwapShort(&header->biBitCount);
}
Beispiel #8
0
/********************************************************************
*	 ConvertUnsignedLongBuffer
********************************************************************/
void ConvertUnsignedLongBuffer(unsigned long *buffer, unsigned long nbLongs)
{
	while (nbLongs-- > 0)
	{
		*buffer = SwapLong(*buffer);
		buffer++;
	}
}
Beispiel #9
0
static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	if (handle != NULL) {
		BITMAPFILEHEADER bitmapfileheader;
		DWORD type = 0;
		BYTE magic[2];

		// we use this offset value to make seemingly absolute seeks relative in the file
		
		long offset_in_file = io->tell_proc(handle);

		// read the magic

		io->read_proc(&magic, sizeof(magic), 1, handle);

		// compare the magic with the number we know

		// somebody put a comment here explaining the purpose of this loop
		while (memcmp(&magic, "BA", 2) == 0) {
			io->read_proc(&bitmapfileheader.bfSize, sizeof(DWORD), 1, handle);
			io->read_proc(&bitmapfileheader.bfReserved1, sizeof(WORD), 1, handle);
			io->read_proc(&bitmapfileheader.bfReserved2, sizeof(WORD), 1, handle);
			io->read_proc(&bitmapfileheader.bfOffBits, sizeof(DWORD), 1, handle);
			io->read_proc(&magic, sizeof(magic), 1, handle);
		}

		// read the fileheader

		io->seek_proc(handle, 0 - sizeof(magic), SEEK_CUR);
		io->read_proc(&bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
		SwapFileHeader(&bitmapfileheader);
#endif

		// read the first byte of the infoheader

		io->read_proc(&type, sizeof(DWORD), 1, handle);
		io->seek_proc(handle, 0 - sizeof(DWORD), SEEK_CUR);
#ifdef FREEIMAGE_BIGENDIAN
		SwapLong(&type);
#endif

		// call the appropriate load function for the found bitmap type

		if (type == 40)
			return LoadWindowsBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits);
		
		if (type == 12)
			return LoadOS21XBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits);

		if (type <= 64)
			return LoadOS22XBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits);

		FreeImage_OutputMessageProc(s_format_id, "unknown bmp subtype with id %d", type);
	}

	return NULL;
}
Beispiel #10
0
static void
SwapInfoHeader(BITMAPINFOHEADER *header) {
	SwapLong(&header->biSize);
	SwapLong((DWORD *)&header->biWidth);
	SwapLong((DWORD *)&header->biHeight);
	SwapShort(&header->biPlanes);
	SwapShort(&header->biBitCount);
	SwapLong(&header->biCompression);
	SwapLong(&header->biSizeImage);
	SwapLong((DWORD *)&header->biXPelsPerMeter);
	SwapLong((DWORD *)&header->biYPelsPerMeter);
	SwapLong(&header->biClrUsed);
	SwapLong(&header->biClrImportant);
}
Beispiel #11
0
/********************************************************************
*	 ConvertUnsignedLongBuffer
********************************************************************/
void ConvertUnsignedLongBuffer(void * ptr, size_t length)
{
    uint32_t * buffer = (uint32_t *)ptr;
    uint32_t nbLongs = (uint32_t)(length / sizeof(uint32_t));

	while (nbLongs-- > 0)
	{
		*buffer = SwapLong(*buffer);
		buffer++;
	}
}
Beispiel #12
0
static void
SwapExtensionArea(TGAEXTENSIONAREA *ex) {
	SwapShort(&ex->extension_size);
	SwapShort(&ex->datetime_stamp[0]);
	SwapShort(&ex->datetime_stamp[1]);
	SwapShort(&ex->datetime_stamp[2]);
	SwapShort(&ex->datetime_stamp[3]);
	SwapShort(&ex->datetime_stamp[4]);
	SwapShort(&ex->datetime_stamp[5]);
	SwapShort(&ex->job_time[0]);
	SwapShort(&ex->job_time[1]);
	SwapShort(&ex->job_time[2]);
	SwapLong (&ex->key_color);
	SwapShort(&ex->pixel_aspect_ratio[0]);
	SwapShort(&ex->pixel_aspect_ratio[1]);
	SwapShort(&ex->gamma_value[0]);
	SwapShort(&ex->gamma_value[1]);
	SwapLong (&ex->color_correction_offset);
	SwapLong (&ex->postage_stamp_offset);
	SwapLong (&ex->scan_line_offset);
}
long input_long_pci_config(int nHandle, long *p)
{
	CARRIERDATA_STRUCT* pCarrier;	/*  local carrier */
	unsigned long data[3];

	pCarrier = GetCarrier(nHandle);
	if(pCarrier == NULL)
		return 0;

        /* place address to read from in data[0]; */
        data[0] = (unsigned long) p;
        /* place device instance to read from @ data[1]; */
        data[1] = (unsigned long) pCarrier->nDevInstance;
        /* pram3 = function: 1=read8bits,2=read16bits,4=read32bits, 0x40=readconfig32bits */
        read( pCarrier->nCarrierDeviceHandle, &data[0], 0x40 );
        return(  SwapLong( (long)data[1] ) );
}
void output_long_pci_config(int nHandle, long *p, long v)
{
	CARRIERDATA_STRUCT* pCarrier;	/*  local carrier */
	unsigned long data[3];

	pCarrier = GetCarrier(nHandle);
	if(pCarrier == NULL)
		return;

        /* place address to write data[0]; */
        data[0] = (unsigned long) p;
        /* place value to write @ address data[1]; */
        data[1] = (unsigned long) SwapLong( v );
        /* place device instance  @ data[2]; */
        data[2] = (unsigned long) pCarrier->nDevInstance;
        /* pram3 = function: 1=write8bits,2=write16bits,4=write32bits, 0x40=writeconfig32bits */
        write( pCarrier->nCarrierDeviceHandle, &data[0], 0x40 );
}
void output_long(int nHandle, long *p, long v)
{
	CARRIERDATA_STRUCT* pCarrier;	/*  local carrier */
	unsigned long data[2];

	pCarrier = GetCarrier(nHandle);
	if(pCarrier == NULL)
		return;

	if( p )
	{
           /* place address to write word in data [0]; */
           data[0] = (unsigned long) p;
           /* place value to write @ address data [1]; */
           data[1] = (unsigned long) SwapLong( v );
           /* pram3 = function: 1=write8bits,2=write16bits,4=write32bits */
           write( pCarrier->nCarrierDeviceHandle, &data[0], 4 );
	}
}
long input_long(int nHandle, long *p)
{
	CARRIERDATA_STRUCT* pCarrier;	/*  local carrier */
	unsigned long data[2];

	pCarrier = GetCarrier(nHandle);
	if(pCarrier == NULL)
		return 0;

	if( p )
	{
           /* place address to read word from in data [0]; */
           data[0] = (unsigned long) p;
           /* pram3 = function: 1=read8bits,2=read16bits,4=read32bits */
           read( pCarrier->nCarrierDeviceHandle, &data[0], 4 );
           return(  SwapLong( (long)data[1] ) );
	}
	return((long)0);
}
Beispiel #17
0
//
// ACS_readOpACS0
//
static int32_t ACS_readOpACS0(acs0_tracer_t *tracer, uint32_t *opSize, uint32_t index)
{
   int32_t op;

   if(tracer->compressed)
   {
      *opSize = 1;
      if((op = tracer->data[index]) >= 240)
      {
         ++*opSize;
         op = 240 + ((op - 240) << 8) + tracer->data[index + 1];
      }
   }
   else
   {
      *opSize = 4;
      op = SwapLong(*(int32_t *)(tracer->data + index));
   }

   return op;
}
Beispiel #18
0
////////////////////////////////////////////////////////////////////////////
//
// LoadLIBShape()
//
int LoadLIBShape(char *SLIB_Filename, char *Filename,struct Shape *SHP)
{
	#define CHUNK(Name)	(*ptr == *Name) &&			\
								(*(ptr+1) == *(Name+1)) &&	\
								(*(ptr+2) == *(Name+2)) &&	\
								(*(ptr+3) == *(Name+3))


	int RT_CODE;
	FILE *fp;
	char CHUNK[5];
	char far *ptr;
	memptr IFFfile = NULL;
	unsigned long FileLen, size, ChunkLen;
	int loop;


	RT_CODE = 1;

	// Decompress to ram and return ptr to data and return len of data in
	//	passed variable...

	if (!LoadLIBFile(SLIB_Filename,Filename,&IFFfile))
		Quit("Error Loading Compressed lib shape!");

	// Evaluate the file
	//
	ptr = MK_FP(IFFfile,0);
	if (!CHUNK("FORM"))
		goto EXIT_FUNC;
	ptr += 4;

	FileLen = *(long far *)ptr;
	SwapLong((long far *)&FileLen);
	ptr += 4;

	if (!CHUNK("ILBM"))
		goto EXIT_FUNC;
	ptr += 4;

	FileLen += 4;
	while (FileLen)
	{
		ChunkLen = *(long far *)(ptr+4);
		SwapLong((long far *)&ChunkLen);
		ChunkLen = (ChunkLen+1) & 0xFFFFFFFE;

		if (CHUNK("BMHD"))
		{
			ptr += 8;
			SHP->bmHdr.w = ((struct BitMapHeader far *)ptr)->w;
			SHP->bmHdr.h = ((struct BitMapHeader far *)ptr)->h;
			SHP->bmHdr.x = ((struct BitMapHeader far *)ptr)->x;
			SHP->bmHdr.y = ((struct BitMapHeader far *)ptr)->y;
			SHP->bmHdr.d = ((struct BitMapHeader far *)ptr)->d;
			SHP->bmHdr.trans = ((struct BitMapHeader far *)ptr)->trans;
			SHP->bmHdr.comp = ((struct BitMapHeader far *)ptr)->comp;
			SHP->bmHdr.pad = ((struct BitMapHeader far *)ptr)->pad;
			SwapWord(&SHP->bmHdr.w);
			SwapWord(&SHP->bmHdr.h);
			SwapWord(&SHP->bmHdr.x);
			SwapWord(&SHP->bmHdr.y);
			ptr += ChunkLen;
		}
		else
		if (CHUNK("BODY"))
		{
			ptr += 4;
			size = *((long far *)ptr);
			ptr += 4;
			SwapLong((long far *)&size);
			SHP->BPR = (SHP->bmHdr.w+7) >> 3;
			MM_GetPtr(&SHP->Data,size);
			if (!SHP->Data)
				goto EXIT_FUNC;
			movedata(FP_SEG(ptr),FP_OFF(ptr),FP_SEG(SHP->Data),0,size);
			ptr += ChunkLen;

			break;
		}
		else
Beispiel #19
0
static void
SwapFooter(TGAFOOTER *footer) {
	SwapLong(&footer->extension_offset);
	SwapLong(&footer->developer_offset);
}
Beispiel #20
0
FIBITMAP* psdParser::ReadImageData(FreeImageIO *io, fi_handle handle) {
	FIBITMAP *Bitmap = NULL;

	if(handle != NULL) {
		BYTE ShortValue[2];
		int n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
		short nCompression = (short)psdGetValue( ShortValue, sizeof(ShortValue) );
		
		switch ( nCompression ) {
			case PSD_COMPRESSION_NONE: // raw data
			{
				int nWidth = _headerInfo._Width;
				int nHeight = _headerInfo._Height;
				int bytes = _headerInfo._BitsPerPixel / 8;

				int nPixels = nWidth * nHeight;
				int nTotalBytes = nPixels * bytes * _headerInfo._Channels;

				if(_headerInfo._BitsPerPixel == 1) {
					// special case for PSD_BITMAP mode
					bytes = 1;
					nWidth = (nWidth + 7) / 8;
					nWidth = ( nWidth > 0 ) ? nWidth : 1;
					nPixels = nWidth * nHeight;
					nTotalBytes = nWidth * nHeight;
				}
				
				BYTE * plData = 0;
				BYTE * plPixel = 0;
				
				int nBytes = 0;

				switch (_headerInfo._ColourMode) {
					case PSD_BITMAP:
					{				
						plData = new BYTE [nTotalBytes];
						plPixel = new BYTE [bytes];
						
						while(nBytes < nTotalBytes) {
							n = (int)io->read_proc(plPixel, bytes, 1, handle);
							memcpy(plData+nBytes, plPixel, bytes );
							nBytes += n * bytes;
						}
						SAFE_DELETE_ARRAY(plPixel);
					}
					break;

					case PSD_INDEXED: // Indexed
					{
						assert( (-1 != _ColourCount) && (0 < _ColourCount) );
						assert( NULL != _colourModeData._plColourData );
						
						plData = new BYTE [nTotalBytes];
						plPixel = new BYTE [bytes];
						
						while(nBytes < nTotalBytes) {
							n = (int)io->read_proc(plPixel, bytes, 1, handle);
							memcpy(plData+nBytes, plPixel, bytes );
							nBytes += n * bytes;
						}
						SAFE_DELETE_ARRAY(plPixel);
					}
					break;
					
					case PSD_GRAYSCALE: // Grayscale
					case PSD_DUOTONE: // Duotone
					case PSD_RGB: // RGB
					{
						plData = new BYTE [nTotalBytes];
						plPixel = new BYTE [bytes];
						int nPixelCounter = 0;
						int nChannels = _headerInfo._Channels;
						
						for(int c = 0; c < nChannels; c++) {
							nPixelCounter = c * bytes;
							for(int nPos = 0; nPos < nPixels; ++nPos) {
								n = (int)io->read_proc(plPixel, bytes, 1, handle);
								if(n == 0) {
									break;
								}								
								if(2 == bytes) { 
									// swap for uint16
									SwapShort((WORD*)&plPixel[0]);
								} else if(4 == bytes) {
									// swap for float
									SwapLong((DWORD*)&plPixel[0]);
								}
								memcpy( plData + nPixelCounter, plPixel, bytes );
								nBytes += n * bytes;
								nPixelCounter += nChannels*bytes;
							}
						}
						SAFE_DELETE_ARRAY(plPixel);
					}
					break;
					
					case PSD_CMYK: // CMYK
					case PSD_MULTICHANNEL: // Multichannel
					{
						plPixel = new BYTE[bytes];
						plData = new BYTE[nTotalBytes];
						
						int nPixelCounter = 0;
						for (int c=0; c<_headerInfo._Channels; c++) {
							nPixelCounter = c*bytes;
							for ( int nPos = 0; nPos < nPixels; ++nPos ) {
								n = (int)io->read_proc(plPixel, bytes, 1, handle);
								if(n == 0) {
									break;
								}
								memcpy(plData + nPixelCounter, plPixel, bytes );
								nBytes += n * bytes;
								
								nPixelCounter += _headerInfo._Channels*bytes;
							}
						}
						SAFE_DELETE_ARRAY(plPixel);
					}
					break;
					
					case PSD_LAB: // Lab
					{
						plPixel = new BYTE[bytes];
						plData = new BYTE[nTotalBytes];
						int nPixelCounter = 0;
						for(int c = 0; c < 3; c++) {
							nPixelCounter = c*bytes;
							for ( int nPos = 0; nPos < nPixels; ++nPos ) {
								n = (int)io->read_proc(plPixel, bytes, 1, handle);
								if(n == 0) {
									break;
								}
								memcpy(plData + nPixelCounter, plPixel, bytes);
								nBytes += n * bytes;
								nPixelCounter += 3*bytes;
							}
						}
						SAFE_DELETE_ARRAY(plPixel);
					}
					break;
				}
				
				assert( nBytes == nTotalBytes );
				if (nBytes == nTotalBytes) {
					if (plData) {
						switch (_headerInfo._BitsPerPixel) {
							case 1: 						
							case 8: 
							case 16:
							case 32:
								Bitmap = ProcessBuffer(plData);
								break;
								
							default: // Unsupported 
								break;
						}
					}
				}

				SAFE_DELETE_ARRAY(plData);
			}
			break;
			
			
			case PSD_COMPRESSION_RLE: // RLE compression
			{
				int nWidth = _headerInfo._Width;
				int nHeight = _headerInfo._Height;
				int bytes = _headerInfo._BitsPerPixel / 8;
				
				int nPixels = nWidth * nHeight;
				int nTotalBytes = nPixels * bytes * _headerInfo._Channels;

				if(_headerInfo._BitsPerPixel == 1) {
					// special case for PSD_BITMAP mode
					bytes = 1;
					nWidth = (nWidth + 7) / 8;
					nWidth = ( nWidth > 0 ) ? nWidth : 1;
					nPixels = nWidth * nHeight;
					nTotalBytes = nWidth * nHeight;
				}
				
				BYTE * plData = new BYTE[nTotalBytes];
				BYTE * p = plData;
				int nValue = 0;
				
				BYTE ByteValue[1];
				
				int Count = 0;
				
				// The RLE-compressed data is preceeded by a 2-byte data count for each row in the data,
				// which we're going to just skip.
				io->seek_proc(handle, nHeight * _headerInfo._Channels * 2, SEEK_CUR);
				
				for (int channel = 0; channel < _headerInfo._Channels; channel++) {
					// Read the RLE data.
					Count = 0;
					while (Count < nPixels) {
						io->read_proc(&ByteValue, sizeof(ByteValue), 1, handle);
						
						int len = psdGetValue( ByteValue, sizeof(ByteValue) );
						if ( 128 > len ) {
							len++;
							Count += len;
							
							while (len) {
								io->read_proc(&ByteValue, sizeof(ByteValue), 1, handle);
								nValue = psdGetValue( ByteValue, sizeof(ByteValue) );
								*p = (BYTE)nValue;
								p += sizeof(ByteValue);
								len--;
							}
						}
						else if ( 128 < len ) {
							// Next -len+1 bytes in the dest are replicated from next source byte.
							// (Interpret len as a negative 8-bit int.)
							len ^= 0x0FF;
							len += 2;
							io->read_proc(&ByteValue, sizeof(ByteValue), 1, handle);
							
							nValue = psdGetValue( ByteValue, sizeof(ByteValue) );
							Count += len;
							while (len) {
								*p = (BYTE)nValue;
								p += sizeof(ByteValue);
								len--;
							}
						}
						else if ( 128 == len ) {
							// Do nothing
						}
					}
				}
				
				BYTE * prSource = plData;
				BYTE * plDest = new BYTE[nTotalBytes];
				memset(plDest, 254, nTotalBytes);
				
				int nPixelCounter = 0;
				for(int c=0; c<_headerInfo._Channels; c++) {
					nPixelCounter = c*bytes;
					for (int nPos = 0; nPos<nPixels; ++nPos) {
						memcpy( plDest + nPixelCounter, prSource, bytes );
						prSource++;
						nPixelCounter += _headerInfo._Channels*bytes;
					}
				}
				SAFE_DELETE_ARRAY(plData);
				
				if (plDest) {
					switch (_headerInfo._BitsPerPixel) {
						case 1: 	
						case 8: 
						case 16:
							Bitmap = ProcessBuffer(plDest);
							break;
							
						default: // Unsupported format
							break;
					}
				}
				SAFE_DELETE_ARRAY(plDest);
			}
			break;

			case 2: // ZIP without prediction, no specification
				break;
				
			case 3: // ZIP with prediction, no specification
				break;
				
			default: // Unknown format
				break;
		}
	}
	
	return Bitmap;

} 
Beispiel #21
0
//
// ACS_LoadScriptACS0
//
void ACS_LoadScriptACS0(ACSVM *vm, WadDirectory *dir, int lump, byte *data)
{
   uint32_t lumpAvail; // Used in bounds checking.
   uint32_t lumpLength = dir->lumpLength(lump);
   int32_t *rover;
   uint32_t tableIndex;

   // Header + table index + script count + string count = 16 bytes.
   if (lumpLength < 16) return;
   lumpAvail = lumpLength - 16;

   rover = (int32_t *)data + 1;

   // Find script table.
   tableIndex = SwapLong(*rover);

   // Aha, but there might really be an ACSE header here!
   if(tableIndex >= 8 && tableIndex <= lumpLength)
   {
      uint32_t fakeHeader = SwapULong(*(uint32_t *)(data + tableIndex - 4));

      if(fakeHeader == ACS_CHUNKID('A', 'C', 'S', 'E'))
      {
         ACS_LoadScriptACSE(vm, dir, lump, data, tableIndex - 8);
         return;
      }
      else if(fakeHeader == ACS_CHUNKID('A', 'C', 'S', 'e'))
      {
         ACS_LoadScriptACSe(vm, dir, lump, data, tableIndex - 8);
         return;
      }
   }

   // At the index there must be at least the script count and string count.
   // Subtracting from lumpLength instead of adding to tableIndex in case the
   // latter would cause an overflow.
   if (tableIndex > lumpLength - 8) return;

   rover = (int32_t *)(data + tableIndex);

   // Read script count.
   vm->numScripts = SwapLong(*rover++);

   // Verify that there is enough space for the given number of scripts.
   if (vm->numScripts * 12 > lumpAvail) return;
   lumpAvail -= vm->numScripts * 12;

   // Also verify that the string count will be inside the lump.
   if (tableIndex + 8 > lumpLength - (vm->numScripts * 12)) return;
   tableIndex += 8 + (vm->numScripts * 12);

   // Read scripts.
   vm->scripts = estructalloctag(ACSScript, vm->numScripts, PU_LEVEL);

   for(ACSScript *itr = vm->scripts, *end = itr + vm->numScripts; itr != end; ++itr)
   {
      itr->number    = SwapLong(*rover++);
      itr->codeIndex = SwapLong(*rover++);
      itr->numArgs   = SwapLong(*rover++);

      itr->numVars   = ACS_NUM_LOCALVARS;
      itr->vm        = vm;

      if(itr->number >= 1000)
      {
         itr->type = ACS_STYPE_OPEN;
         itr->number -= 1000;
      }
      else
         itr->type = ACS_STYPE_CLOSED;
   }

   // Read string count.
   vm->numStrings = SwapLong(*rover++);

   // Again, verify that there is enough space for the table first.
   if (vm->numStrings * 4 > lumpAvail) return;
   lumpAvail -= vm->numStrings * 4;

   // This time, just verify the end of the table is in bounds.
   if (tableIndex > lumpLength - (vm->numStrings * 4)) return;

   // Read strings.
   vm->strings = (uint32_t *)Z_Malloc(vm->numStrings * sizeof(uint32_t), PU_LEVEL, NULL);

   for(uint32_t *itr = vm->strings, *end = itr + vm->numStrings; itr != end; ++itr)
   {
      tableIndex = SwapLong(*rover++);

      if (tableIndex < lumpLength)
         *itr = ACS_LoadStringACS0(data + tableIndex, data + lumpLength);
      else
         *itr = ACS_LoadStringACS0(data + lumpLength, data + lumpLength);
   }

   // The first part of the global string table must match VM-0 for compatibility.
   if(vm->id == 0 && ACSVM::GlobalNumStrings < vm->numStrings)
      vm->addStrings();

   // Read code.
   ACS_LoadScriptCodeACS0(vm, data, lumpLength, false);

   vm->loaded = true;
}
Beispiel #22
0
//
// WadDirectory::addMemoryWad
//
// haleyjd 10/31/12: Add an id wadlink file stored in memory into the directory.
//
bool WadDirectory::addMemoryWad(openwad_t &openData, wfileadd_t &addInfo,
                                int startlump)
{
    // haleyjd 04/07/11
    wadinfo_t    header;
    ZAutoBuffer  fileinfo2free; // killough
    filelump_t  *fileinfo;
    size_t       length;
    size_t       info_offset;
    lumpinfo_t  *lump_p;

    // Read in the header
    memcpy(&header, openData.base, sizeof(header));

    header.numlumps     = SwapLong(header.numlumps);
    header.infotableofs = SwapLong(header.infotableofs);

    // allocate enough fileinfo_t's to hold the wad directory
    length = header.numlumps * sizeof(filelump_t);

    fileinfo2free.alloc(length, true);              // killough
    fileinfo = fileinfo2free.getAs<filelump_t *>();

    info_offset = static_cast<size_t>(header.infotableofs);

    // seek to the directory
    if(info_offset + header.numlumps * sizeof(filelump_t)  > openData.size)
    {
        if(addInfo.flags & WFA_OPENFAILFATAL)
            I_Error("Failed reading directory for in-memory file\n");
        else
        {
            printf("Failed reading directory for in-memory file\n");
            return false;
        }
    }

    // read it in.
    byte *directoryBase = static_cast<byte *>(openData.base) + info_offset;
    memcpy(fileinfo, directoryBase, header.numlumps * sizeof(filelump_t));

    // Add lumpinfo_t's for all lumps in the wad file
    lump_p = reAllocLumpInfo(header.numlumps, startlump);

    // Merge into the directory
    for(int i = startlump; i < numlumps; i++, lump_p++, fileinfo++)
    {
        lump_p->type   = lumpinfo_t::lump_memory; // haleyjd
        lump_p->size   = (size_t)(SwapLong(fileinfo->size));
        lump_p->source = source; // haleyjd

        // setup for memory IO
        lump_p->memory.data     = openData.base;
        lump_p->memory.position = (size_t)(SwapLong(fileinfo->filepos));

        lump_p->li_namespace = addInfo.li_namespace;     // killough 4/17/98

        strncpy(lump_p->name, fileinfo->name, 8);
    }

    incrementSource(openData);

    return true;
}
Beispiel #23
0
/**
   Write a FIBITMAP to a JNG stream
   @param format_id ID of the caller
   @param io Stream i/o functions
   @param dib Image to be saved
   @param handle Stream handle
   @param flags Saving flags
   @return Returns TRUE if successful, returns FALSE otherwise
*/
BOOL
mng_WriteJNG(int format_id, FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int flags) {
    DWORD jng_width = 0;
    DWORD jng_height = 0;
    BYTE jng_color_type = 0;
    BYTE jng_image_sample_depth = 8;
    BYTE jng_image_compression_method = 8;  //  8: ISO-10918-1 Huffman-coded baseline JPEG.
    BYTE jng_image_interlace_method = 0;

    BYTE jng_alpha_sample_depth = 0;
    BYTE jng_alpha_compression_method = 0;
    BYTE jng_alpha_filter_method = 0;
    BYTE jng_alpha_interlace_method = 0;

    BYTE buffer[16];

    FIMEMORY *hJngMemory = NULL;
    FIMEMORY *hJpegMemory = NULL;
    FIMEMORY *hPngMemory = NULL;

    FIBITMAP *dib_rgb = NULL;
    FIBITMAP *dib_alpha = NULL;

    if(!dib || (FreeImage_GetImageType(dib) != FIT_BITMAP)) {
        return FALSE;
    }

    unsigned bpp = FreeImage_GetBPP(dib);

    switch(bpp) {
        case 8:
            if(FreeImage_GetColorType(dib) == FIC_MINISBLACK) {
                dib_rgb = dib;
                jng_color_type = MNG_COLORTYPE_JPEGGRAY;
            } else {
                // JPEG plugin will convert other types (FIC_MINISWHITE, FIC_PALETTE) to 24-bit on the fly
                //dib_rgb = FreeImage_ConvertTo24Bits(dib);
                dib_rgb = dib;
                jng_color_type = MNG_COLORTYPE_JPEGCOLOR;

            }
            break;
        case 24:
            dib_rgb = dib;
            jng_color_type = MNG_COLORTYPE_JPEGCOLOR;
            break;
        case 32:
            dib_rgb = FreeImage_ConvertTo24Bits(dib);
            jng_color_type = MNG_COLORTYPE_JPEGCOLORA;
            jng_alpha_sample_depth = 8;
            break;
        default:
            return FALSE;
    }

    jng_width = (DWORD)FreeImage_GetWidth(dib);
    jng_height = (DWORD)FreeImage_GetHeight(dib);

    try {
        hJngMemory = FreeImage_OpenMemory();

        // --- write JNG file signature ---
        FreeImage_WriteMemory(g_jng_signature, 1, 8, hJngMemory);

        // --- write a JHDR chunk ---
        SwapLong(&jng_width);
        SwapLong(&jng_height);
        memcpy(&buffer[0], &jng_width, 4);
        memcpy(&buffer[4], &jng_height, 4);
        SwapLong(&jng_width);
        SwapLong(&jng_height);
        buffer[8] = jng_color_type;
        buffer[9] = jng_image_sample_depth;
        buffer[10] = jng_image_compression_method;
        buffer[11] = jng_image_interlace_method;
        buffer[12] = jng_alpha_sample_depth;
        buffer[13] = jng_alpha_compression_method;
        buffer[14] = jng_alpha_filter_method;
        buffer[15] = jng_alpha_interlace_method;
        mng_WriteChunk(mng_JHDR, &buffer[0], 16, hJngMemory);

        // --- write a sequence of JDAT chunks ---
        hJpegMemory = FreeImage_OpenMemory();
        flags |= JPEG_BASELINE;
        if(!FreeImage_SaveToMemory(FIF_JPEG, dib_rgb, hJpegMemory, flags)) {
            throw (const char*)NULL;
        }
        if(dib_rgb != dib) {
            FreeImage_Unload(dib_rgb);
            dib_rgb = NULL;
        }
        {
            BYTE *jpeg_data = NULL;
            DWORD size_in_bytes = 0;

            // get a pointer to the stream buffer
            FreeImage_AcquireMemory(hJpegMemory, &jpeg_data, &size_in_bytes);
            // write chunks
            for(DWORD k = 0; k < size_in_bytes;) {
                DWORD bytes_left = size_in_bytes - k;
                DWORD chunk_size = MIN(JPEG_CHUNK_SIZE, bytes_left);
                mng_WriteChunk(mng_JDAT, &jpeg_data[k], chunk_size, hJngMemory);
                k += chunk_size;
            }
        }
        FreeImage_CloseMemory(hJpegMemory);
        hJpegMemory = NULL;

        // --- write alpha layer as a sequence of IDAT chunk ---
        if((bpp == 32) && (jng_color_type == MNG_COLORTYPE_JPEGCOLORA)) {
            dib_alpha = FreeImage_GetChannel(dib, FICC_ALPHA);

            hPngMemory = FreeImage_OpenMemory();
            if(!FreeImage_SaveToMemory(FIF_PNG, dib_alpha, hPngMemory, PNG_DEFAULT)) {
                throw (const char*)NULL;
            }
            FreeImage_Unload(dib_alpha);
            dib_alpha = NULL;
            // get the IDAT chunk
            {
                BOOL bResult = FALSE;
                DWORD start_pos = 0;
                DWORD next_pos = 0;
                long offset = 8;

                do {
                    // find the next IDAT chunk from 'offset' position
                    bResult = mng_FindChunk(hPngMemory, mng_IDAT, offset, &start_pos, &next_pos);
                    if(!bResult) break;

                    BYTE *png_data = NULL;
                    DWORD size_in_bytes = 0;

                    // get a pointer to the stream buffer
                    FreeImage_AcquireMemory(hPngMemory, &png_data, &size_in_bytes);
                    // write the IDAT chunk
                    mng_WriteChunk(mng_IDAT, &png_data[start_pos+8], next_pos - start_pos - 12, hJngMemory);

                    offset = next_pos;

                } while(bResult);
            }

            FreeImage_CloseMemory(hPngMemory);
            hPngMemory = NULL;
        }

        // --- write a IEND chunk ---
        mng_WriteChunk(mng_IEND, NULL, 0, hJngMemory);

        // write the JNG on output stream
        {
            BYTE *jng_data = NULL;
            DWORD size_in_bytes = 0;
            FreeImage_AcquireMemory(hJngMemory, &jng_data, &size_in_bytes);
            io->write_proc(jng_data, 1, size_in_bytes, handle);
        }

        FreeImage_CloseMemory(hJngMemory);
        FreeImage_CloseMemory(hJpegMemory);
        FreeImage_CloseMemory(hPngMemory);

        return TRUE;

    } catch(const char *text) {
        FreeImage_CloseMemory(hJngMemory);
        FreeImage_CloseMemory(hJpegMemory);
        FreeImage_CloseMemory(hPngMemory);
        if(dib_rgb && (dib_rgb != dib)) {
            FreeImage_Unload(dib_rgb);
        }
        FreeImage_Unload(dib_alpha);
        if(text) {
            FreeImage_OutputMessageProc(format_id, text);
        }
        return FALSE;
    }
}
XGWindow *XGWindowFactory::CreateFromData(const unsigned char *data, XGForm *form)
{
    XGSViewHeader h;
    const unsigned char *nptr;
    XGWindow *nwindow;
    long i,len;
    XGView *view;
    XGSViewHeader *ptr;

    /*
     *	Get and parse the header, initialize the data stream
     */

    h = *((XGSViewHeader *)data);

#if OPT_NATIVEORDER != 1
    h.type     = SwapLong(h.type);
    h.sibling  = SwapLong(h.sibling);
    h.children = SwapLong(h.children);
    h.length   = SwapLong(h.length);
#endif

    ptr = (XGSViewHeader *)data;
    XGArgStream stream((unsigned char *)&(ptr->type),h.length + sizeof(long));

    /*
     *	Now create the window. If not found, this will alert the
     *	user and will create the generic 'window' instead.
     */

    nwindow = NULL;
    len = gList.Length();
    for (i = 0; i < len; i++) {
        if (h.type == gList[i].type) {
            nwindow = (gList[i].proc)(stream, form);
            break;
        }
    }
    if (nwindow == NULL) {
        Warning(KXGWindowFactoryError,h.type);
        nwindow = new XGWindow(stream, form);
    }

    /*
     *	I have the window. This will only have one child, the view
     *	object which is to be contained in this window. Scan for
     *	the child object and construct.
     */

    if (h.children) {
        nptr = data + h.children;
        for (;;) {
            view = XGViewFactory::CreateFromData(nptr,nwindow);
            h = *((XGSViewHeader *)nptr);

#if OPT_NATIVEORDER != 1
            h.sibling = SwapLong(h.sibling);
#endif

            if (!h.sibling) break;
            nptr += h.sibling;
        }
    }

    /*
     *	Done creating me and my children.
     */

    return nwindow;
}
Beispiel #25
0
//
// ACS_traceScriptACS0
//
static void ACS_traceScriptACS0(acs0_tracer_t *tracer, uint32_t index)
{
   uint32_t indexNext, opSize;
   int32_t op;
   acs0_opdata_t const *opdata;

   for(;;)
   {
      // Read next instruction from file.
      op = ACS_readOpACS0(tracer, &opSize, index);

      // Invalid opcode terminates tracer.
      if(op >= ACS0_OPMAX || op < 0)
      {
         // But flag it so that a KILL gets generated by the translator.
         ACS_touchScriptACS0(tracer->codeTouched + index, tracer->codeTouched + index + opSize);
         ++tracer->vm->numCode;
         return;
      }

      opdata = &ACS0opdata[op];

      // Calculate next index.
      indexNext = index + ACS_countOpSizeACS0(tracer, index, opSize, opdata);

      // Leaving the bounds of the lump also terminates the tracer.
      if(indexNext > tracer->lumpLength) return;

      // If already touched this instruction, stop tracing.
      if(ACS_touchScriptACS0(tracer->codeTouched + index, tracer->codeTouched + indexNext))
         return;

      // Determine how many internal codes this counts for.
      switch(op)
      {
      case ACS0_OP_LINESPEC1_IMM:
      case ACS0_OP_LINESPEC2_IMM:
      case ACS0_OP_LINESPEC3_IMM:
      case ACS0_OP_LINESPEC4_IMM:
      case ACS0_OP_LINESPEC5_IMM:
      case ACS0_OP_LINESPEC1_IMM_BYTE:
      case ACS0_OP_LINESPEC2_IMM_BYTE:
      case ACS0_OP_LINESPEC3_IMM_BYTE:
      case ACS0_OP_LINESPEC4_IMM_BYTE:
      case ACS0_OP_LINESPEC5_IMM_BYTE:
      case ACS0_OP_GET2_IMM_BYTE:
      case ACS0_OP_GET3_IMM_BYTE:
      case ACS0_OP_GET4_IMM_BYTE:
      case ACS0_OP_GET5_IMM_BYTE:
         tracer->vm->numCode += opdata->args + 2;
         break;

      case ACS0_OP_GETARR_IMM_BYTE:
         tracer->vm->numCode += *(tracer->data + index + opSize) + 2;
         break;

      case ACS0_OP_ACTIVATORHEALTH:
      case ACS0_OP_ACTIVATORARMOR:
      case ACS0_OP_ACTIVATORFRAGS:
      case ACS0_OP_BRANCH_RETURNVOID:
      case ACS0_OP_PLAYERNUMBER:
      case ACS0_OP_ACTIVATORTID:
      case ACS0_OP_SIGILPIECES:
         tracer->vm->numCode += opdata->opdata->args + 1 + 2; // GET_IMM 0
         break;

      case ACS0_OP_GAMETYPE_ONEFLAGCTF:
         tracer->vm->numCode += 2; // GET_IMM
         break;
      case ACS0_OP_GAMETYPE_SINGLEPLAYER:
         tracer->vm->numCode += 4; // GAMETYPE + GET_IMM + CMP_EQ
         break;

      case ACS0_OP_BRANCH_CALLDISCARD:
         tracer->vm->numCode += opdata->opdata->args + 1 + 1; // DROP
         break;

      case ACS0_OP_BRANCH_CASETABLE:
         tracer->vm->numCode += 2;
         // More alignment stuff. (Wow, that's a mouthfull.)
         tracer->vm->numCode += SwapULong(*(uint32_t *)(((uintptr_t)tracer->data + index + opSize + 3) & ~3)) * 2;
         break;

      case ACS0_OP_CALLFUNC:
         if(tracer->compressed)
         {
            uint8_t  argc = tracer->data[index + opSize];
            uint16_t func = SwapUShort(*(uint16_t *)(tracer->data + index + opSize + 1));
            tracer->vm->numCode += ACS_traceFuncACS0(func, argc);
         }
         else
         {
            uint32_t argc = SwapULong(*(uint32_t *)(tracer->data + index + opSize + 0));
            uint32_t func = SwapULong(*(uint32_t *)(tracer->data + index + opSize + 4));
            tracer->vm->numCode += ACS_traceFuncACS0(func, argc);
         }
         break;

      default:
         // Translation to CALLFUNC.
         if(opdata->opdata->op == ACS_OP_CALLFUNC_IMM)
         {
            // Adds the func and argc arguments.
            tracer->vm->numCode += opdata->args + 1 + 2;
            break;
         }

         // Direct translation.
#ifdef RANGECHECK
         // This should never happen.
         if(opdata->opdata->args == -1)
            I_Error("Unknown translation for opcode. opcode %i", (int)op);
#endif

         tracer->vm->numCode += opdata->opdata->args + 1;
         break;
      }

      // Advance the index past the instruction.
      switch(op)
      {
      case ACS0_OP_SCRIPT_TERMINATE:
      case ACS0_OP_BRANCH_RETURN:
      case ACS0_OP_BRANCH_RETURNVOID:
         return;

      case ACS0_OP_BRANCH_IMM:
         ++tracer->jumpCount;
         index = SwapLong(*(int32_t *)(tracer->data + index + opSize));
         continue;

      case ACS0_OP_BRANCH_NOTZERO:
      case ACS0_OP_BRANCH_ZERO:
         ++tracer->jumpCount;
         ACS_traceScriptACS0(tracer, SwapLong(*(int32_t *)(tracer->data + index + opSize)));
         break;

      case ACS0_OP_BRANCH_CASE:
         ++tracer->jumpCount;
         ACS_traceScriptACS0(tracer, SwapLong(*(int32_t *)(tracer->data + index + opSize + 4)));
         break;

      case ACS0_OP_BRANCH_CASETABLE:
         {
            uint32_t jumps, *rover;

            rover = (uint32_t *)(tracer->data + index + opSize);
            // And alignment again.
            rover = (uint32_t *)(((uintptr_t)rover + 3) & ~3);
            jumps = SwapULong(*rover++);

            tracer->jumpCount += jumps;

            // Trace all of the jump targets.
            // Start by incrementing rover to point to address.
            for(++rover; jumps--; rover += 2)
               ACS_traceScriptACS0(tracer, SwapULong(*rover));
         }
         break;
      }

      index = indexNext;
   }
}
Beispiel #26
0
XGView *XGViewFactory::CreateFromData(const unsigned char *data, XGView *parent)
{
	XGSViewHeader h;
	XGSViewHeader *ptr;
	const unsigned char *nptr;
	XGView *nview;
	long i,len;
	
	/*
	 *	Get and parse the header, initialize the data stream
	 */
	
	h = *((XGSViewHeader *)data);

#if OPT_NATIVEORDER != 1
	h.type     = SwapLong(h.type);
	h.sibling  = SwapLong(h.sibling);
	h.children = SwapLong(h.children);
	h.length   = SwapLong(h.length);
#endif

	ptr = (XGSViewHeader *)data;
	XGArgStream stream((unsigned char *)&(ptr->type),h.length + sizeof(long));
	
	/*
	 *	Now create the view. If not found, this will alert the
	 *	user and will create the generic 'view' instead.
	 */
	
	nview = NULL;
	len = gList.Length();
	for (i = 0; i < len; i++) {
		if (h.type == gList[i].type) {
			nview = (gList[i].proc)(parent,stream);
			break;
		}
	}
	if (nview == NULL) {
		Warning(KXGViewFactoryError,h.type);
		nview = new XGView(parent,stream);
	}
	
	/*
	 *	I have the view. Start looking for the children of this
	 *	thing. (The default view constructor will add the child
	 *	view to the specified parent view, so nothing needs to be
	 *	done here.)
	 */
	
	if (h.children) {
		nptr = data + h.children;

		for (;;) {
			CreateFromData(nptr,nview);
			h = *((XGSViewHeader *)nptr);

#if OPT_NATIVEORDER != 1
			h.sibling = SwapLong(h.sibling);
#endif

			if (!h.sibling) break;
			nptr += h.sibling;
		}
	}
	
	/*
	 *	Done creating me and my children. Return
	 */
	
	return nview;		
}
Beispiel #27
0
//
// WadDirectory::addWadFile
//
// haleyjd 10/28/12: Add an id wadlink file into the directory.
//
bool WadDirectory::addWadFile(openwad_t &openData, wfileadd_t &addInfo,
                              int startlump)
{
    // haleyjd 04/07/11
    //HashData     wadHash  = HashData(HashData::SHA1);
    bool         showHash = false;
    bool         doHacks  = (addInfo.flags & WFA_ALLOWHACKS) == WFA_ALLOWHACKS;
    long         baseoffset = static_cast<long>(addInfo.baseoffset);
    wadinfo_t    header;
    ZAutoBuffer  fileinfo2free; // killough
    filelump_t  *fileinfo;
    size_t       length;
    long         info_offset;
    lumpinfo_t  *lump_p;

    // check for in-memory wads
    if(addInfo.flags & WFA_INMEMORY)
        return addMemoryWad(openData, addInfo, startlump);

    // haleyjd: seek to baseoffset first when loading a subfile
    if(addInfo.flags & WFA_SUBFILE)
        fseek(openData.handle, baseoffset, SEEK_SET);

    // -nowadhacks disables all wad directory hacks, in case of unforeseen
    // compatibility problems that would last until the next release
    if(M_CheckParm("-nowadhacks"))
        doHacks = false;

    // -showhashes enables display of the computed SHA-1 hash used to apply
    // wad directory hacks. Quite useful for when a new hack needs to be added.
    if(M_CheckParm("-showhashes"))
        showHash = true;

    if(fread(&header, sizeof(header), 1, openData.handle) < 1)
    {
        if(addInfo.flags & WFA_OPENFAILFATAL)
            I_Error("Failed reading header for wad file %s\n", openData.filename);
        else
        {
            fclose(openData.handle);
            printf("Failed reading header for wad file %s\n", openData.filename);
            return false;
        }
    }

    // Feed the wad header data into the hash computation
    //if(doHacks || showHash)
    //   wadHash.addData((const uint8_t *)&header, (uint32_t)sizeof(header));

    header.numlumps     = SwapLong(header.numlumps);
    header.infotableofs = SwapLong(header.infotableofs);

    // allocate enough fileinfo_t's to hold the wad directory
    length = header.numlumps * sizeof(filelump_t);

    fileinfo2free.alloc(length, true);              // killough
    fileinfo = fileinfo2free.getAs<filelump_t *>();

    info_offset = static_cast<long>(header.infotableofs);

    // subfile wads may exist at a positive base offset in the container file
    if(addInfo.flags & WFA_SUBFILE)
        info_offset += baseoffset;

    // seek to the directory
    fseek(openData.handle, info_offset, SEEK_SET);

    // read it in.
    if(fread(fileinfo, length, 1, openData.handle) < 1)
    {
        if(addInfo.flags & WFA_OPENFAILFATAL)
            I_Error("Failed reading directory for wad file %s\n", openData.filename);
        else
        {
            fclose(openData.handle);
            printf("Failed reading directory for wad file %s\n", openData.filename);
            return false;
        }
    }

    // Feed the wad directory into the hash computation, wrap it up, and if requested,
    // output it to the console.
#if 0
    if(doHacks || showHash)
    {
        wadHash.addData((const uint8_t *)fileinfo, (uint32_t)length);
        wadHash.wrapUp();
        if(in_textmode && showHash)
            printf("\thash = %s\n", wadHash.digestToString());
        // haleyjd 04/08/11: apply wad directory hacks as needed
        if(doHacks)
            W_CheckDirectoryHacks(wadHash, fileinfo, header.numlumps);
    }
#endif

    // update IWAD handle?
    // haleyjd: Must be a public wad file.
    if(!(addInfo.flags & WFA_PRIVATE) && this->ispublic)
    {
        // haleyjd 06/21/04: track handle of first wad added also
        if(ResWADSource == -1)
            ResWADSource = source;

        // haleyjd 07/13/09: only track the first IWAD found
        // haleyjd 11/03/12: Status as the IWAD is now determined by how the file
        // was added to the game (ie., -iwad or -disk, vs. -file, autoloads, etc.)
        if(IWADSource < 0 && (addInfo.flags & WFA_ISIWADFILE))
            IWADSource = source;
    }

    // Add lumpinfo_t's for all lumps in the wad file
    lump_p = reAllocLumpInfo(header.numlumps, startlump);

    // Merge into the directory
    for(int i = startlump; i < this->numlumps; i++, lump_p++, fileinfo++)
    {
        strncpy(lump_p->name, fileinfo->name, 8);

        if(lump_p->name[0] & 0x80) // For psxwadgen, detect compressed lumps
        {
            lump_p->name[0] &= 0x7f;
            lump_p->type = lumpinfo_t::lump_direct_jag;
        }
        else
            lump_p->type = lumpinfo_t::lump_direct; // haleyjd

        lump_p->size   = (size_t)(SwapLong(fileinfo->size));
        lump_p->source = source; // haleyjd

        // setup for direct IO
        lump_p->direct.file     = openData.handle;
        lump_p->direct.position = (size_t)(SwapLong(fileinfo->filepos));

        // for subfiles, add baseoffset to the lump offset
        if(addInfo.flags & WFA_SUBFILE)
            lump_p->direct.position += static_cast<size_t>(baseoffset);

        lump_p->li_namespace = addInfo.li_namespace;     // killough 4/17/98
    }

#if 0
    if(ispublic)
        D_NewWadLumps(source);
#endif

    incrementSource(openData);

    return true;
}
Beispiel #28
0
inline void
mng_SwapLong(DWORD *lp) {
#ifndef FREEIMAGE_BIGENDIAN
    SwapLong(lp);
#endif
}
Beispiel #29
0
static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	SUNHEADER header;	// Sun file header
	WORD linelength;	// Length of raster line in bytes
	WORD fill;			// Number of fill bytes per raster line
	BOOL rle;			// TRUE if RLE file
	BOOL isRGB;			// TRUE if file type is RT_FORMAT_RGB
	BYTE fillchar;

	FIBITMAP *dib = NULL;
	BYTE *bits;			// Pointer to dib data
	WORD x, y;

	if(!handle) {
		return NULL;
	}

	BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;

	try {
		// Read SUN raster header

		io->read_proc(&header, sizeof(SUNHEADER), 1, handle);

#ifndef FREEIMAGE_BIGENDIAN
		// SUN rasterfiles are big endian only

		SwapLong(&header.magic);
		SwapLong(&header.width);
		SwapLong(&header.height);
		SwapLong(&header.depth);
		SwapLong(&header.length);
		SwapLong(&header.type);
		SwapLong(&header.maptype);
		SwapLong(&header.maplength);
#endif

		// Verify SUN identifier

		if (header.magic != RAS_MAGIC) {
			throw FI_MSG_ERROR_MAGIC_NUMBER;
		}

		// Allocate a new DIB

		switch(header.depth) {
			case 1:
			case 8:
				dib = FreeImage_AllocateHeader(header_only, header.width, header.height, header.depth);
				break;

			case 24:
				dib = FreeImage_AllocateHeader(header_only, header.width, header.height, header.depth, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
				break;

			case 32:
				dib = FreeImage_AllocateHeader(header_only, header.width, header.height, header.depth, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
				break;
		}

		if (dib == NULL) {
			throw FI_MSG_ERROR_DIB_MEMORY;
		}

		// Check the file format

		rle = FALSE;
		isRGB = FALSE;

		switch(header.type) {
			case RT_OLD:
			case RT_STANDARD:
			case RT_FORMAT_TIFF: // I don't even know what these format are...
			case RT_FORMAT_IFF: //The TIFF and IFF format types indicate that the raster
				//file was originally converted from either of these file formats.
				//so lets at least try to process them as RT_STANDARD
				break;

			case RT_BYTE_ENCODED:
				rle = TRUE;
				break;

			case RT_FORMAT_RGB:
				isRGB = TRUE;
				break;

			default:
				throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
		}

		// set up the colormap if needed

		switch(header.maptype) {
			case RMT_NONE :
			{				
				if (header.depth < 24) {
					// Create linear color ramp

					RGBQUAD *pal = FreeImage_GetPalette(dib);

					int numcolors = 1 << header.depth;

					for (int i = 0; i < numcolors; i++) {
						pal[i].rgbRed	= (BYTE)((255 * i) / (numcolors - 1));
						pal[i].rgbGreen = (BYTE)((255 * i) / (numcolors - 1));
						pal[i].rgbBlue	= (BYTE)((255 * i) / (numcolors - 1));
					}
				}

				break;
			}

			case RMT_EQUAL_RGB:
			{
				BYTE *r, *g, *b;

				// Read SUN raster colormap

				int numcolors = 1 << header.depth;
				if((DWORD)(3 * numcolors) > header.maplength) {
					// some RAS may have less colors than the full palette
					numcolors = header.maplength / 3;
				} else {
					throw "Invalid palette";
				}

				r = (BYTE*)malloc(3 * numcolors * sizeof(BYTE));
				g = r + numcolors;
				b = g + numcolors;

				RGBQUAD *pal = FreeImage_GetPalette(dib);

				io->read_proc(r, 3 * numcolors, 1, handle);

				for (int i = 0; i < numcolors; i++) {
					pal[i].rgbRed	= r[i];
					pal[i].rgbGreen = g[i];
					pal[i].rgbBlue	= b[i];
				}

				free(r);
				break;
			}

			case RMT_RAW:
			{
				BYTE *colormap;

				// Read (skip) SUN raster colormap.

				colormap = (BYTE *)malloc(header.maplength * sizeof(BYTE));

				io->read_proc(colormap, header.maplength, 1, handle);

				free(colormap);
				break;
			}
		}

		if(header_only) {
			// header only mode
			return dib;
		}

		// Calculate the line + pitch
		// Each row is multiple of 16 bits (2 bytes).

		if (header.depth == 1) {
			linelength = (WORD)((header.width / 8) + (header.width % 8 ? 1 : 0));
		} else {
			linelength = (WORD)header.width;
		}

		fill = (linelength % 2) ? 1 : 0;

		unsigned pitch = FreeImage_GetPitch(dib);

		// Read the image data
		
		switch(header.depth) {
			case 1:
			case 8:
			{
				bits = FreeImage_GetBits(dib) + (header.height - 1) * pitch;

				for (y = 0; y < header.height; y++) {
					ReadData(io, handle, bits, linelength, rle);

					bits -= pitch;

					if (fill) {
						ReadData(io, handle, &fillchar, fill, rle);
					}
				}

				break;
			}

			case 24:
			{
				BYTE *buf, *bp;

				buf = (BYTE*)malloc(header.width * 3);

				for (y = 0; y < header.height; y++) {
					bits = FreeImage_GetBits(dib) + (header.height - 1 - y) * pitch;

					ReadData(io, handle, buf, header.width * 3, rle);

					bp = buf;

					if (isRGB) {
						for (x = 0; x < header.width; x++) {
							bits[FI_RGBA_RED] = *(bp++);	// red
							bits[FI_RGBA_GREEN] = *(bp++);	// green
							bits[FI_RGBA_BLUE] = *(bp++);	// blue

							bits += 3;
						}
					} else {
						for (x = 0; x < header.width; x++) {
							bits[FI_RGBA_RED] = *(bp + 2);	// red
							bits[FI_RGBA_GREEN] = *(bp + 1);// green
							bits[FI_RGBA_BLUE] = *bp;       // blue

							bits += 3; bp += 3;
						}
					}

					if (fill) {
						ReadData(io, handle, &fillchar, fill, rle);
					}
				}

				free(buf);
				break;
			}

			case 32:
			{
				BYTE *buf, *bp;

				buf = (BYTE*)malloc(header.width * 4);

				for (y = 0; y < header.height; y++) {
					bits = FreeImage_GetBits(dib) + (header.height - 1 - y) * pitch;

					ReadData(io, handle, buf, header.width * 4, rle);

					bp = buf;

					if (isRGB) {
						for (x = 0; x < header.width; x++) {
							bits[FI_RGBA_ALPHA] = *(bp++);	// alpha
							bits[FI_RGBA_RED] = *(bp++);	// red
							bits[FI_RGBA_GREEN] = *(bp++);	// green
							bits[FI_RGBA_BLUE] = *(bp++);	// blue

							bits += 4;
						}
					}
					else {
						for (x = 0; x < header.width; x++) {
							bits[FI_RGBA_RED] = *(bp + 3);	// red
							bits[FI_RGBA_GREEN] = *(bp + 2); // green
							bits[FI_RGBA_BLUE] = *(bp + 1);	// blue
							bits[FI_RGBA_ALPHA] = *bp;		// alpha

							bits += 4;
							bp += 4;
						}
					}

					if (fill) {
						ReadData(io, handle, &fillchar, fill, rle);
					}
				}

				free(buf);
				break;
			}
		}
		
		return dib;

	} catch (const char *text) {
		if(dib) {
			FreeImage_Unload(dib);
		}
		FreeImage_OutputMessageProc(s_format_id, text);
	}

	return NULL;
}
Beispiel #30
0
//
// ACS_translateScriptACS0
//
static void ACS_translateScriptACS0(acs0_tracer_t *tracer, int32_t *codeIndexMap)
{
   byte *brover;
   int32_t *codePtr = tracer->vm->code, *rover;
   uint32_t index, opSize;
   int32_t op, temp;
   acs0_opdata_t const *opdata;
   int32_t **jumps, **jumpItr;

   // This is used to store all of the places that need to have a jump target
   // translated. The count was determined by the tracer.
   jumps = (int32_t **)Z_Malloc(tracer->jumpCount * sizeof(int32_t *), PU_STATIC, NULL);
   jumpItr = jumps;

   // Set the first instruction to a KILL.
   *codePtr++ = ACS_OP_KILL;

   for(index = 0; index < tracer->lumpLength;)
   {
      // Search for code.
      if(!tracer->codeTouched[index])
      {
         ++index;
         continue;
      }

      // Read next instruction from file.
      op = ACS_readOpACS0(tracer, &opSize, index);

      rover = (int32_t *)(tracer->data + index + opSize);

      // Unrecognized instructions need to stop execution.
      if(op >= ACS0_OPMAX || op < 0)
      {
         *codePtr++ = ACS_OP_KILL;
         index += opSize;
         continue;
      }

      opdata = &ACS0opdata[op];

      // Record jump target.
      codeIndexMap[index] = codePtr - tracer->vm->code;

      // Calculate next index.
      index += ACS_countOpSizeACS0(tracer, index, opSize, opdata);

      switch(op)
      {
      case ACS0_OP_LINESPEC1:
      case ACS0_OP_LINESPEC2:
      case ACS0_OP_LINESPEC3:
      case ACS0_OP_LINESPEC4:
      case ACS0_OP_LINESPEC5:
         temp = op - ACS0_OP_LINESPEC1 + 1;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = SwapLong(*rover++);
         *codePtr++ = temp;
         break;

      case ACS0_OP_LINESPEC1_IMM:
      case ACS0_OP_LINESPEC2_IMM:
      case ACS0_OP_LINESPEC3_IMM:
      case ACS0_OP_LINESPEC4_IMM:
      case ACS0_OP_LINESPEC5_IMM:
         temp = opdata->args - 1;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = SwapLong(*rover++);
         *codePtr++ = temp;
         while(temp--)
            *codePtr++ = SwapLong(*rover++);
         break;

      case ACS0_OP_LINESPEC5_RET:
         temp = op - ACS0_OP_LINESPEC5_RET + 5;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = SwapLong(*rover++);
         *codePtr++ = temp;
         break;

      case ACS0_OP_LINESPEC1_IMM_BYTE:
      case ACS0_OP_LINESPEC2_IMM_BYTE:
      case ACS0_OP_LINESPEC3_IMM_BYTE:
      case ACS0_OP_LINESPEC4_IMM_BYTE:
      case ACS0_OP_LINESPEC5_IMM_BYTE:
         brover = (byte *)rover;
         temp = opdata->args - 1;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = *brover++;
         *codePtr++ = temp;
         while(temp--)
            *codePtr++ = *brover++;
         break;

      case ACS0_OP_GET_IMM_BYTE:
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = *(byte *)rover;
         break;

      case ACS0_OP_GET2_IMM_BYTE:
      case ACS0_OP_GET3_IMM_BYTE:
      case ACS0_OP_GET4_IMM_BYTE:
      case ACS0_OP_GET5_IMM_BYTE:
         brover = (byte *)rover;
         temp = op - ACS0_OP_GET2_IMM_BYTE + 2;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = temp;
         while(temp--)
            *codePtr++ = *brover++;
         break;

      case ACS0_OP_GET_THINGX:
      case ACS0_OP_GET_THINGY:
      case ACS0_OP_GET_THINGZ:
      case ACS0_OP_GET_THINGFLOORZ:
      case ACS0_OP_GET_THINGANGLE:
      case ACS0_OP_SET_THINGANGLE:
      case ACS0_OP_GET_THINGCEILINGZ:
      case ACS0_OP_GET_THINGPITCH:
      case ACS0_OP_SET_THINGPITCH:
      case ACS0_OP_CHK_THINGCEILINGTEXTURE:
      case ACS0_OP_CHK_THINGFLOORTEXTURE:
      case ACS0_OP_GET_THINGLIGHTLEVEL:
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = ACS_translateThingVarACS0(opdata);
         break;

      case ACS0_OP_GETARR_IMM_BYTE:
         brover = (byte *)rover;
         temp = *brover++;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = temp;
         while(temp--)
            *codePtr++ = *brover++;
         break;

      case ACS0_OP_BRANCH_IMM:
      case ACS0_OP_BRANCH_NOTZERO:
      case ACS0_OP_BRANCH_ZERO:
         *jumpItr++ = codePtr + 1;
         goto case_direct;

      case ACS0_OP_BRANCH_CASE:
         *jumpItr++ = codePtr + 2;
         goto case_direct;

      case ACS0_OP_CHANGEFLOOR_IMM:
      case ACS0_OP_CHANGECEILING_IMM:
         ACS_translateFuncACS0(codePtr, opdata);
         *codePtr++ = SwapLong(*rover++);
         *codePtr++ = tracer->vm->getStringIndex(SwapLong(*rover++)); // tag string
         for(int i = opdata->args - 2; i--;)
            *codePtr++ = SwapLong(*rover++);
         break;

      case ACS0_OP_DELAY_IMM_BYTE:
         brover = (byte *)rover;
         *codePtr++ = opdata->opdata->op;
         for(int i = opdata->args; i--;)
            *codePtr++ = *brover++;
         break;

      case ACS0_OP_ACTIVATORHEALTH:
      case ACS0_OP_ACTIVATORARMOR:
      case ACS0_OP_ACTIVATORFRAGS:
      case ACS0_OP_PLAYERNUMBER:
      case ACS0_OP_ACTIVATORTID:
         *codePtr++ = ACS_OP_GET_IMM;
         *codePtr++ = 0;
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = ACS_translateThingVarACS0(opdata);
         break;

      case ACS0_OP_GAMETYPE_ONEFLAGCTF:
         *codePtr++ = ACS_OP_GET_IMM;
         *codePtr++ = 0;
         break;

      case ACS0_OP_GAMETYPE_SINGLEPLAYER:
         *codePtr++ = opdata->opdata->op;
         *codePtr++ = ACS_OP_GET_IMM;
         *codePtr++ = gt_single;
         *codePtr++ = ACS_OP_CMP_EQ;
         break;

      case ACS0_OP_RANDOM_IMM_BYTE:
         brover = (byte *)rover;
         ACS_translateFuncACS0(codePtr, opdata);
         for(int i = opdata->args; i--;)
            *codePtr++ = *brover++;
         break;

      case ACS0_OP_SETMUSIC_IMM:
      case ACS0_OP_SETMUSICLOCAL_IMM:
      case ACS0_OP_SPAWNPOINT_IMM:
      case ACS0_OP_SPAWNSPOT_IMM:
         ACS_translateFuncACS0(codePtr, opdata);
         *codePtr++ = tracer->vm->getStringIndex(SwapLong(*rover++)); // tag string
         for(int i = opdata->args - 1; i--;)
            *codePtr++ = SwapLong(*rover++);
         break;

      case ACS0_OP_BRANCH_CALLDISCARD:
         *codePtr++ = opdata->opdata->op;
         if(tracer->compressed)
            *codePtr++ = *(byte *)rover;
         else
            *codePtr++ = SwapLong(*rover);
         *codePtr++ = ACS_OP_STACK_DROP;
         break;

      case ACS0_OP_BRANCH_RETURNVOID:
         *codePtr++ = ACS_OP_GET_IMM;
         *codePtr++ = 0;
         *codePtr++ = opdata->opdata->op;
         break;

      case ACS0_OP_BRANCH_CASETABLE:
         // Align rover.
         rover = (int32_t *)(((uintptr_t)rover + 3) & ~3);
         temp = SwapLong(*rover++);

         *codePtr++ = opdata->opdata->op;
         *codePtr++ = temp;

         while(temp--)
         {
            *codePtr++ = SwapLong(*rover++);
            *jumpItr++ = codePtr;
            *codePtr++ = SwapLong(*rover++);
         }
         break;

      case ACS0_OP_CALLFUNC:
         if(tracer->compressed)
         {
            brover = (uint8_t *)rover;
            uint8_t  argc = *brover++;
            uint16_t func = SwapUShort(*(uint16_t *)brover);
            ACS_translateFuncACS0(codePtr, func, argc);
         }
         else
            ACS_translateFuncACS0(codePtr, SwapLong(rover[1]), SwapLong(rover[0]));
         break;

      default: case_direct:
         // Direct translation.
         if(opdata->opdata->op == ACS_OP_CALLFUNC ||
            opdata->opdata->op == ACS_OP_CALLFUNC_IMM)
         {
            ACS_translateFuncACS0(codePtr, opdata);
         }
         else
            *codePtr++ = opdata->opdata->op;

         if(tracer->compressed && opdata->compressed)
         {
            brover = (byte *)rover;
            for(int i = opdata->args; i--;)
               *codePtr++ = *brover++;
         }
         else
         {
            for(int i = opdata->args; i--;)
               *codePtr++ = SwapLong(*rover++);
         }

         break;
      }
   }

   // Set the last instruction to a KILL.
   *codePtr++ = ACS_OP_KILL;

#ifdef RANGECHECK
   // If this isn't true, something very wrong has happened internally.
   if(codePtr != tracer->vm->code + tracer->vm->numCode)
   {
      I_Error("Incorrect code count. %i/%i/%i", (int)(codePtr - tracer->vm->code),
              (int)tracer->vm->numCode, (int)(tracer->lumpLength / 4));
   }

   // Same here, this is just a sanity check.
   if(jumpItr != jumps + tracer->jumpCount)
   {
      I_Error("Incorrect jump count. %i/%i", (int)(jumpItr - jumps),
              (int)tracer->jumpCount);
   }
#endif

   // Translate jumps. Has to be done after code in order to jump forward.
   while(jumpItr != jumps)
   {
      codePtr = *--jumpItr;

      if ((uint32_t)*codePtr < tracer->lumpLength)
         *codePtr = codeIndexMap[*codePtr];
      else
         *codePtr = 0;
   }
}