public override void CloneDataFromRead(PngChunk other)
        {
            PngChunkPLTE otherx = (PngChunkPLTE)other;

            this.SetNentries(otherx.GetNentries());
            System.Array.Copy(otherx.entries, 0, entries, 0, numEntries);
        }
示例#2
0
        /// <summary>
        /// Given an indexed line with a palette, unpacks as a RGB array
        /// </summary>
        /// <param name="line">ImageLine as returned from PngReader</param>
        /// <param name="pal">Palette chunk</param>
        /// <param name="trns">TRNS chunk (optional)</param>
        /// <param name="buf">Preallocated array, optional</param>
        /// <returns>R G B (one byte per sample)</returns>
        public static int[] Palette2rgb(ImageLine line, PngChunkPLTE pal, PngChunkTRNS trns, int[] buf)
        {
            bool isalpha  = trns != null;
            int  channels = isalpha ? 4 : 3;
            int  nsamples = line.ImgInfo.Cols * channels;

            if (buf == null || buf.Length < nsamples)
            {
                buf = new int[nsamples];
            }
            if (!line.SamplesUnpacked)
            {
                line = line.unpackToNewImageLine();
            }
            bool isbyte            = line.SampleType == Hjg.Pngcs.ImageLine.ESampleType.BYTE;
            int  nindexesWithAlpha = trns != null?trns.GetPalletteAlpha().Length : 0;

            for (int c = 0; c < line.ImgInfo.Cols; c++)
            {
                int index = isbyte ? (line.ScanlineB[c] & 0xFF) : line.Scanline[c];
                pal.GetEntryRgb(index, buf, c * channels);
                if (isalpha)
                {
                    int alpha = index < nindexesWithAlpha?trns.GetPalletteAlpha()[index] : 255;

                    buf[c * channels + 3] = alpha;
                }
            }
            return(buf);
        }
示例#3
0
        public static int[] Palette2rgb(ImageLine line, PngChunkPLTE pal, PngChunkTRNS trns, int[] buf)
        {
            bool flag = trns != null;
            int  num  = flag ? 4 : 3;
            int  num2 = line.ImgInfo.Cols * num;

            if (buf == null || buf.Length < num2)
            {
                buf = new int[num2];
            }
            if (!line.SamplesUnpacked)
            {
                line = line.unpackToNewImageLine();
            }
            bool flag2 = line.SampleType == ImageLine.ESampleType.BYTE;
            int  num3  = (trns != null) ? trns.GetPalletteAlpha().Length : 0;

            for (int i = 0; i < line.ImgInfo.Cols; i++)
            {
                int num4 = flag2 ? (line.ScanlineB[i] & 0xFF) : line.Scanline[i];
                pal.GetEntryRgb(num4, buf, i * num);
                if (flag)
                {
                    int num5 = buf[i * num + 3] = ((num4 < num3) ? trns.GetPalletteAlpha()[num4] : 255);
                }
            }
            return(buf);
        }
        public static void doit(String orig)
        {
            string copy = TestsHelper.addSuffixToName(orig, "_tc");

            PngReader pngr = FileHelper.CreatePngReader(orig);

            if (!pngr.ImgInfo.Indexed)
            {
                throw new Exception("Not indexed image");
            }
            PngChunkPLTE plte  = pngr.GetMetadata().GetPLTE();
            PngChunkTRNS trns  = pngr.GetMetadata().GetTRNS(); // transparency metadata, can be null
            bool         alpha = trns != null;
            ImageInfo    im2   = new ImageInfo(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, 8, alpha);
            PngWriter    pngw  = FileHelper.CreatePngWriter(copy, im2, true);

            pngw.CopyChunksFirst(pngr, ChunkCopyBehaviour.COPY_ALL_SAFE);
            int[] buf = null;
            for (int row = 0; row < pngr.ImgInfo.Rows; row++)
            {
                ImageLine line = pngr.ReadRowInt(row);
                buf = ImageLineHelper.Palette2rgb(line, plte, trns, buf);
                pngw.WriteRowInt(buf, row);
            }
            pngw.CopyChunksLast(pngr, ChunkCopyBehaviour.COPY_ALL_SAFE);
            pngr.End();
            pngw.End();
            Console.WriteLine("True color: " + copy);
        }
