Example #1
0
        public static void SetPixel(ImageLine line, int col, int r, int g, int b, int a)
        {
            if (line is null)
            {
                throw new ArgumentNullException(nameof(line));
            }

            var offset = col * line.channels;

            if (line.IsInt())
            {
                line.Scanline[offset++] = r;
                line.Scanline[offset++] = g;
                line.Scanline[offset]   = b;
                if (line.ImgInfo.Alpha)
                {
                    line.Scanline[offset + 1] = a;
                }
            }
            else
            {
                line.ScanlineB[offset++] = (byte)r;
                line.ScanlineB[offset++] = (byte)g;
                line.ScanlineB[offset]   = (byte)b;
                if (line.ImgInfo.Alpha)
                {
                    line.ScanlineB[offset + 1] = (byte)a;
                }
            }
        }
Example #2
0
 /// <summary>
   /// this uses the row number from the imageline!
   /// </summary>
   ///
   public void WriteRow(ImageLine imgline, int rownumber) {
       SetUseUnPackedMode(imgline.SamplesUnpacked);
       if (imgline.SampleType == ImageLine.ESampleType.INT)
           WriteRowInt(imgline.Scanline, rownumber);
       else
           WriteRowByte(imgline.ScanlineB, rownumber);
   }
Example #3
0
 public static int GetPixelToARGB8( ImageLine line, int column )
 {
     if ( line.IsInt () )
         return ToARGB8 ( line.Scanline, column * line.channels, line.ImgInfo.Alpha );
     else
         return ToARGB8 ( line.ScanlineB, column * line.channels, line.ImgInfo.Alpha );
 }
Example #4
0
 public void decodeLastReadRowToInt(int[] buffer, int bytesRead)
 {
     if (ImgInfo.BitDepth <= 8)
     {
         int i   = 0;
         int num = 1;
         for (; i < bytesRead; i++)
         {
             buffer[i] = rowb[num++];
         }
     }
     else
     {
         int num2 = 0;
         int num3 = 1;
         while (num3 < bytesRead)
         {
             buffer[num2] = (rowb[num3++] << 8) + rowb[num3++];
             num2++;
         }
     }
     if (ImgInfo.Packed && unpackedMode)
     {
         ImageLine.unpackInplaceInt(ImgInfo, buffer, buffer, Scale: false);
     }
 }
Example #5
0
      protected void encodeRowFromInt(int[] row) {
            if (row.Length == ImgInfo.SamplesPerRowPacked && !needsPack) {
                // some duplication of code - because this case is typical and it works faster this way
                int j = 1;
                if (ImgInfo.BitDepth <= 8)
                  foreach (int x in row) // optimized
                    rowb[j++] = (byte)x;
                else // 16 bitspc
                  foreach (int x in row) { // optimized
                    rowb[j++] = (byte)(x >> 8);
                    rowb[j++] = (byte)x; 
                  }
            } else {
                // perhaps we need to pack?
                if (row.Length >= ImgInfo.SamplesPerRow && needsPack)
                    ImageLine.packInplaceInt(ImgInfo, row, row, false); // row is packed in place!
                if (ImgInfo.BitDepth <= 8)
                  for (int i = 0, j = 1; i < ImgInfo.SamplesPerRowPacked; i++)
                    rowb[j++] = (byte)row[i];
                else // 16 bitspc
                  for (int i = 0, j = 1; i < ImgInfo.SamplesPerRowPacked; i++) {
                    rowb[j++] = (byte)(row[i] >> 8);
                    rowb[j++] = (byte)row[i];
                  }

            }
        }
        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);
        }
Example #7
0
 public static void endFileTmp(PngWriter png)
 {
     ImageLine imline = new ImageLine(png.ImgInfo);
     for (int i = 0; i < png.ImgInfo.Rows; i++)
         png.WriteRow(imline, i);
     png.End();
 }
Example #8
0
        public static byte[] Pack(ImageInfo imgInfo, byte[] src, byte[] dst, bool scale)
        {
            if (imgInfo is null)
            {
                throw new ArgumentNullException(nameof(imgInfo));
            }

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

            var len0 = imgInfo.SamplesPerRowPacked;

            if (dst is null || dst.Length < len0)
            {
                dst = new byte[len0];
            }

            if (imgInfo.Packed)
            {
                ImageLine.PackInplaceByte(imgInfo, src, dst, scale);
            }
            else
            {
                Array.Copy(src, 0, dst, 0, len0);
            }

            return(dst);
        }
