#include "ProxyHeaders.hpp" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Proxies::WriteTargaFile( const char* filename, int width, int height, DynamicArrayOf &data ) { Check_Pointer(filename); Check_Object(&data); // //--------------------------------------------- // Get the size of the image we will be copying //--------------------------------------------- // TargaHeader targa_header; memset(&targa_header, 0, sizeof(targa_header)); targa_header.widthLow = static_cast(width & 255); targa_header.widthHigh = static_cast(width >> 8); targa_header.heightLow = static_cast(height & 255); targa_header.heightHigh = static_cast(height >> 8); targa_header.imageType = TargaHeader::RLERGB; targa_header.pixelSize = 24; targa_header.flags = TargaHeader::YReversed; // //--------------------- // Write out the header //--------------------- // Check_Object(FileStreamManager::Instance); FileStream targa_file(filename, FileStream::WriteOnly); targa_file.WriteBytes(&targa_header, sizeof(targa_header)); // //---------------------------------------------- // See if we need to deal with the alpha channel //---------------------------------------------- // unsigned channel_size = height * width; Verify(channel_size == data.GetLength()); unsigned pixel_size = 3; unsigned buffer_size = channel_size * pixel_size; DynamicArrayOf buffer(buffer_size); unsigned p = 0; unsigned max_row = Min(width, 128); // //------------------------------------- // Start trying to make an RLE encoding //------------------------------------- // int i=0; while (i 0 && rle_count <= 128); buffer[p++] = static_cast(rle_count + 127); buffer[p++] = data[i].blue; buffer[p++] = data[i].green; buffer[p++] = data[i].red; i = j; } // //------------------------------------------------------------- // This is a singleton run, so check out its space requirements //------------------------------------------------------------- // else { if (buffer_size-p < (pixel_size*rle_count)+1) goto No_RLE; // //--------------- // Write them out //--------------- // Verify(rle_count > 0 && rle_count <= 128); buffer[p++] = static_cast(rle_count-1); for (; i &data ) { Check_Pointer(filename); Check_Object(&data); // //--------------------------------------------- // Get the size of the image we will be copying //--------------------------------------------- // TargaHeader targa_header; memset(&targa_header, 0, sizeof(targa_header)); targa_header.widthLow = static_cast(width & 255); targa_header.widthHigh = static_cast(width >> 8); targa_header.heightLow = static_cast(height & 255); targa_header.heightHigh = static_cast(height >> 8); targa_header.imageType = TargaHeader::RLERGB; targa_header.pixelSize = 32; targa_header.flags = TargaHeader::YReversed; // //--------------------- // Write out the header //--------------------- // Check_Object(FileStreamManager::Instance); FileStream targa_file(filename, FileStream::WriteOnly); targa_file.WriteBytes(&targa_header, sizeof(targa_header)); // //---------------------------------------------- // See if we need to deal with the alpha channel //---------------------------------------------- // unsigned channel_size = height * width; Verify(channel_size == data.GetLength()); unsigned pixel_size = 4; unsigned buffer_size = channel_size * pixel_size; DynamicArrayOf buffer(buffer_size); unsigned p = 0; unsigned max_row = Min(width, 128); // //------------------------------------- // Start trying to make an RLE encoding //------------------------------------- // int i=0; while (i 0 && rle_count <= 128); buffer[p++] = static_cast(rle_count + 127); buffer[p++] = data[i].blue; buffer[p++] = data[i].green; buffer[p++] = data[i].red; buffer[p++] = data[i].alpha; i = j; } // //------------------------------------------------------------- // This is a singleton run, so check out its space requirements //------------------------------------------------------------- // else { if (buffer_size-p < (pixel_size*rle_count)+1) goto No_RLE; // //--------------- // Write them out //--------------- // Verify(rle_count > 0 && rle_count <= 128); buffer[p++] = static_cast(rle_count-1); for (; iReadBytes(header, sizeof(*header)); *width = static_cast(header->widthLow) + (static_cast(header->widthHigh)<<8); *height = static_cast(header->heightLow) + (static_cast(header->heightHigh)<<8); Verify(header->pixelSize == 24 || header->pixelSize == 32); *red_depth = 8; *green_depth = 8; *blue_depth = 8; *alpha_depth = (header->pixelSize == 24) ? 0 : 8; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Proxies::ReadTargaChannels( MemoryStream *file, TargaHeader *header, DynamicArrayOf *data ) { Check_Object(file); Check_Pointer(header); Check_Object(data); // //---------------------------- // Read the file into a buffer //---------------------------- // unsigned len = file->GetBytesRemaining(); DynamicArrayOf buffer(len); file->ReadBytes(&buffer[0], len); // //----------------------------- // Set up the process variables //----------------------------- // bool x_reversed = ((header->flags & TargaHeader::XReversed) != 0), y_reversed = ((header->flags & TargaHeader::YReversed) != 0), compressed = (header->imageType == TargaHeader::RLERGB); unsigned width = static_cast(header->widthLow) + (static_cast(header->widthHigh)<<8); unsigned height = static_cast(header->heightLow) + (static_cast(header->heightHigh)<<8); BYTE run_count = 0, copy_count = 0, control_byte = 0, red = 0, green = 0, blue = 0; unsigned dest = ((y_reversed) ? 0 : width * (height-1)), source = 0; if (x_reversed) dest += width; // //------------------------ // Spin through each texel //------------------------ // for (unsigned y=0; y= 128) run_count = static_cast(control_byte-128); else copy_count = control_byte; } else if (run_count) run_count--; else if (copy_count) copy_count--; } // //----------------------------------- // Otherwise, just get the next color //----------------------------------- // else { blue = buffer[source++]; green = buffer[source++]; red = buffer[source++]; } // //------------------------------ // Put the color in the channels //------------------------------ // if (x_reversed) { (*data)[--dest].red = red; (*data)[dest].green = green; (*data)[dest].blue = blue; } else { (*data)[dest].red = red; (*data)[dest].green = green; (*data)[dest++].blue = blue; } } // //----------------------------- // Move the destination pointer //----------------------------- // if (x_reversed == y_reversed) dest += ((y_reversed) ? 2 : -2) * width; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Proxies::ReadTargaChannels( MemoryStream *file, TargaHeader *header, DynamicArrayOf *data ) { Check_Object(file); Check_Pointer(header); Check_Object(data); // //---------------------------- // Read the file into a buffer //---------------------------- // unsigned len = file->GetBytesRemaining(); DynamicArrayOf buffer(len); file->ReadBytes(&buffer[0], len); // //----------------------------- // Set up the process variables //----------------------------- // bool x_reversed = ((header->flags & TargaHeader::XReversed) != 0), y_reversed = ((header->flags & TargaHeader::YReversed) != 0), compressed = (header->imageType == TargaHeader::RLERGB); unsigned width = static_cast(header->widthLow) + (static_cast(header->widthHigh)<<8); unsigned height = static_cast(header->heightLow) + (static_cast(header->heightHigh)<<8); BYTE run_count = 0, copy_count = 0, control_byte = 0, red = 0, green = 0, blue = 0, alpha = 0; unsigned dest = ((y_reversed) ? 0 : width * (height-1)), source = 0; if (x_reversed) dest += width; // //------------------------ // Spin through each texel //------------------------ // for (unsigned y=0; y= 128) run_count = static_cast(control_byte-128); else copy_count = control_byte; } else if (run_count) run_count--; else if (copy_count) copy_count--; } // //----------------------------------- // Otherwise, just get the next color //----------------------------------- // else { blue = buffer[source++]; green = buffer[source++]; red = buffer[source++]; alpha = buffer[source++]; } // //------------------------------ // Put the color in the channels //------------------------------ // if (x_reversed) { (*data)[--dest].red = red; (*data)[dest].green = green; (*data)[dest].blue = blue; (*data)[dest].alpha = alpha; } else { (*data)[dest].red = red; (*data)[dest].green = green; (*data)[dest].blue = blue; (*data)[dest++].alpha = alpha; } } // //----------------------------- // Move the destination pointer //----------------------------- // if (x_reversed == y_reversed) dest += ((y_reversed) ? 2 : -2) * width; } }