示例#5
0
        private static unsafe Bitmap ReadBitmap(int bitmapIndex, byte[][] buf, PngChunkPLTE pal)
        {
            var bmp = new Bitmap(32, 32, PixelFormat.Format32bppArgb);

            var data = bmp.LockBits(
                new Rectangle(0, 0, 32, 32),
                ImageLockMode.WriteOnly,
                PixelFormat.Format32bppArgb);

            try
            {
                var ptr = (int *)data.Scan0;

                for (var y = 0; y < 32; y++)
                {
                    var line = buf[y];

                    for (var x = 0; x < 32; x++)
                    {
                        var offset    = (bitmapIndex * 32) + x;
                        var bmpOffset = (y * 32) + x;
                        int idx       = line[offset];

                        var rgb = new int[3];
                        pal.GetEntryRgb(idx, rgb);

                        var c = Color.FromArgb(rgb[0], rgb[1], rgb[2]);

                        if (!PaletteFactory.TAPalette.Contains(c))
                        {
                            throw new ArgumentException("Image contains colors not in the TA palette.");
                        }

                        ptr[bmpOffset] = c.ToArgb();
                    }
                }
            }
            finally
            {
                bmp.UnlockBits(data);
            }

            return(bmp);
        }
示例#6
0
        private void ConvertPalettedImage(BinaryReader reader, Stream outStream)
        {
            ImageInfo info = new ImageInfo(Header.Width, Header.Height, Header.BitDepth, false, false, true);
            PngWriter png  = new PngWriter(outStream, info);

            // Add a palette to the PNG
            PngChunkPLTE plte = png.GetMetadata().CreatePLTEChunk();

            plte.SetNentries(Header.NumberOfColours);
            // Populate the palette
            for (int i = 0; i < this.ColorTable.Length; i++)
            {
                var c = this.ColorTable[i];
                plte.SetEntry(i, c.Red, c.Green, c.Blue);
            }

            int pixelsPerByte = 8 / Header.BitCount;
            int bytesPerLine  = (Header.Width * Header.BitCount + 31) / 32 * 4;
            //if (Header.BitDepth == 8)
            //    bytesPerLine = (Header.Width / 4 + 1) * 4;

            long dataStart = Header.DataOffset;
            int  dataEnd   = Header.FileSize - Header.DataOffset; //Header.ImageSize;

            for (int y = 0; y < Header.Height; y++)
            {
                // Seek to the start of the line
                Stream.Seek(dataStart + (dataEnd - (bytesPerLine * y) - bytesPerLine), SeekOrigin.Begin);

                byte[]    bmpLine = new byte[bytesPerLine];
                ImageLine pngLine = new ImageLine(info, ImageLine.ESampleType.BYTE);
                Stream.Read(bmpLine, 0, bytesPerLine);

                // Bitmap lines are already packed for palleted images, so just copy it over
                Array.Copy(bmpLine, 0, pngLine.ScanlineB, 0, Math.Min(bytesPerLine, Header.Width));

                Stream.ReadByte(); //skip the padded byte

                png.WriteRow(pngLine, y);
            }

            png.End();
        }
示例#7
0
    bool ReadPalette(PngChunkPLTE _palette)
    {
        int[] rgb = new int[4];
        int   c;

        for (c = 0; c < m_coloursInPalette; c++)
        {
            int c2 = c;
            if (m_config.m_colorRemapSourceToDest.ContainsKey(c))
            {
                c2 = m_config.m_colorRemapSourceToDest[c];
            }

            _palette.GetEntryRgb(c2, rgb);
            float fr = ((float)rgb[0]) / 255.0f;
            float fg = ((float)rgb[1]) / 255.0f;
            float fb = ((float)rgb[2]) / 255.0f;
            //float fa = ((float)a) / 255.0f;
            float fa = 1.0f;

            /*
             * if((c%16) == 0 )
             *      fa = 0.0f;
             * else
             *      fa = 1.0f;
             */

            Color col = new Color(fr, fg, fb, fa);
            m_palette.Add(col);
            m_colorUsed.Add(false);
        }

        while (c < 16)
        {
            m_palette.Add(new Color(1.0f, 0.0f, 1.0f, 1.0f));
            m_colorUsed.Add(false);
            c++;
        }

        return(true);
    }
示例#8
0
        /// <summary>
        /// Given an indexed line with a palette, unpacks as a RGB array
        /// </summary>
        /// <param name="line">ImageLine as returned from PngReader</param>
        /// <param name="pal">Palette chunk</param>
        /// <param name="trns">TRNS chunk (optional)</param>
        /// <param name="buf">Preallocated array, optional</param>
        /// <returns>R G B (one byte per sample)</returns>
        public static int[] Palette2rgb(ImageLine line, PngChunkPLTE pal, PngChunkTRNS trns, int[] buf)
        {
            if (line is null)
            {
                throw new ArgumentNullException(nameof(line));
            }

            if (pal is null)
            {
                throw new ArgumentNullException(nameof(pal));
            }

            var isalpha  = trns is object;
            var channels = isalpha ? 4 : 3;
            var nsamples = line.ImgInfo.Cols * channels;

            if (buf is null || buf.Length < nsamples)
            {
                buf = new int[nsamples];
            }

            if (!line.SamplesUnpacked)
            {
                line = line.UnpackToNewImageLine();
            }

            var isbyte            = line.SampleType == Hjg.Pngcs.ImageLine.ESampleType.BYTE;
            var nindexesWithAlpha = trns?.GetPalletteAlpha().Length ?? 0;

            for (var c = 0; c < line.ImgInfo.Cols; c++)
            {
                var index = isbyte ? (line.ScanlineB[c] & 0xFF) : line.Scanline[c];
                pal.GetEntryRgb(index, buf, c * channels);
                if (isalpha)
                {
                    buf[(c * channels) + 3] = index < nindexesWithAlpha?trns.GetPalletteAlpha()[index] : 255;
                }
            }

            return(buf);
        }