Example #9
0
        public static void SetPixel(ImageLine line, int col, int r, int g, int b, int a)
        {
            int offset = col * line.channels;

            if (line.IsInt())
            {
                line.Scanline[offset++] = r;
                line.Scanline[offset++] = g;
                line.Scanline[offset]   = b;
                if (line.ImgInfo.Alpha)
                {
                    line.Scanline[offset + 1] = a;
                }
            }
            else
            {
                line.ScanlineB[offset++] = (byte)r;
                line.ScanlineB[offset++] = (byte)g;
                line.ScanlineB[offset]   = (byte)b;
                if (line.ImgInfo.Alpha)
                {
                    line.ScanlineB[offset + 1] = (byte)a;
                }
            }
        }
Example #10
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);
        }
Example #11
0
 public static int GetPixelToARGB8(ImageLine line, int column)
 {
     if (line.IsInt())
     {
         return(ToARGB8(line.Scanline, column * line.channels, line.ImgInfo.Alpha));
     }
     return(ToARGB8(line.ScanlineB, column * line.channels, line.ImgInfo.Alpha));
 }
Example #12
0
 public static double ReadDouble(ImageLine line, int pos)
 {
     if (line.IsInt())
     {
         return((double)line.Scanline[pos] / ((double)line.maxSampleVal + 0.9));
     }
     return((double)(int)line.ScanlineB[pos] / ((double)line.maxSampleVal + 0.9));
 }
Example #13
0
        public static void SetPixel(ImageLine line, int col, int r, int g, int b)
        {
            if (line is null)
            {
                throw new ArgumentNullException(nameof(line));
            }

            SetPixel(line, col, r, g, b, line.MaxSampleVal);
        }
Example #14
0
 public static void WriteDouble(ImageLine line, double d, int pos)
 {
     if (line.IsInt())
     {
         line.Scanline[pos] = (int)(d * (line.maxSampleVal + 0.99));
     }
     else
     {
         line.ScanlineB[pos] = (byte)(d * (line.maxSampleVal + 0.99));
     }
 }
Example #15
0
 public static void SetPixelFromARGB8(ImageLine line, int column, int argb)
 {
     if (line.IsInt())
     {
         FromARGB8(argb, line.Scanline, column * line.channels, line.ImgInfo.Alpha);
     }
     else
     {
         FromARGB8(argb, line.ScanlineB, column * line.channels, line.ImgInfo.Alpha);
     }
 }
Example #16
0
 public static double ReadDouble(ImageLine line, int pos)
 {
     if (line.IsInt())
     {
         return(line.Scanline[pos] / (line.maxSampleVal + 0.9));
     }
     else
     {
         return((line.ScanlineB[pos]) / (line.maxSampleVal + 0.9));
     }
 }
Example #17
0
        public ImageLine packToNewImageLine()
        {
            ImageLine newline = new ImageLine(ImgInfo, SampleType, false);

            if (SampleType == ESampleType.INT)
            {
                packInplaceInt(ImgInfo, Scanline, newline.Scanline, false);
            }
            else
            {
                packInplaceByte(ImgInfo, ScanlineB, newline.ScanlineB, false);
            }
            return(newline);
        }
Example #18
0
        public ImageLine packToNewImageLine()
        {
            ImageLine imageLine = new ImageLine(ImgInfo, SampleType, unpackedMode: false);

            if (SampleType == ESampleType.INT)
            {
                packInplaceInt(ImgInfo, Scanline, imageLine.Scanline, scaled: false);
            }
            else
            {
                packInplaceByte(ImgInfo, ScanlineB, imageLine.ScanlineB, scaled: false);
            }
            return(imageLine);
        }
Example #19
0
        /// <summary>
        /// Constructs and returns an ImageLine object backed by a matrix row.
        /// This is quite efficient, no deep copy.
        /// </summary>
        /// <param name="mrow">Row number inside the matrix</param>
        /// <returns></returns>
        public ImageLine GetImageLineAtMatrixRow(int mrow)
        {
            if (mrow < 0 || mrow > Nrows)
            {
                throw new PngjException("Bad row " + mrow + ". Should be positive and less than "
                                        + Nrows);
            }
            ImageLine imline = sampleType == ImageLine.ESampleType.INT ? new ImageLine(ImgInfo, sampleType,
                                                                                       SamplesUnpacked, Scanlines[mrow], null) : new ImageLine(ImgInfo, sampleType,
                                                                                                                                               SamplesUnpacked, null, ScanlinesB[mrow]);

            imline.Rown = MatrixRowToImageRow(mrow);
            return(imline);
        }
Example #20
0
 public ImageLine ReadRowByte(int nrow)
 {
     if (imgLine == null)
     {
         imgLine = new ImageLine(ImgInfo, ImageLine.ESampleType.BYTE, unpackedMode);
     }
     if (imgLine.Rown == nrow) // already read
     {
         return(imgLine);
     }
     ReadRowByte(imgLine.ScanlineB, nrow);
     imgLine.FilterUsed = (FilterType)rowbfilter[0];
     imgLine.Rown       = nrow;
     return(imgLine);
 }
