예제 #1
0
        private IEnumerable <Bitmap> ReadRowChunk(PngReader reader, int chunkIndex)
        {
            if (!reader.ImgInfo.Indexed)
            {
                throw new ArgumentException("Only indexed color PNGs are supported.");
            }

            var lines = new byte[32][];
            var pal   = reader.GetMetadata().GetPLTE();

            for (var i = 0; i < 32; i++)
            {
                lines[i] = reader.ReadRowByte(
                    new byte[reader.ImgInfo.Cols],
                    (chunkIndex * 32) + i);
            }

            var bitmapsPerRow = reader.ImgInfo.Cols / 32;

            for (var i = 0; i < bitmapsPerRow; i++)
            {
                var bmp = ReadBitmap(i, lines, pal);
                this.tileCache.GetOrAddBitmap(bmp);
                yield return(bmp);
            }
        }
예제 #2
0
        private static void additionalTestInterlaced(string orig, string origni)
        {
            // tests also read/write in packed format
            PngReader pngr = FileHelper.CreatePngReader(orig);
            string    copy = TestsHelper.addSuffixToName(orig, "_icopy");

            pngr.SetUnpackedMode(false);
            PngWriter pngw = FileHelper.CreatePngWriter(copy, pngr.ImgInfo, true);

            pngw.CopyChunksFirst(pngr, ChunkCopyBehaviour.COPY_ALL);
            pngw.SetUseUnPackedMode(false);
            Random random  = new Random();
            bool   useByte = random.NextDouble() > 0.5 && pngr.ImgInfo.BitDepth < 16;

            for (int row = 0; row < pngr.ImgInfo.Rows; row++)
            {
                if (useByte)
                {
                    ImageLine line = pngr.ReadRowByte(row);
                    pngw.WriteRow(line, row);
                }
                else
                {
                    ImageLine line = pngr.ReadRowInt(row);
                    pngw.WriteRow(line, row);
                }
            }
            pngr.End();
            pngw.End();
            TestsHelper.testEqual(copy, origni);
            System.IO.File.Delete(copy);
        }
예제 #3
0
        /// <summary>
        /// Saves the PNGFile to disk.
        /// </summary>
        /// <param name="path">Output path for the PNGFile.</param>
        public void SaveAs(string path)
        {
            PngReader reader = FileHelper.CreatePngReader(originalFile);
            PngWriter writer = FileHelper.CreatePngWriter(path, reader.ImgInfo, true);

            writer.CopyChunksFirst(reader, ChunkCopyBehaviour.COPY_ALL_SAFE);

            for (var x = 0; x < reader.ImgInfo.Rows; x++)
            {
                ImageLine line = reader.ReadRowByte(x);
                for (var y = 0; y < line.ScanlineB.Length; y += reader.ImgInfo.BytesPixel)
                {
                    line.ScanlineB[y]     = lines[x][y / reader.ImgInfo.BytesPixel].Red;
                    line.ScanlineB[y + 1] = lines[x][(y + 1) / reader.ImgInfo.BytesPixel].Green;
                    line.ScanlineB[y + 2] = lines[x][(y + 2) / reader.ImgInfo.BytesPixel].Blue;
                    if (reader.ImgInfo.Alpha)
                    {
                        line.ScanlineB[y + 3] = lines[x][(y + 3) / reader.ImgInfo.BytesPixel].Alpha;
                    }
                }
                writer.WriteRow(line, x);
            }
            writer.CopyChunksLast(reader, ChunkCopyBehaviour.COPY_ALL_SAFE);
            writer.End();
            reader.End();
        }
예제 #4
0
        private void LoadRGBAImage(PngReader source)
        {
            byte[] buffer = null;

            for (int dataY = 0; dataY < pixelHeight; dataY++)
            {
                buffer = source.ReadRowByte(buffer, dataY);

                for (int dataX = 0, bufX = 0; bufX < buffer.Length;)
                {
                    imgData[dataY, dataX++] = buffer[bufX++];
                    imgData[dataY, dataX++] = buffer[bufX++];
                    imgData[dataY, dataX++] = buffer[bufX++];
                    imgData[dataY, dataX++] = buffer[bufX++];
                }
            }
        }
