예제 #1
0
파일: ImageGSA.cs 프로젝트: zxc120/GARbro
 public override ImageData Read(IBinaryStream file, ImageMetaData info)
 {
     using (var reader = new GsaReader(file, (GsaMetaData)info))
     {
         var pixels = reader.Unpack();
         if (PartFileNameRe.IsMatch(file.Name))
         {
             var base_name = Path.ChangeExtension(file.Name, "GSA");
             if (VFS.FileExists(base_name))
             {
                 try
                 {
                     var image = TryBlendImage(base_name, reader, info);
                     if (image != null)
                     {
                         return(image);
                     }
                 }
                 catch { /* ignore failed blending attempt */ }
             }
         }
         return(ImageData.CreateFlipped(info, reader.Format, null, pixels, reader.Stride));
     }
 }
예제 #2
0
파일: ImageGSA.cs 프로젝트: zxc120/GARbro
        ImageData TryBlendImage(string base_name, GsaReader overlay, ImageMetaData overlay_info)
        {
            int ovl_x      = overlay_info.OffsetX;
            int ovl_y      = overlay_info.OffsetY;
            int ovl_width  = (int)overlay_info.Width;
            int ovl_height = (int)overlay_info.Height;

            if (ovl_x < 0)
            {
                ovl_width += ovl_x;
                ovl_x      = 0;
            }
            if (ovl_y < 0)
            {
                ovl_height += ovl_y;
                ovl_y       = 0;
            }
            using (var input = VFS.OpenBinaryStream(base_name))
            {
                var base_info = ReadMetaData(input) as GsaMetaData;
                if (null == base_info)
                {
                    return(null);
                }
                int base_width  = (int)base_info.Width;
                int base_height = (int)base_info.Height;
                if (checked (ovl_x + ovl_width) > base_width)
                {
                    ovl_width = base_width - ovl_x;
                }
                if (checked (ovl_y + ovl_height) > base_height)
                {
                    ovl_height = base_height - ovl_y;
                }
                if (ovl_height <= 0 || ovl_width <= 0)
                {
                    return(null);
                }

                input.Position = 0;
                var reader      = new GsaReader(input, base_info);
                var base_pixels = reader.Unpack();

                int src_pixel_size = overlay.PixelSize;
                int dst_pixel_size = reader.PixelSize;
                int dst            = ovl_y * reader.Stride + ovl_x * dst_pixel_size;
                int src            = 0;
                for (int y = 0; y < ovl_height; ++y)
                {
                    int src_pixel = src;
                    int dst_pixel = dst;
                    for (int x = 0; x < ovl_width; ++x)
                    {
                        int src_alpha = overlay.Data[src_pixel + 3];
                        if (src_alpha > 0)
                        {
                            if (0xFF == src_alpha)
                            {
                                Buffer.BlockCopy(overlay.Data, src_pixel, base_pixels, dst_pixel, dst_pixel_size);
                            }
                            else // assume destination has no alpha channel
                            {
                                base_pixels[dst_pixel + 0] = (byte)((overlay.Data[src_pixel + 0] * src_alpha
                                                                     + base_pixels[dst_pixel + 0] * (0xFF - src_alpha)) / 0xFF);
                                base_pixels[dst_pixel + 1] = (byte)((overlay.Data[src_pixel + 1] * src_alpha
                                                                     + base_pixels[dst_pixel + 1] * (0xFF - src_alpha)) / 0xFF);
                                base_pixels[dst_pixel + 2] = (byte)((overlay.Data[src_pixel + 2] * src_alpha
                                                                     + base_pixels[dst_pixel + 2] * (0xFF - src_alpha)) / 0xFF);
                            }
                        }
                        src_pixel += src_pixel_size;
                        dst_pixel += dst_pixel_size;
                    }
                    src += overlay.Stride;
                    dst += reader.Stride;
                }
                return(ImageData.CreateFlipped(base_info, reader.Format, null, base_pixels, reader.Stride));
            }
        }