Example #21
0
 public ImageLine ReadRowInt(int nrow)
 {
     if (imgLine == null)
     {
         imgLine = new ImageLine(ImgInfo, ImageLine.ESampleType.INT, unpackedMode);
     }
     if (imgLine.Rown == nrow)
     {
         return(imgLine);
     }
     ReadRowInt(imgLine.Scanline, nrow);
     imgLine.FilterUsed = (FilterType)rowbfilter[0];
     imgLine.Rown       = nrow;
     return(imgLine);
 }
Example #22
0
        public static void WriteDouble(ImageLine line, double d, int pos)
        {
            if (line is null)
            {
                throw new ArgumentNullException(nameof(line));
            }

            if (line.IsInt())
            {
                line.Scanline[pos] = (int)(d * (line.MaxSampleVal + 0.99));
            }
            else
            {
                line.ScanlineB[pos] = (byte)(d * (line.MaxSampleVal + 0.99));
            }
        }
Example #23
0
        public static void SetPixelFromARGB8(ImageLine line, int column, int argb)
        {
            if (line is null)
            {
                throw new ArgumentNullException(nameof(line));
            }

            if (line.IsInt())
            {
                FromARGB8(argb, line.Scanline, column * line.channels, line.ImgInfo.Alpha);
            }
            else
            {
                FromARGB8(argb, line.ScanlineB, column * line.channels, line.ImgInfo.Alpha);
            }
        }
Example #24
0
        public static double ReadDouble(ImageLine line, int pos)
        {
            if (line is null)
            {
                throw new ArgumentNullException(nameof(line));
            }

            if (line.IsInt())
            {
                return(line.Scanline[pos] / (line.MaxSampleVal + 0.9));
            }
            else
            {
                return(line.ScanlineB[pos] / (line.MaxSampleVal + 0.9));
            }
        }
Example #25
0
        public static int GetPixelToARGB8(ImageLine line, int column)
        {
            if (line is null)
            {
                throw new ArgumentNullException(nameof(line));
            }

            if (line.IsInt())
            {
                return(ToARGB8(line.Scanline, column * line.channels, line.ImgInfo.Alpha));
            }
            else
            {
                return(ToARGB8(line.ScanlineB, column * line.channels, line.ImgInfo.Alpha));
            }
        }
Example #26
0
        private void EncodeRowFromByte(byte[] row)
        {
            if (row.Length == ImgInfo.SamplesPerRowPacked && !needsPack)
            {
                // some duplication of code - because this case is typical and it works faster this way
                var j = 1;
                if (ImgInfo.BitDepth <= 8)
                {
                    foreach (var x in row)
                    { // optimized
                        rowb[j++] = x;
                    }
                }
                else
                {     // 16 bitspc
                    foreach (var x in row)
                    { // optimized
                        rowb[j] = x;
                        j      += 2;
                    }
                }
            }
            else
            {
                // perhaps we need to pack?
                if (row.Length >= ImgInfo.SamplesPerRow && needsPack)
                {
                    ImageLine.PackInplaceByte(ImgInfo, row, row, false); // row is packed in place!
                }

                if (ImgInfo.BitDepth <= 8)
                {
                    for (int i = 0, j = 1; i < ImgInfo.SamplesPerRowPacked; i++)
                    {
                        rowb[j++] = row[i];
                    }
                }
                else
                { // 16 bitspc
                    for (int i = 0, j = 1; i < ImgInfo.SamplesPerRowPacked; i++)
                    {
                        rowb[j++] = row[i];
                        rowb[j++] = 0;
                    }
                }
            }
        }
Example #27
0
        /// <summary>
        /// this uses the row number from the imageline!
        /// </summary>
        ///
        public void WriteRow(ImageLine imgline, int rownumber)
        {
            if (imgline is null)
            {
                throw new ArgumentNullException(nameof(imgline));
            }

            SetUseUnPackedMode(imgline.SamplesUnpacked);
            if (imgline.SampleType == ImageLine.ESampleType.INT)
            {
                WriteRowInt(imgline.Scanline, rownumber);
            }
            else
            {
                WriteRowByte(imgline.ScanlineB, rownumber);
            }
        }
Example #28
0
 private void decodeLastReadRowToByte(byte[] buffer, int bytesRead)              // see http://www.libpng.org/pub/png/spec/1.2/PNG-DataRep.html
 {
     if (ImgInfo.BitDepth <= 8)
     {
         Array.Copy(rowb, 1, buffer, 0, bytesRead);
     }
     else     // 16 bitspc
     {
         for (int i = 0, j = 1; j < bytesRead; i++, j += 2)
         {
             buffer[i] = rowb[j]; // 16 bits in 1 byte: this discards the LSB!!!
         }
     }
     if (ImgInfo.Packed && unpackedMode)
     {
         ImageLine.unpackInplaceByte(ImgInfo, buffer, buffer, false);
     }
 }
