private static void ExtractHg3ImageJpegAlpha(BinaryReader reader, Hg3FrameInfo frameInfo, HgxOptions options, string pngFile) { HG3STDINFO std = frameInfo.StdInfo; HG3IMG_AL img = frameInfo.ImgAl.Data; HG3TAG tag = frameInfo.ImgJpg.Tag; reader.BaseStream.Position = frameInfo.ImgAl.Offset; // WGC handles bad alpha buffer errors gracefully, so we should too byte[] alphaBuffer; try { alphaBuffer = Zlib.Decompress(reader, img.CompressedLength, img.DecompressedLength); } catch (ZlibException ex) { if (ex.Result == ZResult.DataError || ex.Result == ZResult.BufferError) { alphaBuffer = ex.OutputBuffer; } else { throw; } } reader.BaseStream.Position = frameInfo.ImgJpg.Offset; byte[] buffer = reader.ReadBytes(tag.Length); if (!CatDebug.SpeedTestHgx) { WriteJpegAlphaMaskToPng(buffer, alphaBuffer, std, options, pngFile); } }
private static void ExtractHg3ImageAlpha(BinaryReader reader, Hg3FrameInfo frameInfo, HgxOptions options, string pngFile) { HG3STDINFO std = frameInfo.StdInfo; HG3IMG_AL img = frameInfo.ImgAl.Data; reader.BaseStream.Position = frameInfo.ImgAl.Offset; // WGC handles bad alpha buffer errors gracefully, so we should too byte[] alphaBuffer; try { alphaBuffer = Zlib.Decompress(reader, img.CompressedLength, img.DecompressedLength); } catch (ZlibException ex) { if (ex.Result == ZResult.DataError || ex.Result == ZResult.BufferError) { alphaBuffer = ex.OutputBuffer; } else { throw; } } int depthBytes = (std.DepthBits + 7) / 8; int stride = (std.Width * depthBytes + 3) & ~3; int minStride = (std.Width * depthBytes); int alphaStride = std.Width; byte[] pixelBuffer = new byte[stride * std.Height]; for (int y = 0; y < std.Height; y++) { int src = y * alphaStride; int dst = y * stride; for (int x = 0; x < std.Width; x++) { int alphaIndex = src + x; int pixelIndex = dst + x * depthBytes; byte alpha = unchecked ((byte)(byte.MaxValue - alphaBuffer[alphaIndex])); pixelBuffer[pixelIndex + 0] = alpha; pixelBuffer[pixelIndex + 1] = alpha; pixelBuffer[pixelIndex + 2] = alpha; if (depthBytes == 4) { pixelBuffer[pixelIndex + 3] = byte.MaxValue; } } } if (!CatDebug.SpeedTestHgx) { WritePng(pixelBuffer, std, options, pngFile); } }
private static Hg3FrameInfo ReadHg3FrameInfo(BinaryReader reader, HGXHDR hdr, bool frameOnly) { Stream stream = reader.BaseStream; long frameOffset = stream.Position; HG3FRAMEHDR frameHdr = reader.ReadUnmanaged <HG3FRAMEHDR>(); long tagStartPosition = stream.Position; HG3TAG tag = reader.ReadUnmanaged <HG3TAG>(); if (!HG3STDINFO.HasTagSignature(tag.Signature)) { throw new Exception("Expected \"stdinfo\" tag!"); } HG3STDINFO stdInfo = reader.ReadUnmanaged <HG3STDINFO>(); Hg3FrameInfo frameInfo = new Hg3FrameInfo(frameHdr, stdInfo, frameOffset); while (tag.OffsetNext != 0) { stream.Position = tagStartPosition + tag.OffsetNext; tagStartPosition = stream.Position; tag = reader.ReadUnmanaged <HG3TAG>(); string signature = tag.Signature; if (HG3IMG.HasTagSignature(signature, out int imdId)) // "img####" { HG3IMG img = reader.ReadUnmanaged <HG3IMG>(); frameInfo.AddTagImg(stream, tag, img, imdId); } else if (HG3IMG_AL.HasTagSignature(signature)) // "img_al" { HG3IMG_AL img = reader.ReadUnmanaged <HG3IMG_AL>(); frameInfo.AddTagImg(stream, tag, img, 0); } else if (HG3IMG_JPG.HasTagSignature(signature)) // "img_jpg" // There is no image info, reading it would increment by one byte which we don't want { frameInfo.AddTagImg(stream, tag, new HG3IMG_JPG(), 0); } else if (frameOnly) { if (frameInfo.Type != Hg3ImageType.None) { return(frameInfo); } } else if (HG3ATS.HasTagSignature(signature, out int atsId)) // "ats####" { HG3ATS ats = reader.ReadUnmanaged <HG3ATS>(); frameInfo.Ats.Add(atsId, ats); } else if (HG3CPTYPE.HasTagSignature(signature)) // "cptype" { HG3CPTYPE cpType = reader.ReadUnmanaged <HG3CPTYPE>(); frameInfo.CpType = cpType; } else if (HG3IMGMODE.HasTagSignature(signature)) // "imgmode" { HG3IMGMODE imgMode = reader.ReadUnmanaged <HG3IMGMODE>(); frameInfo.ImgMode = imgMode; } else { Trace.WriteLine($"UNKNOWN TAG: \"{signature}\""); } } return(frameInfo); }