/******************************Module*Header*******************************\ * Module Name: ssimage.c * Operations on .rgb files * Copyright (c) 1995 Microsoft Corporation */ #include #include #include #include #include "tk.h" #include "sscommon.h" #define IMAGIC 0x01da #define IMAGIC_SWAP 0xda01 #define SWAP_SHORT_BYTES(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) #define SWAP_LONG_BYTES(x) (((((x) & 0xff) << 24) | (((x) & 0xff00) << 8)) | \ ((((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))) typedef struct _rawImageRec { unsigned short imagic; unsigned short type; unsigned short dim; unsigned short sizeX, sizeY, sizeZ; unsigned long min, max; unsigned long wasteBytes; char name[80]; unsigned long colorMap; HANDLE file; unsigned char *tmp, *tmpR, *tmpG, *tmpB; unsigned long rleEnd; unsigned long *rowStart; long *rowSize; // !!! Hack to stick in a pointer to the resource data - shouldn't be // a problem, since rgb files always have 512 byte header unsigned char *data; } rawImageRec; static void RawImageClose(rawImageRec *raw); /* * Hacked form of tk_RGBImageLoad(), for reading a .rgb file from a resource * Copyright (c) 1995 Microsoft Corporation */ #include static rawImageRec *RawImageOpen( PVOID pv ) { rawImageRec *raw; unsigned long *rowStart, *rowSize, ulTmp; int x; DWORD dwBytesRead; raw = (rawImageRec *)malloc(sizeof(rawImageRec)); if (raw == NULL) { return 0; } // Make a copy of the resource header, since we may be doing some byte // swapping, and resources are read-only *raw = *((rawImageRec *) pv); if (raw->imagic == IMAGIC_SWAP) { raw->type = SWAP_SHORT_BYTES(raw->type); raw->dim = SWAP_SHORT_BYTES(raw->dim); raw->sizeX = SWAP_SHORT_BYTES(raw->sizeX); raw->sizeY = SWAP_SHORT_BYTES(raw->sizeY); raw->sizeZ = SWAP_SHORT_BYTES(raw->sizeZ); } raw->tmp = (unsigned char *)malloc(raw->sizeX*256); raw->tmpR = (unsigned char *)malloc(raw->sizeX*256); raw->tmpG = (unsigned char *)malloc(raw->sizeX*256); raw->tmpB = (unsigned char *)malloc(raw->sizeX*256); if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL || raw->tmpB == NULL) { RawImageClose(raw); return 0; } if ((raw->type & 0xFF00) == 0x0100) { x = raw->sizeY * raw->sizeZ * sizeof(long); raw->rowStart = (unsigned long *)malloc(x); raw->rowSize = (long *)malloc(x); if (raw->rowStart == NULL || raw->rowSize == NULL) { RawImageClose(raw); return 0; } //mf: not used (?) raw->rleEnd = 512 + (2 * x); //mf: hack to point to resource data raw->data = ((unsigned char *) pv); RtlCopyMemory( raw->rowStart, raw->data + 512, x ); RtlCopyMemory( raw->rowSize, raw->data + 512 + x, x ); if (raw->imagic == IMAGIC_SWAP) { x /= sizeof(long); rowStart = raw->rowStart; rowSize = (unsigned long *) raw->rowSize; while (x--) { ulTmp = *rowStart; *rowStart++ = SWAP_LONG_BYTES(ulTmp); ulTmp = *rowSize; *rowSize++ = SWAP_LONG_BYTES(ulTmp); } } } return raw; } static void RawImageClose(rawImageRec *raw) { if( !raw ) return; if( raw->tmp ) free(raw->tmp); if( raw->tmpR ) free(raw->tmpR); if( raw->tmpG ) free(raw->tmpG); if( raw->tmpB ) free(raw->tmpB); free(raw); } static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z) { unsigned char *iPtr, *oPtr, pixel; int count; DWORD dwBytesRead; if ((raw->type & 0xFF00) == 0x0100) { RtlCopyMemory(raw->tmp, raw->data + raw->rowStart[y+z*raw->sizeY], (unsigned int)raw->rowSize[y+z*raw->sizeY] ); iPtr = raw->tmp; oPtr = buf; while (1) { pixel = *iPtr++; count = (int)(pixel & 0x7F); if (!count) { return; } if (pixel & 0x80) { while (count--) { *oPtr++ = *iPtr++; } } else { pixel = *iPtr++; while (count--) { *oPtr++ = pixel; } } } } else { iPtr = raw->data + 512 + (y*raw->sizeX)+(z*raw->sizeX*raw->sizeY); RtlCopyMemory( buf, iPtr, raw->sizeX ); } } static void RawImageGetData(rawImageRec *raw, TEXTURE *ptex) { unsigned char *ptr; int i, j; ptex->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4); if (ptex->data == NULL) { return; } ptr = ptex->data; for (i = 0; i < raw->sizeY; i++) { RawImageGetRow(raw, raw->tmpR, i, 0); RawImageGetRow(raw, raw->tmpG, i, 1); RawImageGetRow(raw, raw->tmpB, i, 2); for (j = 0; j < raw->sizeX; j++) { *ptr++ = *(raw->tmpR + j); *ptr++ = *(raw->tmpG + j); *ptr++ = *(raw->tmpB + j); } } } BOOL ss_RGBImageLoad( PVOID pv, TEXTURE *ptex ) { rawImageRec *raw; if( !(raw = RawImageOpen( pv )) ) return FALSE; ptex->width = raw->sizeX; ptex->height = raw->sizeY; ptex->format = GL_RGB; ptex->components = 3; ptex->pal_size = 0; ptex->pal = NULL; RawImageGetData(raw, ptex); RawImageClose(raw); return TRUE; } /******************************Public*Routine******************************\ * bVerifyRGB * Stripped down version of tkRGBImageLoadAW that verifies that an rgb * file is valid and, if so, returns the bitmap dimensions. * Returns: * TRUE if valid rgb file; otherwise, FALSE. */ BOOL bVerifyRGB(LPTSTR pszFileName, ISIZE *pSize ) { rawImageRec *raw; DWORD dwBytesRead; BOOL bRet = FALSE; raw = (rawImageRec *) LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, sizeof(rawImageRec) ); if (raw == NULL) { return FALSE; } raw->file = CreateFile((LPTSTR) pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); if (raw->file == INVALID_HANDLE_VALUE) { goto bVerifyRGB_cleanup; } ReadFile(raw->file, (LPVOID) raw, 12, &dwBytesRead, (LPOVERLAPPED) NULL); if( raw->imagic == IMAGIC_SWAP ) { raw->sizeX = SWAP_SHORT_BYTES(raw->sizeX); raw->sizeY = SWAP_SHORT_BYTES(raw->sizeY); bRet = TRUE; } else if( raw->imagic == IMAGIC) bRet = TRUE; bVerifyRGB_cleanup: if( bRet && pSize ) { pSize->width = raw->sizeX; pSize->height = raw->sizeY; } if( raw->file != INVALID_HANDLE_VALUE ) CloseHandle( raw->file ); LocalFree( raw ); return bRet; }