Example #29
0
        public static int[] Pack(ImageInfo imgInfo, int[] src, int[] dst, bool scale)
        {
            int samplesPerRowPacked = imgInfo.SamplesPerRowPacked;

            if (dst == null || dst.Length < samplesPerRowPacked)
            {
                dst = new int[samplesPerRowPacked];
            }
            if (imgInfo.Packed)
            {
                ImageLine.packInplaceInt(imgInfo, src, dst, scale);
            }
            else
            {
                Array.Copy(src, 0, dst, 0, samplesPerRowPacked);
            }
            return(dst);
        }
Example #30
0
        public static byte[] Pack(ImageInfo imgInfo, byte[] src, byte[] dst, bool scale)
        {
            int len0 = imgInfo.SamplesPerRowPacked;

            if (dst == null || dst.Length < len0)
            {
                dst = new byte[len0];
            }
            if (imgInfo.Packed)
            {
                ImageLine.packInplaceByte(imgInfo, src, dst, scale);
            }
            else
            {
                Array.Copy(src, 0, dst, 0, len0);
            }
            return(dst);
        }
Example #31
0
        public static int[] Unpack(ImageInfo imgInfo, int[] src, int[] dst, bool scale)
        {
            int len1 = imgInfo.SamplesPerRow;
            int len0 = imgInfo.SamplesPerRowPacked;

            if (dst == null || dst.Length < len1)
            {
                dst = new int[len1];
            }
            if (imgInfo.Packed)
            {
                ImageLine.unpackInplaceInt(imgInfo, src, dst, scale);
            }
            else
            {
                Array.Copy(src, 0, dst, 0, len0);
            }
            return(dst);
        }
Example #32
0
        public static byte[] Unpack(ImageInfo imgInfo, byte[] src, byte[] dst, bool scale)
        {
            int samplesPerRow       = imgInfo.SamplesPerRow;
            int samplesPerRowPacked = imgInfo.SamplesPerRowPacked;

            if (dst == null || dst.Length < samplesPerRow)
            {
                dst = new byte[samplesPerRow];
            }
            if (imgInfo.Packed)
            {
                ImageLine.unpackInplaceByte(imgInfo, src, dst, scale);
            }
            else
            {
                Array.Copy(src, 0, dst, 0, samplesPerRowPacked);
            }
            return(dst);
        }
Example #33
0
 public static string createWaves(String suffix, double scale, ImageInfo imi)
 {
     string f = getTmpFile(suffix);
     // open image for writing to a output stream
     PngWriter png = FileHelper.CreatePngWriter(f, imi, true);
     png.GetMetadata().SetText("key1", "val1");
     ImageLine iline = new ImageLine(imi, ImageLine.ESampleType.BYTE, true);
     for (int row = 0; row < png.ImgInfo.Rows; row++) {
         for (int x = 0; x < imi.Cols; x++) {
             int r = (int)((Math.Sin((row + x) * 0.073 * scale) + 1) * 128);
             int g = (int)((Math.Sin((row + x * 0.22) * 0.08 * scale) + 1) * 128);
             int b = (int)((Math.Sin((row * 0.52 - x * 0.2) * 0.21 * scale) + 1) * 128);
             iline.ScanlineB[x * imi.Channels] = (byte)r;
             iline.ScanlineB[x * imi.Channels + 1] = (byte)g;
             iline.ScanlineB[x * imi.Channels + 2] = (byte)b;
             if (imi.Channels == 4)
                 iline.ScanlineB[x * imi.Channels + 3] = (byte)((b + g) / 2);
         }
         png.WriteRow(iline, row);
     }
     png.End();
     return f;
 }
 public static void Create(string filename, int cols, int rows)
 {
     ImageInfo imi = new ImageInfo(cols, rows, 8, false); // 8 bits per channel, no alpha
     // open image for writing
     PngWriter png = FileHelper.CreatePngWriter(filename, imi, true);
     // add some optional metadata (chunks)
     png.GetMetadata().SetDpi(100.0);
     png.GetMetadata().SetTimeNow(0); // 0 seconds fron now = now
     png.GetMetadata().SetText(PngChunkTextVar.KEY_Title, "Just a text image");
     PngChunk chunk = png.GetMetadata().SetText("my key", "my text .. bla bla");
     chunk.Priority = true; // this chunk will be written as soon as possible
     ImageLine iline = new ImageLine(imi);
     for (int col = 0; col < imi.Cols; col++) { // this line will be written to all rows
         int r = 255;
         int g = 127;
         int b = 255 * col / imi.Cols;
         ImageLineHelper.SetPixel(iline , col, r, g, b); // orange-ish gradient
     }
     for (int row = 0; row < png.ImgInfo.Rows; row++) {
         png.WriteRow(iline, row);
     }
     png.End();
 }
