static void decodeStandard16( System.Drawing.Imaging.BitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { // i must convert the input stream to a sequence of uint values // which I then unpack. tgaCD cd = new tgaCD(); cd.RMask = 0x00f80000; // from 0xF800 cd.GMask = 0x0000fc00; // from 0x07E0 cd.BMask = 0x000000f8; // from 0x001F cd.AMask = 0x00000000; cd.RShift = 8; cd.GShift = 5; cd.BShift = 3; cd.AShift = 0; cd.FinalOr = 0xff000000; if (hdr.RleEncoded) { decodeRle(b, 2, cd, br, hdr.ImageSpec.BottomUp); } else { decodePlain(b, 2, cd, br, hdr.ImageSpec.BottomUp); } }
static void decodeStandard32(System.Drawing.Imaging.BitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { // i must convert the input stream to a sequence of uint values // which I then unpack. tgaCD cd = new tgaCD(); cd.RMask = 0x00ff0000; cd.GMask = 0x0000ff00; cd.BMask = 0x000000ff; cd.AMask = 0xff000000; cd.RShift = 0; cd.GShift = 0; cd.BShift = 0; cd.AShift = 0; cd.FinalOr = 0x00000000; cd.NeedNoConvert = true; if (hdr.RleEncoded) { decodeRle(b, 4, cd, br, hdr.ImageSpec.BottomUp); } else { decodePlain(b, 4, cd, br, hdr.ImageSpec.BottomUp); } }
static void decodeSpecial16( BitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { // i must convert the input stream to a sequence of uint values // which I then unpack. tgaCD cd = new tgaCD(); cd.RMask = 0x00f00000; cd.GMask = 0x0000f000; cd.BMask = 0x000000f0; cd.AMask = 0xf0000000; cd.RShift = 12; cd.GShift = 8; cd.BShift = 4; cd.AShift = 16; cd.FinalOr = 0; if (hdr.RleEncoded) { decodeRle(b, 2, cd, br, hdr.ImageSpec.BottomUp); } else { decodePlain(b, 2, cd, br, hdr.ImageSpec.BottomUp); } }
static void decodeStandard8( System.Drawing.Imaging.BitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { tgaCD cd = new tgaCD(); cd.RMask = 0x000000ff; cd.GMask = 0x000000ff; cd.BMask = 0x000000ff; cd.AMask = 0x000000ff; cd.RShift = 0; cd.GShift = 0; cd.BShift = 0; cd.AShift = 0; cd.FinalOr = 0x00000000; if (hdr.RleEncoded) { decodeRle(b, 1, cd, br, hdr.ImageSpec.BottomUp); } else { decodePlain(b, 1, cd, br, hdr.ImageSpec.BottomUp); } }
static unsafe void decodeLine( System.Drawing.Imaging.BitmapData b, int line, int byp, byte[] data, ref tgaCD cd) { if (cd.NeedNoConvert) { // fast copy uint *linep = (uint *)((byte *)b.Scan0.ToPointer() + line * b.Stride); fixed(byte *ptr = data) { uint *sptr = (uint *)ptr; for (int i = 0; i < b.Width; ++i) { linep[i] = sptr[i]; } } } else { byte *linep = (byte *)b.Scan0.ToPointer() + line * b.Stride; uint *up = (uint *)linep; int rdi = 0; fixed(byte *ptr = data) { for (int i = 0; i < b.Width; ++i) { uint x = 0; for (int j = 0; j < byp; ++j) { x |= ((uint)ptr[rdi]) << (j << 3); ++rdi; } up[i] = UnpackColor(x, ref cd); } } } }
static uint UnpackColor( uint sourceColor, ref tgaCD cd) { if (cd.RMask == 0xFF && cd.GMask == 0xFF && cd.BMask == 0xFF) { // Special case to deal with 8-bit TGA files that we treat as alpha masks return(sourceColor << 24); } else { uint rpermute = (sourceColor << cd.RShift) | (sourceColor >> (32 - cd.RShift)); uint gpermute = (sourceColor << cd.GShift) | (sourceColor >> (32 - cd.GShift)); uint bpermute = (sourceColor << cd.BShift) | (sourceColor >> (32 - cd.BShift)); uint apermute = (sourceColor << cd.AShift) | (sourceColor >> (32 - cd.AShift)); uint result = (rpermute & cd.RMask) | (gpermute & cd.GMask) | (bpermute & cd.BMask) | (apermute & cd.AMask) | cd.FinalOr; return(result); } }
static uint UnpackColor( uint sourceColor, ref tgaCD cd) { uint rpermute = (sourceColor << cd.RShift) | (sourceColor >> (32 - cd.RShift)); uint gpermute = (sourceColor << cd.GShift) | (sourceColor >> (32 - cd.GShift)); uint bpermute = (sourceColor << cd.BShift) | (sourceColor >> (32 - cd.BShift)); uint apermute = (sourceColor << cd.AShift) | (sourceColor >> (32 - cd.AShift)); uint result = (rpermute & cd.RMask) | (gpermute & cd.GMask) | (bpermute & cd.BMask) | (apermute & cd.AMask) | cd.FinalOr; /*if (result >= 0x10000000) * result |= 0x0F000000; * /*else if (result >= 0x10000000) * result = 0x66222222;*/ /*else * result = 0;*/ return(result); }
static void decodePlain( System.Drawing.Imaging.BitmapData b, int byp, tgaCD cd, System.IO.BinaryReader br, bool bottomUp) { int w = b.Width; byte[] linebuffer = new byte[w * byp]; for (int j = 0; j < b.Height; ++j) { br.Read(linebuffer, 0, w * byp); if (!bottomUp) { decodeLine(b, b.Height - j - 1, byp, linebuffer, ref cd); } else { decodeLine(b, j, byp, linebuffer, ref cd); } } }
static void decodeStandard32(System.Drawing.Imaging.BitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { // i must convert the input stream to a sequence of uint values // which I then unpack. tgaCD cd = new tgaCD(); cd.RMask = 0x00ff0000; cd.GMask = 0x0000ff00; cd.BMask = 0x000000ff; cd.AMask = 0xff000000; cd.RShift = 0; cd.GShift = 0; cd.BShift = 0; cd.AShift = 0; cd.FinalOr = 0x00000000; cd.NeedNoConvert = true; if (hdr.RleEncoded) decodeRle(b, 4, cd, br, hdr.ImageSpec.BottomUp); else decodePlain(b, 4, cd, br, hdr.ImageSpec.BottomUp); }
static void decodeStandard16( System.Drawing.Imaging.BitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { // i must convert the input stream to a sequence of uint values // which I then unpack. tgaCD cd = new tgaCD(); cd.RMask = 0x00f80000; // from 0xF800 cd.GMask = 0x0000fc00; // from 0x07E0 cd.BMask = 0x000000f8; // from 0x001F cd.AMask = 0x00000000; cd.RShift = 8; cd.GShift = 5; cd.BShift = 3; cd.AShift = 0; cd.FinalOr = 0xff000000; if (hdr.RleEncoded) decodeRle(b, 2, cd, br, hdr.ImageSpec.BottomUp); else decodePlain(b, 2, cd, br, hdr.ImageSpec.BottomUp); }
static void decodeStandard8( System.Drawing.Imaging.BitmapData b, tgaHeader hdr, System.IO.BinaryReader br) { tgaCD cd = new tgaCD(); cd.RMask = 0x000000ff; cd.GMask = 0x000000ff; cd.BMask = 0x000000ff; cd.AMask = 0x000000ff; cd.RShift = 0; cd.GShift = 0; cd.BShift = 0; cd.AShift = 0; cd.FinalOr = 0x00000000; if (hdr.RleEncoded) decodeRle(b, 1, cd, br, hdr.ImageSpec.BottomUp); else decodePlain(b, 1, cd, br, hdr.ImageSpec.BottomUp); }
static void decodePlain( System.Drawing.Imaging.BitmapData b, int byp, tgaCD cd, System.IO.BinaryReader br, bool bottomUp) { int w = b.Width; byte[] linebuffer = new byte[w * byp]; for (int j = 0; j < b.Height; ++j) { br.Read(linebuffer, 0, w * byp); if (!bottomUp) decodeLine(b, b.Height - j - 1, byp, linebuffer, ref cd); else decodeLine(b, j, byp, linebuffer, ref cd); } }
static void decodeRle( System.Drawing.Imaging.BitmapData b, int byp, tgaCD cd, System.IO.BinaryReader br, bool bottomUp) { try { int w = b.Width; // make buffer larger, so in case of emergency I can decode // over line ends. byte[] linebuffer = new byte[(w + 128) * byp]; int maxindex = w * byp; int index = 0; for (int j = 0; j < b.Height; ++j) { while (index < maxindex) { byte blocktype = br.ReadByte(); int bytestoread; int bytestocopy; if (blocktype >= 0x80) { bytestoread = byp; bytestocopy = byp * (blocktype - 0x80); } else { bytestoread = byp * (blocktype + 1); bytestocopy = 0; } //if (index + bytestoread > maxindex) // throw new System.ArgumentException ("Corrupt TGA"); br.Read(linebuffer, index, bytestoread); index += bytestoread; for (int i = 0; i != bytestocopy; ++i) { linebuffer[index + i] = linebuffer[index + i - bytestoread]; } index += bytestocopy; } if (!bottomUp) decodeLine(b, b.Height - j - 1, byp, linebuffer, ref cd); else decodeLine(b, j, byp, linebuffer, ref cd); if (index > maxindex) { Array.Copy(linebuffer, maxindex, linebuffer, 0, index - maxindex); index -= maxindex; } else index = 0; } } catch (System.IO.EndOfStreamException) { } }
static unsafe void decodeLine( System.Drawing.Imaging.BitmapData b, int line, int byp, byte[] data, ref tgaCD cd) { if (cd.NeedNoConvert) { // fast copy uint* linep = (uint*)((byte*)b.Scan0.ToPointer() + line * b.Stride); fixed (byte* ptr = data) { uint* sptr = (uint*)ptr; for (int i = 0; i < b.Width; ++i) { linep[i] = sptr[i]; } } } else { byte* linep = (byte*)b.Scan0.ToPointer() + line * b.Stride; uint* up = (uint*)linep; int rdi = 0; fixed (byte* ptr = data) { for (int i = 0; i < b.Width; ++i) { uint x = 0; for (int j = 0; j < byp; ++j) { x |= ((uint)ptr[rdi]) << (j << 3); ++rdi; } up[i] = UnpackColor(x, ref cd); } } } }
static uint UnpackColor( uint sourceColor, ref tgaCD cd) { if (cd.RMask == 0xFF && cd.GMask == 0xFF && cd.BMask == 0xFF) { // Special case to deal with 8-bit TGA files that we treat as alpha masks return sourceColor << 24; } else { uint rpermute = (sourceColor << cd.RShift) | (sourceColor >> (32 - cd.RShift)); uint gpermute = (sourceColor << cd.GShift) | (sourceColor >> (32 - cd.GShift)); uint bpermute = (sourceColor << cd.BShift) | (sourceColor >> (32 - cd.BShift)); uint apermute = (sourceColor << cd.AShift) | (sourceColor >> (32 - cd.AShift)); uint result = (rpermute & cd.RMask) | (gpermute & cd.GMask) | (bpermute & cd.BMask) | (apermute & cd.AMask) | cd.FinalOr; return result; } }
static void decodeRle( System.Drawing.Imaging.BitmapData b, int byp, tgaCD cd, System.IO.BinaryReader br, bool bottomUp) { try { int w = b.Width; // make buffer larger, so in case of emergency I can decode // over line ends. byte[] linebuffer = new byte[(w + 128) * byp]; int maxindex = w * byp; int index = 0; for (int j = 0; j < b.Height; ++j) { while (index < maxindex) { byte blocktype = br.ReadByte(); int bytestoread; int bytestocopy; if (blocktype >= 0x80) { bytestoread = byp; bytestocopy = byp * (blocktype - 0x80); } else { bytestoread = byp * (blocktype + 1); bytestocopy = 0; } //if (index + bytestoread > maxindex) // throw new System.ArgumentException ("Corrupt TGA"); br.Read(linebuffer, index, bytestoread); index += bytestoread; for (int i = 0; i != bytestocopy; ++i) { linebuffer[index + i] = linebuffer[index + i - bytestoread]; } index += bytestocopy; } if (!bottomUp) { decodeLine(b, b.Height - j - 1, byp, linebuffer, ref cd); } else { decodeLine(b, j, byp, linebuffer, ref cd); } if (index > maxindex) { Array.Copy(linebuffer, maxindex, linebuffer, 0, index - maxindex); index -= maxindex; } else { index = 0; } } } catch (System.IO.EndOfStreamException) { } }