private static int LowLevelReadTGABitsFromBuffer(ImageBuffer imageToReadTo, byte[] wholeFileBuffer, int DestBitDepth) { STargaHeader TargaHeader = new STargaHeader(); int FileReadOffset; if (!ReadTGAInfo(wholeFileBuffer, out TargaHeader)) { return(0); } // if the frame we are loading is different then the one we have allocated // or we don't have any bits allocated if ((imageToReadTo.Width * imageToReadTo.Height) != (TargaHeader.Width * TargaHeader.Height)) { imageToReadTo.Allocate(TargaHeader.Width, TargaHeader.Height, TargaHeader.Width * DestBitDepth / 8, DestBitDepth); } // work out the line width switch (imageToReadTo.BitDepth) { case 24: TGABytesPerLine = imageToReadTo.Width * 3; if (imageToReadTo.GetRecieveBlender() == null) { imageToReadTo.SetRecieveBlender(new BlenderBGR()); } break; case 32: TGABytesPerLine = imageToReadTo.Width * 4; if (imageToReadTo.GetRecieveBlender() == null) { imageToReadTo.SetRecieveBlender(new BlenderBGRA()); } break; default: throw new System.Exception("Bad bit depth."); } if (TGABytesPerLine > 0) { byte[] BufferToDecompressTo = null; FileReadOffset = TargaHeaderSize + TargaHeader.PostHeaderSkip; if (TargaHeader.ImageType == 10) // 10 is RLE compressed { BufferToDecompressTo = new byte[TGABytesPerLine * 2]; } // read all the lines * for (int i = 0; i < imageToReadTo.Height; i++) { byte[] BufferToCopyFrom; int CopyOffset = 0; int CurReadLine; // bit 5 tells us if the image is stored top to bottom or bottom to top if ((TargaHeader.Descriptor & 0x20) != 0) { // bottom to top CurReadLine = imageToReadTo.Height - i - 1; } else { // top to bottom CurReadLine = i; } if (TargaHeader.ImageType == 10) // 10 is RLE compressed { FileReadOffset = Decompress(BufferToDecompressTo, wholeFileBuffer, FileReadOffset, imageToReadTo.Width, TargaHeader.BPP, CurReadLine); BufferToCopyFrom = BufferToDecompressTo; } else { BufferToCopyFrom = wholeFileBuffer; CopyOffset = FileReadOffset; } int bufferOffset; byte[] imageBuffer = imageToReadTo.GetBuffer(out bufferOffset); switch (imageToReadTo.BitDepth) { case 8: switch (TargaHeader.BPP) { case 24: Do24To8Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; case 32: Do32To8Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; } break; case 24: switch (TargaHeader.BPP) { case 24: Do24To24Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; case 32: Do32To24Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; } break; case 32: switch (TargaHeader.BPP) { case 24: Do24To32Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; case 32: Do32To32Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; } break; default: throw new System.Exception("Bad bit depth"); } if (TargaHeader.ImageType != 10) // 10 is RLE compressed { FileReadOffset += TGABytesPerLine; } } } return(TargaHeader.Width); }
private static bool ReadTGAInfo(byte[] WorkPtr, out STargaHeader TargaHeader) { TargaHeader.PostHeaderSkip = WorkPtr[0]; TargaHeader.ColorMapType = WorkPtr[1]; TargaHeader.ImageType = WorkPtr[2]; TargaHeader.ColorMapStart = BitConverter.ToUInt16(WorkPtr, 3); TargaHeader.ColorMapLength = BitConverter.ToUInt16(WorkPtr, 5); TargaHeader.ColorMapBits = WorkPtr[7]; TargaHeader.XStart = BitConverter.ToUInt16(WorkPtr, 8); TargaHeader.YStart = BitConverter.ToUInt16(WorkPtr, 10); TargaHeader.Width = BitConverter.ToUInt16(WorkPtr, 12); TargaHeader.Height = BitConverter.ToUInt16(WorkPtr, 14); TargaHeader.BPP = WorkPtr[16]; TargaHeader.Descriptor = WorkPtr[17]; // check the header if (TargaHeader.ColorMapType != 0 || // 0 = RGB, 1 = Palette // 1 = Palette, 2 = RGB, 3 = mono, 9 = RLE Palette, 10 = RLE RGB, 11 RLE mono (TargaHeader.ImageType != 2 && TargaHeader.ImageType != 10 && TargaHeader.ImageType != 9) || (TargaHeader.BPP != 24 && TargaHeader.BPP != 32)) { #if DEBUG throw new NotImplementedException("Unsupported TGA mode"); #endif #if ASSERTS_ENABLED if (((byte *)pTargaHeader)[0] == 'B' && ((byte *)pTargaHeader)[1] == 'M') { assert(!"This TGA's header looks like a BMP!"); // look at the first two bytes and see if they are 'BM' // if so it's a BMP not a TGA } else { byte *pColorMapType = NULL; switch (TargaHeader.ColorMapType) { case 0: pColorMapType = "RGB Color Map"; break; case 1: pColorMapType = "Palette Color Map"; break; default: pColorMapType = "<Illegal Color Map>"; break; } byte *pImageType = NULL; switch (TargaHeader.ImageType) { case 1: pImageType = "Palette Image Type"; break; case 2: pImageType = "RGB Image Type"; break; case 3: pImageType = "mono Image Type"; break; case 9: pImageType = "RLE Palette Image Type"; break; case 10: pImageType = "RLE RGB Image Type"; break; case 11: pImageType = "RLE mono Image Type"; break; default: pImageType = "<Illegal Image Type>"; break; } int ColorDepth = TargaHeader.BPP; CJString ErrorString; ErrorString.Format("Image type %s %s (%u bpp) not supported!", pColorMapType, pImageType, ColorDepth); ShowSystemMessage("TGA File IO Error", ErrorString.GetBytePtr(), "TGA Error"); } #endif // ASSERTS_ENABLED return(false); } return(true); }
private static unsafe int LowLevelReadTGABitsFromBuffer(ImageBuffer imageToReadTo, byte[] wholeFileBuffer, int DestBitDepth) { STargaHeader TargaHeader = new STargaHeader(); int FileReadOffset; if (!ReadTGAInfo(wholeFileBuffer, out TargaHeader)) { return 0; } // if the frame we are loading is different then the one we have allocated // or we don't have any bits allocated if ((imageToReadTo.Width * imageToReadTo.Height) != (TargaHeader.Width * TargaHeader.Height)) { imageToReadTo.Allocate(TargaHeader.Width, TargaHeader.Height, TargaHeader.Width * DestBitDepth / 8, DestBitDepth); } // work out the line width switch (imageToReadTo.BitDepth) { case 24: TGABytesPerLine = imageToReadTo.Width * 3; if (imageToReadTo.GetRecieveBlender() == null) { imageToReadTo.SetRecieveBlender(new BlenderBGR()); } break; case 32: TGABytesPerLine = imageToReadTo.Width * 4; if (imageToReadTo.GetRecieveBlender() == null) { imageToReadTo.SetRecieveBlender(new BlenderBGRA()); } break; default: throw new System.Exception("Bad bit depth."); } if (TGABytesPerLine > 0) { byte[] BufferToDecompressTo = null; FileReadOffset = TargaHeaderSize + TargaHeader.PostHeaderSkip; if (TargaHeader.ImageType == 10) // 10 is RLE compressed { BufferToDecompressTo = new byte[TGABytesPerLine * 2]; } // read all the lines * for (int i = 0; i < imageToReadTo.Height; i++) { byte[] BufferToCopyFrom; int CopyOffset = 0; int CurReadLine; // bit 5 tells us if the image is stored top to bottom or bottom to top if ((TargaHeader.Descriptor & 0x20) != 0) { // bottom to top CurReadLine = imageToReadTo.Height - i - 1; } else { // top to bottom CurReadLine = i; } if (TargaHeader.ImageType == 10) // 10 is RLE compressed { FileReadOffset = Decompress(BufferToDecompressTo, wholeFileBuffer, FileReadOffset, imageToReadTo.Width, TargaHeader.BPP, CurReadLine); BufferToCopyFrom = BufferToDecompressTo; } else { BufferToCopyFrom = wholeFileBuffer; CopyOffset = FileReadOffset; } int bufferOffset; byte[] imageBuffer = imageToReadTo.GetBuffer(out bufferOffset); switch (imageToReadTo.BitDepth) { case 8: switch (TargaHeader.BPP) { case 24: Do24To8Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; case 32: Do32To8Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; } break; case 24: switch (TargaHeader.BPP) { case 24: Do24To24Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; case 32: Do32To24Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; } break; case 32: switch (TargaHeader.BPP) { case 24: Do24To32Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; case 32: Do32To32Bit(imageBuffer, BufferToCopyFrom, CopyOffset, imageToReadTo.Width, CurReadLine); break; } break; default: throw new System.Exception("Bad bit depth"); } if (TargaHeader.ImageType != 10) // 10 is RLE compressed { FileReadOffset += TGABytesPerLine; } } } return TargaHeader.Width; }
private static bool ReadTGAInfo(byte[] WorkPtr, out STargaHeader TargaHeader) { TargaHeader.PostHeaderSkip = WorkPtr[0]; TargaHeader.ColorMapType = WorkPtr[1]; TargaHeader.ImageType = WorkPtr[2]; TargaHeader.ColorMapStart = BitConverter.ToUInt16(WorkPtr, 3); TargaHeader.ColorMapLength = BitConverter.ToUInt16(WorkPtr, 5); TargaHeader.ColorMapBits = WorkPtr[7]; TargaHeader.XStart = BitConverter.ToUInt16(WorkPtr, 8); TargaHeader.YStart = BitConverter.ToUInt16(WorkPtr, 10); TargaHeader.Width = BitConverter.ToUInt16(WorkPtr, 12); TargaHeader.Height = BitConverter.ToUInt16(WorkPtr, 14); TargaHeader.BPP = WorkPtr[16]; TargaHeader.Descriptor = WorkPtr[17]; // check the header if (TargaHeader.ColorMapType != 0 || // 0 = RGB, 1 = Palette // 1 = Palette, 2 = RGB, 3 = mono, 9 = RLE Palette, 10 = RLE RGB, 11 RLE mono (TargaHeader.ImageType != 2 && TargaHeader.ImageType != 10 && TargaHeader.ImageType != 9) || (TargaHeader.BPP != 24 && TargaHeader.BPP != 32)) { #if ASSERTS_ENABLED if ( ((byte*)pTargaHeader)[0] == 'B' && ((byte*)pTargaHeader)[1] == 'M' ) { assert(!"This TGA's header looks like a BMP!"); // look at the first two bytes and see if they are 'BM' // if so it's a BMP not a TGA } else { byte * pColorMapType = NULL; switch (TargaHeader.ColorMapType) { case 0: pColorMapType = "RGB Color Map"; break; case 1: pColorMapType = "Palette Color Map"; break; default: pColorMapType = "<Illegal Color Map>"; break; } byte * pImageType = NULL; switch (TargaHeader.ImageType) { case 1: pImageType = "Palette Image Type"; break; case 2: pImageType = "RGB Image Type"; break; case 3: pImageType = "mono Image Type"; break; case 9: pImageType = "RLE Palette Image Type"; break; case 10: pImageType = "RLE RGB Image Type"; break; case 11: pImageType = "RLE mono Image Type"; break; default: pImageType = "<Illegal Image Type>"; break; } int ColorDepth = TargaHeader.BPP; CJString ErrorString; ErrorString.Format( "Image type %s %s (%u bpp) not supported!", pColorMapType, pImageType, ColorDepth); ShowSystemMessage("TGA File IO Error", ErrorString.GetBytePtr(), "TGA Error"); } #endif // ASSERTS_ENABLED return false; } return true; }
static unsafe int LowLevelReadTGABitsFromBuffer(Image <T> Input, Byte[] WholeFileBuffer, int DestBitDepth) { STargaHeader TargaHeader = new STargaHeader(); int FileReadOffset; fixed(byte *pWorkPtr = WholeFileBuffer) { if (!ReadTGAInfo(pWorkPtr, out TargaHeader)) { return(0); } } // if the frame we are loading is different then the one we have allocated // or we don't have any bits allocated if ((Input.Width * Input.Height) != (TargaHeader.Width * TargaHeader.Height)) { Input.Allocate(TargaHeader.Width, TargaHeader.Height, DestBitDepth, TargaHeader.Width * DestBitDepth / 8); } // work out the line width switch (TargaHeader.BPP) { case 24: TGABytesPerLine = Input.Width * 3; break; case 32: TGABytesPerLine = Input.Width * 4; break; default: throw new System.Exception("Bad bit depth."); } if (TGABytesPerLine > 0) { Byte[] BufferToDecompressTo = null; FileReadOffset = TargaHeaderSize + TargaHeader.PostHeaderSkip; if (TargaHeader.ImageType == 10) // 10 is RLE compressed { BufferToDecompressTo = new Byte[TGABytesPerLine * 2]; } // read all the lines * for (int i = 0; i < Input.Height; i++) { Byte[] BufferToCopyFrom; int CopyOffset = 0; int CurReadLine; // bit 5 tells us if the image is stored top to bottom or bottom to top if ((TargaHeader.Descriptor & 0x20) != 0) { // top to bottom CurReadLine = i; } else { // bottom to top CurReadLine = Input.Height - i - 1; } if (TargaHeader.ImageType == 10) // 10 is RLE compressed { FileReadOffset = Decompress(BufferToDecompressTo, WholeFileBuffer, FileReadOffset, Input.Width, TargaHeader.BPP, CurReadLine); BufferToCopyFrom = BufferToDecompressTo; } else { BufferToCopyFrom = WholeFileBuffer; CopyOffset = FileReadOffset; } switch (Input.BitDepth) { case 8: switch (TargaHeader.BPP) { case 24: Do24To8Bit(Input.ImageBuffer, BufferToCopyFrom, CopyOffset, Input.Width, CurReadLine); break; case 32: Do32To8Bit(Input.ImageBuffer, BufferToCopyFrom, CopyOffset, Input.Width, CurReadLine); break; } break; case 24: switch (TargaHeader.BPP) { case 24: Do24To24Bit(Input.ImageBuffer, BufferToCopyFrom, CopyOffset, Input.Width, CurReadLine); break; case 32: Do32To24Bit(Input.ImageBuffer, BufferToCopyFrom, CopyOffset, Input.Width, CurReadLine); break; } break; case 32: switch (TargaHeader.BPP) { case 24: Do24To32Bit(Input.ImageBuffer, BufferToCopyFrom, CopyOffset, Input.Width, CurReadLine); break; case 32: Do32To32Bit(Input.ImageBuffer, BufferToCopyFrom, CopyOffset, Input.Width, CurReadLine); break; } break; default: throw new System.Exception("Bad bit depth"); } if (TargaHeader.ImageType != 10) // 10 is RLE compressed { FileReadOffset += TGABytesPerLine; } } } return(TargaHeader.Width); }
//********************************************************************************************************************* static unsafe bool ReadTGAInfo(Byte *WorkPtr, out STargaHeader TargaHeader) { TargaHeader.PostHeaderSkip = WorkPtr[0]; TargaHeader.ColorMapType = WorkPtr[1]; TargaHeader.ImageType = WorkPtr[2]; TargaHeader.ColorMapStart = *((ushort *)(&WorkPtr[3])); TargaHeader.ColorMapLength = *((ushort *)(&WorkPtr[5])); TargaHeader.ColorMapBits = WorkPtr[7]; TargaHeader.XStart = *((ushort *)(&WorkPtr[8])); TargaHeader.YStart = *((ushort *)(&WorkPtr[10])); TargaHeader.Width = *((ushort *)(&WorkPtr[12])); TargaHeader.Height = *((ushort *)(&WorkPtr[14])); TargaHeader.BPP = WorkPtr[16]; TargaHeader.Descriptor = WorkPtr[17]; // check the header if (TargaHeader.ColorMapType != 0 || // 0 = RGB, 1 = Palette // 1 = Palette, 2 = RGB, 3 = mono, 9 = RLE Palette, 10 = RLE RGB, 11 RLE mono (TargaHeader.ImageType != 2 && TargaHeader.ImageType != 10 && TargaHeader.ImageType != 9) || (TargaHeader.BPP != 24 && TargaHeader.BPP != 32)) { #if ASSERTS_ENABLED if (((Byte *)pTargaHeader)[0] == 'B' && ((Byte *)pTargaHeader)[1] == 'M') { assert(!"This TGA's header looks like a BMP!"); // look at the first two bytes and see if they are 'BM' // if so it's a BMP not a TGA } else { Byte *pColorMapType = NULL; switch (TargaHeader.ColorMapType) { case 0: pColorMapType = "RGB Color Map"; break; case 1: pColorMapType = "Palette Color Map"; break; default: pColorMapType = "<Illegal Color Map>"; break; } Byte *pImageType = NULL; switch (TargaHeader.ImageType) { case 1: pImageType = "Palette Image Type"; break; case 2: pImageType = "RGB Image Type"; break; case 3: pImageType = "mono Image Type"; break; case 9: pImageType = "RLE Palette Image Type"; break; case 10: pImageType = "RLE RGB Image Type"; break; case 11: pImageType = "RLE mono Image Type"; break; default: pImageType = "<Illegal Image Type>"; break; } int ColorDepth = TargaHeader.BPP; CJString ErrorString; ErrorString.Format("Image type %s %s (%u bpp) not supported!", pColorMapType, pImageType, ColorDepth); ShowSystemMessage("TGA File IO Error", ErrorString.GetBytePtr()); } #endif // ASSERTS_ENABLED return(false); } return(true); }