示例#9
0
    static public PalettizedImage LoadPNG(string _path, PalettizedImageConfig _config)
    {
        PngReader pngr = FileHelper.CreatePngReader(_path);

        if (!pngr.ImgInfo.Indexed)
        {
            Debug.LogException(new UnityException("Image wasn't indexed"));
            return(null);
        }

        PngChunkPLTE palette = pngr.GetMetadata().GetPLTE();

        PalettizedImage image = new PalettizedImage(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, palette.GetNentries());

        image.SetConfig(_config);
        image.m_fileName = System.IO.Path.GetFileNameWithoutExtension(_path);

        image.ReadPalette(palette);
        image.ReadImage(pngr);

        return(image);
    }
示例#10
0
        private static void additionalTestPalette(string orig, string truecolor)
        {
            // covnert to true color 8 bits and check equality
            PngReader    pngr  = FileHelper.CreatePngReader(orig);
            PngChunkPLTE plte  = pngr.GetMetadata().GetPLTE();
            PngChunkTRNS trns  = pngr.GetMetadata().GetTRNS();
            string       copy  = TestsHelper.addSuffixToName(orig, "_tccopy");
            bool         alpha = trns != null;
            ImageInfo    im2   = new ImageInfo(pngr.ImgInfo.Cols, pngr.ImgInfo.Rows, 8, alpha);
            PngWriter    pngw  = FileHelper.CreatePngWriter(copy, im2, true);

            pngw.CopyChunksFirst(pngr, ChunkCopyBehaviour.COPY_ALL_SAFE);
            int[] buf = null;
            for (int row = 0; row < pngr.ImgInfo.Rows; row++)
            {
                ImageLine line = pngr.ReadRowInt(row);
                buf = ImageLineHelper.Palette2rgb(line, plte, trns, buf);
                pngw.WriteRowInt(buf, row);
            }
            pngr.End();
            pngw.End();
            TestsHelper.testEqual(copy, truecolor);
            System.IO.File.Delete(copy);
        }
示例#11
0
 public static int[] Palette2rgb(ImageLine line, PngChunkPLTE pal, int[] buf)
 {
     return(Palette2rgb(line, pal, null, buf));
 }
示例#12
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));
        }
