Image* LoadHLWBuff( byte* buffer ){ byte *buf_p; unsigned long mipdatasize; int columns, rows, numPixels; byte *pixbuf; int row, column; byte *palette; LPWAD3_MIP lpMip; unsigned char red, green, blue, alphabyte; lpMip = (LPWAD3_MIP)buffer; //!\todo Make endian-safe. mipdatasize = GET_MIP_DATA_SIZE( lpMip->width,lpMip->height ); palette = buffer + mipdatasize + 2; buf_p = buffer + lpMip->offsets[0]; columns = lpMip->width; rows = lpMip->height; numPixels = columns * rows; RGBAImage* image = new RGBAImage( columns, rows ); for ( row = 0; row < rows; row++ ) { pixbuf = image->getRGBAPixels() + row * columns * 4; for ( column = 0; column < columns; column++ ) { int palIndex; palIndex = *buf_p++; red = *( palette + ( palIndex * 3 ) ); green = *( palette + ( palIndex * 3 ) + 1 ); blue = *( palette + ( palIndex * 3 ) + 2 ); // HalfLife engine makes pixels that are BLUE transparent. // So show them that way in the editor. if ( blue == 0xff && red == 0x00 && green == 0x00 ) { alphabyte = 0x00; blue = 0x00; // don't set the resulting pixel to blue } else { alphabyte = 0xff; } *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = alphabyte; } } return image; }
static Image* LoadJPGBuff_( const void *src_buffer, int src_size ){ struct jpeg_decompress_struct cinfo; struct my_jpeg_error_mgr jerr; cinfo.err = jpeg_std_error( &jerr.pub ); jerr.pub.error_exit = my_jpeg_error_exit; if ( setjmp( jerr.setjmp_buffer ) ) { //< TODO: use c++ exceptions instead of setjmp/longjmp to handle errors globalErrorStream() << "WARNING: JPEG library error: " << errormsg << "\n"; jpeg_destroy_decompress( &cinfo ); return 0; } jpeg_create_decompress( &cinfo ); jpeg_buffer_src( &cinfo, const_cast<void*>( src_buffer ), src_size ); jpeg_read_header( &cinfo, TRUE ); jpeg_start_decompress( &cinfo ); int row_stride = cinfo.output_width * cinfo.output_components; RGBAImage* image = new RGBAImage( cinfo.output_width, cinfo.output_height ); JSAMPARRAY buffer = ( *cinfo.mem->alloc_sarray )( ( j_common_ptr ) & cinfo, JPOOL_IMAGE, row_stride, 1 ); while ( cinfo.output_scanline < cinfo.output_height ) { jpeg_read_scanlines( &cinfo, buffer, 1 ); if ( cinfo.out_color_components == 4 ) { j_putRGBAScanline( buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline - 1 ); } else if ( cinfo.out_color_components == 3 ) { j_putRGBScanline( buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline - 1 ); } else if ( cinfo.out_color_components == 1 ) { j_putGrayScanlineToRGB( buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline - 1 ); } } jpeg_finish_decompress( &cinfo ); jpeg_destroy_decompress( &cinfo ); return image; }
static Image* LoadImage (ArchiveFile& file, const char *extension) { RGBAImage* image = (RGBAImage *) 0; /* load the buffer from pk3 or filesystem */ ScopedArchiveBuffer buffer(file); GdkPixbufLoader *loader = gdk_pixbuf_loader_new_with_type(extension, (GError**) 0); if (loader == (GdkPixbufLoader*)0) { g_warning("could not get a loader for: '%s'\n", extension); return image; } GError *error = (GError *) 0; if (gdk_pixbuf_loader_write(loader, (const guchar *) buffer.buffer, static_cast<gsize> (buffer.length), &error)) { int pos = 0; GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); const int width = gdk_pixbuf_get_width(pixbuf); const int height = gdk_pixbuf_get_height(pixbuf); const gboolean hasAlpha = gdk_pixbuf_get_has_alpha(pixbuf); const int stepWidth = gdk_pixbuf_get_n_channels(pixbuf); const guchar *pixels = gdk_pixbuf_get_pixels(pixbuf); image = new RGBAImage(width, height, false); byte *rgba = image->getRGBAPixels(); const int rowextra = gdk_pixbuf_get_rowstride(pixbuf) - width * stepWidth; for (int y = 0; y < height; ++y, pixels += rowextra) { for (int x = 0; x < width; ++x) { rgba[pos++] = *(pixels++); rgba[pos++] = *(pixels++); rgba[pos++] = *(pixels++); if (hasAlpha && *pixels != 255) image->setHasAlpha(true); rgba[pos++] = hasAlpha ? *(pixels++) : 255; } } g_object_unref(pixbuf); } else { g_warning("image could not get loaded: '%s' %s\n", file.getName().c_str(), (error != (GError *) 0) ? error->message : ""); if (error) g_error_free(error); } gdk_pixbuf_loader_close(loader, (GError**) 0); return image; }
Image* LoadDDSBuff( const byte* buffer ){ int width, height; ddsPF_t pixelFormat; if ( DDSGetInfo( reinterpret_cast<ddsBuffer_t*>( const_cast<byte*>( buffer ) ), &width, &height, &pixelFormat ) == -1 ) { return 0; } RGBAImage* image = new RGBAImage( width, height ); if ( DDSDecompress( reinterpret_cast<ddsBuffer_t*>( const_cast<byte*>( buffer ) ), image->getRGBAPixels() ) == -1 ) { image->release(); return 0; } return image; }
Image* LoadMDLImageBuff( byte* buffer ){ if ( !LoadPalette() ) { return 0; } if ( !ident_equal( buffer, MDL_IDENT ) ) { globalErrorStream() << "LoadMDLImage: data has wrong ident\n"; return 0; } PointerInputStream inputStream( buffer ); inputStream.seek( 4 + 4 + 12 + 12 + 4 + 12 ); //int numskins = istream_read_int32_le( inputStream ); int skinwidth = istream_read_int32_le( inputStream ); int skinheight = istream_read_int32_le( inputStream ); inputStream.seek( 4 + 4 + 4 + 4 + 4 + 4 ); switch ( istream_read_int32_le( inputStream ) ) { case MDL_SKIN_SINGLE: break; case MDL_SKIN_GROUP: int numskins = istream_read_int32_le( inputStream ); inputStream.seek( numskins * 4 ); break; } RGBAImage* image = new RGBAImage( skinwidth, skinheight ); unsigned char* pRGBA = image->getRGBAPixels(); for ( int i = 0; i < ( skinheight ); i++ ) { for ( int j = 0; j < ( skinwidth ); j++ ) { byte index = istream_read_byte( inputStream ); *pRGBA++ = mdl_palette[index * 3 + 0]; *pRGBA++ = mdl_palette[index * 3 + 1]; *pRGBA++ = mdl_palette[index * 3 + 2]; *pRGBA++ = 255; } } return image; }
Image* LoadIDSPBuff( byte *buffer ){ byte *buf_p; int columns, rows; byte *pixbuf; int row, column; byte *palette; unsigned char red, green, blue, alphabyte; dspriteheader_t *header; dspritev1_t *pinv1; dspritev2_t *pinv2; dspriteframetype_t *pframetype; int version; int numframes; dspriteframe_t *spriteframe; header = (dspriteheader_t *)buffer; if ( header->ident != IDSPRITEHEADER ) { globalWarningStream() << "WARNING: IDSP file has wrong header\n"; return 0; } version = header->version; if ( version != 1 && version != 2 ) { globalWarningStream() << "WARNING: IDSP file has wrong version number " "(" << version << " should be 1 or 2)\n"; return 0; } // initialise variables depending on the sprite version. switch ( version ) { case 1: pinv1 = (dspritev1_t *)( header + 1 ); numframes = pinv1->numframes; columns = pinv1->width; rows = pinv1->height; pframetype = (dspriteframetype_t *)( pinv1 + 1 ); break; case 2: pinv2 = (dspritev2_t *)( header + 1 ); numframes = pinv2->numframes; columns = pinv2->width; rows = pinv2->height; pframetype = (dspriteframetype_t *)( pinv2 + 1 ); break; default: globalWarningStream() << "WARNING: IDSP file has unsupported version\n"; return 0; } if ( numframes > 1 ) { globalWarningStream() << "WARNING: IDSP file has multiple frames, only the first frame will be used.\n"; } // palette = buffer+mipdatasize+2; // buf_p = buffer+lpMip->offsets[0]; RGBAImage* image = new RGBAImage( columns, rows ); #ifdef DEBUG frametype = spriteframetype_t( pframetype->type ); if ( frametype == SPR_SINGLE ) { globalOutputStream() << "Single Frame\n"; } else if ( frametype == SPR_GROUP ) { globalOutputStream() << "Group of Frames\n"; } else { globalWarningStream() << "Bleh!\n"; // <-- we always get this, wtf! } #endif palette = (byte *)( pframetype + 1 ); spriteframe = (dspriteframe_t *)( palette + ( 256 * 3 ) + 4 ); // what are those 4 extra bytes ? what's missing ? buf_p = (byte *)( spriteframe + 1 ); for ( row = 0; row < rows; row++ ) { pixbuf = image->getRGBAPixels() + row * columns * 4; for ( column = 0; column < columns; column++ ) { int palIndex; palIndex = *buf_p++; red = *( palette + ( palIndex * 3 ) ); green = *( palette + ( palIndex * 3 ) + 1 ); blue = *( palette + ( palIndex * 3 ) + 2 ); // HalfLife engine makes pixels that are BLUE transparent. (RGB = 0x0000FF) // So show them that way in the editor. if ( blue == 0xff && red == 0x00 && green == 0x00 ) { alphabyte = 0xff; //FIXME: backwards? (so sprite models to render correctly) blue = 0x00; // don't set the resulting pixel to blue } else { alphabyte = 0x00; //FIXME: backwards? (so sprite models to render correctly) } *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = alphabyte; } } return image; }