예제 #5
0
 public void Decode(ExtendedImage image, Stream stream)
 {
     using (MemoryStream ms = new MemoryStream())
     {
         PngReader reader = new PngReader(stream);
         for (int row = 0; row < reader.ImgInfo.Rows; row++)
         {
             ImageLine line = reader.ReadRowByte(row);
             //int[] scline1 = line.Scanline;
             byte[] buffers = line.ScanlineB;
             ms.Write(buffers, 0, buffers.Length);
         }
         ms.Flush();
         image.SetPixels(ms.ToArray());
         image.PixelHeight   = reader.ImgInfo.Rows;
         image.PixelWidth    = reader.ImgInfo.Cols;
         image.DensityXInt32 = image.DensityYInt32 = 96;
     }
 }
예제 #6
0
    bool ReadImage(PngReader _png)
    {
        /*
         * ImageLine line = pngr.ReadRowInt( y );
         * int[] scanline = line.Scanline;
         *
         * string l = "";
         * for( int x=0; x<scanline.Length; x++ )
         * {
         *      int ci = scanline[ x ];
         *      l += ci.ToString() + ",";
         * }
         *
         * Debug.Log ("line " + y + ": " + l );
         */


        int x, y;

        for (y = 0; y < m_height; y++)
        {
            ImageLine line = _png.ReadRowByte(y);
            //byte[] lineBytes = _png.ReadRowByte( y );
            byte[] lineBytes = line.ScanlineB;            // GetScanlineInt();

            for (x = 0; x < m_width; x++)
            {
                byte src_c      = lineBytes[x];
                byte remapped_c = src_c;
                if (m_config.m_colorRemapSourceToDest.ContainsKey((int)src_c))
                {
                    remapped_c = (byte)m_config.m_colorRemapSourceToDest[src_c];
                }
                m_colorUsed[remapped_c] = true;

                int dst_i = (y * m_width) + x;
                m_image[dst_i] = remapped_c;
            }
        }

        return(true);
    }
예제 #7
0
        public Texture(string filename, bool multiplyAlpha = false)
        {
            using (FileStream stream = File.OpenRead(filename))
            {
                PngReader reader = new PngReader(stream);
                byte[]    data   = new byte[reader.ImgInfo.Rows * reader.ImgInfo.Cols * 4];
                int       widx   = 0;
                for (int row = 0; row < reader.ImgInfo.Rows; row++)
                {
                    ImageLine line = reader.ReadRowByte(row);
                    int       idx  = 0;
                    for (int col = 0; col < reader.ImgInfo.Cols; col++)
                    {
                        byte R = line.ScanlineB[idx++];
                        byte G = line.ScanlineB[idx++];
                        byte B = line.ScanlineB[idx++];
                        byte A = line.ScanlineB[idx++];
                        if (multiplyAlpha)
                        {
                            float alpha = A / 255.0f;
                            R = (byte)Math.Round(R * alpha);
                            G = (byte)Math.Round(G * alpha);
                            B = (byte)Math.Round(B * alpha);
                        }
                        data[widx++] = R;
                        data[widx++] = G;
                        data[widx++] = B;
                        data[widx++] = A;
                    }
                }

                m_Id = GL.GenTexture();
                GL.BindTexture(TextureTarget.Texture2D, m_Id);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
                GL.TexImage2D <byte>(TextureTarget2d.Texture2D, 0, TextureComponentCount.Rgba, reader.ImgInfo.Cols, reader.ImgInfo.Rows, 0, PixelFormat.Rgba, PixelType.UnsignedByte, data);
                GL.BindTexture(TextureTarget.Texture2D, 0);
            }
        }
