public override System.Drawing.Bitmap ExtractImage() { byte[] imageData = new byte[ImageDataSize]; Array.Copy(RawData, DataOffset, imageData, 0, imageData.Length); if (imageData.Select((v, i) => (v == PNGHeader[i])).All(b => b) || imageData.Select((v, i) => (v == GIFHeader[i])).All(b => b)) { // png or gif return(BitmapFromBytes(imageData, 0, imageData.Length)); } else { // jpeg with alpha using (var imageStream = new MemoryStream(imageData)) { using (var rawjpeg = new Bitmap(imageStream)) { BitmapData rawjpegdata = rawjpeg.LockBits(new Rectangle(0, 0, rawjpeg.Width, rawjpeg.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); byte[] rawjpegCanvas = new byte[rawjpegdata.Stride * rawjpeg.Height]; Marshal.Copy(rawjpegdata.Scan0, rawjpegCanvas, 0, rawjpegCanvas.Length); byte[] alphaCanvas = TagUtilities.DecompressDeflate(RawData, DataOffset + ImageDataSize, DataLength - ImageDataSize, rawjpeg.Width * rawjpeg.Height); var result = new Bitmap(rawjpeg.Width, rawjpeg.Height, PixelFormat.Format32bppPArgb); BitmapData resultData = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppPArgb); byte[] resultCanvas = new byte[resultData.Stride * resultData.Height]; int width = rawjpegdata.Width; int width_in = rawjpegdata.Stride; int width_out = resultData.Stride; int height = rawjpegdata.Height; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int i = y * width_out + x * 4; int j = y * width_in + x * 3; resultCanvas[i + 3] = alphaCanvas[y * width + x]; resultCanvas[i + 2] = rawjpegCanvas[j + 2]; resultCanvas[i + 1] = rawjpegCanvas[j + 1]; resultCanvas[i + 0] = rawjpegCanvas[j + 0]; } } Marshal.Copy(resultCanvas, 0, resultData.Scan0, resultCanvas.Length); result.UnlockBits(resultData); return(result); } } } }
internal DefineSound(byte[] data, int offset) : base(data, offset) { SoundFormat = (SoundFormat)TagUtilities.PickBits(data, DataOffset, 0, 4); SoundRate = (int)TagUtilities.PickBits(data, DataOffset, 4, 2); SoundSize = (int)TagUtilities.PickBits(data, DataOffset, 6, 1); IsStereo = TagUtilities.PickBits(data, DataOffset, 7, 1) != 0; SampleCount = (int)TagUtilities.PickBytes32(data, DataOffset + 1); DataOffset += 5; }
public override System.Drawing.Bitmap ExtractImage() { switch (BitmapFormat) { case BitsLossless2BitmapFormat.Format8bppIndexed: { byte[] decompressed = TagUtilities.DecompressDeflate(RawData, DataOffset, DataLength, ColorTableSize * 4 + TagUtilities.GetStride(BitmapSize.Width) * BitmapSize.Height); var result = new Bitmap(BitmapSize.Width, BitmapSize.Height, PixelFormat.Format8bppIndexed); var palette = result.Palette; for (int i = 0; i < ColorTableSize; i++) { // 乗算済みカラーを通常色に戻す palette.Entries[i] = Color.FromArgb(decompressed[i * 4 + 3], decompressed[i * 4 + 3] == 0 ? 0 : decompressed[i * 4 + 0] * 255 / decompressed[i * 4 + 3], decompressed[i * 4 + 3] == 0 ? 0 : decompressed[i * 4 + 1] * 255 / decompressed[i * 4 + 3], decompressed[i * 4 + 3] == 0 ? 0 : decompressed[i * 4 + 2] * 255 / decompressed[i * 4 + 3]); } result.Palette = palette; BitmapData resultData = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); Marshal.Copy(decompressed, ColorTableSize * 4, resultData.Scan0, resultData.Stride * resultData.Height); result.UnlockBits(resultData); return(result); } case BitsLossless2BitmapFormat.Format32bppArgb: { byte[] decompressed = TagUtilities.DecompressDeflate(RawData, DataOffset, DataLength, BitmapSize.Width * BitmapSize.Height * 4); var result = new Bitmap(BitmapSize.Width, BitmapSize.Height, PixelFormat.Format32bppPArgb); var resultData = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppPArgb); byte[] resultCanvas = new byte[resultData.Stride * resultData.Height]; for (int i = 0; i < resultData.Stride * resultData.Height; i += 4) { resultCanvas[i + 3] = decompressed[i + 0]; resultCanvas[i + 2] = decompressed[i + 1]; resultCanvas[i + 1] = decompressed[i + 2]; resultCanvas[i + 0] = decompressed[i + 3]; } Marshal.Copy(resultCanvas, 0, resultData.Scan0, resultCanvas.Length); result.UnlockBits(resultData); return(result); } default: throw new NotSupportedException(); } }
internal DefineBitsLossless2(byte[] data, int offset) : base(data, offset) { BitmapFormat = (BitsLossless2BitmapFormat)TagUtilities.PickBytes(data, DataOffset + 0, 1); BitmapSize = new Size((int)TagUtilities.PickBytes16(data, DataOffset + 1), (int)TagUtilities.PickBytes16(data, DataOffset + 3)); DataOffset += 5; if (BitmapFormat == BitsLossless2BitmapFormat.Format8bppIndexed) { ColorTableSize = (int)TagUtilities.PickBytes(data, DataOffset, 1) + 1; DataOffset += 1; } }
internal SwfTag(byte[] data, int offset) { RawData = data; Offset = offset; TagCode = GetTagCode(RawData, offset); Length = (int)TagUtilities.PickBits(RawData, offset, 10, 6); offset += 2; if (Length == 0x3f) { Length = (int)TagUtilities.PickBytes32(RawData, offset) + 4; offset += 4; } Length += 2; // tag and length の分 DataOffset = offset; }
internal DefineSprite(byte[] data, int offset) : base(data, offset) { FrameCount = TagUtilities.PickBytes16(data, DataOffset + 0); DataOffset += 2; _controlTags = new List <SwfTag>(); int index = DataOffset; while (index <= Offset + Length) { var tag = SwfParser.GetTag(data, index); if (tag == null) { break; } _controlTags.Add(tag); index += tag.Length; } }
internal static TagType GetTagCode(byte[] data, int offset) { return((TagType)TagUtilities.PickBits(data, offset, 0, 10)); }
internal CharacterTag(byte[] data, int offset) : base(data, offset) { CharacterID = TagUtilities.PickBytes16(data, DataOffset); DataOffset += 2; }
internal DefineBitsJPEG3(byte[] data, int offset) : base(data, offset) { ImageDataSize = (int)TagUtilities.PickBytes32(data, DataOffset); DataOffset += 4; }
// clip actions are not implemented internal PlaceObject2(byte[] data, int offset) : base(data, offset) { DataOffset -= 2; // character id HasClipActions = TagUtilities.PickBits(data, DataOffset + 0, 0, 1) != 0; HasClipDepth = TagUtilities.PickBits(data, DataOffset + 0, 1, 1) != 0; HasName = TagUtilities.PickBits(data, DataOffset + 0, 2, 1) != 0; HasRatio = TagUtilities.PickBits(data, DataOffset + 0, 3, 1) != 0; HasColorTransform = TagUtilities.PickBits(data, DataOffset + 0, 4, 1) != 0; HasMatrix = TagUtilities.PickBits(data, DataOffset + 0, 5, 1) != 0; HasCharacter = TagUtilities.PickBits(data, DataOffset + 0, 6, 1) != 0; Move = TagUtilities.PickBits(data, DataOffset + 0, 7, 1) != 0; Depth = TagUtilities.PickBytes16(data, DataOffset + 1); int index = DataOffset + 3; if (HasCharacter) { CharacterID = TagUtilities.PickBytes16(data, index); index += 2; } else { CharacterID = -1; } if (HasMatrix) { Matrix mat; index += Matrix.GetMatrix(data, index, out mat); Matrix = mat; } if (HasColorTransform) { ColorTransformWithAlpha trans; index += ColorTransformWithAlpha.GetColorTransformWithAlpha(data, index, out trans); ColorTransform = trans; } if (HasRatio) { Ratio = TagUtilities.PickBytes16(data, index); index += 2; } if (HasName) { int n; for (n = index; data[n] != 0; n++) { ; } var encoding = Encoding.GetEncoding(65001); Name = encoding.GetString(data, index, n - index); index += n - index + 1; } if (HasClipDepth) { ClipDepth = TagUtilities.PickBytes16(data, index); index += 2; } // clip actions are not implemented }