diff --git a/ComicCompress.csproj b/ComicCompress.csproj
index 8d860f2..bb552af 100644
--- a/ComicCompress.csproj
+++ b/ComicCompress.csproj
@@ -8,20 +8,28 @@
True
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
+
@@ -30,5 +38,9 @@
+
+
+
+
diff --git a/ComicCompress.csproj.user b/ComicCompress.csproj.user
index e2ee5ae..9adce7d 100644
--- a/ComicCompress.csproj.user
+++ b/ComicCompress.csproj.user
@@ -5,6 +5,7 @@
DEV_HOME
+ <_LastSelectedProfileId>E:\_COMIX\_TOOLS_\comic-compress-new\Properties\PublishProfiles\FolderProfile.pubxml
ProjectDebugger
diff --git a/ComicCompress.sln b/ComicCompress.sln
index 7b2586c..a8d0cf7 100644
--- a/ComicCompress.sln
+++ b/ComicCompress.sln
@@ -5,6 +5,10 @@ VisualStudioVersion = 17.5.33530.505
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComicCompress", "ComicCompress.csproj", "{2625C71D-E4EC-4768-BF04-87AAB364916A}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iMGcompress", "..\iMGcompress\iMGcompress.csproj", "{7330E00C-6C24-44B3-9768-1604802532FB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iMGcompress-core", "..\iMGcompress-core\iMGcompress-core.csproj", "{990E9DC1-B842-4E0E-AD7F-00CB2EF24AF4}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +19,14 @@ Global
{2625C71D-E4EC-4768-BF04-87AAB364916A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2625C71D-E4EC-4768-BF04-87AAB364916A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2625C71D-E4EC-4768-BF04-87AAB364916A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7330E00C-6C24-44B3-9768-1604802532FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7330E00C-6C24-44B3-9768-1604802532FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7330E00C-6C24-44B3-9768-1604802532FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7330E00C-6C24-44B3-9768-1604802532FB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {990E9DC1-B842-4E0E-AD7F-00CB2EF24AF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {990E9DC1-B842-4E0E-AD7F-00CB2EF24AF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {990E9DC1-B842-4E0E-AD7F-00CB2EF24AF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {990E9DC1-B842-4E0E-AD7F-00CB2EF24AF4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Compressor.cs b/Compressor.cs
index f11f16d..02cc503 100644
--- a/Compressor.cs
+++ b/Compressor.cs
@@ -14,6 +14,7 @@ using javax.swing.plaf;
using SharpCompress.Readers;
using SharpCompress.Writers;
using SharpCompress.Compressors.Xz;
+using iMGcompress_core;
//using SixLabors.ImageSharp;
//using SixLabors.ImageSharp;
//using SixLabors.ImageSharp.Processing;
@@ -213,7 +214,8 @@ namespace ComicCompressor
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
- output.SaveTo(outputPath, CompressionType.Deflate);
+// output.SaveTo(outputPath, CompressionType.Deflate);
+ output.SaveTo(outputPath, CompressionType.None);
//output.SaveTo(outputPath, CompressionType.None);
diff --git a/FileParser.cs b/FileParser.cs
deleted file mode 100644
index 2dec604..0000000
--- a/FileParser.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System.Collections.Generic;
-using System.IO;
-
-namespace ComicCompressor
-{
- public class FileParser
- {
- public IList ListAllFiles(string input, bool recursive)
- {
- Queue unexplored;
- IList files = new List();
-
- if (Directory.Exists(input))
- {
- unexplored = new Queue(Directory.GetFileSystemEntries(input));
- }
- else
- {
- // No directory but must exist so it is a file
- unexplored = new Queue();
- unexplored.Enqueue(input);
- }
-
- while(unexplored.Count > 0)
- {
- var file = unexplored.Dequeue();
-
- if (File.Exists(file))
- {
- files.Add(file);
- }
- else if (recursive)
- {
- foreach (var f in Directory.GetFileSystemEntries(file))
- {
- unexplored.Enqueue(f);
- }
- }
- }
-
- return files;
-
- }
- }
-
-}
\ No newline at end of file
diff --git a/ImageExtractor.cs b/ImageExtractor.cs
deleted file mode 100644
index 8ce5c8e..0000000
--- a/ImageExtractor.cs
+++ /dev/null
@@ -1,205 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Drawing;
-using System.IO;
-using System.Runtime.ConstrainedExecution;
-using ikvm.extensions;
-using Imazen.WebP;
-
-using iTextSharp.text.pdf;
-using iTextSharp.text.pdf.parser;
-
-using SharpCompress.Archives;
-using SharpCompress.Archives.Zip;
-using SharpCompress.Common;
-
-using Path = System.IO.Path;
-
-namespace ComicCompressor
-{
- ///
- /// Helper lass to dump all images from a PDF into separate files
- ///
- public class ImageExtractor : IRenderListener
- {
- int _currentPage = 1;
- int _imageCount = 0;
- readonly string _outputFilePrefix = "";
- //readonly string _outputFolder;
- //readonly bool _overwriteExistingFiles;
- private bool Cover = true;
- private Logger Logger { get; set; }
- SimpleEncoder encoder = new SimpleEncoder();
- public int Quality { get; set; } = 75;
- private List imageStreams = null;
- public ZipArchive output = null;
-
- public ImageExtractor(Logger logger)
- {
- Logger = logger;
- //_outputFilePrefix = outputFilePrefix;
- //_outputFolder = outputFolder;
- //_overwriteExistingFiles = overwriteExistingFiles;
- }
- public int GetPlace(int value, int place)
- {
- return ((value % (place * 10)) - (value % place)) / place;
- }
- ///
- /// Extract all images from a PDF file
- ///
- /// Full path and file name of PDF file
- /// Basic name of exported files. If null then uses same name as PDF file.
- /// Where to save images. If null or empty then uses same folder as PDF file.
- /// True to overwrite existing image files, false to skip past them
- /// Count of number of images extracted.
- public int ExtractImagesFromFile(string pdfPath, string outputFolder, int quality = 75)
- {
- // Handle setting of any default values
- //outputFilePrefix = outputFilePrefix ?? Path.GetFileNameWithoutExtension(pdfPath);
- //outputFolder = String.IsNullOrEmpty(outputFolder) ? Path.GetDirectoryName(pdfPath) : outputFolder;
-
- quality = quality;
-
- Stopwatch sw = Stopwatch.StartNew();
- using (var pdfReader = new PdfReader(pdfPath))
- {
- Logger.Log($"Processing[{pdfReader.NumberOfPages}]: " + pdfPath, LogLevel.Verbose);
-
- if (pdfReader.IsEncrypted())
- throw new ApplicationException(pdfPath + " is encrypted.");
-
- var pdfParser = new PdfReaderContentParser(pdfReader);
-
- output = ZipArchive.Create();
- {
- imageStreams = new List();
- int count = 0;
- Cover = true;
- while (_currentPage <= pdfReader.NumberOfPages)
- {
- pdfParser.ProcessContent(_currentPage, this);
-
- _currentPage++;
- count++;
- if (count % 10 == 0)
- {
- string digit = GetPlace(count, 10).ToString();
- Logger.Log(digit, LogLevel.Verbose, false);
- }
- }
-
-
- Directory.CreateDirectory(Path.GetDirectoryName(outputFolder));
-
- output.SaveTo(outputFolder, CompressionType.Deflate);
-
- //output.SaveTo(outputPath, CompressionType.None);
-
- imageStreams.ForEach(i => i.Dispose());
- }
- output.Dispose();
- int nop = pdfReader.NumberOfPages;
- if (nop == 0) nop = 1;
- long elapsed = sw.ElapsedMilliseconds;
- //Logger.Log($"\r\nFinished({save.ToString("0.##")}): " + pdfPath, LogLevel.Verbose);
- Logger.Log($"\r\nFinished({0.ToString("0.##")} [{elapsed}][{elapsed / nop}]): " + pdfPath, LogLevel.Verbose);
-
- }
-
- return _imageCount;
- }
- private Bitmap ChangePixelFormat(Bitmap orig, System.Drawing.Imaging.PixelFormat format = System.Drawing.Imaging.PixelFormat.Format24bppRgb)
- {
- Bitmap clone = new Bitmap(orig.Width, orig.Height, format);
-
- using (Graphics gr = Graphics.FromImage(clone))
- {
- gr.DrawImage(orig, new Rectangle(0, 0, clone.Width, clone.Height));
- }
-
- return clone;
-
- }
-
- #region Implementation of IRenderListener
-
- public void BeginTextBlock()
- {
- }
-
- public void EndTextBlock()
- {
- }
-
- public void RenderText(TextRenderInfo renderInfo)
- {
- var text = renderInfo.GetText();
- }
-
- public void RenderImage(ImageRenderInfo renderInfo)
- {
- try
- {
- var type = renderInfo.GetType();
- var str = renderInfo.toString();
- //var ftype = renderInfo.GetFileType();
- var imageObject = renderInfo.GetImage();
-
- //var imageFileName = String.Format("{0}_{1}_{2}.{3}", _outputFilePrefix, _currentPage, _imageCount,
- // imageObject.GetFileType());
- var imageFileName = String.Format($"{_imageCount.ToString("0000")}");
- //var imagePath = Path.Combine(_outputFolder, imageFileName);
-
- //if (_overwriteExistingFiles || !File.Exists(imagePath))
- {
- var imageRawBytes = imageObject.GetImageAsBytes();
- var image = imageObject.GetDrawingImage();
-
- //File.WriteAllBytes(imagePath, imageRawBytes);
- if (image.Width < 512 || image.Height < 512)
- return;
-
- if (image.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)
- {
- var newBits = ChangePixelFormat((Bitmap)image);
- image.Dispose();
- image = newBits;
- }
-
- var ms = new MemoryStream();
- encoder.Encode((Bitmap)image, ms, Quality);
- if (!Cover && ms.Length < imageRawBytes.Length)
- {
- imageStreams.Add(ms);
- output.AddEntry(imageFileName + ".webp", ms);
- Logger.Log(".", LogLevel.Verbose, false);
- }
- else
- {
- var mso = new MemoryStream();
- mso.Write(imageRawBytes);
- output.AddEntry(imageFileName + imageObject.GetFileType(), mso);
- Logger.Log(Cover ? "C" : "=", LogLevel.Verbose, false);
- Cover = false;
- }
- }
-
- // Subtle: Always increment even if file is not written. This ensures consistency should only some
- // of a PDF file's images actually exist.
- _imageCount++;
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- throw;
- }
-
- }
-
- #endregion // Implementation of IRenderListener
-
- }
-}
-
diff --git a/ImageExtractor7.cs b/ImageExtractor7.cs
deleted file mode 100644
index ed1f147..0000000
--- a/ImageExtractor7.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-
-using iText.Kernel.Geom;
-using iText.Kernel.Pdf;
-using iText.Kernel.Pdf.Xobject;
-using iText.Layout;
-using iText.Layout.Element;
-
-using java.util;
-using org.apache.pdfbox.pdmodel.graphics.xobject;
-using org.apache.pdfbox.pdmodel;
-
-namespace ComicCompressor
-{
- public class ImageExtractor7
- {
- public static readonly String DEST = "K:\\_COMIX\\_TOOLS_\\comic-compress-master\\bin\\Debug\\net6.0\\_NEW_PDF_\\Fan SUP 18.cbz";
-
- public static readonly String SRC = "K:\\_COMIX\\_TOOLS_\\comic-compress-master\\bin\\Debug\\net6.0\\_PDF_\\Fan SUP 18.pdf";
-
- public static void Main7()
- {
- FileInfo file = new FileInfo(DEST);
- file.Directory.Create();
-
- new ImageExtractor7().ManipulatePdf(DEST);
- }
-
- protected void ManipulatePdf(String dest)
- {
- PdfDocument resultDoc = new PdfDocument(new PdfWriter(dest));
- PdfDocument srcDoc = new PdfDocument(new PdfReader(SRC));
-
- // Assume that there is a single XObject in the source document
- // and this single object is an image.
- PdfDictionary pageDict = srcDoc.GetFirstPage().GetPdfObject();
- PdfDictionary pageResources = pageDict.GetAsDictionary(PdfName.Resources);
- PdfDictionary pageXObjects = pageResources.GetAsDictionary(PdfName.XObject);
- var ks = pageXObjects.KeySet();
- PdfName imgRef = pageXObjects.KeySet().First();
- PdfStream imgStream = pageXObjects.GetAsStream(imgRef);
- PdfImageXObject imgObject = new PdfImageXObject((PdfStream)imgStream.CopyTo(resultDoc));
- Image image = new Image(imgObject);
- image.ScaleToFit(14400, 14400);
- image.SetFixedPosition(0, 0);
-
-
- srcDoc.Close();
-
- PageSize pageSize = new PageSize(image.GetImageScaledWidth(), image.GetImageScaledHeight());
- Document doc = new Document(resultDoc, pageSize);
- doc.Add(image);
-
- doc.Close();
- }
-
-
- public static void MainBox()
- {
- new ImageExtractor7().ManipulatePdf(DEST);
- }
-
- protected void ManipulatePdfBox(String dest)
- {
- PDDocument document = null;
- document = PDDocument.load(SRC);
- java.util.List pages = document.getDocumentCatalog().getAllPages();
- Iterator iter = pages.iterator();
- while (iter.hasNext())
- {
- PDPage page = (PDPage)iter.next();
- PDResources resources = page.getResources();
- Map pageImages = resources.getImages();
- if (pageImages != null)
- {
- Iterator imageIter = pageImages.keySet().iterator();
- while (imageIter.hasNext())
- {
- String key = (String)imageIter.next();
- PDXObjectImage image = (PDXObjectImage)pageImages.get(key);
- //image.write2OutputStream(/* some output stream */);
- }
- }
- }
- }
- }
-}
diff --git a/Logger.cs b/Logger.cs
deleted file mode 100644
index 6a025bb..0000000
--- a/Logger.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-using System;
-using System.Drawing;
-using System.IO;
-using System.Runtime.CompilerServices;
-
-using Pastel;
-
-namespace ComicCompressor
-{
- public class Logger
- {
- public LogLevel LoggingLevel { get; set; } = LogLevel.Warning;
- public bool Debug = false;
-
- // Set to null for stdout
- public string LogFile { get; set; } = null;
-
- public void Log(object message, LogLevel logLevel, Color? col = null)
- {
- Log(message.ToString(), logLevel, col:col);
- }
-
- public void Log(string message, LogLevel logLevel,bool newLine = true, Color? col = null)
- {
- if (logLevel > LoggingLevel) return;
-
- if (LogFile == null)
- {
- if(newLine)
- Console.WriteLine(message.Pastel(col ?? Color.FromArgb(0,204,204,204)));
- else
- Console.Write(message.Pastel(col ?? Color.FromArgb(0, 204, 204, 204)));
- return;
- }
-
- WriteToFile(message);
- }
-
- public void LogError(string message, Color? col = null)
- {
- Log(message, LogLevel.Error, col:col);
- }
-
- public void LogError(object message, Color? col = null)
- {
- Log(message, LogLevel.Error, col:col);
- }
-
- public void LogDebug(string message, LogLevel logLevel, Color? col = null)
- {
- if (!Debug) return;
- Log(message, logLevel,col:col);
- }
-
- public void LogDebug(object message, LogLevel logLevel, Color? col = null)
- {
- LogDebug(message.ToString(), logLevel, col:col);
- }
-
- [MethodImpl(MethodImplOptions.Synchronized)]
- private void WriteToFile(string message)
- {
- if (LogFile == null) return;
-
- if (!Path.IsPathRooted(LogFile) && !LogFile.StartsWith("."))
- {
- LogFile = Path.Join(".", LogFile);
- }
-
- try
- {
- Directory.CreateDirectory(Path.GetDirectoryName(LogFile));
- File.AppendAllText(Path.GetFullPath(LogFile), message + "\n");
- }
- catch (UnauthorizedAccessException)
- {
- Console.WriteLine("Error: User does not have permissions for log file: " + LogFile);
- return;
- }
- catch (Exception)
- {
- Console.WriteLine("Error: could not write to log file: " + LogFile);
- return;
- }
- }
-
- }
-
- public enum LogLevel
- {
- Error = 2, Warning = 3, Info = 4, Verbose = 5
- }
-}
diff --git a/PixelMap.cs b/PixelMap.cs
deleted file mode 100644
index f8d2432..0000000
--- a/PixelMap.cs
+++ /dev/null
@@ -1,631 +0,0 @@
-using System;
-using System.Buffers;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-using System.Threading;
-
-
-//using Microsoft.Xna.Framework;
-//using Microsoft.Xna.Framework.Graphics;
-
-//using XnaColor = Microsoft.Xna.Framework.Graphics.Color;
-//using XnaRectangle = Microsoft.Xna.Framework.Rectangle;
-using SysColor = System.Drawing.Color;
-using SysRectangle = System.Drawing.Rectangle;
-
-namespace ComicCompressor
-{
- ///
- /// This class provides a managed C# abstraction for Portable Bit Map (.pbm), Portable Grey Map (.pgm) and
- /// Portable Pixel Map (.ppm)images. The class is able to handle P1 (ASCII .pbm), P2 (ASCII .pgm) P3 (ASCII .ppm),
- /// P5 (binary .pgm), and P6 (binary .ppm) files and streams. P4 (binary .pbm) is not supported. The class can
- /// process normal images, which have widths that are multiples of 4 pixels wide, and can also handle "off-size"
- /// images using a less efficient algorithm. It presents .pbm and .pgm images using the 8bppIndexed pixel format,
- /// and presents .ppm images using the 24bppRGB pixel format. It can convert these images into a visually pleasing
- /// greyscale bitmap image (in a less efficient 24bppRGB pixel format), which is accessible using the GreyMap
- /// property.
- ///
- /// To use this class:
- /// 1. Copy the PixelMap.cs file into your own project.
- /// 2. Change the namespace of the class (above this summary) from "PixelMap" to the namespace of your project.
- /// 3. Compile.
- ///
- /// This class is used by the PixelMapViewer application.
- ///
- public class PixelMap
- {
- private PixelMapHeader header;
- ///
- /// The header portion of the PixelMap.
- ///
- public PixelMapHeader Header
- {
- get { return header; }
- set { header = value; }
- }
-
- private byte[] imageData;
- ///
- /// The data portion of the PixelMap.
- ///
- public byte[] ImageData
- {
- get { return imageData; }
- set { imageData = value; }
- }
-
- private PixelFormat pixelFormat;
- ///
- /// The pixel format used by the BitMap generated by this PixelMap.
- ///
- public PixelFormat PixelFormat
- {
- get { return pixelFormat; }
- }
-
- private int bytesPerPixel;
- ///
- /// The number of bytes per pixel.
- ///
- public int BytesPerPixel
- {
- get { return bytesPerPixel; }
- }
-
- private int stride;
- ///
- /// The stride of the scan across the image. Typically this is width * bytesPerPixel, and is a multiple of 4.
- ///
- public int Stride
- {
- get { return stride; }
- set { stride = value; }
- }
-
- private Bitmap bitmap;
- ///
- /// The Bitmap created from the PixelMap.
- ///
- public Bitmap BitMap
- {
- get { return bitmap; }
- }
-
- ///
- /// A 24bpp Grey map (really only 8bpp of information, since R,G,B bytes are identical) created from the PixelMap.
- ///
- public Bitmap GreyMap
- {
- get { return CreateGreyMap(); }
- }
-
- ///
- /// File-based constructor.
- ///
- /// The name of the .pbm, .pbm, or .ppm file.
- public PixelMap(string filename)
- {
- if (File.Exists(filename))
- {
- FileStream stream = new FileStream(filename, FileMode.Open);
- this.FromStream(stream);
- stream.Close();
- }
- else
- {
- throw new FileNotFoundException("The file " + filename + " does not exist", filename);
- }
- }
-
- ///
- /// Stream-based constructor. Typically, the stream will be a FileStream, but it may also be a MemoryStream
- /// or other object derived from the Stream class.
- ///
- /// A stream containing the header and data portions of the .pbm, .pgm, or .ppm image.
- public PixelMap(Stream stream)
- {
- this.FromStream(stream);
- }
-
- private void FromStream(Stream stream)
- {
- int index;
- this.header = new PixelMapHeader();
- int headerItemCount = 0;
- stream.Position = 0;
- BinaryReader binReader = new BinaryReader(stream, Encoding.ASCII);
- try
- {
- //1. Read the Header.
- while (headerItemCount < 4)
- {
- char nextChar = (char)binReader.PeekChar();
- if (nextChar == '#') // comment
- {
- while (binReader.ReadChar() != '\n') ; // ignore the rest of the line.
- }
- else if (Char.IsWhiteSpace(nextChar)) // whitespace
- {
- binReader.ReadChar(); // ignore whitespace
- }
- else
- {
- switch (headerItemCount)
- {
- case 0: // next item is Magic Number
- // Read the first 2 characters and determine the type of pixelmap.
- char[] chars = binReader.ReadChars(2);
- this.header.MagicNumber = chars[0].ToString() + chars[1].ToString();
- headerItemCount++;
- break;
- case 1: // next item is the width.
- this.header.Width = ReadValue(binReader);
- headerItemCount++;
- break;
- case 2: // next item is the height.
- this.header.Height = ReadValue(binReader);
- headerItemCount++;
- break;
- case 3: // next item is the depth.
- if (this.header.MagicNumber == "P1" | this.header.MagicNumber == "P4")
- {
- // no depth value for PBM type.
- headerItemCount++;
- }
- else
- {
- this.header.Depth = ReadValue(binReader);
- headerItemCount++;
- }
- break;
- default:
- throw new Exception("Error parsing the file header.");
- }
- }
- }
-
- // 2. Read the image data.
- // 2.1 Size the imageData array to hold the image bytes.
- switch (this.header.MagicNumber)
- {
- case "P1": // 1 byte per pixel
- this.pixelFormat = PixelFormat.Format8bppIndexed;
- this.bytesPerPixel = 1;
- break;
- case "P2": // 1 byte per pixel
- this.pixelFormat = PixelFormat.Format8bppIndexed;
- this.bytesPerPixel = 1;
- break;
- case "P3": // 3 bytes per pixel
- this.pixelFormat = PixelFormat.Format24bppRgb;
- this.bytesPerPixel = 3;
- break;
- case "P4":
- this.pixelFormat = PixelFormat.Format8bppIndexed;
- this.bytesPerPixel = 1;
- //throw new Exception("Binary .pbm (Magic Number P4) is not supported at this time.");
- break;
- case "P5": // 1 byte per pixel
- this.pixelFormat = PixelFormat.Format8bppIndexed;
- this.bytesPerPixel = 1;
- break;
- case "P6": // 3 bytes per pixel
- this.pixelFormat = PixelFormat.Format24bppRgb;
- this.bytesPerPixel = 3;
- break;
- default:
- throw new Exception("Unknown Magic Number: " + this.header.MagicNumber);
- }
- this.imageData = new byte[this.header.Width * this.header.Height * this.bytesPerPixel];
- this.stride = this.header.Width * this.bytesPerPixel;
- //while ((this.stride % 4) != 0)
- //{
- // this.stride++;
- //}
- if (this.header.MagicNumber == "P1" | this.header.MagicNumber == "P2" | this.header.MagicNumber == "P3") // ASCII Encoding
- {
- int charsLeft = (int)(binReader.BaseStream.Length - binReader.BaseStream.Position);
- char[] charData = binReader.ReadChars(charsLeft); // read all the data into an array in one go, for efficiency.
- string valueString = string.Empty;
- index = 0;
- for (int i = 0; i < charData.Length; i++)
- {
- if (Char.IsWhiteSpace(charData[i])) // value is ignored if empty, or converted to byte and added to array otherwise.
- {
- if (valueString != string.Empty)
- {
- this.imageData[index] = (byte)int.Parse(valueString);
- valueString = string.Empty;
- index++;
- }
- }
- else // add the character to the end of the valueString.
- {
- valueString += charData[i];
- }
- }
- }
- else if(this.header.MagicNumber == "P4")
- {
- byte[] pixels = ReadP4(this.Header.Width, this.Header.Height, binReader);
- this.imageData = pixels;
- }
- else // binary encoding.
- {
- int bytesLeft = (int)(binReader.BaseStream.Length - binReader.BaseStream.Position);
- this.imageData = binReader.ReadBytes(bytesLeft);
- }
-
- // 3. We need to change the byte order of this.imageData from BGR to RGB.
- ReorderBGRtoRGB();
-
- // 4. Create the BitMap
- if (this.stride % 4 == 0)
- {
- this.bitmap = CreateBitMap();
- }
- else
- {
- this.bitmap = CreateBitmapOffSize();
- }
-
- // 5. Rotate the BitMap by 180 degrees so it is in the same orientation as the original image.
- this.bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
- }
-
- // If the end of the stream is reached before reading all of the expected values raise an exception.
- catch (EndOfStreamException e)
- {
- Console.WriteLine(e.Message);
- throw new Exception("Error reading the stream! ", e);
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- throw new Exception("Error reading the stream! ", ex);
- }
- finally
- {
- binReader.Close();
- }
- }
-
- private static byte[] ReadP4(int Width, int Height, BinaryReader binReader)
- {
-
- (int imageWidth, int imageHeight) = (Width, Height);
- int srcStride = (imageWidth + (8 - 1)) / 8; // Ceiling
- int srcSize = imageHeight * srcStride;
- var pixels = new byte[Height * Width * 1+8];
- //byte[] buffer = ArrayPool.Shared.Rent(srcSize);
- try
- {
- int charsLeft = (int)(binReader.BaseStream.Length - binReader.BaseStream.Position);
- byte[] buffer = binReader.ReadBytes(charsLeft); // read all the data into an array in one go, for efficiency.
- string valueString = string.Empty;
- //index = 0;
-
- //int readSize = await stream.ReadAsync(buffer.AsMemory(0, srcSize), cancellationToken);
- //if (readSize != srcSize)
- // throw new NotImplementedException($"Unable to read the intended size. Expected={srcSize}, Actual={readSize}");
-
- unsafe
- {
- fixed (byte* destHeadPtr = pixels)
- fixed (byte* srcHeadPtr = buffer)
- {
- byte* srcTailPtr = srcHeadPtr + (srcStride * imageHeight);
- byte* dest = destHeadPtr;
- (int srcWidthMax, int remainder) = Math.DivRem(imageWidth, 8);
-
- for (byte* srcRowPtr = srcHeadPtr; srcRowPtr < srcTailPtr; srcRowPtr += srcStride)
- {
- byte* srcRowTailPtr = srcRowPtr + srcWidthMax;
- for (byte* p = srcRowPtr; p < srcRowTailPtr; p++)
- {
- //Console.Write($" {(*p).ToString("X2")}");
-
- //*((ulong*)dest) =
- // (((*p & 0x80) is 0) ? 0UL : 0x0000_0000_0000_0001)
- // | (((*p & 0x40) is 0) ? 0UL : 0x0000_0000_0000_0100)
- // | (((*p & 0x20) is 0) ? 0UL : 0x0000_0000_0001_0000)
- // | (((*p & 0x10) is 0) ? 0UL : 0x0000_0000_0100_0000)
- // | (((*p & 0x08) is 0) ? 0UL : 0x0000_0001_0000_0000)
- // | (((*p & 0x04) is 0) ? 0UL : 0x0000_0100_0000_0000)
- // | (((*p & 0x02) is 0) ? 0UL : 0x0001_0000_0000_0000)
- // | (((*p & 0x01) is 0) ? 0UL : 0x0100_0000_0000_0000);
- *((ulong*)dest) =
- (((*p & 0x80) is 0) ? 0UL : 0x0000_0000_0000_00ff)
- | (((*p & 0x40) is 0) ? 0UL : 0x0000_0000_0000_ff00)
- | (((*p & 0x20) is 0) ? 0UL : 0x0000_0000_00ff_0000)
- | (((*p & 0x10) is 0) ? 0UL : 0x0000_0000_ff00_0000)
- | (((*p & 0x08) is 0) ? 0UL : 0x0000_00ff_0000_0000)
- | (((*p & 0x04) is 0) ? 0UL : 0x0000_ff00_0000_0000)
- | (((*p & 0x02) is 0) ? 0UL : 0x00ff_0000_0000_0000)
- | (((*p & 0x01) is 0) ? 0UL : 0xff00_0000_0000_0000);
-
- dest += sizeof(ulong);
-
- }
-
- if (remainder > 0)
- {
- const byte start = 0x80;
- byte end = (byte)(start >> remainder);
-
- for (int mask = start; mask > end; mask >>= 1)
- *(dest++) = ((*srcRowTailPtr & mask) is 0) ? (byte)0 : (byte)1;
- }
- }
- }
- }
- return pixels;
- }
- catch(Exception ex)
- {
- Console.WriteLine(ex.Message + " - " + ex.StackTrace);
- }
- finally
- {
- }
- return pixels;
- }
-
-
- ///
- /// As it stands, the native byte order in .pbm, .pgm, and .ppm images is BGR. We need to reverse the order
- /// into RGB as this is what is needed for 24bppRGB bitmap pixel format on Windows.
- ///
- private void ReorderBGRtoRGB()
- {
- byte[] tempData = new byte[this.imageData.Length];
- for (int i = 0; i < this.imageData.Length; i++)
- {
- tempData[i] = this.imageData[this.imageData.Length - 1 - i];
- }
- this.imageData = tempData;
- }
-
- private int ReadValue(BinaryReader binReader)
- {
- string value = string.Empty;
- while (!Char.IsWhiteSpace((char)binReader.PeekChar()))
- {
- value += binReader.ReadChar().ToString();
- }
- binReader.ReadByte(); // get rid of the whitespace.
- return int.Parse(value);
- }
-
- private Bitmap CreateBitMap()
- {
- IntPtr pImageData = Marshal.AllocHGlobal(this.imageData.Length);
- Marshal.Copy(this.imageData, 0, pImageData, this.imageData.Length);
- Bitmap bitmap = new Bitmap(this.header.Width, this.header.Height, this.stride, this.pixelFormat, pImageData);
- return bitmap;
- }
-
- private Bitmap CreateGreyMap()
- {
- byte[] greyData = new byte[this.header.Width * this.header.Height * 3];
- int stride = this.header.Width * 3;
- //while (stride % 4 != 0)
- //{
- // stride++;
- //}
- if (stride % 4 != 0)
- {
- return CreateGreyMapOffSize(greyData);
- }
- byte grey;
- switch (this.pixelFormat)
- {
- case PixelFormat.Format24bppRgb:
- int red, green, blue;
- for (int i = 0; i < this.imageData.Length; i = i + 3)
- {
- red = (int)this.imageData[i];
- green = (int)this.imageData[i + 1];
- blue = (int)this.imageData[i + 2];
- grey = (byte)((red + green + blue) / 3);
- greyData[i] = grey;
- greyData[i + 1] = grey;
- greyData[i + 2] = grey;
- }
- break;
- case PixelFormat.Format8bppIndexed:
- int index = 0;
- for (int i = 0; i < this.imageData.Length; i++)
- {
- index = 3 * i;
- grey = this.imageData[i];
- if (this.header.MagicNumber == "P1")
- {
- if ((int)grey == 1)
- {
- grey = (byte)255;
- }
- }
- greyData[index] = grey;
- greyData[index + 1] = grey;
- greyData[index + 2] = grey;
- }
- break;
- default:
- throw new Exception("Unsupported Pixel Format: " + this.pixelFormat.ToString());
- }
- IntPtr pGreyData = Marshal.AllocHGlobal(greyData.Length);
- Marshal.Copy(greyData, 0, pGreyData, greyData.Length);
- Bitmap bitmap = new Bitmap(this.header.Width, this.header.Height, stride, PixelFormat.Format24bppRgb, pGreyData);
- bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
- return bitmap;
- }
-
- ///
- /// This method is able to handle the process of creating Bitmaps that are not sized in widths that are multiples
- /// of 4 pixels (which is needed for the rapid drawing using the Marshal class.) Unfortunately, this is a very slow
- /// method, since it uses SetPixel().
- ///
- ///
- private Bitmap CreateBitmapOffSize()
- {
- Bitmap bitmap = new Bitmap(this.header.Width, this.header.Height, PixelFormat.Format24bppRgb);
- SysColor sysColor = new SysColor();
- int red, green, blue, grey;
- int index;
-
- for (int x = 0; x < this.header.Width; x++)
- {
- for (int y = 0; y < this.header.Height; y++)
- {
- index = x + y * this.header.Width;
-
- switch (this.header.MagicNumber)
- {
- case "P1":
- grey = (int)this.imageData[index];
- if (grey == 1)
- {
- grey = 255;
- }
- sysColor = SysColor.FromArgb(grey, grey, grey);
- break;
- case "P2":
- grey = (int)this.imageData[index];
- sysColor = SysColor.FromArgb(grey, grey, grey);
- break;
- case "P3":
- index = 3 * index;
- blue = (int)this.imageData[index];
- green = (int)this.imageData[index + 1];
- red = (int)this.imageData[index + 2];
- sysColor = SysColor.FromArgb(red, green, blue);
- break;
- case "P4":
- break;
- case "P5":
- grey = (int)this.imageData[index];
- sysColor = SysColor.FromArgb(grey, grey, grey);
- break;
- case "P6":
- index = 3 * index;
- blue = (int)this.imageData[index];
- green = (int)this.imageData[index + 1];
- red = (int)this.imageData[index + 2];
- sysColor = SysColor.FromArgb(red, green, blue);
- break;
- default:
- break;
- }
- bitmap.SetPixel(x, y, sysColor);
- }
- }
- return bitmap;
- }
-
- private Bitmap CreateGreyMapOffSize(byte[] greyData)
- {
- Bitmap bitmap = new Bitmap(this.header.Width, this.header.Height, PixelFormat.Format24bppRgb);
- SysColor sysColor = new SysColor();
- int index = 0;
- int x = 0;
- int y = -1;
- switch (this.pixelFormat)
- {
- case PixelFormat.Format24bppRgb:
- int red, green, blue, grey;
- for (int i = 0; i < this.imageData.Length; i = i + 3)
- {
- index = i / 3; // the current pixel
- if (index%this.header.Width == 0) y++; // the current row = y;
- x = index - y * this.header.Width; // the current column = x;
- red = (int)this.imageData[i];
- green = (int)this.imageData[i + 1];
- blue = (int)this.imageData[i + 2];
- grey = (byte)((red + green + blue) / 3);
- sysColor = SysColor.FromArgb(grey, grey, grey);
- bitmap.SetPixel(x, y, sysColor);
- }
- break;
- case PixelFormat.Format8bppIndexed:
- for (int i = 0; i < this.imageData.Length; i++)
- {
- index = i; // the current pixel
- if (index % this.header.Width == 0) y++; // the current row = y;
- x = index - y * this.header.Width; // the current column = x;
-
- grey = this.imageData[i];
- if (this.header.MagicNumber == "P1")
- {
- if ((int)grey == 1)
- {
- grey = (byte)255;
- }
- }
- sysColor = SysColor.FromArgb(grey, grey, grey);
- bitmap.SetPixel(x, y, sysColor);
- }
- break;
- default:
- throw new Exception("Unsupported Pixel Format: " + this.pixelFormat.ToString());
- }
- bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
- return bitmap;
- }
-
- ///
- /// This struct contains the objects that are found in the header of .pbm, .pgm, and .ppm files.
- ///
- [Serializable]
- public struct PixelMapHeader
- {
- private string magicNumber;
- ///
- /// The "Magic Number" that identifies the type of Pixelmap. P1 = PBM (ASCII); P2 = PGM (ASCII); P3 = PPM (ASCII); P4 is not used;
- /// P5 = PGM (Binary); P6 = PPM (Binary).
- ///
- public string MagicNumber
- {
- get { return magicNumber; }
- set { magicNumber = value; }
- }
-
- private int width;
- ///
- /// The width of the image.
- ///
- public int Width
- {
- get { return width; }
- set { width = value; }
- }
-
- private int height;
- ///
- /// The height of the image.
- ///
- public int Height
- {
- get { return height; }
- set { height = value; }
- }
-
- private int depth;
- ///
- /// The depth (maximum color value in each channel) of the image. This allows the format to represent
- /// more than a single byte (0-255) for each color channel.
- ///
- public int Depth
- {
- get { return depth; }
- set { depth = value; }
- }
- }
- }
-}
diff --git a/Program.cs b/Program.cs
index e65235f..d5e9e5f 100644
--- a/Program.cs
+++ b/Program.cs
@@ -35,6 +35,10 @@ using Xabe.FFmpeg.Downloader;
using System.Reflection;
using Microsoft.VisualBasic;
using BinaryKits.Zpl.Viewer;
+using iMGcompress_core;
+
+
+
namespace ComicCompressor
{
@@ -125,8 +129,27 @@ namespace ComicCompressor
// static Color randomColor = Color.FromKnownColor(randomColorName);
public Color[] myColors = null;
+
+
+
+ //static void TestPar2()
+ //{
+ // var items = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+
+ // // Create a SingleItemPartitioner from the collection
+ // var partitioner = new Partitioner(items);
+
+ // // Use Parallel.ForEach to process items in parallel
+ // Parallel.ForEach(partitioner, item =>
+ // {
+ // Console.WriteLine($"Processing item: {item}");
+ // });
+ //}
+
private void OnExecute()
{
+
+
File_statistics.Clear();
@@ -141,7 +164,7 @@ namespace ComicCompressor
Stopwatch sw = Stopwatch.StartNew();
Logger = new Logger();
- Logger.Debug = true;
+ Logger.DebugOn = true;
Logger.LoggingLevel = LogLevel.Verbose;
Logger.Log(progVersion, LogLevel.Verbose, true);
diff --git a/Properties/PublishProfiles/FolderProfile.pubxml b/Properties/PublishProfiles/FolderProfile.pubxml
new file mode 100644
index 0000000..10f1155
--- /dev/null
+++ b/Properties/PublishProfiles/FolderProfile.pubxml
@@ -0,0 +1,11 @@
+
+
+
+
+ Release
+ Any CPU
+ bin\Release\net8.0\publish\
+ FileSystem
+ <_TargetId>Folder
+
+
\ No newline at end of file
diff --git a/Properties/PublishProfiles/FolderProfile.pubxml.user b/Properties/PublishProfiles/FolderProfile.pubxml.user
new file mode 100644
index 0000000..4144f92
--- /dev/null
+++ b/Properties/PublishProfiles/FolderProfile.pubxml.user
@@ -0,0 +1,8 @@
+
+
+
+
+ True|2025-03-12T20:02:41.5913059Z||;
+
+
+
\ No newline at end of file
diff --git a/pdfimages.exe b/pdfimages.exe
new file mode 100644
index 0000000..08a87cd
Binary files /dev/null and b/pdfimages.exe differ