private void DrawPixels(ClutDefinitionSegment cds, int pixelCode, int runLength, ref int x, ref int y) { var c = Color.Red; if (cds != null) { foreach (var item in cds.Entries) { if (item.ClutEntryId == pixelCode) { c = item.GetColor(); break; } } } for (int k = 0; k < runLength; k++) { if (y < _fastImage.Height && x < _fastImage.Width) { _fastImage.SetPixel(x, y, c); } x++; } }
public Bitmap GetImage(ObjectDataSegment ods) { if (SubtitleSegments == null) { ParseSegments(); } if (ods.Image != null) { return(ods.Image); } ClutDefinitionSegment cds = GetClutDefinitionSegment(ods); ods.DecodeImage(_dataBuffer, ods.BufferIndex, cds); return(ods.Image); }
public void DecodeImage(byte[] buffer, int index, ClutDefinitionSegment cds) { if (ObjectCodingMethod == 0) { var twoToFourBitColorLookup = new List <int> { 0, 1, 2, 3 }; var twoToEightBitColorLookup = new List <int> { 0, 1, 2, 3 }; var fourToEightBitColorLookup = new List <int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; int pixelCode = 0; int runLength = 0; int dataType = buffer[index + 7]; int length = TopFieldDataBlockLength; if (length + index + 7 > buffer.Length) // check if buffer is large enough { Image = new Bitmap(1, 1); return; } index += 8; int start = index; int x = 0; int y = 0; // Pre-decoding to determine image size int width = 0; while (index < start + TopFieldDataBlockLength) { index = CalculateSize(buffer, index, ref dataType, start, ref x, ref y, length, ref runLength, ref width); } if (width > 2000) { width = 2000; } if (y > 500) { y = 500; } Image = new Bitmap(width, y + 1); _fastImage = new FastBitmap(Image); _fastImage.LockImage(); x = 0; y = 0; index = start; while (index < start + TopFieldDataBlockLength) { index = ProcessDataType(buffer, index, cds, ref dataType, start, twoToFourBitColorLookup, fourToEightBitColorLookup, twoToEightBitColorLookup, ref x, ref y, length, ref pixelCode, ref runLength); } x = 0; y = 1; if (BottomFieldDataBlockLength == 0) { index = start; } else { length = BottomFieldDataBlockLength; index = start + TopFieldDataBlockLength; start = index; } dataType = buffer[index - 1]; while (index < start + BottomFieldDataBlockLength - 1) { index = ProcessDataType(buffer, index, cds, ref dataType, start, twoToFourBitColorLookup, fourToEightBitColorLookup, twoToEightBitColorLookup, ref x, ref y, length, ref pixelCode, ref runLength); } _fastImage.UnlockImage(); } else if (ObjectCodingMethod == 1) { Image = new Bitmap(1, 1); NumberOfCodes = buffer[index + 3]; } }
private int ProcessDataType(byte[] buffer, int index, ClutDefinitionSegment cds, ref int dataType, int start, List <int> twoToFourBitColorLookup, List <int> fourToEightBitColorLookup, List <int> twoToEightBitColorLookup, ref int x, ref int y, int length, ref int pixelCode, ref int runLength) { if (dataType == PixelDecoding2Bit) { int bitIndex = 0; while (index < start + length - 1 && TwoBitPixelDecoding(buffer, ref index, ref bitIndex, out pixelCode, out runLength)) { DrawPixels(cds, twoToFourBitColorLookup[pixelCode], runLength, ref x, ref y); } } else if (dataType == PixelDecoding4Bit) { bool startHalf = false; while (index < start + length - 1 && FourBitPixelDecoding(buffer, ref index, ref startHalf, out pixelCode, out runLength)) { DrawPixels(cds, fourToEightBitColorLookup[pixelCode], runLength, ref x, ref y); } } else if (dataType == PixelDecoding8Bit) { while (index < start + length - 1 && EightBitPixelDecoding(buffer, ref index, out pixelCode, out runLength)) { DrawPixels(cds, pixelCode, runLength, ref x, ref y); } } else if (dataType == MapTable2To4Bit) { //4 entry numbers of 4-bits each; entry number 0 first, entry number 3 last twoToFourBitColorLookup[0] = buffer[index] >> 4; twoToFourBitColorLookup[1] = buffer[index] & Helper.B00001111; index++; twoToFourBitColorLookup[2] = buffer[index] >> 4; twoToFourBitColorLookup[3] = buffer[index] & Helper.B00001111; index++; } else if (dataType == MapTable2To8Bit) { //4 entry numbers of 8-bits each; entry number 0 first, entry number 3 last twoToEightBitColorLookup[0] = buffer[index]; index++; twoToEightBitColorLookup[1] = buffer[index]; index++; twoToEightBitColorLookup[2] = buffer[index]; index++; twoToEightBitColorLookup[3] = buffer[index]; index++; } else if (dataType == MapTable4To8Bit) { // 16 entry numbers of 8-bits each for (int k = 0; k < 16; k++) { fourToEightBitColorLookup[k] = buffer[index]; index++; } } else if (dataType == EndOfObjectLineCode) { x = 0; y += 2; // interlaced - skip one line } if (index < start + length) { dataType = buffer[index]; index++; } return(index); }
public void DecodeImage(byte[] buffer, int index, ClutDefinitionSegment cds) { if (ObjectCodingMethod == 0) { var twoToFourBitColorLookup = new List<int> { 0, 1, 2, 3 }; var twoToEightBitColorLookup = new List<int> { 0, 1, 2, 3 }; var fourToEightBitColorLookup = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; int pixelCode = 0; int runLength = 0; int dataType = buffer[index + 7]; int length = TopFieldDataBlockLength; index += 8; int start = index; int x = 0; int y = 0; // Pre-decoding to determine image size int width = 0; while (index < start + TopFieldDataBlockLength) { index = CalculateSize(buffer, index, ref dataType, start, ref x, ref y, length, ref runLength, ref width); } if (width > 2000) width = 2000; if (y > 500) y = 500; Image = new Bitmap(width, y + 1); _fastImage = new FastBitmap(Image); _fastImage.LockImage(); x = 0; y = 0; index = start; while (index < start + TopFieldDataBlockLength) { index = ProcessDataType(buffer, index, cds, ref dataType, start, twoToFourBitColorLookup, fourToEightBitColorLookup, twoToEightBitColorLookup, ref x, ref y, length, ref pixelCode, ref runLength); } x = 0; y = 1; if (BottomFieldDataBlockLength == 0) { index = start; } else { length = BottomFieldDataBlockLength; index = start + TopFieldDataBlockLength; start = index; } dataType = buffer[index - 1]; while (index < start + BottomFieldDataBlockLength - 1) { index = ProcessDataType(buffer, index, cds, ref dataType, start, twoToFourBitColorLookup, fourToEightBitColorLookup, twoToEightBitColorLookup, ref x, ref y, length, ref pixelCode, ref runLength); } _fastImage.UnlockImage(); } else if (ObjectCodingMethod == 1) { Image = new Bitmap(1, 1); NumberOfCodes = buffer[index + 3]; } }
private int ProcessDataType(byte[] buffer, int index, ClutDefinitionSegment cds, ref int dataType, int start, List<int> twoToFourBitColorLookup, List<int> fourToEightBitColorLookup, List<int> twoToEightBitColorLookup, ref int x, ref int y, int length, ref int pixelCode, ref int runLength) { if (dataType == PixelDecoding2Bit) { int bitIndex = 0; while (index < start + length - 1 && TwoBitPixelDecoding(buffer, ref index, ref bitIndex, out pixelCode, out runLength)) { DrawPixels(cds, twoToFourBitColorLookup[pixelCode], runLength, ref x, ref y); } } else if (dataType == PixelDecoding4Bit) { bool startHalf = false; while (index < start + length - 1 && FourBitPixelDecoding(buffer, ref index, ref startHalf, out pixelCode, out runLength)) { DrawPixels(cds, fourToEightBitColorLookup[pixelCode], runLength, ref x, ref y); } } else if (dataType == PixelDecoding8Bit) { while (index < start + length - 1 && EightBitPixelDecoding(buffer, ref index, out pixelCode, out runLength)) { DrawPixels(cds, pixelCode, runLength, ref x, ref y); } } else if (dataType == MapTable2To4Bit) { //4 entry numbers of 4-bits each; entry number 0 first, entry number 3 last twoToFourBitColorLookup[0] = buffer[index] >> 4; twoToFourBitColorLookup[1] = buffer[index] & Helper.B00001111; index++; twoToFourBitColorLookup[2] = buffer[index] >> 4; twoToFourBitColorLookup[3] = buffer[index] & Helper.B00001111; index++; } else if (dataType == MapTable2To8Bit) { //4 entry numbers of 8-bits each; entry number 0 first, entry number 3 last twoToEightBitColorLookup[0] = buffer[index]; index++; twoToEightBitColorLookup[1] = buffer[index]; index++; twoToEightBitColorLookup[2] = buffer[index]; index++; twoToEightBitColorLookup[3] = buffer[index]; index++; } else if (dataType == MapTable4To8Bit) { // 16 entry numbers of 8-bits each for (int k = 0; k < 16; k++) { fourToEightBitColorLookup[k] = buffer[index]; index++; } } else if (dataType == EndOfObjectLineCode) { x = 0; y += 2; // interlaced - skip one line } if (index < start + length) { dataType = buffer[index]; index++; } return index; }
private void DrawPixels(ClutDefinitionSegment cds, int pixelCode, int runLength, ref int x, ref int y) { var c = Color.Red; if (cds != null) { foreach (var item in cds.Entries) { if (item.ClutEntryId == pixelCode) { c = item.GetColor(); break; } } } for (int k = 0; k < runLength; k++) { if (y < _fastImage.Height && x < _fastImage.Width) _fastImage.SetPixel(x, y, c); x++; } }