Example #35
0
 public static ImageLine generateNoiseLine(ImageInfo imi)
 {
     // byte format!
     ImageLine line = new ImageLine(imi, ImageLine.ESampleType.BYTE, true);
     Random r = new Random();
     r.NextBytes(line.ScanlineB);
     return line;
 }
Example #36
0
 public ImageLine ReadRowByte(int nrow)
 {
     if (imgLine == null)
         imgLine = new ImageLine(ImgInfo, ImageLine.ESampleType.BYTE, unpackedMode);
     if (imgLine.Rown == nrow) // already read
         return imgLine;
     ReadRowByte(imgLine.ScanlineB, nrow);
     imgLine.FilterUsed = (FilterType)rowbfilter[0];
     imgLine.Rown = nrow;
     return imgLine;
 }
Example #37
0
 public ImageLine ReadRowInt( int nrow )
 {
     if ( imgLine == null )
         imgLine = new ImageLine ( ImgInfo, ImageLine.ESampleType.INT, unpackedMode );
     if ( imgLine.Rown == nrow )
         return imgLine;
     ReadRowInt ( imgLine.Scanline, nrow );
     imgLine.FilterUsed = ( FilterType ) rowbfilter [ 0 ];
     imgLine.Rown = nrow;
     return imgLine;
 }
Example #38
0
 public static void WriteDouble( ImageLine line, double d, int pos )
 {
     if ( line.IsInt () )
         line.Scanline [ pos ] = ( int ) ( d * ( line.maxSampleVal + 0.99 ) );
     else
         line.ScanlineB [ pos ] = ( byte ) ( d * ( line.maxSampleVal + 0.99 ) );
 }
Example #39
0
 public static int[] Palette2rgb( ImageLine line, PngChunkPLTE pal, int [] buf )
 {
     return Palette2rgb ( line, pal, null, buf );
 }