예제 #8
0
        static void Test1()
        {
            using (System.IO.FileStream fs = new System.IO.FileStream("d:\\WImageTest\\a01_4_1.png", System.IO.FileMode.Open))
            {
                PngReader reader1 = new PngReader(fs);
                var       imgInfo = reader1.ImgInfo;
                int       j       = imgInfo.Rows;
                using (System.Drawing.Bitmap newBMP = new System.Drawing.Bitmap(imgInfo.Cols, imgInfo.Rows, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
                {
                    System.Drawing.Imaging.BitmapData data = newBMP.LockBits(
                        new System.Drawing.Rectangle(0, 0, imgInfo.Cols, imgInfo.Rows),
                        System.Drawing.Imaging.ImageLockMode.ReadWrite,
                        newBMP.PixelFormat);

                    byte[] buffer = new byte[imgInfo.Cols * 4 * imgInfo.Rows];

                    int rowLen    = data.Stride;
                    int targetpos = 0;
                    for (int i = 0; i < j; ++i)
                    {
                        ImageLine imgline = reader1.ReadRowByte(i);

                        byte[] scanlineBytes = imgline.ScanlineB;
                        //copy
                        System.Buffer.BlockCopy(
                            scanlineBytes, 0,
                            buffer, targetpos, scanlineBytes.Length);
                        targetpos += rowLen;
                    }
                    System.Runtime.InteropServices.Marshal.Copy(
                        buffer,
                        0,
                        data.Scan0, buffer.Length);

                    newBMP.UnlockBits(data);
                    newBMP.Save("d:\\WImageTest\\pngcs1.png");
                }
            }
        }
예제 #9
0
        private unsafe void ReadPng(Stream bitmapStream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption)
        {
            var pngr = new PngReader(bitmapStream);

            if (pngr.ImgInfo.Channels > 4 || pngr.ImgInfo.Channels < 3 || pngr.ImgInfo.BitDepth
                != 8)
            {
                throw new NotSupportedException("PNG must be RGB8/RGBA8");
            }

            var channels = pngr.ImgInfo.Channels;
            var data     = new byte[pngr.ImgInfo.Cols * pngr.ImgInfo.Rows * channels];
            var alpha    = (channels == 4);

            if (alpha)
            {
                fixed(byte *dataStart = &data[0])
                {
                    var d = dataStart;

                    for (var i = 0; i < pngr.ImgInfo.Rows; i++)
                    {
                        var line = pngr.ReadRowByte(i);
                        for (var j = 0; j < pngr.ImgInfo.Cols; j++)
                        {
                            var j2  = j * channels;
                            *   d++ = line.ScanlineB[j2 + 2];
                            *   d++ = line.ScanlineB[j2 + 1];
                            *   d++ = line.ScanlineB[j2];
                            *   d++ = line.ScanlineB[j2 + 3];
                        }
                    }

                    Source = BitmapSource.Create(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, 100, 100, PixelFormats.Bgra32, null, (IntPtr)dataStart, pngr.ImgInfo.Cols * pngr.ImgInfo.Rows * channels,
                                                 pngr.ImgInfo.Cols * channels);
                }

                //for (int i = 0; i < pngr.ImgInfo.Rows; i++)
                //{
                //    var i1 = i * pngr.ImgInfo.Cols * channels;
                //    ImageLine line = pngr.ReadRowInt(i);
                //    for (int j = 0; j < pngr.ImgInfo.Cols; j++)
                //    {
                //        var j1 = i1 + j * channels;
                //        var j2 = j * channels;
                //        data[j1+2] = (byte)line.Scanline[j2++];
                //        data[j1 + 1] = (byte)line.Scanline[j2++];
                //        data[j1] = (byte)line.Scanline[j2++];
                //        data[j1 + 3] = (byte)line.Scanline[j2];
                //    }
                //}
                //Source = BitmapSource.Create(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, 100, 100, PixelFormats.Bgra32, null, data, pngr.ImgInfo.Cols * channels);
                //Source = BitmapSource.Create(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, 100, 100, PixelFormats.Bgra32, null, data, stride);
            }
            else
            {
                fixed(byte *dataStart = &data[0])
                {
                    var d = dataStart;

                    for (var i = 0; i < pngr.ImgInfo.Rows; i++)
                    {
                        var line = pngr.ReadRowInt(i);
                        for (var j = 0; j < pngr.ImgInfo.Cols; j++)
                        {
                            var j2  = j * channels;
                            *   d++ = (byte)line.Scanline[j2 + 2];
                            *   d++ = (byte)line.Scanline[j2 + 1];
                            *   d++ = (byte)line.Scanline[j2];
                        }
                    }
                    Source = BitmapSource.Create(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, 100, 100, PixelFormats.Bgr24, null, data, pngr.ImgInfo.Cols * channels);
                }
            }
            pngr.End();

            //double dpi = 96;
            //int width = 128;
            //int height = 128;
            //byte[] pixelData = new byte[width * height];

            //for (int y = 0; y < height; ++y)
            //{
            //    int yIndex = y * width;
            //    for (int x = 0; x < width; ++x)
            //    {
            //        pixelData[x + yIndex] = (byte)(x + y);
            //    }
            //}
            //Source = BitmapSource.Create(width, height, dpi, dpi,
            //        PixelFormats.Gray8, null, pixelData, width);
            //Source = source;
            Source.Freeze();
        }
예제 #10
0
        public sprite_params setup(PngReader _png_reader, bool _apply_palette, bool _crop_image, int _palette_slot)
        {
            sprite_params spr_params = new sprite_params(this);

            if (_png_reader == null)
            {
                return(spr_params);
            }

            int img_width  = _png_reader.ImgInfo.Cols;
            int img_height = _png_reader.ImgInfo.Rows;

            List <byte[]> lines_arr = new List <byte[]>(img_height);

            int i;
            int j;

            int min_x = 0;
            int max_x = img_width - 1;

            int min_y = 0;
            int max_y = img_height - 1;

            byte[] pixels_line = null;

            PngChunkPLTE plte = _png_reader.GetMetadata().GetPLTE();
            PngChunkTRNS trns = _png_reader.GetMetadata().GetTRNS();
            ImageLine    line = null;

            int alpha_ind  = -1;
            int num_colors = plte.GetNentries();

            // detect useful image borders
            {
                if (trns != null)
                {
                    int size;

                    alpha_ind = trns.GetPalletteAlpha().Length - 1;

                    if (_crop_image)
                    {
                        min_x = img_width + 1;
                        max_x = -1;

                        min_y = img_height + 1;
                        max_y = -1;
                    }

                    bool transp_line = false;

                    for (i = 0; i < img_height; i++)
                    {
                        line = _png_reader.ReadRowByte(i);

                        if (line.ImgInfo.Packed)
                        {
                            line = line.unpackToNewImageLine();
                        }

                        pixels_line = new byte[img_width];

                        Array.Copy(line.GetScanlineByte(), pixels_line, img_width);

                        lines_arr.Add(pixels_line);

                        size = pixels_line.Length;

                        transp_line = true;

                        for (j = 0; j < size; j++)
                        {
                            // if pixel is not transparent
                            if (_crop_image && (pixels_line[j] != alpha_ind))
                            {
                                if (min_x > j)
                                {
                                    min_x = j;
                                }

                                if (max_x < j)
                                {
                                    max_x = j;
                                }

                                transp_line = false;
                            }
                        }

                        // if line is not transparent
                        if (_crop_image && !transp_line)
                        {
                            if (min_y > i)
                            {
                                min_y = i;
                            }

                            if (max_y < i)
                            {
                                max_y = i;
                            }
                        }
                    }
                }

                // find nearest colors
                if (_apply_palette)
                {
#if DEF_FIXED_LEN_PALETTE16_ARR
                    palettes_array plt_arr = palettes_array.Instance;
                    plt_arr.palette_index = _palette_slot;
#endif
                    for (i = 0; i < num_colors; i++)
                    {
#if DEF_FIXED_LEN_PALETTE16_ARR
                        plt_arr.update_color(_palette_slot, i, utils.find_nearest_color_ind(plte.GetEntry((trns != null) ? (i + alpha_ind) % num_colors:i)));
#else
                        palette_group.Instance.get_palettes_arr()[i / utils.CONST_NUM_SMALL_PALETTES].get_color_inds()[i % utils.CONST_NUM_SMALL_PALETTES] = utils.find_nearest_color_ind(plte.GetEntry((trns != null) ? (i + alpha_ind) % num_colors:i));
#endif
                    }

#if DEF_FIXED_LEN_PALETTE16_ARR
                    plt_arr.update_palette();
#else
                    for (i = 0; i < utils.CONST_NUM_SMALL_PALETTES; i++)
                    {
                        palette_group.Instance.get_palettes_arr()[i].update();
                    }
#endif
#if DEF_NES
                    palette_group.Instance.active_palette = 0;
#endif
                }

                // fill the lines_arr if sprite has no transparency
                if (lines_arr.Count == 0)
                {
                    for (i = 0; i < img_height; i++)
                    {
                        line = _png_reader.ReadRowByte(i);

                        if (line.ImgInfo.Packed)
                        {
                            line = line.unpackToNewImageLine();
                        }

                        pixels_line = new byte[img_width];

                        Array.Copy(line.GetScanlineByte(), pixels_line, img_width);

                        lines_arr.Add(pixels_line);
                    }
                }
            }

            return(cut_CHRs(spr_params, min_x, max_x, min_y, max_y, lines_arr, (trns != null), alpha_ind, num_colors, _crop_image, _palette_slot));
        }
        /// <summary> Reads samples using given reader </summary>
        static void ReadSamples(PngReader reader, ReadColorsResult results)
        {
            var info     = reader.ImgInfo;
            int channels = info.Channels;
            int bitDepth = info.BitDepth;
            int numCols  = results.width;
            int numRows  = results.height;

            Color[] pixels = results.pixels;
            float   max    = GetBitDepthMaxValue(bitDepth);

            if (!info.Indexed)
            {
                if (!info.Packed)
                {
                    for (int row = 0; row < numRows; row++)
                    {
                        ImageLine imageLine = reader.ReadRow(row);
                        ProcessNByteRow(imageLine, pixels);
                    }
                }
                else
                {
                    if (bitDepth == 4)
                    {
                        for (int row = 0; row < numRows; row++)
                        {
                            ImageLine imageLine = reader.ReadRowByte(row);
                            Process4BitRow(imageLine, pixels);
                        }
                    }
                    else if (bitDepth == 2)
                    {
                        throw new System.Exception($"bit depth {bitDepth} for {channels} channels not implemented\n");
                    }
                    else if (bitDepth == 1)
                    {
                        for (int row = 0; row < numRows; row++)
                        {
                            ImageLine imageLine = reader.ReadRowByte(row);
                            Process1BitRow(imageLine, pixels);
                        }
                    }
                    else
                    {
                        throw new System.Exception($"bit depth {bitDepth} for {channels} channels not implemented\n");
                    }
                }
            }
            else
            {
                var plte = reader.GetMetadata().GetPLTE();
                if (bitDepth == 8)
                {
                    if (info.Alpha)
                    {
                        var trns = reader.GetMetadata().GetTRNS();                        // transparency metadata, can be null
                        for (int row = 0; row < numRows; row++)
                        {
                            ImageLine imageLine = reader.ReadRow(row);
                            Process8BitIndexedRow(imageLine, plte, trns, pixels);
                        }
                    }
                    else
                    {
                        for (int row = 0; row < numRows; row++)
                        {
                            ImageLine imageLine = reader.ReadRow(row);
                            Process8BitIndexedRow(imageLine, plte, pixels);
                        }
                    }
                }
                else if (bitDepth == 4)
                {
                    for (int row = 0; row < numRows; row++)
                    {
                        ImageLine imageLine = reader.ReadRow(row);
                        Process4BitIndexedRow(imageLine, plte, pixels);
                    }
                }
                else
                {
                    throw new System.Exception($"bit depth {bitDepth} for {channels} channels not implemented\n");
                }
            }
        }