annotate dynamin/lodepng/encode.d @ 0:aa4efef0f0b1

Initial commit of code.
author Jordan Miner <jminer7@gmail.com>
date Mon, 15 Jun 2009 22:10:48 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
1 // Written in the D programming language
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
2 // www.digitalmars.com/d/
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
3
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
4 /***************************************************************************************************
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
5 License:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
6 Copyright (c) 2005-2007 Lode Vandevenne
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
7 All rights reserved.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
8
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
9 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
10
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
11 - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.<br>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
12 - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.<br>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
13 - Neither the name of Lode Vandevenne nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission.<br>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
14
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
16
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
17 Authors: Lode Vandevenne (original version in C++), Lutger Blijdestijn (D version) : lutger dot blijdestijn at gmail dot com,
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
18 Stewart Gordon (bug fixes)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
19
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
20 Date: August 7, 2007
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
21
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
22 About:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
23 The lodepng encoder can encode images of any of the supported png color formats to 24-bit RGB or
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
24 32-bit RGBA png images. Conversion, if needed, is done automatically. It is compatible with the
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
25 Phobos and Tango libraries. For Tango, lodepng expects the zlib binding from phobos in etc.c.zlib.d<br>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
26 This module publicly imports lodepng.Common, where you'll find the data types used by both the encoder
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
27 and decoder, as well as some utility and image format conversion routines.<br>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
28
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
29 Features:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
30 The following features are supported by the encoder:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
31 <ul>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
32 <li> conformant encoding of 24-bit RGB and 32-bit RGBA PNG images </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
33 <li> automatic conversion of other color formats </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
34 <li> setting the compression and filter methods </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
35 <li> textual key-value metadata: normal and compressed latin1, unicode (utf-8) </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
36 <li> transparency / colorkey </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
37 <li> the following chunks are written by the encoder
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
38 <ul>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
39 <li>IHDR (image information)</li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
40 <li>IDAT (pixel data)</li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
41 <li>IEND (the final chunk)</li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
42 <li>tRNS (colorkey)</li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
43 <li>bKGD (suggested background color) </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
44 <li>tEXt (uncompressed latin-1 key-value strings)</li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
45 <li>zTXt (compressed latin-1 key-value strings)</li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
46 <li>iTXt (utf8 key-value strings)</li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
47 </ul>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
48 </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
49 </UL>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
50
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
51 <b>Limitations:</b><br>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
52 The following features are not supported.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
53 <ul>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
54 <li> Ouput in any color formats other than 24-bit RGB or 32-bit RGBA</li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
55 <li> Interlacing </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
56 <li> The following chunk types are not written by the encoder
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
57 <ul>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
58 <li>PLTE (color palette)</li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
59 <li>cHRM (device independent color info) </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
60 <li>gAMA (device independent color info) </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
61 <li>iCCP (device independent color info) </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
62 <li>sBIT (original number of significant bits) </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
63 <li>sRGB (device independent color info) </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
64 <li>pHYs (physical pixel dimensions) </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
65 <li>sPLT (suggested reduced palette) </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
66 <li>tIME (last image modification time) </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
67 </ul>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
68 </li>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
69 </ul>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
70
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
71 References:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
72 $(LINK2 http://members.gamedev.net/lode/projects/LodePNG/, Original lodepng) <br>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
73 $(LINK2 http://www.w3.org/TR/PNG/, PNG Specification) <br>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
74 $(LINK2 http://www.libpng.org/pub/png/pngsuite.html, PNG Suite: set of test images) <br>
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
75 $(LINK2 http://optipng.sourceforge.net/, OptiPNG: tool to experimentally optimize png images)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
76 ***************************************************************************************************/
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
77 module dynamin.lodepng.encode;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
78
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
79 version (Tango)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
80 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
81 import tango.math.Math;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
82 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
83 else
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
84 import std.math;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
85 import dynamin.lodepng.zlib_codec;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
86 public import dynamin.lodepng.common;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
87
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
88 /***************************************************************************************************
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
89 Returns a png image of the raw pixels provided by source and described by original
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
90
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
91 This function will attempt to convert to 24-bit RGB if it is a lossless operation, otherwise
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
92 the resulting png image will be in the 32-bit RGBA format. The array returned can be written to disk
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
93 as a png file.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
94
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
95 throws: PngException
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
96 ***************************************************************************************************/
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
97 ubyte[] encode(in ubyte[] source, in PngInfo original)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
98 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
99 ubyte[] buf;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
100 return _encode(source, original, EncodeOptions(), buf);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
101 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
102
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
103 /**************************************************************************************************
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
104 Returns a png image of the raw pixels provided by source and described by original.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
105
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
106 See also: EncodeOptions
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
107
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
108 throws: PngException
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
109 ***************************************************************************************************/
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
110 ubyte[] encode(in ubyte[] source, in PngInfo original, in EncodeOptions options)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
111 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
112 ubyte[] buf;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
113 return _encode(source, original, options, buf);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
114 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
115
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
116 /***************************************************************************************************
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
117 Combinations of filter and compression trade-offs
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
118
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
119 The png compression scheme works by applying lossless filters on the image data and then
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
120 compressing with the deflate (zlib) algorithm. The filters condition the data for better
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
121 compression. This enumeration can be used with EncodeOptions, see FilterStrategy and
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
122 CompressionStrategy for more control over how the image is encoded.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
123
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
124 ***************************************************************************************************/
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
125 enum EncodingStrategy
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
126 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
127 /// source data is stored as is
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
128 Store,
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
129
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
130 /** this gives zero compression but can be useful for storage in a zlib compressed file, in
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
131 which case the filtering conditions the data for better compression **/
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
132 FilterOnly,
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
133
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
134 /// aim for reasonable compression but with emphasis on speed
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
135 Fast,
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
136
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
137 /// aim for good compression / speed tradeoff
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
138 Normal,
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
139
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
140 /// aim for best compression
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
141 Best
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
142 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
143
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
144 /***************************************************************************************************
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
145 Filter method
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
146
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
147 The png specification defines five types of filters. In addition each scanline can have a
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
148 different filtering method applied (Dynamic). The latter method gives the best compression,
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
149 when a fixed method is preffered usually paeth works best.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
150
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
151 ***************************************************************************************************/
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
152 enum FilterStrategy : ubyte
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
153 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
154 None = 0, ///
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
155 Up = 1, ///
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
156 Sub = 2, ///
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
157 Average = 3, ///
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
158 Paeth = 4, ///
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
159 Dynamic, ///
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
160 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
161
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
162 /***************************************************************************************************
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
163 Zlib compression method
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
164
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
165 Which compression scheme works best depends on the type of image. Tools such as optipng can
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
166 figure this out experimentally.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
167
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
168 ***************************************************************************************************/
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
169 enum CompressionStrategy : ubyte
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
170 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
171
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
172 Default = 0, ///
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
173 Filtered = 1, ///
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
174 RLE = 3, ///
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
175 None = ubyte.max ///
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
176 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
177
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
178 /// Controls how a png image is encoded and what auxiliary data is to be written
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
179 struct EncodeOptions
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
180 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
181 /// constructors
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
182 static EncodeOptions opCall()
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
183 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
184 EncodeOptions result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
185 return result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
186 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
187
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
188 /// ditto
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
189 static EncodeOptions opCall(ColorType colorType,
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
190 EncodingStrategy strategy = EncodingStrategy.Normal,
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
191 bool autoRemoveAlpha = true)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
192 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
193 EncodeOptions result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
194 result.setStrategy(strategy);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
195
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
196 with (result)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
197 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
198 autoRemoveAlpha = autoRemoveAlpha;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
199 targetColorType = colorType;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
200 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
201 return result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
202 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
203
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
204 /// ditto
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
205 static EncodeOptions opCall(EncodingStrategy strategy,
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
206 bool autoRemoveAlpha = true)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
207 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
208 EncodeOptions result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
209 result.setStrategy(strategy);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
210 return result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
211 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
212
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
213 /// ditto
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
214 static EncodeOptions opCall(CompressionStrategy compression, FilterStrategy filter = FilterStrategy.Dynamic)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
215 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
216 EncodeOptions result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
217 result.compressionLevel = 9;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
218 result.compressionStrategy = compression;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
219 result.filterStrategy = filter;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
220 return result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
221 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
222
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
223 invariant
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
224 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
225 assert(compressionLevel >=0 && compressionLevel <= 9, "invalid zlib compression level");
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
226 assert(targetColorType == ColorType.Any ||
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
227 targetColorType == ColorType.RGB ||
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
228 targetColorType == ColorType.RGBA, "colortype is not supported");
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
229 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
230
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
231 /***********************************************************************************************
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
232 The colortype of the target image
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
233
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
234 lodepng can only encode in RGB(A) format. If the format is set ColorType.Any, RGB or
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
235 RGBA is chosen depending on whether the source image has an alpha channel.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
236 ***********************************************************************************************/
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
237 ColorType targetColorType = ColorType.Any;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
238
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
239 /***********************************************************************************************
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
240 Remove alpha channel
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
241
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
242 If set to true and the source image has an alpha channel, this will be removed if (and
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
243 only if) the image is fully opaque or a colorkey can be written. This is considered a
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
244 lossless operation.
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
245 ***********************************************************************************************/
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
246 bool autoRemoveAlpha = true;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
247
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
248 PngText text; /// key-value strings to be written, see also: lodepng.Common.PngText
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
249 bool compressText = false; /// if zlib compression is to be used on text
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
250
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
251 ubyte[] backgroundColor; /// suggested background RGB-triplet, must be either 3 or 6 bytes
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
252
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
253 bool colorKey = false; /// colorkey, set to true if it is to be encoded
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
254 ubyte keyR; /// red/greyscale component of color key
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
255 ubyte keyG; /// green component of color key
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
256 ubyte keyB; /// blue component of color key
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
257
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
258 ubyte compressionLevel = 6; /// zlib compression level, affects memory use. Must be in range 0-9
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
259 FilterStrategy filterStrategy = FilterStrategy.Dynamic; /// see FilterStrategy
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
260 CompressionStrategy compressionStrategy = CompressionStrategy.RLE; /// see CompressionStrategy
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
261
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
262 /// This will set compressionLevel, compressionStrategy and filterStrategy
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
263 void setStrategy(EncodingStrategy strategy)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
264 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
265 switch (strategy)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
266 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
267 case EncodingStrategy.Store:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
268 compressionLevel = 0;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
269 compressionStrategy = CompressionStrategy.None;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
270 filterStrategy = FilterStrategy.None;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
271 break;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
272 case EncodingStrategy.FilterOnly:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
273 compressionLevel = 0;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
274 compressionStrategy = CompressionStrategy.None;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
275 filterStrategy = FilterStrategy.Dynamic;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
276 break;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
277 case EncodingStrategy.Fast:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
278 compressionLevel = 6;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
279 compressionStrategy = CompressionStrategy.RLE;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
280 filterStrategy = FilterStrategy.Paeth;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
281 break;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
282 case EncodingStrategy.Normal:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
283 compressionLevel = 6;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
284 compressionStrategy = CompressionStrategy.RLE;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
285 filterStrategy = FilterStrategy.Dynamic;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
286 break;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
287 case EncodingStrategy.Best:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
288 compressionLevel = 9;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
289 compressionStrategy = CompressionStrategy.Filtered;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
290 filterStrategy = FilterStrategy.Dynamic;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
291 break;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
292 /+ TODO: decide to implement or leave it out
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
293 case EncodingStrategy.ByteCrunch:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
294 compressionLevel = 9;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
295 compressionStrategy = CompressionStrategy.Filtered;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
296 filterStrategy = FilterStrategy.Dynamic;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
297 break;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
298 +/
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
299 default:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
300 assert(false, "I don't know about this strategy");
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
301 break;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
302 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
303 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
304 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
305
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
306 private
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
307 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
308 ubyte[] _encode( in ubyte[] source, in PngInfo original, in EncodeOptions options, ref ubyte[] buffer)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
309 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
310 // TODO: be more sparing with memory here, can at least avoid one array copy
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
311
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
312 Chunk[] ChunkList;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
313
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
314 // find out what colortype of target should be and whether colorkey (tRNS) should be made
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
315 ColorType destColor = (options.targetColorType == ColorType.RGB ||
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
316 options.targetColorType == ColorType.RGBA) ? options.targetColorType :
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
317 original.image.colorType;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
318 if (!(destColor == ColorType.RGB || destColor == ColorType.RGBA))
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
319 destColor = (hasAlphaChannel(original.image.colorType)) ? ColorType.RGBA : ColorType.RGB;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
320 if (options.autoRemoveAlpha && destColor == ColorType.RGBA && !options.colorKey)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
321 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
322 ubyte[] colorKey;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
323 if (opaqueOrColorkey(source, original, colorKey))
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
324 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
325 if (colorKey.length)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
326 ChunkList ~= Chunk(tRNS, colorKey);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
327 destColor = ColorType.RGB;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
328 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
329 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
330
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
331 // properties of image to be written
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
332 auto image = PngImage(original.image.width, original.image.height, 8, destColor);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
333
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
334 // convert original if necessary
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
335 ubyte[] pixels;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
336 if (original.image.colorType != destColor || original.image.bitDepth != 8)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
337 pixels = convert(source, original, destColor);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
338 else
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
339 pixels = source;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
340
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
341 ChunkList ~= Chunk(IHDR, headerData(image));
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
342 ChunkList ~= Chunk(IDAT,
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
343 Encoder.create(options.compressionStrategy, options.compressionLevel)(filter(pixels, image, options.filterStrategy)));
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
344 if(options.colorKey)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
345 ChunkList ~= Chunk(tRNS, [0, cast(ubyte)options.keyR, 0, cast(ubyte)options.keyG, 0, cast(ubyte)options.keyB]);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
346 if(options.backgroundColor.length == 3)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
347 ChunkList ~= Chunk( bKGD, [
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
348 0, options.backgroundColor[0],
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
349 0, options.backgroundColor[1],
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
350 0, options.backgroundColor[2] ]);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
351 else if(options.backgroundColor.length == 6)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
352 ChunkList ~= Chunk( bKGD, options.backgroundColor);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
353 if (options.text !is null && (options.text.latin1Text.length > 0 || options.text.unicodeText.length > 0))
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
354 ChunkList ~= chunkifyText(options);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
355 ChunkList.sort;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
356 ChunkList ~= Chunk(IEND, []);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
357
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
358 // pre-allocate space needed
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
359 uint pngLength = 8;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
360 foreach(chunk; ChunkList)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
361 pngLength += chunk.length;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
362 buffer.length = pngLength;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
363 buffer.length = 0;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
364
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
365 // create and write all data
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
366 writeSignature(buffer);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
367 foreach(chunk; ChunkList)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
368 writeChunk(buffer, chunk);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
369
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
370 return buffer;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
371 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
372
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
373 Chunk[] chunkifyText(EncodeOptions options)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
374 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
375 Chunk[] result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
376 if (options.compressText)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
377 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
378 auto enc = Encoder.create();
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
379 foreach(ubyte[] keyword, ubyte[] value; options.text)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
380 result ~= Chunk(zTXt, keyword ~ cast(ubyte[])[0, 0] ~ enc(value));
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
381 foreach(char[] keyword, char[] value; options.text)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
382 result ~= Chunk(iTXt, cast(ubyte[])keyword ~ cast(ubyte[])[0, 1, 0, 0, 0] ~ enc(cast(ubyte[])value));
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
383 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
384 else
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
385 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
386 foreach(ubyte[] keyword, ubyte[] value; options.text)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
387 result ~= Chunk(tEXt, keyword ~ cast(ubyte[])[0] ~ value);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
388 foreach(char[] keyword, char[] value; options.text)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
389 result ~= Chunk(iTXt, cast(ubyte[])keyword ~ cast(ubyte[])[0, 0, 0, 0, 0] ~ cast(ubyte[])value);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
390 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
391 return result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
392 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
393
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
394 ubyte[] filter(in ubyte[] source, ref PngImage image, FilterStrategy filterMethod = FilterStrategy.Dynamic)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
395 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
396 /* adaptive filtering */
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
397
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
398 ubyte[] buffer = new ubyte[image.width * (image.bpp / 8) * image.height];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
399 uint bytewidth = (image.bpp + 7) / 8;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
400
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
401 uint scanlength = image.width * bytewidth;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
402 buffer.length = image.height * (scanlength + 1) + image.height;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
403 ubyte[] line, previous;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
404 buffer.length = 0;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
405 line = source[0..scanlength];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
406 ubyte bestFilter = 0;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
407
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
408 uint absSum(ubyte[] array)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
409 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
410 uint result = 0;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
411 foreach(value; array)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
412 result += abs(cast(int)(cast(byte)value));
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
413 return result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
414 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
415
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
416 uint smallest = absSum(filterMap(line, &None, bytewidth));
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
417
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
418 void setSmallest(uint sum, ubyte filterType)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
419 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
420 if (sum < smallest)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
421 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
422 smallest = sum;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
423 bestFilter = filterType;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
424 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
425 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
426
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
427 if (filterMethod == FilterStrategy.Dynamic)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
428 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
429 for (ubyte f = 1; f < 5; f++)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
430 setSmallest(absSum(dynFilterMap(line, f, bytewidth)), f);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
431 buffer ~= bestFilter;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
432 buffer ~= dynFilterMap(line, bestFilter, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
433
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
434 for (int y = 1; y < image.height; y++)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
435 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
436 line = source[scanlength * y..scanlength * y + scanlength];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
437 previous = source[scanlength * (y - 1)..scanlength * y];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
438
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
439 bestFilter = 0;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
440 smallest = absSum(filterMap(line, &None, bytewidth));
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
441 for (ubyte f = 1; f < 5; f++)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
442 setSmallest(absSum(dynFilterMap(previous, line, f, bytewidth)), f);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
443
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
444 buffer ~= bestFilter;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
445 buffer ~= dynFilterMap(previous, line, bestFilter, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
446 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
447 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
448 else
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
449 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
450 buffer ~= cast(ubyte)filterMethod;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
451 buffer ~= dynFilterMap(line, cast(ubyte)filterMethod, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
452
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
453 for (int y = 1; y < image.height; y++)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
454 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
455 line = source[scanlength * y..scanlength * y + scanlength];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
456 previous = source[scanlength * (y - 1)..scanlength * y];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
457
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
458 buffer ~= cast(ubyte)filterMethod;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
459 buffer ~= dynFilterMap(previous, line, cast(ubyte)filterMethod, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
460 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
461 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
462 return buffer;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
463 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
464
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
465 bool opaqueOrColorkey(in ubyte[] image, in PngInfo info, out ubyte[] colorKey)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
466 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
467 if (info.image.colorType == ColorType.Greyscale || info.image.colorType == ColorType.RGB)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
468 return false;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
469 else if (info.image.colorType == ColorType.RGBA )
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
470 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
471 uint numpixels = info.image.width * info.image.height;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
472
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
473 ubyte[3] ckey;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
474 bool hasCkey = false;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
475
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
476 for(size_t i = 0; i < numpixels; i++)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
477 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
478 if(image[i * 4 + 3] != 255)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
479 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
480 if(image[i * 4 + 3] == 0)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
481 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
482 if (hasCkey)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
483 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
484 if (ckey[0] != image[i * 4] || ckey[1] != image[i * 4 + 1] ||
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
485 ckey[2] != image[i * 4 + 2] )
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
486 return false;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
487 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
488 else
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
489 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
490 hasCkey = true;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
491 ckey[0..2] = image[i * 4 .. i * 4 + 2];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
492 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
493 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
494 else
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
495 return false;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
496 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
497 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
498 if (hasCkey)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
499 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
500 colorKey = new ubyte[6];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
501 colorKey[1] = ckey[0];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
502 colorKey[3] = ckey[1];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
503 colorKey[5] = ckey[2];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
504 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
505 return true;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
506 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
507 else if(info.image.colorType == ColorType.GreyscaleAlpha)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
508 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
509 size_t numpixels = image.length / 2;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
510
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
511 ubyte[1] ckey;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
512 bool hasCkey = false;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
513
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
514 for(size_t i = 0; i < numpixels; i++)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
515 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
516 if(image[i * 2 + 1] != 255)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
517 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
518 if (hasCkey)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
519 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
520 if (ckey[0] != image[i * 2])
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
521 return false;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
522 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
523 else
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
524 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
525 hasCkey = true;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
526 ckey[0] = image[i * 2];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
527 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
528 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
529 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
530 if (hasCkey)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
531 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
532 colorKey = new ubyte[2];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
533 colorKey[1] = ckey[0];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
534 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
535 return true;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
536 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
537 else if (info.image.colorType == ColorType.Palette)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
538 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
539 // TODO: implement this (compression optimization)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
540 return false;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
541 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
542 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
543
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
544 ubyte[] headerData(PngImage image)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
545 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
546 ubyte[] header = new ubyte[13];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
547 header.length = 0;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
548
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
549 header.concatUint(image.width);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
550 header.concatUint(image.height);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
551 header ~= image.bitDepth;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
552 header ~= image.colorType;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
553 header ~= 0; //compression method
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
554 header ~= 0; //filter method
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
555 header ~= 0; //interlace method
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
556
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
557 return header;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
558 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
559
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
560 void concatUint(ref ubyte[] bytestream, uint num)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
561 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
562 bytestream.length = bytestream.length + 4;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
563 bytestream[$-4] = num >> 24;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
564 bytestream[$-3] = num >> 16;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
565 bytestream[$-2] = num >> 8;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
566 bytestream[$-1] = num;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
567 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
568
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
569 void writeChunk(ref ubyte[] bytestream, ref Chunk chunk)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
570 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
571 bytestream.concatUint(chunk.data.length);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
572
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
573 bytestream.length = bytestream.length + 4;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
574 bytestream[$-4] = (chunk.type & 0xff000000) >> 24 ;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
575 bytestream[$-3] = (chunk.type & 0x00ff0000) >> 16;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
576 bytestream[$-2] = (chunk.type & 0x0000ff00) >> 8;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
577 bytestream[$-1] = chunk.type & 0x000000ff;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
578
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
579 bytestream.length = bytestream.length + chunk.data.length;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
580 bytestream[$ - chunk.data.length..$] = chunk.data;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
581
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
582 uint CRC = createCRC(bytestream[$ - chunk.data.length - 4.. $]);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
583 bytestream.concatUint(CRC);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
584 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
585
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
586 void writeSignature(ref ubyte[] byteStream)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
587 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
588 byteStream ~= [137, 80, 78, 71, 13, 10, 26, 10];
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
589 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
590
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
591 /++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
592 From the png spec: pixels for filtering are defined as follows such, where x is the current
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
593 being filtered and c, b correspond to the previous scanline:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
594 c b
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
595 a x
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
596
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
597 filters: construction Reconstruction
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
598 0 None Filt(x) = Orig(x) Recon(x) = Filt(x)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
599 1 Sub Filt(x) = Orig(x) - Orig(a) Recon(x) = Filt(x) + Recon(a)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
600 2 Up Filt(x) = Orig(x) - Orig(b) Recon(x) = Filt(x) + Recon(b)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
601 3 Average Filt(x) = Orig(x) - floor((Orig(a) + Orig(b)) / 2) Recon(x) = Filt(x) + floor((Recon(a) + Recon(b)) / 2)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
602 4 Paeth Filt(x) = Orig(x) - PaethPredictor(Orig(a), Orig(b), Orig(c)) Recon(x) = Filt(x) + PaethPredictor(Recon(a), Recon(b), Recon(c)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
603 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
604 ubyte None (ubyte c, ubyte b, ubyte a, ubyte x) { return x; }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
605 ubyte Sub (ubyte c, ubyte b, ubyte a, ubyte x) { return x - a; }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
606 ubyte Up (ubyte c, ubyte b, ubyte a, ubyte x) { return x - b; }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
607 ubyte Average (ubyte c, ubyte b, ubyte a, ubyte x) { return x - (a + b) / 2; }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
608 ubyte Paeth (ubyte c, ubyte b, ubyte a, ubyte x) { return x - paethPredictor(a,b,c); }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
609
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
610 /* map for filtering. seq1 contains the previous scanline and seq2 the current
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
611 * pixels are passed in the order they appear in the serialized image (left to right, top to bottom)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
612 */
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
613 ubyte[] filterMap(T)(ubyte[] seq1, ubyte[] seq2, T op, uint bytewidth)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
614 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
615 ubyte[] result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
616 result.length = seq1.length < seq2.length ? seq1.length : seq2.length;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
617
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
618 auto bw = bytewidth;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
619 while (bw--)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
620 result[bw] = op(0, seq1[bw], 0, seq2[bw]);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
621 for (int i = bytewidth; i < result.length; i++)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
622 result[i] = op(seq1[i - bytewidth], seq1[i], seq2[i - bytewidth], seq2[i]);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
623 return result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
624 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
625
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
626 /* see filterMap above, this is a special case for the top scanline, where pixels from the
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
627 * previous scanline are set to zero
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
628 */
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
629 ubyte[] filterMap(T)(ubyte[] seq, T op, uint bytewidth)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
630 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
631 ubyte[] result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
632 result.length = seq.length;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
633
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
634 auto bw = bytewidth;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
635 while (bw--)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
636 result[bw] = op(0, 0, 0, seq[bw]);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
637 for (int i = bytewidth; i < result.length; i++)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
638 result[i] = op(0, 0, seq[i - bytewidth], seq[i]);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
639 return result;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
640 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
641
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
642 ubyte[] dynFilterMap(ubyte[] seq1, ubyte[] seq2, ubyte fOp, uint bytewidth)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
643 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
644 switch(fOp)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
645 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
646 case 0: return filterMap(seq1,seq2, &None, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
647 case 1: return filterMap(seq1,seq2, &Sub, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
648 case 2: return filterMap(seq1,seq2, &Up, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
649 case 3: return filterMap(seq1,seq2, &Average, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
650 case 4: return filterMap(seq1,seq2, &Paeth, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
651 default:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
652 mixin(pngEnforce(`false`, "wrong png filter"));
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
653 break;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
654 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
655 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
656
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
657 ubyte[] dynFilterMap(ubyte[] seq, ubyte fOp, uint bytewidth)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
658 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
659 switch(fOp)
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
660 {
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
661 case 0: return filterMap(seq, &None, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
662 case 1: return filterMap(seq, &Sub, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
663 case 2: return filterMap(seq, &Up, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
664 case 3: return filterMap(seq, &Average, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
665 case 4: return filterMap(seq, &Paeth, bytewidth);
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
666 default:
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
667 mixin(pngEnforce(`false`, "wrong png filter"));
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
668 break;
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
669 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
670 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
671 }
aa4efef0f0b1 Initial commit of code.
Jordan Miner <jminer7@gmail.com>
parents:
diff changeset
672