Example #40
0
 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;
 }
        private void SaveMazeAsImageDeluxePngWithDynamicallyGeneratedPath(String fileName, IEnumerable<MazePointPos> pathPosjes, Action<int, int> lineSavingProgress)
        {
            ImageInfo imi = new ImageInfo(this.Width - 1, this.Height - 1, 8, false); // 8 bits per channel, no alpha
            // open image for writing
            PngWriter png = FileHelper.CreatePngWriter(fileName, imi, true);
            // add some optional metadata (chunks)
            png.GetMetadata().SetDpi(100.0);
            png.GetMetadata().SetTimeNow(0); // 0 seconds fron now = now
            png.CompLevel = 4;
            //png.GetMetadata().SetText(PngChunkTextVar.KEY_Title, "Just a text image");
            //PngChunk chunk = png.GetMetadata().SetText("my key", "my text .. bla bla");
            //chunk.Priority = true; // this chunk will be written as soon as possible

            for (int yChunkStart = 0; yChunkStart < this.Height - 1; yChunkStart += Maze.LineChunks)
            {
                var yChunkEnd = Math.Min(yChunkStart + Maze.LineChunks, this.Height - 1);

                var pathPointsHere = pathPosjes.Where(t => t.Y >= yChunkStart && t.Y < yChunkEnd).ToList();
                pathPointsHere.Sort((first, second) =>
                {
                    if (first.Y == second.Y)
                    {
                        return first.X - second.X;
                    }
                    return first.Y - second.Y;
                });
                int curpos = 0;

                for (int y = yChunkStart; y < yChunkEnd; y++)
                {
                    ImageLine iline = new ImageLine(imi);

                    for (int x = 0; x < this.Width - 1; x++)
                    {

                        int r = 0;
                        int g = 0;
                        int b = 0;

                        MazePointPos curPathPos;
                        if (curpos < pathPointsHere.Count)
                        {
                            curPathPos = pathPointsHere[curpos];
                            if (curPathPos.X == x && curPathPos.Y == y)
                            {
                                r = curPathPos.RelativePos;
                                g = 255 - curPathPos.RelativePos;
                                b = 0;
                                curpos++;
                            }
                            else if (this.innerMap[x, y])
                            {
                                r = 255;
                                g = 255;
                                b = 255;
                            }
                        }
                        else if (this.innerMap[x, y])
                        {
                            r = 255;
                            g = 255;
                            b = 255;
                        }

                        ImageLineHelper.SetPixel(iline, x, r, g, b);
                    }
                    png.WriteRow(iline, y);
                    lineSavingProgress(y, this.Height - 2);
                }
            }
            png.End();
        }
        /// <summary>
        /// This method performs a preanalysis on the path to make sure there's no super high memory usage for a certain area
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="pathPosjes"></param>
        /// <param name="lineSavingProgress"></param>
        /// <param name="debugMessageCallback"></param>
        private void SaveMazeAsImageDeluxePngWithDynamicallyGeneratedPathWithAnalysis(string fileName, IEnumerable<MazePointPos> pathPosjes, Action<int, int> lineSavingProgress, Action<string> debugMessageCallback = null)
        {
            if (debugMessageCallback == null)
            {
                debugMessageCallback = (x) => { };
            }

            debugMessageCallback("Performing path analysis...");

            var pathPointsPerRow = new int[this.Height];
            long totalPathLength = 0;

            for (int i = 0; i < this.Height; i++)
            {
                pathPointsPerRow[i] = 0;
            }

            foreach (var pathPos in pathPosjes)
            {
                pathPointsPerRow[pathPos.Y]++;
                totalPathLength++;
            }

            debugMessageCallback(string.Format("Path analysis completed. Total path length: {0}, this would take up {1}mb.", totalPathLength, Math.Round(totalPathLength * 9.0 / 1024.0 / 1024.0, 2)));

            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            var compinfo = new Microsoft.VisualBasic.Devices.ComputerInfo();
            var memoryFree = compinfo.AvailablePhysicalMemory;

            debugMessageCallback(string.Format("Memory free: {0}mb", memoryFree / 1024 / 1024));
            memoryFree = (ulong)(memoryFree * 0.6);
            debugMessageCallback(string.Format("Setting max usage to 60% of this: {0}mb", memoryFree / 1024 / 1024));

            debugMessageCallback("Determining desired rows to generate each path cycle...");
            int rowsPerPathDeterminingCycle = FindTheMinimalRowsToWriteForPng(debugMessageCallback, pathPointsPerRow, memoryFree);

            int tiffTileSize = HybridInnerMap.GridSize;

            if (rowsPerPathDeterminingCycle < tiffTileSize)
            {
                debugMessageCallback(string.Format("We can't work with the default tilesize of '{0}' so we have to scale it back to RowsPerCycle: '{1}'", tiffTileSize, rowsPerPathDeterminingCycle));
                tiffTileSize = rowsPerPathDeterminingCycle;
            }

            debugMessageCallback(string.Format("TiffTileSize: {0}", tiffTileSize));

            debugMessageCallback("Starting generation of Maze Path and saving maze...");

            //Should actually be Width -1 -1 but since we use the full Width it's only once -1
            //This will count the amount of tiles per line so if it's 15 Pixels we still want 2 tiles of 8
            int tilesInWidth = (((this.Width - 1) / tiffTileSize) + 1);

            ImageInfo imi = new ImageInfo(this.Width - 1, this.Height - 1, 8, false); // 8 bits per channel, no alpha
            // open image for writing
            PngWriter png = CreatePngWriter(fileName, imi);
            // add some optional metadata (chunks)
            png.GetMetadata().SetDpi(100.0);
            png.GetMetadata().SetTimeNow(0); // 0 seconds fron now = now
            png.CompLevel = 4;
            //png.GetMetadata().SetText(PngChunkTextVar.KEY_Title, "Just a text image");
            //PngChunk chunk = png.GetMetadata().SetText("my key", "my text .. bla bla");
            //chunk.Priority = true; // this chunk will be written as soon as possible

            //int stepsPerLoop = rowsPerPathDeterminingCycle;

            int partNumber = 0;

            int yChunkStart = 0;
            while (yChunkStart < this.Height - 1)
            {
                //We must use rowsperpathdeterminingcycle here instead of tifftilesize because else you might get into a scenario where the first 4 values and the second 4 values are beneath 1000. But if we would take value 2 to 6 which are also 4 values we would go above 1000.
                //And yes I thought about this pretty well, it needs to be like this because you get forced into reading 500 lines of path from for example 1000 to 1500 where the other thing is 2000, hmmmm...
                //Or not I really need to think about this a bit more. Because if the chunk size is 1000 then you can never end up reading something smaller then that which works because the rowsperpath is always bigger.
                //So yeah, because rows per path is always a multiple or equal to tifftilesize you can never go out of sync becuase no matter what happens, e.g. tifftile = 500 and perpath = 2000. When you're at 2500 you just need to read 500. And you are never forced in reading anything that was
                //not measured. Because you can't end up in having to read somewhere from 1250 to 1750 because of the multiple thingy. Ok I'm quite sure now it needs to be tiffTileSize.
                //
                //Additional note, it always needs to be a multiple of tiffTileSize because we write tiles at a time (we can't write half tiles). So that's why we don't want some stupidly small numbers here.
                int stepsThisLoop = FindTheMaxPathRowsThatWouldFitInMemoryFromHerePng(debugMessageCallback, pathPointsPerRow, yChunkStart, tiffTileSize, memoryFree);

                var yChunkEnd = Math.Min(yChunkStart + stepsThisLoop, this.Height - 1);
                stepsThisLoop = yChunkEnd - yChunkStart;

                var wObtainPathPart = Stopwatch.StartNew();

                //We don't use a ToList here because we do actually know the expected list size beforehand. This way we make sure we don't have to do any internal Array Resizing.
                var expectedPathCount = pathPointsPerRow.Skip(yChunkStart).Take(yChunkEnd - yChunkStart).Sum();
                var pathPointsHere = new List<MazePointPos>(expectedPathCount);
                int currentPathPosPoint = 0;
                foreach (var pathPos in pathPosjes.Where(t => t.Y >= yChunkStart && t.Y < yChunkEnd))
                {
                    pathPointsHere.Add(pathPos);
                    currentPathPosPoint++;
                }
                wObtainPathPart.Stop();

                if (pathPointsHere.Count != expectedPathCount)
                {
                    debugMessageCallback(string.Format("Warning: Something strange is happening where the actual path point count '{0}' is not equal to the expected path point count '{1}' (Maze will still save correctly but it uses more memory then expected)", pathPointsHere.Count, expectedPathCount));
                }

                var wSort = Stopwatch.StartNew();
                pathPointsHere.Sort((first, second) =>
                {
                    if (first.Y == second.Y)
                    {
                        return first.X - second.X;
                    }
                    return first.Y - second.Y;
                });
                wSort.Stop();

                var wGmemorifiedPieceOpMap = Stopwatch.StartNew();

                var innerMapTemporaryInMemoryCopy = new BitArreintjeFastInnerMap(this.Width, stepsThisLoop);

                for (int startY = yChunkStart; startY < yChunkEnd; startY += tiffTileSize)
                {

                    for (int startX = 0; startX < this.Width - 1; startX += tiffTileSize)
                    {
                        int yStart = startY - yChunkStart;
                        int yEnd = yStart + tiffTileSize;

                        for (int y = startY, othery = yStart; othery < yEnd; y++, othery++)
                        {
                            for (int x = startX, otherx = 0; otherx < tiffTileSize; x++, otherx++)
                            {
                                innerMapTemporaryInMemoryCopy[x, othery] = innerMap[x, y];
                            }
                        }
                    }

                }

                wGmemorifiedPieceOpMap.Stop();

                int curpos = 0;

                var wSaveAsImage = Stopwatch.StartNew();

                var yChunkMaxRealEnzo = Math.Min(yChunkEnd, this.Height - 1);

                for (int startY = yChunkStart, y = 0; startY < yChunkMaxRealEnzo; startY += 1, y++)
                {
                    ImageLine iline = new ImageLine(imi);

                    //int xMax = Math.Min(this.Width - 1 - startX, tiffTileSize);
                    int yMax = Math.Min(this.Height - 1 - startY, tiffTileSize);
                    for (int x = 0, otherx = 0; otherx < this.Width - 1; x++, otherx++)
                    {
                        byte r = 0;
                        byte g = 0;
                        byte b = 0;

                        MazePointPos curPathPos;
                        if (curpos < pathPointsHere.Count)
                        {
                            curPathPos = pathPointsHere[curpos];
                            if (curPathPos.X == x && curPathPos.Y == startY)
                            {
                                r = curPathPos.RelativePos;
                                g = (byte)(255 - curPathPos.RelativePos);
                                b = 0;
                                curpos++;
                            }
                            else if (innerMapTemporaryInMemoryCopy[x, y])
                            {
                                r = 255;
                                g = 255;
                                b = 255;
                            }
                        }
                        else if (innerMapTemporaryInMemoryCopy[x, y])
                        {
                            r = 255;
                            g = 255;
                            b = 255;
                        }

                        ImageLineHelper.SetPixel(iline, x, r, g, b);
                    }

                    //var result = tif.WriteEncodedTile(tileNumber, color_ptr, tiffTileSize * tiffTileSize * 3);
                    //var result = tif.WriteTile(color_ptr, startX / tileSize, startY / tileSize, 0, 0);
                    //var result = tif.WriteRawTile(tileNumber, color_ptr, tileSize * tileSize * 3);
                    //Result should not be -1

                    //lineSavingProgress((int)Math.Min((tileNumber + 1L) * tiffTileSize / tilesInWidth, this.Height - 2), this.Height - 2);
                    png.WriteRow(iline, y + yChunkStart);
                    lineSavingProgress(y + yChunkStart, this.Height - 2);
                }

                wSaveAsImage.Stop();

                debugMessageCallback(string.Format("{0}: YChunkStart: {1}, YChunkEnd: {2}, Rows written: {3}, Count: {4}, Time to generate this part: {5} sec, Time to sort this part: {6} sec, Time to put this part in memory: {7}, Time to save this part in the image: {8} sec, Combined time: {9} sec, Size: {10}mb",
                    partNumber,
                    yChunkStart,
                    yChunkEnd,
                    stepsThisLoop,
                    pathPointsHere.Count,
                    Math.Round(wObtainPathPart.Elapsed.TotalSeconds, 2),
                    Math.Round(wSort.Elapsed.TotalSeconds, 2),
                    Math.Round(wGmemorifiedPieceOpMap.Elapsed.TotalSeconds, 2),
                    Math.Round(wSaveAsImage.Elapsed.TotalSeconds, 2),
                    Math.Round(wObtainPathPart.Elapsed.TotalSeconds + wSort.Elapsed.TotalSeconds + wGmemorifiedPieceOpMap.Elapsed.TotalSeconds + wSaveAsImage.Elapsed.TotalSeconds, 2),
                    Math.Round(pathPointsHere.Count * 9.0 / 1024.0 / 1024.0, 3)));
                partNumber++;

                yChunkStart += stepsThisLoop;

                //Do some forced garbage collection since we're finished with this loop
                pathPointsHere = null;
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
            }

            png.End();

            //    tif.FlushData();
            //}
        }
