減色プログラム
Revisão | e4f8378bd0b313586a1ac38e565bc321ee1737e2 (tree) |
---|---|
Hora | 2011-05-29 18:52:29 |
Autor | berupon <berupon@gmai...> |
Commiter | berupon |
scolorqの処理を別ファイルに移動。他の減色処理の実装準備。
@@ -1,4 +1,4 @@ | ||
1 | - | |
1 | +#include "stdafx.h" | |
2 | 2 | #include "File.h" |
3 | 3 | |
4 | 4 | #include <io.h> |
@@ -1,46 +1,15 @@ | ||
1 | 1 | |
2 | 2 | // color quantization program by berupon |
3 | 3 | |
4 | -// original program scolorq | |
5 | -/* Copyright (c) 2006 Derrick Coetzee | |
6 | - | |
7 | -Permission is hereby granted, free of charge, to any person obtaining | |
8 | -a copy of this software and associated documentation files (the | |
9 | -"Software"), to deal in the Software without restriction, including | |
10 | -without limitation the rights to use, copy, modify, merge, publish, | |
11 | -distribute, sublicense, and/or sell copies of the Software, and to | |
12 | -permit persons to whom the Software is furnished to do so, subject to | |
13 | -the following conditions: | |
14 | - | |
15 | -The above copyright notice and this permission notice shall be | |
16 | -included in all copies or substantial portions of the Software. | |
17 | - | |
18 | -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
19 | -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
20 | -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
21 | -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
22 | -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
23 | -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
24 | -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
25 | -*/ | |
26 | - | |
27 | - | |
28 | 4 | #include "stdafx.h" |
29 | 5 | |
30 | -#include <algorithm> | |
31 | -#include <math.h> | |
32 | -#include <stdio.h> | |
33 | -#include <time.h> | |
34 | 6 | #include <vector> |
35 | -#include <deque> | |
36 | 7 | #include <limits> |
37 | -#include <iostream> | |
38 | 8 | |
39 | 9 | #include "ImageIO/ImageIO.h" |
40 | 10 | #include "ImageIO/File.h" |
41 | 11 | |
42 | -#include "quantize.h" | |
43 | -#include "dxor.h" | |
12 | +#include "scolorq.h" | |
44 | 13 | |
45 | 14 | // http://proglab.aki.gs/mediaproc/colors.html |
46 | 15 |
@@ -48,8 +17,8 @@ size_t call_count = 0; | ||
48 | 17 | |
49 | 18 | int _tmain(int argc, _TCHAR* argv[]) |
50 | 19 | { |
51 | - if (argc < 1+3 || argc > 1+5) { | |
52 | - puts("Usage: color_quantizer <source image.bmp> <output image.bmp> <desired palette size> [dithering level] [filter size (1/3/5)]\n"); | |
20 | + if (argc != 1+3) { | |
21 | + puts("Usage: color_quantizer <source image.bmp> <output image.bmp> <desired palette size>\n"); | |
53 | 22 | return -1; |
54 | 23 | } |
55 | 24 |
@@ -59,7 +28,6 @@ int _tmain(int argc, _TCHAR* argv[]) | ||
59 | 28 | return -1; |
60 | 29 | } |
61 | 30 | |
62 | - sdxor156(time(NULL)); | |
63 | 31 | ImageInfo imageInfo; |
64 | 32 | FILE* f = _tfopen(argv[1], _T("rb")); |
65 | 33 | if (!f) { |
@@ -111,88 +79,16 @@ int _tmain(int argc, _TCHAR* argv[]) | ||
111 | 79 | pLine += width; |
112 | 80 | pSrcLine += lineBytes; |
113 | 81 | } |
114 | - Color buff_filter1_weights[1*1]; | |
115 | - Color buff_filter3_weights[3*3]; | |
116 | - Color buff_filter5_weights[5*5]; | |
117 | - | |
118 | - Image filter1_weights(1, 1, buff_filter1_weights); | |
119 | - Image filter3_weights(3, 3, buff_filter3_weights); | |
120 | - Image filter5_weights(5, 5, buff_filter5_weights); | |
121 | 82 | std::vector<uint8_t> buff_quantized(width * height); |
122 | 83 | Array2D<uint8_t> quantized_image(width, height, &buff_quantized[0]); |
123 | 84 | Color palette[256]; |
124 | 85 | |
125 | - filter1_weights[0][0] = Color(1.0, 1.0, 1.0, 0.0); | |
126 | - | |
127 | - for (size_t i=0; i<num_colors; ++i) { | |
128 | - palette[i] = Color( | |
129 | - dxor156(), | |
130 | - dxor156(), | |
131 | - dxor156(), | |
132 | - 0.0 | |
133 | - ); | |
134 | - } | |
135 | - | |
136 | - Array3D<double>* coarse_variables; | |
137 | - double dithering_level = 0.09*log((double)image.width_*image.height_) - 0.04*log((double)num_colors) + 0.001; | |
138 | - if (argc > 1+3) { | |
139 | - dithering_level = _ttof(argv[4]); | |
140 | - if (dithering_level <= 0.0) { | |
141 | - puts("Dithering level must be more than zero.\n"); | |
142 | - return -1; | |
143 | - } | |
144 | - } | |
145 | - int filter_size = 3; | |
146 | - if (argc > 1+4) { | |
147 | - filter_size = _ttoi(argv[5]); | |
148 | - if (filter_size != 1 && filter_size != 3 && filter_size != 5) { | |
149 | - puts("Filter size must be one of 1, 3, or 5.\n"); | |
150 | - return -1; | |
151 | - } | |
152 | - } | |
153 | - | |
154 | - double stddev = dithering_level; | |
155 | - double sum = 0.0; | |
156 | - for (int i=0; i<3; i++) { | |
157 | - for (int j=0; j<3; j++) { | |
158 | - double w = exp(-sqrt((double)((i-1)*(i-1) + (j-1)*(j-1)))/(stddev*stddev)); | |
159 | - filter3_weights[i][j] = Color(w,w,w,0); | |
160 | - sum += w; | |
161 | - } | |
162 | - } | |
163 | - double invSum = 1.0 / sum; | |
164 | - for (int i=0; i<3; i++) { | |
165 | - for (int j=0; j<3; j++) { | |
166 | - filter3_weights[i][j] *= invSum; | |
167 | - } | |
168 | - } | |
169 | - sum = 0.0; | |
170 | - for (int i=0; i<5; i++) { | |
171 | - for (int j=0; j<5; j++) { | |
172 | - double w = exp(-sqrt((double)((i-2)*(i-2) + (j-2)*(j-2)))/(stddev*stddev)); | |
173 | - filter5_weights[i][j] = Color(w,w,w,0); | |
174 | - sum += w; | |
175 | - } | |
176 | - } | |
177 | - invSum = 1.0 / sum; | |
178 | - for (int i=0; i<5; i++) { | |
179 | - for (int j=0; j<5; j++) { | |
180 | - filter5_weights[i][j] *= invSum; | |
181 | - } | |
182 | - } | |
183 | - | |
184 | - Image* filters[] = { | |
185 | - NULL, | |
186 | - &filter1_weights, | |
187 | - NULL, | |
188 | - &filter3_weights, | |
189 | - NULL, | |
190 | - &filter5_weights | |
191 | - }; | |
192 | 86 | |
193 | 87 | DWORD started = ::timeGetTime(); |
194 | 88 | |
195 | - spatial_color_quant(image, *filters[filter_size], quantized_image, palette, num_colors, coarse_variables, 1.0, 0.001, 3, 1); | |
89 | + if (!scolorq(image, quantized_image, palette, num_colors)) { | |
90 | + return -1; | |
91 | + } | |
196 | 92 | |
197 | 93 | DWORD timeTaken = ::timeGetTime() - started; |
198 | 94 | printf("time taken : %d ms, call count : %d\n", timeTaken, call_count); |
@@ -204,15 +100,22 @@ int _tmain(int argc, _TCHAR* argv[]) | ||
204 | 100 | return -1; |
205 | 101 | } |
206 | 102 | File file(out); |
103 | + uint8_t bytePalettes[256][3]; | |
104 | + for (size_t i=0; i<num_colors; ++i) { | |
105 | + Color col = palette[i]; | |
106 | + bytePalettes[i][0] = (unsigned char)(pow(col[0], gamma) * 255.0); | |
107 | + bytePalettes[i][1] = (unsigned char)(pow(col[1], gamma) * 255.0); | |
108 | + bytePalettes[i][2] = (unsigned char)(pow(col[2], gamma) * 255.0); | |
109 | + } | |
207 | 110 | std::vector<uint8_t> bytes(imageInfo.width * imageInfo.height * 3); |
208 | 111 | uint8_t* pLine = &bytes[0]; |
209 | 112 | for (int y=0; y<height; y++) { |
210 | 113 | for (int x=0; x<width; x++) { |
211 | 114 | const uint8_t idx = quantized_image[y][x]; |
212 | - Color col = palette[idx]; | |
213 | - *pLine++ = (unsigned char)(pow(col[0], gamma) * 255.0); | |
214 | - *pLine++ = (unsigned char)(pow(col[1], gamma) * 255.0); | |
215 | - *pLine++ = (unsigned char)(pow(col[2], gamma) * 255.0); | |
115 | + const uint8_t* pal = bytePalettes[idx]; | |
116 | + *pLine++ = pal[0]; | |
117 | + *pLine++ = pal[1]; | |
118 | + *pLine++ = pal[2]; | |
216 | 119 | } |
217 | 120 | } |
218 | 121 | WriteImage(file, imageInfo, &bytes[0], imageInfo.width * 3); |
@@ -1,21 +0,0 @@ | ||
1 | -#pragma once | |
2 | - | |
3 | -#include "Array.h" | |
4 | -#include "Color4d_sse.h" | |
5 | -//#include "Color4d_avx.h" | |
6 | - | |
7 | -typedef Color4d Color; | |
8 | -typedef Array2D<Color> Image; | |
9 | - | |
10 | -void spatial_color_quant( | |
11 | - Image& image, | |
12 | - Image& filter_weights, | |
13 | - Array2D<uint8_t>& quantized_image, | |
14 | - Color* palette, size_t num_colors, | |
15 | - Array3D<double>*& p_coarse_variables, | |
16 | - double initial_temperature, | |
17 | - double final_temperature, | |
18 | - int temps_per_level, | |
19 | - int repeats_per_temp | |
20 | -); | |
21 | - |
@@ -31,7 +31,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
31 | 31 | |
32 | 32 | #include "stdafx.h" |
33 | 33 | |
34 | -#include "quantize.h" | |
34 | +#include "scolorq.h" | |
35 | 35 | |
36 | 36 | #include <algorithm> |
37 | 37 | #include <math.h> |
@@ -754,3 +754,83 @@ void spatial_color_quant( | ||
754 | 754 | |
755 | 755 | } |
756 | 756 | |
757 | +bool scolorq( | |
758 | + Image& image, | |
759 | + Array2D<uint8_t>& quantized_image, | |
760 | + Color* palette, | |
761 | + size_t num_colors | |
762 | + ) | |
763 | +{ | |
764 | + sdxor156(time(NULL)); | |
765 | + | |
766 | + for (size_t i=0; i<num_colors; ++i) { | |
767 | + palette[i] = Color( | |
768 | + dxor156(), | |
769 | + dxor156(), | |
770 | + dxor156(), | |
771 | + 0.0 | |
772 | + ); | |
773 | + } | |
774 | + | |
775 | + Array3D<double>* coarse_variables; | |
776 | + double dithering_level = // 0.09*log((double)image.width_*image.height_) - 0.04*log((double)num_colors) + 0.001; | |
777 | + 1.2; | |
778 | + if (dithering_level <= 0.0) { | |
779 | + puts("Dithering level must be more than zero.\n"); | |
780 | + return false; | |
781 | + } | |
782 | + int filter_size = 3; | |
783 | + if (filter_size != 1 && filter_size != 3 && filter_size != 5) { | |
784 | + puts("Filter size must be one of 1, 3, or 5.\n"); | |
785 | + return false; | |
786 | + } | |
787 | + | |
788 | + Color buff_filter1_weights[1*1]; | |
789 | + Color buff_filter3_weights[3*3]; | |
790 | + Color buff_filter5_weights[5*5]; | |
791 | + Image filter1_weights(1, 1, buff_filter1_weights); | |
792 | + Image filter3_weights(3, 3, buff_filter3_weights); | |
793 | + Image filter5_weights(5, 5, buff_filter5_weights); | |
794 | + filter1_weights[0][0] = Color(1.0, 1.0, 1.0, 0.0); | |
795 | + double stddev = dithering_level; | |
796 | + double sum = 0.0; | |
797 | + for (int i=0; i<3; i++) { | |
798 | + for (int j=0; j<3; j++) { | |
799 | + double w = exp(-sqrt((double)((i-1)*(i-1) + (j-1)*(j-1)))/(stddev*stddev)); | |
800 | + filter3_weights[i][j] = Color(w,w,w,0); | |
801 | + sum += w; | |
802 | + } | |
803 | + } | |
804 | + double invSum = 1.0 / sum; | |
805 | + for (int i=0; i<3; i++) { | |
806 | + for (int j=0; j<3; j++) { | |
807 | + filter3_weights[i][j] *= invSum; | |
808 | + } | |
809 | + } | |
810 | + sum = 0.0; | |
811 | + for (int i=0; i<5; i++) { | |
812 | + for (int j=0; j<5; j++) { | |
813 | + double w = exp(-sqrt((double)((i-2)*(i-2) + (j-2)*(j-2)))/(stddev*stddev)); | |
814 | + filter5_weights[i][j] = Color(w,w,w,0); | |
815 | + sum += w; | |
816 | + } | |
817 | + } | |
818 | + invSum = 1.0 / sum; | |
819 | + for (int i=0; i<5; i++) { | |
820 | + for (int j=0; j<5; j++) { | |
821 | + filter5_weights[i][j] *= invSum; | |
822 | + } | |
823 | + } | |
824 | + | |
825 | + Image* filters[] = { | |
826 | + NULL, | |
827 | + &filter1_weights, | |
828 | + NULL, | |
829 | + &filter3_weights, | |
830 | + NULL, | |
831 | + &filter5_weights | |
832 | + }; | |
833 | + | |
834 | + spatial_color_quant(image, *filters[filter_size], quantized_image, palette, num_colors, coarse_variables, 1.0, 0.001, 3, 1); | |
835 | + return true; | |
836 | +} |
@@ -0,0 +1,16 @@ | ||
1 | +#pragma once | |
2 | + | |
3 | +#include "Array.h" | |
4 | +#include "Color4d_sse.h" | |
5 | +//#include "Color4d_avx.h" | |
6 | + | |
7 | +typedef Color4d Color; | |
8 | +typedef Array2D<Color> Image; | |
9 | + | |
10 | +bool scolorq( | |
11 | + Image& image, | |
12 | + Array2D<uint8_t>& quantized_image, | |
13 | + Color* palette, | |
14 | + size_t num_colors | |
15 | +); | |
16 | + |
@@ -351,7 +351,7 @@ | ||
351 | 351 | > |
352 | 352 | </File> |
353 | 353 | <File |
354 | - RelativePath="..\quantize.cpp" | |
354 | + RelativePath="..\scolorq.cpp" | |
355 | 355 | > |
356 | 356 | </File> |
357 | 357 | <File |
@@ -401,7 +401,7 @@ | ||
401 | 401 | > |
402 | 402 | </File> |
403 | 403 | <File |
404 | - RelativePath="..\quantize.h" | |
404 | + RelativePath="..\scolorq.h" | |
405 | 405 | > |
406 | 406 | </File> |
407 | 407 | <File |
@@ -94,11 +94,12 @@ | ||
94 | 94 | </Link> |
95 | 95 | </ItemDefinitionGroup> |
96 | 96 | <ItemGroup> |
97 | + <ClCompile Include="..\ImageIO\File.cpp" /> | |
98 | + <ClCompile Include="..\ImageIO\ImageIO.cpp" /> | |
99 | + <ClCompile Include="..\ImageIO\ImageIO_bmp.cpp" /> | |
97 | 100 | <ClCompile Include="..\lib.cpp" /> |
98 | 101 | <ClCompile Include="..\main.cpp" /> |
99 | - <ClCompile Include="..\quantize.cpp" /> | |
100 | - <ClCompile Include="..\ReadImage\File.cpp" /> | |
101 | - <ClCompile Include="..\ReadImage\ReadImage.cpp" /> | |
102 | + <ClCompile Include="..\scolorq.cpp" /> | |
102 | 103 | <ClCompile Include="..\stdafx.cpp" /> |
103 | 104 | </ItemGroup> |
104 | 105 | <ItemGroup> |
@@ -107,10 +108,11 @@ | ||
107 | 108 | <ClInclude Include="..\Color4d_sse.h" /> |
108 | 109 | <ClInclude Include="..\common.h" /> |
109 | 110 | <ClInclude Include="..\dxor.h" /> |
110 | - <ClInclude Include="..\quantize.h" /> | |
111 | - <ClInclude Include="..\ReadImage\File.h" /> | |
112 | - <ClInclude Include="..\ReadImage\IFile.h" /> | |
113 | - <ClInclude Include="..\ReadImage\ReadImage.h" /> | |
111 | + <ClInclude Include="..\ImageIO\File.h" /> | |
112 | + <ClInclude Include="..\ImageIO\IFile.h" /> | |
113 | + <ClInclude Include="..\ImageIO\ImageIO.h" /> | |
114 | + <ClInclude Include="..\ImageIO\ImageIO_bmp.h" /> | |
115 | + <ClInclude Include="..\scolorq.h" /> | |
114 | 116 | <ClInclude Include="..\stdafx.h" /> |
115 | 117 | <ClInclude Include="..\stdint.h" /> |
116 | 118 | <ClInclude Include="..\targetver.h" /> |