示例#13
0
        public static Image Load(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            PngReader pngReader = new PngReader(stream);

            pngReader.ShouldCloseStream  = false;
            pngReader.ChunkLoadBehaviour = ChunkLoadBehaviour.LOAD_CHUNK_NEVER;
            pngReader.MaxTotalBytesRead  = long.MaxValue;
            ImageLines imageLines = pngReader.ReadRowsByte();

            pngReader.End();
            if (imageLines.ImgInfo.BitDepth == 8 && imageLines.ImgInfo.Channels == 4)
            {
                Image image = new Image(pngReader.ImgInfo.Cols, pngReader.ImgInfo.Rows);
                int   i     = 0;
                int   num   = 0;
                for (; i < image.Height; i++)
                {
                    byte[] array = imageLines.ScanlinesB[i];
                    int    j     = 0;
                    int    num2  = 0;
                    for (; j < image.Width; j++)
                    {
                        byte r = array[num2++];
                        byte g = array[num2++];
                        byte b = array[num2++];
                        byte a = array[num2++];
                        image.Pixels[num++] = new Color(r, g, b, a);
                    }
                }
                return(image);
            }
            if (imageLines.ImgInfo.BitDepth == 8 && imageLines.ImgInfo.Channels == 3)
            {
                Image image2 = new Image(pngReader.ImgInfo.Cols, pngReader.ImgInfo.Rows);
                int   k      = 0;
                int   num3   = 0;
                for (; k < image2.Height; k++)
                {
                    byte[] array2 = imageLines.ScanlinesB[k];
                    int    l      = 0;
                    int    num4   = 0;
                    for (; l < image2.Width; l++)
                    {
                        byte r2 = array2[num4++];
                        byte g2 = array2[num4++];
                        byte b2 = array2[num4++];
                        image2.Pixels[num3++] = new Color(r2, g2, b2);
                    }
                }
                return(image2);
            }
            if (imageLines.ImgInfo.BitDepth == 8 && imageLines.ImgInfo.Channels == 2 && imageLines.ImgInfo.Greyscale)
            {
                Image image3 = new Image(pngReader.ImgInfo.Cols, pngReader.ImgInfo.Rows);
                int   m      = 0;
                int   num5   = 0;
                for (; m < image3.Height; m++)
                {
                    byte[] array3 = imageLines.ScanlinesB[m];
                    int    n      = 0;
                    int    num6   = 0;
                    for (; n < image3.Width; n++)
                    {
                        byte b3 = array3[num6++];
                        byte a2 = array3[num6++];
                        image3.Pixels[num5++] = new Color(b3, b3, b3, a2);
                    }
                }
                return(image3);
            }
            if (imageLines.ImgInfo.BitDepth == 8 && imageLines.ImgInfo.Channels == 1 && imageLines.ImgInfo.Greyscale)
            {
                Image image4 = new Image(pngReader.ImgInfo.Cols, pngReader.ImgInfo.Rows);
                int   num7   = 0;
                int   num8   = 0;
                for (; num7 < image4.Height; num7++)
                {
                    byte[] array4 = imageLines.ScanlinesB[num7];
                    int    num9   = 0;
                    int    num10  = 0;
                    for (; num9 < image4.Width; num9++)
                    {
                        byte b4 = array4[num10++];
                        image4.Pixels[num8++] = new Color(b4, b4, b4);
                    }
                }
                return(image4);
            }
            if (imageLines.ImgInfo.BitDepth == 8 && imageLines.ImgInfo.Channels == 1 && imageLines.ImgInfo.Indexed)
            {
                PngChunkPLTE pngChunkPLTE = (PngChunkPLTE)pngReader.GetChunksList().GetById1("PLTE");
                if (pngChunkPLTE == null)
                {
                    throw new InvalidOperationException("PLTE chunk not found in indexed PNG.");
                }
                Image image5 = new Image(pngReader.ImgInfo.Cols, pngReader.ImgInfo.Rows);
                int   num11  = 0;
                int   num12  = 0;
                for (; num11 < image5.Height; num11++)
                {
                    byte[] array5 = imageLines.ScanlinesB[num11];
                    int    num13  = 0;
                    int    num14  = 0;
                    for (; num13 < image5.Width; num13++)
                    {
                        byte n2    = array5[num14++];
                        int  entry = pngChunkPLTE.GetEntry(n2);
                        image5.Pixels[num12++] = new Color((entry >> 16) & 0xFF, (entry >> 8) & 0xFF, entry & 0xFF);
                    }
                }
                return(image5);
            }
            throw new InvalidOperationException("Unsupported PNG pixel format.");
        }
示例#14
0
        public IEnumerable <RGBA> EnRGBA()
        {
            PngChunkPLTE oplte = null;
            PngChunkTRNS otrns = null; // transparency metadata, can be null

            if (pngr.ImgInfo.Indexed)
            {
                oplte = pngr.GetMetadata().GetPLTE();
                otrns = pngr.GetMetadata().GetTRNS();
            }

            for (var row = 0; row < pngr.ImgInfo.Rows; row++)
            {
                var line = pngr.ReadRowInt(row);
                if (pngr.ImgInfo.Indexed)
                {
                    var rgrgba = ImageLineHelper.Palette2rgb(line, oplte, otrns, null);
                    for (var irgba = 0; irgba < rgrgba.Length;)
                    {
                        yield return(new RGBA
                        {
                            r = rgrgba[irgba++],
                            g = rgrgba[irgba++],
                            b = rgrgba[irgba++],
                            a = (otrns != null ? rgrgba[irgba++] : 255),
                        });
                    }
                }
                else
                {
                    if (pngr.ImgInfo.Packed)
                    {
                        line = line.unpackToNewImageLine();
                    }
                    for (var col = 0; col < pngr.ImgInfo.Cols; col++)
                    {
                        switch (pngr.ImgInfo.Channels)
                        {
                        case 1:
                            yield return(new RGBA
                            {
                                r = Read8(col, line),
                                g = Read8(col, line),
                                b = Read8(col, line),
                            });

                            break;

                        case 2:
                            yield return(new RGBA
                            {
                                r = Read8(col * 2, line),
                                g = Read8(col * 2, line),
                                b = Read8(col * 2, line),
                                a = Read8(col * 2 + 1, line),
                            });

                            break;

                        case 3:
                            yield return(new RGBA
                            {
                                r = Read8(col * 3, line),
                                g = Read8(col * 3 + 1, line),
                                b = Read8(col * 3 + 2, line),
                            });

                            break;

                        case 4:
                            yield return(new RGBA
                            {
                                r = Read8(col * 4, line),
                                g = Read8(col * 4 + 1, line),
                                b = Read8(col * 4 + 2, line),
                                a = Read8(col * 4 + 3, line),
                            });

                            break;
                        }
                    }
                }
            }
        }