Example #43
0
 static void mirrorLine(ImageLine imline)
 {
     // unpacked line !
     if (!imline.SamplesUnpacked)
         throw new PngjException("this requires unpacked lines");
     int channels = imline.ImgInfo.Channels;
     for (int c1 = 0, c2 = imline.ImgInfo.Cols - 1; c1 < c2; c1++, c2--) {
         for (int i = 0; i < channels; i++) {
             int s1 = c1 * channels + i; // sample left
             int s2 = c2 * channels + i; // sample right
             if (imline.SampleType == ImageLine.ESampleType.INT) {
                 int aux = imline.Scanline[s1]; // swap
                 imline.Scanline[s1] = imline.Scanline[s2];
                 imline.Scanline[s2] = aux;
             } else {
                 byte auxb = imline.ScanlineB[s1]; // swap
                 imline.ScanlineB[s1] = imline.ScanlineB[s2];
                 imline.ScanlineB[s2] = auxb;
             }
         }
     }
 }
Example #44
0
 public static double ReadDouble( ImageLine line, int pos )
 {
     if ( line.IsInt () )
         return line.Scanline [ pos ] / ( line.maxSampleVal + 0.9 );
     else
         return ( line.ScanlineB [ pos ] ) / ( line.maxSampleVal + 0.9 );
 }
Example #45
0
 public static void SetPixelFromARGB8( ImageLine line, int column, int argb )
 {
     if ( line.IsInt () )
         FromARGB8 ( argb, line.Scanline, column * line.channels, line.ImgInfo.Alpha );
     else
         FromARGB8 ( argb, line.ScanlineB, column * line.channels, line.ImgInfo.Alpha );
 }
Example #46
0
 public ImageLine unpackToNewImageLine()
 {
     ImageLine newline = new ImageLine(ImgInfo, SampleType, true);
     if (SampleType == ESampleType.INT)
         unpackInplaceInt(ImgInfo, Scanline, newline.Scanline, false);
     else
         unpackInplaceByte(ImgInfo, ScanlineB, newline.ScanlineB, false);
     return newline;
 }
Example #47
0
 public static void SetPixel( ImageLine line, int col, int r, int g, int b, int a )
 {
     int offset = col * line.channels;
     if ( line.IsInt () )
     {
         line.Scanline [ offset++ ] = r;
         line.Scanline [ offset++ ] = g;
         line.Scanline [ offset ] = b;
         if ( line.ImgInfo.Alpha )
             line.Scanline [ offset + 1 ] = a;
     }
     else
     {
         line.ScanlineB [ offset++ ] = ( byte ) r;
         line.ScanlineB [ offset++ ] = ( byte ) g;
         line.ScanlineB [ offset ] = ( byte ) b;
         if ( line.ImgInfo.Alpha )
             line.ScanlineB [ offset + 1 ] = ( byte ) a;
     }
 }
Example #48
0
 public void WriteRow( ImageLine imgline, int rownumber )
 {
     SetUseUnPackedMode ( imgline.SamplesUnpacked );
     if ( imgline.SampleType == ImageLine.ESampleType.INT )
         WriteRowInt ( imgline.Scanline, rownumber );
     else
         WriteRowByte ( imgline.ScanlineB, rownumber );
 }
Example #49
0
 public static void SetPixel( ImageLine line, int col, int r, int g, int b )
 {
     SetPixel ( line, col, r, g, b, line.maxSampleVal );
 }