File: | home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx |
Warning: | line 481, column 42 The result of the left shift is undefined due to shifting by '32', which is greater or equal to the width of type 'int' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |||
2 | /* | |||
3 | * This file is part of the LibreOffice project. | |||
4 | * | |||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | |||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |||
8 | * | |||
9 | * This file incorporates work covered by the following license notice: | |||
10 | * | |||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | |||
12 | * contributor license agreements. See the NOTICE file distributed | |||
13 | * with this work for additional information regarding copyright | |||
14 | * ownership. The ASF licenses this file to you under the Apache | |||
15 | * License, Version 2.0 (the "License"); you may not use this file | |||
16 | * except in compliance with the License. You may obtain a copy of | |||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | |||
18 | */ | |||
19 | ||||
20 | #include <math.h> | |||
21 | ||||
22 | #include <vcl/bitmapaccess.hxx> | |||
23 | #include <vcl/bitmapex.hxx> | |||
24 | #include <vcl/bitmap.hxx> | |||
25 | #include <config_features.h> | |||
26 | #include <sal/log.hxx> | |||
27 | #include <osl/diagnose.h> | |||
28 | #include <tools/helpers.hxx> | |||
29 | #if HAVE_FEATURE_OPENGL1 | |||
30 | #include <vcl/opengl/OpenGLHelper.hxx> | |||
31 | #endif | |||
32 | #if HAVE_FEATURE_SKIA1 | |||
33 | #include <vcl/skia/SkiaHelper.hxx> | |||
34 | #endif | |||
35 | #include <vcl/BitmapMonochromeFilter.hxx> | |||
36 | ||||
37 | #include <BitmapScaleSuperFilter.hxx> | |||
38 | #include <BitmapScaleConvolutionFilter.hxx> | |||
39 | #include <BitmapFastScaleFilter.hxx> | |||
40 | #include <BitmapInterpolateScaleFilter.hxx> | |||
41 | #include <bitmapwriteaccess.hxx> | |||
42 | #include <bitmap/impoctree.hxx> | |||
43 | #include <bitmap/Octree.hxx> | |||
44 | #include <svdata.hxx> | |||
45 | #include <salinst.hxx> | |||
46 | #include <salbmp.hxx> | |||
47 | ||||
48 | #include "impvect.hxx" | |||
49 | ||||
50 | #include <memory> | |||
51 | ||||
52 | #define GAMMA( _def_cVal, _def_InvGamma )(static_cast<sal_uInt8>(MinMax(FRound(pow( _def_cVal/255.0 ,_def_InvGamma)*255.0),0,255))) (static_cast<sal_uInt8>(MinMax(FRound(pow( _def_cVal/255.0,_def_InvGamma)*255.0),0,255))) | |||
53 | ||||
54 | #define CALC_ERRORSnTemp = p1T[nX++] >> 12; nBErr = MinMax( nTemp, 0, 255 ) ; nBErr = nBErr - FloydIndexMap[ nBC = FloydMap[nBErr] ]; nTemp = p1T[nX++] >> 12; nGErr = MinMax( nTemp, 0, 255 ); nGErr = nGErr - FloydIndexMap[ nGC = FloydMap[nGErr] ]; nTemp = p1T [nX] >> 12; nRErr = MinMax( nTemp, 0, 255 ); nRErr = nRErr - FloydIndexMap[ nRC = FloydMap[nRErr] ]; \ | |||
55 | nTemp = p1T[nX++] >> 12; \ | |||
56 | nBErr = MinMax( nTemp, 0, 255 ); \ | |||
57 | nBErr = nBErr - FloydIndexMap[ nBC = FloydMap[nBErr] ]; \ | |||
58 | nTemp = p1T[nX++] >> 12; \ | |||
59 | nGErr = MinMax( nTemp, 0, 255 ); \ | |||
60 | nGErr = nGErr - FloydIndexMap[ nGC = FloydMap[nGErr] ]; \ | |||
61 | nTemp = p1T[nX] >> 12; \ | |||
62 | nRErr = MinMax( nTemp, 0, 255 ); \ | |||
63 | nRErr = nRErr - FloydIndexMap[ nRC = FloydMap[nRErr] ]; | |||
64 | ||||
65 | #define CALC_TABLES3p2T[nX++] += FloydError3[nBErr]; p2T[nX++] += FloydError3[nGErr ]; p2T[nX++] += FloydError3[nRErr]; \ | |||
66 | p2T[nX++] += FloydError3[nBErr]; \ | |||
67 | p2T[nX++] += FloydError3[nGErr]; \ | |||
68 | p2T[nX++] += FloydError3[nRErr]; | |||
69 | ||||
70 | #define CALC_TABLES5p2T[nX++] += FloydError5[nBErr]; p2T[nX++] += FloydError5[nGErr ]; p2T[nX++] += FloydError5[nRErr]; \ | |||
71 | p2T[nX++] += FloydError5[nBErr]; \ | |||
72 | p2T[nX++] += FloydError5[nGErr]; \ | |||
73 | p2T[nX++] += FloydError5[nRErr]; | |||
74 | ||||
75 | #define CALC_TABLES7p1T[++nX] += FloydError7[nBErr]; p2T[nX++] += FloydError1[nBErr ]; p1T[nX] += FloydError7[nGErr]; p2T[nX++] += FloydError1[nGErr ]; p1T[nX] += FloydError7[nRErr]; p2T[nX] += FloydError1[nRErr ]; \ | |||
76 | p1T[++nX] += FloydError7[nBErr]; \ | |||
77 | p2T[nX++] += FloydError1[nBErr]; \ | |||
78 | p1T[nX] += FloydError7[nGErr]; \ | |||
79 | p2T[nX++] += FloydError1[nGErr]; \ | |||
80 | p1T[nX] += FloydError7[nRErr]; \ | |||
81 | p2T[nX] += FloydError1[nRErr]; | |||
82 | ||||
83 | const extern sal_uLong nVCLRLut[ 6 ] = { 16, 17, 18, 19, 20, 21 }; | |||
84 | const extern sal_uLong nVCLGLut[ 6 ] = { 0, 6, 12, 18, 24, 30 }; | |||
85 | const extern sal_uLong nVCLBLut[ 6 ] = { 0, 36, 72, 108, 144, 180 }; | |||
86 | ||||
87 | const extern sal_uLong nVCLDitherLut[ 256 ] = | |||
88 | { | |||
89 | 0, 49152, 12288, 61440, 3072, 52224, 15360, 64512, 768, 49920, 13056, | |||
90 | 62208, 3840, 52992, 16128, 65280, 32768, 16384, 45056, 28672, 35840, 19456, | |||
91 | 48128, 31744, 33536, 17152, 45824, 29440, 36608, 20224, 48896, 32512, 8192, | |||
92 | 57344, 4096, 53248, 11264, 60416, 7168, 56320, 8960, 58112, 4864, 54016, | |||
93 | 12032, 61184, 7936, 57088, 40960, 24576, 36864, 20480, 44032, 27648, 39936, | |||
94 | 23552, 41728, 25344, 37632, 21248, 44800, 28416, 40704, 24320, 2048, 51200, | |||
95 | 14336, 63488, 1024, 50176, 13312, 62464, 2816, 51968, 15104, 64256, 1792, | |||
96 | 50944, 14080, 63232, 34816, 18432, 47104, 30720, 33792, 17408, 46080, 29696, | |||
97 | 35584, 19200, 47872, 31488, 34560, 18176, 46848, 30464, 10240, 59392, 6144, | |||
98 | 55296, 9216, 58368, 5120, 54272, 11008, 60160, 6912, 56064, 9984, 59136, | |||
99 | 5888, 55040, 43008, 26624, 38912, 22528, 41984, 25600, 37888, 21504, 43776, | |||
100 | 27392, 39680, 23296, 42752, 26368, 38656, 22272, 512, 49664, 12800, 61952, | |||
101 | 3584, 52736, 15872, 65024, 256, 49408, 12544, 61696, 3328, 52480, 15616, | |||
102 | 64768, 33280, 16896, 45568, 29184, 36352, 19968, 48640, 32256, 33024, 16640, | |||
103 | 45312, 28928, 36096, 19712, 48384, 32000, 8704, 57856, 4608, 53760, 11776, | |||
104 | 60928, 7680, 56832, 8448, 57600, 4352, 53504, 11520, 60672, 7424, 56576, | |||
105 | 41472, 25088, 37376, 20992, 44544, 28160, 40448, 24064, 41216, 24832, 37120, | |||
106 | 20736, 44288, 27904, 40192, 23808, 2560, 51712, 14848, 64000, 1536, 50688, | |||
107 | 13824, 62976, 2304, 51456, 14592, 63744, 1280, 50432, 13568, 62720, 35328, | |||
108 | 18944, 47616, 31232, 34304, 17920, 46592, 30208, 35072, 18688, 47360, 30976, | |||
109 | 34048, 17664, 46336, 29952, 10752, 59904, 6656, 55808, 9728, 58880, 5632, | |||
110 | 54784, 10496, 59648, 6400, 55552, 9472, 58624, 5376, 54528, 43520, 27136, | |||
111 | 39424, 23040, 42496, 26112, 38400, 22016, 43264, 26880, 39168, 22784, 42240, | |||
112 | 25856, 38144, 21760 | |||
113 | }; | |||
114 | ||||
115 | const extern sal_uLong nVCLLut[ 256 ] = | |||
116 | { | |||
117 | 0, 1286, 2572, 3858, 5144, 6430, 7716, 9002, | |||
118 | 10288, 11574, 12860, 14146, 15432, 16718, 18004, 19290, | |||
119 | 20576, 21862, 23148, 24434, 25720, 27006, 28292, 29578, | |||
120 | 30864, 32150, 33436, 34722, 36008, 37294, 38580, 39866, | |||
121 | 41152, 42438, 43724, 45010, 46296, 47582, 48868, 50154, | |||
122 | 51440, 52726, 54012, 55298, 56584, 57870, 59156, 60442, | |||
123 | 61728, 63014, 64300, 65586, 66872, 68158, 69444, 70730, | |||
124 | 72016, 73302, 74588, 75874, 77160, 78446, 79732, 81018, | |||
125 | 82304, 83590, 84876, 86162, 87448, 88734, 90020, 91306, | |||
126 | 92592, 93878, 95164, 96450, 97736, 99022,100308,101594, | |||
127 | 102880,104166,105452,106738,108024,109310,110596,111882, | |||
128 | 113168,114454,115740,117026,118312,119598,120884,122170, | |||
129 | 123456,124742,126028,127314,128600,129886,131172,132458, | |||
130 | 133744,135030,136316,137602,138888,140174,141460,142746, | |||
131 | 144032,145318,146604,147890,149176,150462,151748,153034, | |||
132 | 154320,155606,156892,158178,159464,160750,162036,163322, | |||
133 | 164608,165894,167180,168466,169752,171038,172324,173610, | |||
134 | 174896,176182,177468,178754,180040,181326,182612,183898, | |||
135 | 185184,186470,187756,189042,190328,191614,192900,194186, | |||
136 | 195472,196758,198044,199330,200616,201902,203188,204474, | |||
137 | 205760,207046,208332,209618,210904,212190,213476,214762, | |||
138 | 216048,217334,218620,219906,221192,222478,223764,225050, | |||
139 | 226336,227622,228908,230194,231480,232766,234052,235338, | |||
140 | 236624,237910,239196,240482,241768,243054,244340,245626, | |||
141 | 246912,248198,249484,250770,252056,253342,254628,255914, | |||
142 | 257200,258486,259772,261058,262344,263630,264916,266202, | |||
143 | 267488,268774,270060,271346,272632,273918,275204,276490, | |||
144 | 277776,279062,280348,281634,282920,284206,285492,286778, | |||
145 | 288064,289350,290636,291922,293208,294494,295780,297066, | |||
146 | 298352,299638,300924,302210,303496,304782,306068,307354, | |||
147 | 308640,309926,311212,312498,313784,315070,316356,317642, | |||
148 | 318928,320214,321500,322786,324072,325358,326644,327930 | |||
149 | }; | |||
150 | ||||
151 | const long FloydMap[256] = | |||
152 | { | |||
153 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
154 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, | |||
155 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||
156 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||
157 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, | |||
158 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |||
159 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |||
160 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |||
161 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |||
162 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |||
163 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |||
164 | 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |||
165 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |||
166 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |||
167 | 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |||
168 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 | |||
169 | }; | |||
170 | ||||
171 | const long FloydError1[61] = | |||
172 | { | |||
173 | -7680, -7424, -7168, -6912, -6656, -6400, -6144, | |||
174 | -5888, -5632, -5376, -5120, -4864, -4608, -4352, | |||
175 | -4096, -3840, -3584, -3328, -3072, -2816, -2560, | |||
176 | -2304, -2048, -1792, -1536, -1280, -1024, -768, | |||
177 | -512, -256, 0, 256, 512, 768, 1024, 1280, 1536, | |||
178 | 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, | |||
179 | 3840, 4096, 4352, 4608, 4864, 5120, 5376, 5632, | |||
180 | 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680 | |||
181 | }; | |||
182 | ||||
183 | const long FloydError3[61] = | |||
184 | { | |||
185 | -23040, -22272, -21504, -20736, -19968, -19200, | |||
186 | -18432, -17664, -16896, -16128, -15360, -14592, | |||
187 | -13824, -13056, -12288, -11520, -10752, -9984, | |||
188 | -9216, -8448, -7680, -6912, -6144, -5376, -4608, | |||
189 | -3840, -3072, -2304, -1536, -768, 0, 768, 1536, | |||
190 | 2304, 3072, 3840, 4608, 5376, 6144, 6912, 7680, | |||
191 | 8448, 9216, 9984, 10752, 11520, 12288, 13056, | |||
192 | 13824, 14592, 15360, 16128, 16896, 17664, 18432, | |||
193 | 19200, 19968, 20736, 21504, 22272, 23040 | |||
194 | }; | |||
195 | ||||
196 | const long FloydError5[61] = | |||
197 | { | |||
198 | -38400, -37120, -35840, -34560, -33280, -32000, | |||
199 | -30720, -29440, -28160, -26880, -25600, -24320, | |||
200 | -23040, -21760, -20480, -19200, -17920, -16640, | |||
201 | -15360, -14080, -12800, -11520, -10240, -8960, | |||
202 | -7680, -6400, -5120, -3840, -2560, -1280, 0, | |||
203 | 1280, 2560, 3840, 5120, 6400, 7680, 8960, 10240, | |||
204 | 11520, 12800, 14080, 15360, 16640, 17920, 19200, | |||
205 | 20480, 21760, 23040, 24320, 25600, 26880, 28160, | |||
206 | 29440, 30720, 32000, 33280, 34560, 35840, 37120, | |||
207 | 38400 | |||
208 | }; | |||
209 | ||||
210 | const long FloydError7[61] = | |||
211 | { | |||
212 | -53760, -51968, -50176, -48384, -46592, -44800, | |||
213 | -43008, -41216, -39424, -37632, -35840, -34048, | |||
214 | -32256, -30464, -28672, -26880, -25088, -23296, | |||
215 | -21504, -19712, -17920, -16128, -14336, -12544, | |||
216 | -10752, -8960, -7168, -5376, -3584, -1792, 0, | |||
217 | 1792, 3584, 5376, 7168, 8960, 10752, 12544, 14336, | |||
218 | 16128, 17920, 19712, 21504, 23296, 25088, 26880, | |||
219 | 28672, 30464, 32256, 34048, 35840, 37632, 39424, | |||
220 | 41216, 43008, 44800, 46592, 48384, 50176, 51968, | |||
221 | 53760 | |||
222 | }; | |||
223 | ||||
224 | const long FloydIndexMap[6] = | |||
225 | { | |||
226 | -30, 21, 72, 123, 174, 225 | |||
227 | }; | |||
228 | ||||
229 | bool Bitmap::Convert( BmpConversion eConversion ) | |||
230 | { | |||
231 | // try to convert in backend | |||
232 | if (mxSalBmp) | |||
233 | { | |||
234 | // avoid large chunk of obsolete and hopefully rarely used conversions. | |||
235 | if (eConversion == BmpConversion::N8BitNoConversion) | |||
236 | { | |||
237 | std::shared_ptr<SalBitmap> xImpBmp(ImplGetSVData()->mpDefInst->CreateSalBitmap()); | |||
238 | // frequently used conversion for creating alpha masks | |||
239 | if (xImpBmp->Create(*mxSalBmp) && xImpBmp->InterpretAs8Bit()) | |||
240 | { | |||
241 | ImplSetSalBitmap(xImpBmp); | |||
242 | SAL_INFO( "vcl.opengl", "Ref count: " << mxSalBmp.use_count() )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.opengl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Ref count: " << mxSalBmp.use_count()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.opengl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "242" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Ref count: " << mxSalBmp.use_count ()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Ref count: " << mxSalBmp.use_count(); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.opengl"), ( "/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "242" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Ref count: " << mxSalBmp.use_count()) == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.opengl" ), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "242" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Ref count: " << mxSalBmp.use_count ()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Ref count: " << mxSalBmp.use_count(); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.opengl"), ( "/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "242" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
243 | return true; | |||
244 | } | |||
245 | } | |||
246 | if (eConversion == BmpConversion::N8BitGreys) | |||
247 | { | |||
248 | std::shared_ptr<SalBitmap> xImpBmp(ImplGetSVData()->mpDefInst->CreateSalBitmap()); | |||
249 | if (xImpBmp->Create(*mxSalBmp) && xImpBmp->ConvertToGreyscale()) | |||
250 | { | |||
251 | ImplSetSalBitmap(xImpBmp); | |||
252 | SAL_INFO( "vcl.opengl", "Ref count: " << mxSalBmp.use_count() )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.opengl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Ref count: " << mxSalBmp.use_count()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.opengl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "252" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Ref count: " << mxSalBmp.use_count ()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Ref count: " << mxSalBmp.use_count(); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.opengl"), ( "/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "252" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Ref count: " << mxSalBmp.use_count()) == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.opengl" ), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "252" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Ref count: " << mxSalBmp.use_count ()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Ref count: " << mxSalBmp.use_count(); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.opengl"), ( "/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "252" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
253 | return true; | |||
254 | } | |||
255 | } | |||
256 | } | |||
257 | ||||
258 | const sal_uInt16 nBitCount = GetBitCount (); | |||
259 | bool bRet = false; | |||
260 | ||||
261 | switch( eConversion ) | |||
262 | { | |||
263 | case BmpConversion::N1BitThreshold: | |||
264 | { | |||
265 | BitmapEx aBmpEx(*this); | |||
266 | bRet = BitmapFilter::Filter(aBmpEx, BitmapMonochromeFilter(128)); | |||
267 | *this = aBmpEx.GetBitmap(); | |||
268 | } | |||
269 | break; | |||
270 | ||||
271 | case BmpConversion::N4BitGreys: | |||
272 | bRet = ImplMakeGreyscales( 16 ); | |||
273 | break; | |||
274 | ||||
275 | case BmpConversion::N4BitColors: | |||
276 | { | |||
277 | if( nBitCount < 4 ) | |||
278 | bRet = ImplConvertUp( 4 ); | |||
279 | else if( nBitCount > 4 ) | |||
280 | bRet = ImplConvertDown( 4 ); | |||
281 | else | |||
282 | bRet = true; | |||
283 | } | |||
284 | break; | |||
285 | ||||
286 | case BmpConversion::N8BitGreys: | |||
287 | case BmpConversion::N8BitNoConversion: | |||
288 | bRet = ImplMakeGreyscales( 256 ); | |||
289 | break; | |||
290 | ||||
291 | case BmpConversion::N8BitColors: | |||
292 | { | |||
293 | if( nBitCount < 8 ) | |||
294 | bRet = ImplConvertUp( 8 ); | |||
295 | else if( nBitCount > 8 ) | |||
296 | bRet = ImplConvertDown( 8 ); | |||
297 | else | |||
298 | bRet = true; | |||
299 | } | |||
300 | break; | |||
301 | ||||
302 | case BmpConversion::N8BitTrans: | |||
303 | { | |||
304 | Color aTrans( BMP_COL_TRANSColor( 252, 3, 251 ) ); | |||
305 | ||||
306 | if( nBitCount < 8 ) | |||
307 | bRet = ImplConvertUp( 8, &aTrans ); | |||
308 | else | |||
309 | bRet = ImplConvertDown( 8, &aTrans ); | |||
310 | } | |||
311 | break; | |||
312 | ||||
313 | case BmpConversion::N24Bit: | |||
314 | { | |||
315 | if( nBitCount < 24 ) | |||
316 | bRet = ImplConvertUp( 24 ); | |||
317 | else | |||
318 | bRet = true; | |||
319 | } | |||
320 | break; | |||
321 | ||||
322 | case BmpConversion::N32Bit: | |||
323 | { | |||
324 | if( nBitCount < 32 ) | |||
325 | bRet = ImplConvertUp( 32 ); | |||
326 | else | |||
327 | bRet = true; | |||
328 | } | |||
329 | break; | |||
330 | ||||
331 | default: | |||
332 | OSL_FAIL( "Bitmap::Convert(): Unsupported conversion" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "332" ": "), "%s", "Bitmap::Convert(): Unsupported conversion" ); } } while (false); | |||
333 | break; | |||
334 | } | |||
335 | ||||
336 | return bRet; | |||
337 | } | |||
338 | ||||
339 | bool Bitmap::ImplMakeGreyscales( sal_uInt16 nGreys ) | |||
340 | { | |||
341 | SAL_WARN_IF( nGreys != 16 && nGreys != 256, "vcl", "Only 16 or 256 greyscales are supported!" )do { if (true && (nGreys != 16 && nGreys != 256 )) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Only 16 or 256 greyscales are supported!") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ( "/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "341" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Only 16 or 256 greyscales are supported!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Only 16 or 256 greyscales are supported!"; ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "341" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Only 16 or 256 greyscales are supported!") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ( "/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "341" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Only 16 or 256 greyscales are supported!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Only 16 or 256 greyscales are supported!"; ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "341" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
342 | ||||
343 | ScopedReadAccess pReadAcc(*this); | |||
344 | bool bRet = false; | |||
345 | ||||
346 | if( pReadAcc ) | |||
347 | { | |||
348 | const BitmapPalette& rPal = GetGreyPalette( nGreys ); | |||
349 | sal_uLong nShift = ( ( nGreys == 16 ) ? 4UL : 0UL ); | |||
350 | bool bPalDiffers = !pReadAcc->HasPalette() || ( rPal.GetEntryCount() != pReadAcc->GetPaletteEntryCount() ); | |||
351 | ||||
352 | if( !bPalDiffers ) | |||
353 | bPalDiffers = ( rPal != pReadAcc->GetPalette() ); | |||
354 | ||||
355 | if( bPalDiffers ) | |||
356 | { | |||
357 | Bitmap aNewBmp( GetSizePixel(), ( nGreys == 16 ) ? 4 : 8, &rPal ); | |||
358 | BitmapScopedWriteAccess pWriteAcc(aNewBmp); | |||
359 | ||||
360 | if( pWriteAcc ) | |||
361 | { | |||
362 | const long nWidth = pWriteAcc->Width(); | |||
363 | const long nHeight = pWriteAcc->Height(); | |||
364 | ||||
365 | if( pReadAcc->HasPalette() ) | |||
366 | { | |||
367 | for( long nY = 0; nY < nHeight; nY++ ) | |||
368 | { | |||
369 | Scanline pScanline = pWriteAcc->GetScanline(nY); | |||
370 | Scanline pScanlineRead = pReadAcc->GetScanline(nY); | |||
371 | for( long nX = 0; nX < nWidth; nX++ ) | |||
372 | { | |||
373 | const sal_uInt8 cIndex = pReadAcc->GetIndexFromData( pScanlineRead, nX ); | |||
374 | pWriteAcc->SetPixelOnData( pScanline, nX, | |||
375 | BitmapColor(pReadAcc->GetPaletteColor( cIndex ).GetLuminance() >> nShift) ); | |||
376 | } | |||
377 | } | |||
378 | } | |||
379 | else if( pReadAcc->GetScanlineFormat() == ScanlineFormat::N24BitTcBgr && | |||
380 | pWriteAcc->GetScanlineFormat() == ScanlineFormat::N8BitPal ) | |||
381 | { | |||
382 | nShift += 8; | |||
383 | ||||
384 | for( long nY = 0; nY < nHeight; nY++ ) | |||
385 | { | |||
386 | Scanline pReadScan = pReadAcc->GetScanline( nY ); | |||
387 | Scanline pWriteScan = pWriteAcc->GetScanline( nY ); | |||
388 | ||||
389 | for( long nX = 0; nX < nWidth; nX++ ) | |||
390 | { | |||
391 | const sal_uLong nB = *pReadScan++; | |||
392 | const sal_uLong nG = *pReadScan++; | |||
393 | const sal_uLong nR = *pReadScan++; | |||
394 | ||||
395 | *pWriteScan++ = static_cast<sal_uInt8>( ( nB * 28UL + nG * 151UL + nR * 77UL ) >> nShift ); | |||
396 | } | |||
397 | } | |||
398 | } | |||
399 | else if( pReadAcc->GetScanlineFormat() == ScanlineFormat::N24BitTcRgb && | |||
400 | pWriteAcc->GetScanlineFormat() == ScanlineFormat::N8BitPal ) | |||
401 | { | |||
402 | nShift += 8; | |||
403 | ||||
404 | for( long nY = 0; nY < nHeight; nY++ ) | |||
405 | { | |||
406 | Scanline pReadScan = pReadAcc->GetScanline( nY ); | |||
407 | Scanline pWriteScan = pWriteAcc->GetScanline( nY ); | |||
408 | ||||
409 | for( long nX = 0; nX < nWidth; nX++ ) | |||
410 | { | |||
411 | const sal_uLong nR = *pReadScan++; | |||
412 | const sal_uLong nG = *pReadScan++; | |||
413 | const sal_uLong nB = *pReadScan++; | |||
414 | ||||
415 | *pWriteScan++ = static_cast<sal_uInt8>( ( nB * 28UL + nG * 151UL + nR * 77UL ) >> nShift ); | |||
416 | } | |||
417 | } | |||
418 | } | |||
419 | else | |||
420 | { | |||
421 | for( long nY = 0; nY < nHeight; nY++ ) | |||
422 | { | |||
423 | Scanline pScanline = pWriteAcc->GetScanline(nY); | |||
424 | Scanline pScanlineRead = pReadAcc->GetScanline(nY); | |||
425 | for( long nX = 0; nX < nWidth; nX++ ) | |||
426 | pWriteAcc->SetPixelOnData( pScanline, nX, BitmapColor(pReadAcc->GetPixelFromData( pScanlineRead, nX ).GetLuminance() >> nShift) ); | |||
427 | } | |||
428 | } | |||
429 | ||||
430 | pWriteAcc.reset(); | |||
431 | bRet = true; | |||
432 | } | |||
433 | ||||
434 | pReadAcc.reset(); | |||
435 | ||||
436 | if( bRet ) | |||
437 | { | |||
438 | const MapMode aMap( maPrefMapMode ); | |||
439 | const Size aSize( maPrefSize ); | |||
440 | ||||
441 | *this = aNewBmp; | |||
442 | ||||
443 | maPrefMapMode = aMap; | |||
444 | maPrefSize = aSize; | |||
445 | } | |||
446 | } | |||
447 | else | |||
448 | { | |||
449 | pReadAcc.reset(); | |||
450 | bRet = true; | |||
451 | } | |||
452 | } | |||
453 | ||||
454 | return bRet; | |||
455 | } | |||
456 | ||||
457 | bool Bitmap::ImplConvertUp(sal_uInt16 nBitCount, Color const * pExtColor) | |||
458 | { | |||
459 | SAL_WARN_IF( nBitCount <= GetBitCount(), "vcl", "New BitCount must be greater!" )do { if (true && (nBitCount <= GetBitCount())) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "New BitCount must be greater!") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "459" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "New BitCount must be greater!"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "New BitCount must be greater!"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "459" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "New BitCount must be greater!") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "459" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "New BitCount must be greater!"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "New BitCount must be greater!"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "459" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
460 | ||||
461 | Bitmap::ScopedReadAccess pReadAcc(*this); | |||
462 | bool bRet = false; | |||
463 | ||||
464 | if (pReadAcc) | |||
465 | { | |||
466 | BitmapPalette aPalette; | |||
467 | Bitmap aNewBmp(GetSizePixel(), nBitCount, pReadAcc->HasPalette() ? &pReadAcc->GetPalette() : &aPalette); | |||
468 | BitmapScopedWriteAccess pWriteAcc(aNewBmp); | |||
469 | ||||
470 | if (pWriteAcc) | |||
471 | { | |||
472 | const long nWidth = pWriteAcc->Width(); | |||
473 | const long nHeight = pWriteAcc->Height(); | |||
474 | ||||
475 | if (pWriteAcc->HasPalette()) | |||
476 | { | |||
477 | const BitmapPalette& rOldPalette = pReadAcc->GetPalette(); | |||
478 | const sal_uInt16 nOldCount = rOldPalette.GetEntryCount(); | |||
479 | assert(nOldCount <= (1 << GetBitCount()))(static_cast <bool> (nOldCount <= (1 << GetBitCount ())) ? void (0) : __assert_fail ("nOldCount <= (1 << GetBitCount())" , "/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" , 479, __extension__ __PRETTY_FUNCTION__)); | |||
480 | ||||
481 | aPalette.SetEntryCount(1 << nBitCount); | |||
| ||||
482 | ||||
483 | for (sal_uInt16 i = 0; i < nOldCount; i++) | |||
484 | aPalette[i] = rOldPalette[i]; | |||
485 | ||||
486 | if (pExtColor) | |||
487 | aPalette[aPalette.GetEntryCount() - 1] = *pExtColor; | |||
488 | ||||
489 | pWriteAcc->SetPalette(aPalette); | |||
490 | ||||
491 | for (long nY = 0; nY < nHeight; nY++) | |||
492 | { | |||
493 | Scanline pScanline = pWriteAcc->GetScanline(nY); | |||
494 | Scanline pScanlineRead = pReadAcc->GetScanline(nY); | |||
495 | for (long nX = 0; nX < nWidth; nX++) | |||
496 | { | |||
497 | pWriteAcc->SetPixelOnData(pScanline, nX, pReadAcc->GetPixelFromData(pScanlineRead, nX)); | |||
498 | } | |||
499 | } | |||
500 | } | |||
501 | else | |||
502 | { | |||
503 | if (pReadAcc->HasPalette()) | |||
504 | { | |||
505 | for (long nY = 0; nY < nHeight; nY++) | |||
506 | { | |||
507 | Scanline pScanline = pWriteAcc->GetScanline(nY); | |||
508 | Scanline pScanlineRead = pReadAcc->GetScanline(nY); | |||
509 | for (long nX = 0; nX < nWidth; nX++) | |||
510 | { | |||
511 | pWriteAcc->SetPixelOnData(pScanline, nX, pReadAcc->GetPaletteColor(pReadAcc->GetIndexFromData(pScanlineRead, nX))); | |||
512 | } | |||
513 | } | |||
514 | } | |||
515 | else | |||
516 | { | |||
517 | for (long nY = 0; nY < nHeight; nY++) | |||
518 | { | |||
519 | Scanline pScanline = pWriteAcc->GetScanline(nY); | |||
520 | Scanline pScanlineRead = pReadAcc->GetScanline(nY); | |||
521 | for (long nX = 0; nX < nWidth; nX++) | |||
522 | { | |||
523 | pWriteAcc->SetPixelOnData(pScanline, nX, pReadAcc->GetPixelFromData(pScanlineRead, nX)); | |||
524 | } | |||
525 | } | |||
526 | } | |||
527 | } | |||
528 | bRet = true; | |||
529 | } | |||
530 | ||||
531 | if (bRet) | |||
532 | { | |||
533 | const MapMode aMap(maPrefMapMode); | |||
534 | const Size aSize(maPrefSize); | |||
535 | ||||
536 | *this = aNewBmp; | |||
537 | ||||
538 | maPrefMapMode = aMap; | |||
539 | maPrefSize = aSize; | |||
540 | } | |||
541 | } | |||
542 | ||||
543 | return bRet; | |||
544 | } | |||
545 | ||||
546 | bool Bitmap::ImplConvertDown(sal_uInt16 nBitCount, Color const * pExtColor) | |||
547 | { | |||
548 | SAL_WARN_IF(nBitCount > GetBitCount(), "vcl", "New BitCount must be lower ( or equal when pExtColor is set )!")do { if (true && (nBitCount > GetBitCount())) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "New BitCount must be lower ( or equal when pExtColor is set )!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "548" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "New BitCount must be lower ( or equal when pExtColor is set )!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "New BitCount must be lower ( or equal when pExtColor is set )!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "548" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "New BitCount must be lower ( or equal when pExtColor is set )!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "548" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "New BitCount must be lower ( or equal when pExtColor is set )!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "New BitCount must be lower ( or equal when pExtColor is set )!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "548" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
549 | ||||
550 | Bitmap::ScopedReadAccess pReadAcc(*this); | |||
551 | bool bRet = false; | |||
552 | ||||
553 | if (pReadAcc) | |||
554 | { | |||
555 | BitmapPalette aPalette; | |||
556 | Bitmap aNewBmp(GetSizePixel(), nBitCount, &aPalette); | |||
557 | BitmapScopedWriteAccess pWriteAcc(aNewBmp); | |||
558 | ||||
559 | if (pWriteAcc) | |||
560 | { | |||
561 | const sal_uInt16 nCount = 1 << nBitCount; | |||
562 | const long nWidth = pWriteAcc->Width(); | |||
563 | const long nWidth1 = nWidth - 1; | |||
564 | const long nHeight = pWriteAcc->Height(); | |||
565 | Octree aOctree(*pReadAcc, pExtColor ? (nCount - 1) : nCount); | |||
566 | aPalette = aOctree.GetPalette(); | |||
567 | InverseColorMap aColorMap(aPalette); | |||
568 | BitmapColor aColor; | |||
569 | ImpErrorQuad aErrQuad; | |||
570 | std::vector<ImpErrorQuad> aErrQuad1(nWidth); | |||
571 | std::vector<ImpErrorQuad> aErrQuad2(nWidth); | |||
572 | ImpErrorQuad* pQLine1 = aErrQuad1.data(); | |||
573 | ImpErrorQuad* pQLine2 = nullptr; | |||
574 | long nYTmp = 0; | |||
575 | sal_uInt8 cIndex; | |||
576 | bool bQ1 = true; | |||
577 | ||||
578 | if (pExtColor) | |||
579 | { | |||
580 | aPalette.SetEntryCount(aPalette.GetEntryCount() + 1); | |||
581 | aPalette[aPalette.GetEntryCount() - 1] = *pExtColor; | |||
582 | } | |||
583 | ||||
584 | // set Black/White always, if we have enough space | |||
585 | if (aPalette.GetEntryCount() < (nCount - 1)) | |||
586 | { | |||
587 | aPalette.SetEntryCount(aPalette.GetEntryCount() + 2); | |||
588 | aPalette[aPalette.GetEntryCount() - 2] = COL_BLACK; | |||
589 | aPalette[aPalette.GetEntryCount() - 1] = COL_WHITE; | |||
590 | } | |||
591 | ||||
592 | pWriteAcc->SetPalette(aPalette); | |||
593 | ||||
594 | for (long nY = 0; nY < std::min(nHeight, 2L); nY++, nYTmp++) | |||
595 | { | |||
596 | pQLine2 = !nY ? aErrQuad1.data() : aErrQuad2.data(); | |||
597 | Scanline pScanlineRead = pReadAcc->GetScanline(nYTmp); | |||
598 | for (long nX = 0; nX < nWidth; nX++) | |||
599 | { | |||
600 | if (pReadAcc->HasPalette()) | |||
601 | pQLine2[nX] = pReadAcc->GetPaletteColor(pReadAcc->GetIndexFromData(pScanlineRead, nX)); | |||
602 | else | |||
603 | pQLine2[nX] = pReadAcc->GetPixelFromData(pScanlineRead, nX); | |||
604 | } | |||
605 | } | |||
606 | ||||
607 | assert(pQLine2 || nHeight == 0)(static_cast <bool> (pQLine2 || nHeight == 0) ? void (0 ) : __assert_fail ("pQLine2 || nHeight == 0", "/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" , 607, __extension__ __PRETTY_FUNCTION__)); | |||
608 | ||||
609 | for (long nY = 0; nY < nHeight; nY++, nYTmp++) | |||
610 | { | |||
611 | // first pixel in the line | |||
612 | cIndex = static_cast<sal_uInt8>(aColorMap.GetBestPaletteIndex(pQLine1[0].ImplGetColor())); | |||
613 | Scanline pScanline = pWriteAcc->GetScanline(nY); | |||
614 | pWriteAcc->SetPixelOnData(pScanline, 0, BitmapColor(cIndex)); | |||
615 | ||||
616 | long nX; | |||
617 | for (nX = 1; nX < nWidth1; nX++) | |||
618 | { | |||
619 | aColor = pQLine1[nX].ImplGetColor(); | |||
620 | cIndex = static_cast<sal_uInt8>(aColorMap.GetBestPaletteIndex(aColor)); | |||
621 | aErrQuad = (ImpErrorQuad(aColor) -= pWriteAcc->GetPaletteColor(cIndex)); | |||
622 | pQLine1[++nX].ImplAddColorError7(aErrQuad); | |||
623 | pQLine2[nX--].ImplAddColorError1(aErrQuad); | |||
624 | pQLine2[nX--].ImplAddColorError5(aErrQuad); | |||
625 | pQLine2[nX++].ImplAddColorError3(aErrQuad); | |||
626 | pWriteAcc->SetPixelOnData(pScanline, nX, BitmapColor(cIndex)); | |||
627 | } | |||
628 | ||||
629 | // Last RowPixel | |||
630 | if (nX < nWidth) | |||
631 | { | |||
632 | cIndex = static_cast<sal_uInt8>(aColorMap.GetBestPaletteIndex(pQLine1[nWidth1].ImplGetColor())); | |||
633 | pWriteAcc->SetPixelOnData(pScanline, nX, BitmapColor(cIndex)); | |||
634 | } | |||
635 | ||||
636 | // Refill/copy row buffer | |||
637 | pQLine1 = pQLine2; | |||
638 | bQ1 = !bQ1; | |||
639 | pQLine2 = bQ1 ? aErrQuad2.data() : aErrQuad1.data(); | |||
640 | ||||
641 | if (nYTmp < nHeight) | |||
642 | { | |||
643 | Scanline pScanlineRead = pReadAcc->GetScanline(nYTmp); | |||
644 | for (nX = 0; nX < nWidth; nX++) | |||
645 | { | |||
646 | if (pReadAcc->HasPalette()) | |||
647 | pQLine2[nX] = pReadAcc->GetPaletteColor(pReadAcc->GetIndexFromData(pScanlineRead, nX)); | |||
648 | else | |||
649 | pQLine2[nX] = pReadAcc->GetPixelFromData(pScanlineRead, nX); | |||
650 | } | |||
651 | } | |||
652 | } | |||
653 | ||||
654 | bRet = true; | |||
655 | } | |||
656 | pWriteAcc.reset(); | |||
657 | ||||
658 | if(bRet) | |||
659 | { | |||
660 | const MapMode aMap(maPrefMapMode); | |||
661 | const Size aSize(maPrefSize); | |||
662 | ||||
663 | *this = aNewBmp; | |||
664 | ||||
665 | maPrefMapMode = aMap; | |||
666 | maPrefSize = aSize; | |||
667 | } | |||
668 | } | |||
669 | ||||
670 | return bRet; | |||
671 | } | |||
672 | ||||
673 | bool Bitmap::Scale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag ) | |||
674 | { | |||
675 | if(basegfx::fTools::equalZero(rScaleX) || basegfx::fTools::equalZero(rScaleY)) | |||
676 | { | |||
677 | // no scale | |||
678 | return true; | |||
679 | } | |||
680 | ||||
681 | if(basegfx::fTools::equal(rScaleX, 1.0) && basegfx::fTools::equal(rScaleY, 1.0)) | |||
682 | { | |||
683 | // no scale | |||
684 | return true; | |||
685 | } | |||
686 | ||||
687 | const sal_uInt16 nStartCount(GetBitCount()); | |||
688 | ||||
689 | if (mxSalBmp && mxSalBmp->ScalingSupported()) | |||
690 | { | |||
691 | // implementation specific scaling | |||
692 | std::shared_ptr<SalBitmap> xImpBmp(ImplGetSVData()->mpDefInst->CreateSalBitmap()); | |||
693 | if (xImpBmp->Create(*mxSalBmp) && xImpBmp->Scale(rScaleX, rScaleY, nScaleFlag)) | |||
694 | { | |||
695 | ImplSetSalBitmap(xImpBmp); | |||
696 | SAL_INFO( "vcl.opengl", "Ref count: " << mxSalBmp.use_count() )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl.opengl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Ref count: " << mxSalBmp.use_count()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl.opengl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "696" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Ref count: " << mxSalBmp.use_count ()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Ref count: " << mxSalBmp.use_count(); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.opengl"), ( "/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "696" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Ref count: " << mxSalBmp.use_count()) == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.opengl" ), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "696" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Ref count: " << mxSalBmp.use_count ()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Ref count: " << mxSalBmp.use_count(); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.opengl"), ( "/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "696" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
697 | maPrefMapMode = MapMode( MapUnit::MapPixel ); | |||
698 | maPrefSize = xImpBmp->GetSize(); | |||
699 | return true; | |||
700 | } | |||
701 | } | |||
702 | ||||
703 | // fdo#33455 | |||
704 | // | |||
705 | // If we start with a 1 bit image, then after scaling it in any mode except | |||
706 | // BmpScaleFlag::Fast we have a 24bit image which is perfectly correct, but we | |||
707 | // are going to down-shift it to mono again and Bitmap::MakeMonochrome just | |||
708 | // has "Bitmap aNewBmp( GetSizePixel(), 1 );" to create a 1 bit bitmap which | |||
709 | // will default to black/white and the colors mapped to which ever is closer | |||
710 | // to black/white | |||
711 | // | |||
712 | // So the easiest thing to do to retain the colors of 1 bit bitmaps is to | |||
713 | // just use the fast scale rather than attempting to count unique colors in | |||
714 | // the other converters and pass all the info down through | |||
715 | // Bitmap::MakeMonochrome | |||
716 | if (nStartCount == 1) | |||
717 | nScaleFlag = BmpScaleFlag::Fast; | |||
718 | ||||
719 | BitmapEx aBmpEx(*this); | |||
720 | bool bRetval(false); | |||
721 | ||||
722 | switch(nScaleFlag) | |||
723 | { | |||
724 | case BmpScaleFlag::Default: | |||
725 | if (GetSizePixel().Width() < 2 || GetSizePixel().Height() < 2) | |||
726 | bRetval = BitmapFilter::Filter(aBmpEx, BitmapFastScaleFilter(rScaleX, rScaleY)); | |||
727 | else | |||
728 | bRetval = BitmapFilter::Filter(aBmpEx, BitmapScaleSuperFilter(rScaleX, rScaleY)); | |||
729 | break; | |||
730 | ||||
731 | case BmpScaleFlag::Fast: | |||
732 | case BmpScaleFlag::NearestNeighbor: | |||
733 | bRetval = BitmapFilter::Filter(aBmpEx, BitmapFastScaleFilter(rScaleX, rScaleY)); | |||
734 | break; | |||
735 | ||||
736 | case BmpScaleFlag::Interpolate: | |||
737 | bRetval = BitmapFilter::Filter(aBmpEx, BitmapInterpolateScaleFilter(rScaleX, rScaleY)); | |||
738 | break; | |||
739 | ||||
740 | case BmpScaleFlag::Super: | |||
741 | bRetval = BitmapFilter::Filter(aBmpEx, BitmapScaleSuperFilter(rScaleX, rScaleY)); | |||
742 | break; | |||
743 | case BmpScaleFlag::BestQuality: | |||
744 | case BmpScaleFlag::Lanczos: | |||
745 | bRetval = BitmapFilter::Filter(aBmpEx, vcl::BitmapScaleLanczos3Filter(rScaleX, rScaleY)); | |||
746 | break; | |||
747 | ||||
748 | case BmpScaleFlag::BiCubic: | |||
749 | bRetval = BitmapFilter::Filter(aBmpEx, vcl::BitmapScaleBicubicFilter(rScaleX, rScaleY)); | |||
750 | break; | |||
751 | ||||
752 | case BmpScaleFlag::BiLinear: | |||
753 | bRetval = BitmapFilter::Filter(aBmpEx, vcl::BitmapScaleBilinearFilter(rScaleX, rScaleY)); | |||
754 | break; | |||
755 | } | |||
756 | ||||
757 | if (bRetval) | |||
758 | *this = aBmpEx.GetBitmap(); | |||
759 | ||||
760 | OSL_ENSURE(!bRetval || nStartCount == GetBitCount(), "Bitmap::Scale has changed the ColorDepth, this should *not* happen (!)")do { if (true && (!(!bRetval || nStartCount == GetBitCount ()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "760" ": "), "%s", "Bitmap::Scale has changed the ColorDepth, this should *not* happen (!)" ); } } while (false); | |||
761 | return bRetval; | |||
762 | } | |||
763 | ||||
764 | bool Bitmap::Scale( const Size& rNewSize, BmpScaleFlag nScaleFlag ) | |||
765 | { | |||
766 | const Size aSize( GetSizePixel() ); | |||
767 | bool bRet; | |||
768 | ||||
769 | if( aSize.Width() && aSize.Height() ) | |||
770 | { | |||
771 | bRet = Scale( static_cast<double>(rNewSize.Width()) / aSize.Width(), | |||
772 | static_cast<double>(rNewSize.Height()) / aSize.Height(), | |||
773 | nScaleFlag ); | |||
774 | } | |||
775 | else | |||
776 | bRet = true; | |||
777 | ||||
778 | return bRet; | |||
779 | } | |||
780 | ||||
781 | bool Bitmap::HasFastScale() | |||
782 | { | |||
783 | #if HAVE_FEATURE_SKIA1 | |||
784 | if( SkiaHelper::isVCLSkiaEnabled() && SkiaHelper::renderMethodToUse() != SkiaHelper::RenderRaster) | |||
785 | return true; | |||
786 | #endif | |||
787 | #if HAVE_FEATURE_OPENGL1 | |||
788 | if( OpenGLHelper::isVCLOpenGLEnabled()) | |||
789 | return true; | |||
790 | #endif | |||
791 | return false; | |||
792 | } | |||
793 | ||||
794 | void Bitmap::AdaptBitCount(Bitmap& rNew) const | |||
795 | { | |||
796 | // aNew is the result of some operation; adapt it's BitCount to the original (this) | |||
797 | if(GetBitCount() == rNew.GetBitCount()) | |||
| ||||
798 | return; | |||
799 | ||||
800 | switch(GetBitCount()) | |||
801 | { | |||
802 | case 1: | |||
803 | { | |||
804 | rNew.Convert(BmpConversion::N1BitThreshold); | |||
805 | break; | |||
806 | } | |||
807 | case 4: | |||
808 | { | |||
809 | if(HasGreyPaletteAny()) | |||
810 | { | |||
811 | rNew.Convert(BmpConversion::N4BitGreys); | |||
812 | } | |||
813 | else | |||
814 | { | |||
815 | rNew.Convert(BmpConversion::N4BitColors); | |||
816 | } | |||
817 | break; | |||
818 | } | |||
819 | case 8: | |||
820 | { | |||
821 | if(HasGreyPaletteAny()) | |||
822 | { | |||
823 | rNew.Convert(BmpConversion::N8BitGreys); | |||
824 | } | |||
825 | else | |||
826 | { | |||
827 | rNew.Convert(BmpConversion::N8BitColors); | |||
828 | } | |||
829 | break; | |||
830 | } | |||
831 | case 24: | |||
832 | { | |||
833 | rNew.Convert(BmpConversion::N24Bit); | |||
834 | break; | |||
835 | } | |||
836 | case 32: | |||
837 | { | |||
838 | rNew.Convert(BmpConversion::N32Bit); | |||
839 | break; | |||
840 | } | |||
841 | default: | |||
842 | { | |||
843 | SAL_WARN("vcl", "BitDepth adaptation failed, from " << rNew.GetBitCount() << " to " << GetBitCount())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BitDepth adaptation failed, from " << rNew .GetBitCount() << " to " << GetBitCount()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "843" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "BitDepth adaptation failed, from " << rNew.GetBitCount() << " to " << GetBitCount()), 0 ); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BitDepth adaptation failed, from " << rNew.GetBitCount () << " to " << GetBitCount(); ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "843" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BitDepth adaptation failed, from " << rNew .GetBitCount() << " to " << GetBitCount()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "843" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "BitDepth adaptation failed, from " << rNew.GetBitCount() << " to " << GetBitCount()), 0 ); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BitDepth adaptation failed, from " << rNew.GetBitCount () << " to " << GetBitCount(); ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/gdi/bitmap3.cxx" ":" "843" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
844 | break; | |||
845 | } | |||
846 | } | |||
847 | } | |||
848 | ||||
849 | bool Bitmap::Dither() | |||
850 | { | |||
851 | const Size aSize( GetSizePixel() ); | |||
852 | ||||
853 | if( aSize.Width() == 1 || aSize.Height() == 1 ) | |||
854 | return true; | |||
855 | ||||
856 | bool bRet = false; | |||
857 | ||||
858 | if( ( aSize.Width() > 3 ) && ( aSize.Height() > 2 ) ) | |||
859 | { | |||
860 | ScopedReadAccess pReadAcc(*this); | |||
861 | Bitmap aNewBmp( GetSizePixel(), 8 ); | |||
862 | BitmapScopedWriteAccess pWriteAcc(aNewBmp); | |||
863 | ||||
864 | if( pReadAcc && pWriteAcc ) | |||
865 | { | |||
866 | BitmapColor aColor; | |||
867 | long nWidth = pReadAcc->Width(); | |||
868 | long nWidth1 = nWidth - 1; | |||
869 | long nHeight = pReadAcc->Height(); | |||
870 | long nX; | |||
871 | long nW = nWidth * 3; | |||
872 | long nW2 = nW - 3; | |||
873 | long nRErr, nGErr, nBErr; | |||
874 | long nRC, nGC, nBC; | |||
875 | std::unique_ptr<long[]> p1(new long[ nW ]); | |||
876 | std::unique_ptr<long[]> p2(new long[ nW ]); | |||
877 | long* p1T = p1.get(); | |||
878 | long* p2T = p2.get(); | |||
879 | long* pTmp; | |||
880 | bool bPal = pReadAcc->HasPalette(); | |||
881 | ||||
882 | pTmp = p2T; | |||
883 | ||||
884 | if( bPal ) | |||
885 | { | |||
886 | Scanline pScanlineRead = pReadAcc->GetScanline(0); | |||
887 | for( long nZ = 0; nZ < nWidth; nZ++ ) | |||
888 | { | |||
889 | aColor = pReadAcc->GetPaletteColor( pReadAcc->GetIndexFromData( pScanlineRead, nZ ) ); | |||
890 | ||||
891 | *pTmp++ = static_cast<long>(aColor.GetBlue()) << 12; | |||
892 | *pTmp++ = static_cast<long>(aColor.GetGreen()) << 12; | |||
893 | *pTmp++ = static_cast<long>(aColor.GetRed()) << 12; | |||
894 | } | |||
895 | } | |||
896 | else | |||
897 | { | |||
898 | Scanline pScanlineRead = pReadAcc->GetScanline(0); | |||
899 | for( long nZ = 0; nZ < nWidth; nZ++ ) | |||
900 | { | |||
901 | aColor = pReadAcc->GetPixelFromData( pScanlineRead, nZ ); | |||
902 | ||||
903 | *pTmp++ = static_cast<long>(aColor.GetBlue()) << 12; | |||
904 | *pTmp++ = static_cast<long>(aColor.GetGreen()) << 12; | |||
905 | *pTmp++ = static_cast<long>(aColor.GetRed()) << 12; | |||
906 | } | |||
907 | } | |||
908 | ||||
909 | for( long nY = 1, nYAcc = 0; nY <= nHeight; nY++, nYAcc++ ) | |||
910 | { | |||
911 | pTmp = p1T; | |||
912 | p1T = p2T; | |||
913 | p2T = pTmp; | |||
914 | ||||
915 | if( nY < nHeight ) | |||
916 | { | |||
917 | if( bPal ) | |||
918 | { | |||
919 | Scanline pScanlineRead = pReadAcc->GetScanline(nY); | |||
920 | for( long nZ = 0; nZ < nWidth; nZ++ ) | |||
921 | { | |||
922 | aColor = pReadAcc->GetPaletteColor( pReadAcc->GetIndexFromData( pScanlineRead, nZ ) ); | |||
923 | ||||
924 | *pTmp++ = static_cast<long>(aColor.GetBlue()) << 12; | |||
925 | *pTmp++ = static_cast<long>(aColor.GetGreen()) << 12; | |||
926 | *pTmp++ = static_cast<long>(aColor.GetRed()) << 12; | |||
927 | } | |||
928 | } | |||
929 | else | |||
930 | { | |||
931 | Scanline pScanlineRead = pReadAcc->GetScanline(nY); | |||
932 | for( long nZ = 0; nZ < nWidth; nZ++ ) | |||
933 | { | |||
934 | aColor = pReadAcc->GetPixelFromData( pScanlineRead, nZ ); | |||
935 | ||||
936 | *pTmp++ = static_cast<long>(aColor.GetBlue()) << 12; | |||
937 | *pTmp++ = static_cast<long>(aColor.GetGreen()) << 12; | |||
938 | *pTmp++ = static_cast<long>(aColor.GetRed()) << 12; | |||
939 | } | |||
940 | } | |||
941 | } | |||
942 | ||||
943 | // Examine first Pixel separately | |||
944 | nX = 0; | |||
945 | long nTemp; | |||
946 | CALC_ERRORSnTemp = p1T[nX++] >> 12; nBErr = MinMax( nTemp, 0, 255 ) ; nBErr = nBErr - FloydIndexMap[ nBC = FloydMap[nBErr] ]; nTemp = p1T[nX++] >> 12; nGErr = MinMax( nTemp, 0, 255 ); nGErr = nGErr - FloydIndexMap[ nGC = FloydMap[nGErr] ]; nTemp = p1T [nX] >> 12; nRErr = MinMax( nTemp, 0, 255 ); nRErr = nRErr - FloydIndexMap[ nRC = FloydMap[nRErr] ];; | |||
947 | CALC_TABLES7p1T[++nX] += FloydError7[nBErr]; p2T[nX++] += FloydError1[nBErr ]; p1T[nX] += FloydError7[nGErr]; p2T[nX++] += FloydError1[nGErr ]; p1T[nX] += FloydError7[nRErr]; p2T[nX] += FloydError1[nRErr ];; | |||
948 | nX -= 5; | |||
949 | CALC_TABLES5p2T[nX++] += FloydError5[nBErr]; p2T[nX++] += FloydError5[nGErr ]; p2T[nX++] += FloydError5[nRErr];; | |||
950 | Scanline pScanline = pWriteAcc->GetScanline(nYAcc); | |||
951 | pWriteAcc->SetPixelOnData( pScanline, 0, BitmapColor(static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ])) ); | |||
952 | ||||
953 | // Get middle Pixels using a loop | |||
954 | long nXAcc; | |||
955 | for ( nX = 3, nXAcc = 1; nX < nW2; nXAcc++ ) | |||
956 | { | |||
957 | CALC_ERRORSnTemp = p1T[nX++] >> 12; nBErr = MinMax( nTemp, 0, 255 ) ; nBErr = nBErr - FloydIndexMap[ nBC = FloydMap[nBErr] ]; nTemp = p1T[nX++] >> 12; nGErr = MinMax( nTemp, 0, 255 ); nGErr = nGErr - FloydIndexMap[ nGC = FloydMap[nGErr] ]; nTemp = p1T [nX] >> 12; nRErr = MinMax( nTemp, 0, 255 ); nRErr = nRErr - FloydIndexMap[ nRC = FloydMap[nRErr] ];; | |||
958 | CALC_TABLES7p1T[++nX] += FloydError7[nBErr]; p2T[nX++] += FloydError1[nBErr ]; p1T[nX] += FloydError7[nGErr]; p2T[nX++] += FloydError1[nGErr ]; p1T[nX] += FloydError7[nRErr]; p2T[nX] += FloydError1[nRErr ];; | |||
959 | nX -= 8; | |||
960 | CALC_TABLES3p2T[nX++] += FloydError3[nBErr]; p2T[nX++] += FloydError3[nGErr ]; p2T[nX++] += FloydError3[nRErr];; | |||
961 | CALC_TABLES5p2T[nX++] += FloydError5[nBErr]; p2T[nX++] += FloydError5[nGErr ]; p2T[nX++] += FloydError5[nRErr];; | |||
962 | pWriteAcc->SetPixelOnData( pScanline, nXAcc, BitmapColor(static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ])) ); | |||
963 | } | |||
964 | ||||
965 | // Treat last Pixel separately | |||
966 | CALC_ERRORSnTemp = p1T[nX++] >> 12; nBErr = MinMax( nTemp, 0, 255 ) ; nBErr = nBErr - FloydIndexMap[ nBC = FloydMap[nBErr] ]; nTemp = p1T[nX++] >> 12; nGErr = MinMax( nTemp, 0, 255 ); nGErr = nGErr - FloydIndexMap[ nGC = FloydMap[nGErr] ]; nTemp = p1T [nX] >> 12; nRErr = MinMax( nTemp, 0, 255 ); nRErr = nRErr - FloydIndexMap[ nRC = FloydMap[nRErr] ];; | |||
967 | nX -= 5; | |||
968 | CALC_TABLES3p2T[nX++] += FloydError3[nBErr]; p2T[nX++] += FloydError3[nGErr ]; p2T[nX++] += FloydError3[nRErr];; | |||
969 | CALC_TABLES5p2T[nX++] += FloydError5[nBErr]; p2T[nX++] += FloydError5[nGErr ]; p2T[nX++] += FloydError5[nRErr];; | |||
970 | pWriteAcc->SetPixelOnData( pScanline, nWidth1, BitmapColor(static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ])) ); | |||
971 | } | |||
972 | ||||
973 | bRet = true; | |||
974 | } | |||
975 | ||||
976 | pReadAcc.reset(); | |||
977 | pWriteAcc.reset(); | |||
978 | ||||
979 | if( bRet ) | |||
980 | { | |||
981 | const MapMode aMap( maPrefMapMode ); | |||
982 | const Size aPrefSize( maPrefSize ); | |||
983 | ||||
984 | *this = aNewBmp; | |||
985 | ||||
986 | maPrefMapMode = aMap; | |||
987 | maPrefSize = aPrefSize; | |||
988 | } | |||
989 | } | |||
990 | ||||
991 | return bRet; | |||
992 | } | |||
993 | ||||
994 | void Bitmap::Vectorize( GDIMetaFile& rMtf, sal_uInt8 cReduce, const Link<long,void>* pProgress ) | |||
995 | { | |||
996 | ImplVectorizer::ImplVectorize( *this, rMtf, cReduce, pProgress ); | |||
997 | } | |||
998 | ||||
999 | bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent, | |||
1000 | short nChannelRPercent, short nChannelGPercent, short nChannelBPercent, | |||
1001 | double fGamma, bool bInvert, bool msoBrightness ) | |||
1002 | { | |||
1003 | bool bRet = false; | |||
1004 | ||||
1005 | // nothing to do => return quickly | |||
1006 | if( !nLuminancePercent && !nContrastPercent && | |||
1007 | !nChannelRPercent && !nChannelGPercent && !nChannelBPercent && | |||
1008 | ( fGamma == 1.0 ) && !bInvert ) | |||
1009 | { | |||
1010 | bRet = true; | |||
1011 | } | |||
1012 | else | |||
1013 | { | |||
1014 | BitmapScopedWriteAccess pAcc(*this); | |||
1015 | ||||
1016 | if( pAcc ) | |||
1017 | { | |||
1018 | BitmapColor aCol; | |||
1019 | const long nW = pAcc->Width(); | |||
1020 | const long nH = pAcc->Height(); | |||
1021 | std::unique_ptr<sal_uInt8[]> cMapR(new sal_uInt8[ 256 ]); | |||
1022 | std::unique_ptr<sal_uInt8[]> cMapG(new sal_uInt8[ 256 ]); | |||
1023 | std::unique_ptr<sal_uInt8[]> cMapB(new sal_uInt8[ 256 ]); | |||
1024 | double fM, fROff, fGOff, fBOff, fOff; | |||
1025 | ||||
1026 | // calculate slope | |||
1027 | if( nContrastPercent >= 0 ) | |||
1028 | fM = 128.0 / ( 128.0 - 1.27 * MinMax( nContrastPercent, 0, 100 ) ); | |||
1029 | else | |||
1030 | fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100, 0 ) ) / 128.0; | |||
1031 | ||||
1032 | if(!msoBrightness) | |||
1033 | // total offset = luminance offset + contrast offset | |||
1034 | fOff = MinMax( nLuminancePercent, -100, 100 ) * 2.55 + 128.0 - fM * 128.0; | |||
1035 | else | |||
1036 | fOff = MinMax( nLuminancePercent, -100, 100 ) * 2.55; | |||
1037 | ||||
1038 | // channel offset = channel offset + total offset | |||
1039 | fROff = nChannelRPercent * 2.55 + fOff; | |||
1040 | fGOff = nChannelGPercent * 2.55 + fOff; | |||
1041 | fBOff = nChannelBPercent * 2.55 + fOff; | |||
1042 | ||||
1043 | // calculate gamma value | |||
1044 | fGamma = ( fGamma <= 0.0 || fGamma > 10.0 ) ? 1.0 : ( 1.0 / fGamma ); | |||
1045 | const bool bGamma = ( fGamma != 1.0 ); | |||
1046 | ||||
1047 | // create mapping table | |||
1048 | for( long nX = 0; nX < 256; nX++ ) | |||
1049 | { | |||
1050 | if(!msoBrightness) | |||
1051 | { | |||
1052 | cMapR[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( nX * fM + fROff ), 0, 255 )); | |||
1053 | cMapG[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( nX * fM + fGOff ), 0, 255 )); | |||
1054 | cMapB[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( nX * fM + fBOff ), 0, 255 )); | |||
1055 | } | |||
1056 | else | |||
1057 | { | |||
1058 | // LO simply uses (in a somewhat optimized form) "newcolor = (oldcolor-128)*contrast+brightness+128" | |||
1059 | // as the formula, i.e. contrast first, brightness afterwards. MSOffice, for whatever weird reason, | |||
1060 | // use neither first, but apparently it applies half of brightness before contrast and half afterwards. | |||
1061 | cMapR[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( (nX+fROff/2-128) * fM + 128 + fROff/2 ), 0, 255 )); | |||
1062 | cMapG[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( (nX+fGOff/2-128) * fM + 128 + fGOff/2 ), 0, 255 )); | |||
1063 | cMapB[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( (nX+fBOff/2-128) * fM + 128 + fBOff/2 ), 0, 255 )); | |||
1064 | } | |||
1065 | if( bGamma ) | |||
1066 | { | |||
1067 | cMapR[ nX ] = GAMMA( cMapR[ nX ], fGamma )(static_cast<sal_uInt8>(MinMax(FRound(pow( cMapR[ nX ]/ 255.0,fGamma)*255.0),0,255))); | |||
1068 | cMapG[ nX ] = GAMMA( cMapG[ nX ], fGamma )(static_cast<sal_uInt8>(MinMax(FRound(pow( cMapG[ nX ]/ 255.0,fGamma)*255.0),0,255))); | |||
1069 | cMapB[ nX ] = GAMMA( cMapB[ nX ], fGamma )(static_cast<sal_uInt8>(MinMax(FRound(pow( cMapB[ nX ]/ 255.0,fGamma)*255.0),0,255))); | |||
1070 | } | |||
1071 | ||||
1072 | if( bInvert ) | |||
1073 | { | |||
1074 | cMapR[ nX ] = ~cMapR[ nX ]; | |||
1075 | cMapG[ nX ] = ~cMapG[ nX ]; | |||
1076 | cMapB[ nX ] = ~cMapB[ nX ]; | |||
1077 | } | |||
1078 | } | |||
1079 | ||||
1080 | // do modifying | |||
1081 | if( pAcc->HasPalette() ) | |||
1082 | { | |||
1083 | BitmapColor aNewCol; | |||
1084 | ||||
1085 | for( sal_uInt16 i = 0, nCount = pAcc->GetPaletteEntryCount(); i < nCount; i++ ) | |||
1086 | { | |||
1087 | const BitmapColor& rCol = pAcc->GetPaletteColor( i ); | |||
1088 | aNewCol.SetRed( cMapR[ rCol.GetRed() ] ); | |||
1089 | aNewCol.SetGreen( cMapG[ rCol.GetGreen() ] ); | |||
1090 | aNewCol.SetBlue( cMapB[ rCol.GetBlue() ] ); | |||
1091 | pAcc->SetPaletteColor( i, aNewCol ); | |||
1092 | } | |||
1093 | } | |||
1094 | else if( pAcc->GetScanlineFormat() == ScanlineFormat::N24BitTcBgr ) | |||
1095 | { | |||
1096 | for( long nY = 0; nY < nH; nY++ ) | |||
1097 | { | |||
1098 | Scanline pScan = pAcc->GetScanline( nY ); | |||
1099 | ||||
1100 | for( long nX = 0; nX < nW; nX++ ) | |||
1101 | { | |||
1102 | *pScan = cMapB[ *pScan ]; pScan++; | |||
1103 | *pScan = cMapG[ *pScan ]; pScan++; | |||
1104 | *pScan = cMapR[ *pScan ]; pScan++; | |||
1105 | } | |||
1106 | } | |||
1107 | } | |||
1108 | else if( pAcc->GetScanlineFormat() == ScanlineFormat::N24BitTcRgb ) | |||
1109 | { | |||
1110 | for( long nY = 0; nY < nH; nY++ ) | |||
1111 | { | |||
1112 | Scanline pScan = pAcc->GetScanline( nY ); | |||
1113 | ||||
1114 | for( long nX = 0; nX < nW; nX++ ) | |||
1115 | { | |||
1116 | *pScan = cMapR[ *pScan ]; pScan++; | |||
1117 | *pScan = cMapG[ *pScan ]; pScan++; | |||
1118 | *pScan = cMapB[ *pScan ]; pScan++; | |||
1119 | } | |||
1120 | } | |||
1121 | } | |||
1122 | else | |||
1123 | { | |||
1124 | for( long nY = 0; nY < nH; nY++ ) | |||
1125 | { | |||
1126 | Scanline pScanline = pAcc->GetScanline(nY); | |||
1127 | for( long nX = 0; nX < nW; nX++ ) | |||
1128 | { | |||
1129 | aCol = pAcc->GetPixelFromData( pScanline, nX ); | |||
1130 | aCol.SetRed( cMapR[ aCol.GetRed() ] ); | |||
1131 | aCol.SetGreen( cMapG[ aCol.GetGreen() ] ); | |||
1132 | aCol.SetBlue( cMapB[ aCol.GetBlue() ] ); | |||
1133 | pAcc->SetPixelOnData( pScanline, nX, aCol ); | |||
1134 | } | |||
1135 | } | |||
1136 | } | |||
1137 | ||||
1138 | pAcc.reset(); | |||
1139 | bRet = true; | |||
1140 | } | |||
1141 | } | |||
1142 | ||||
1143 | return bRet; | |||
1144 | } | |||
1145 | ||||
1146 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||
2 | /* | ||||
3 | * This file is part of the LibreOffice project. | ||||
4 | * | ||||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | ||||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
8 | * | ||||
9 | * This file incorporates work covered by the following license notice: | ||||
10 | * | ||||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | ||||
12 | * contributor license agreements. See the NOTICE file distributed | ||||
13 | * with this work for additional information regarding copyright | ||||
14 | * ownership. The ASF licenses this file to you under the Apache | ||||
15 | * License, Version 2.0 (the "License"); you may not use this file | ||||
16 | * except in compliance with the License. You may obtain a copy of | ||||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | ||||
18 | */ | ||||
19 | |||||
20 | #ifndef INCLUDED_VCL_BMPACC_HXX | ||||
21 | #define INCLUDED_VCL_BMPACC_HXX | ||||
22 | |||||
23 | #include <vcl/dllapi.h> | ||||
24 | #include <vcl/bitmap.hxx> | ||||
25 | #include <vcl/Scanline.hxx> | ||||
26 | #include <vcl/BitmapBuffer.hxx> | ||||
27 | #include <vcl/BitmapColor.hxx> | ||||
28 | #include <vcl/BitmapAccessMode.hxx> | ||||
29 | |||||
30 | typedef BitmapColor (*FncGetPixel)(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
31 | typedef void (*FncSetPixel)(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
32 | |||||
33 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) BitmapInfoAccess | ||||
34 | { | ||||
35 | friend class BitmapReadAccess; | ||||
36 | |||||
37 | public: | ||||
38 | BitmapInfoAccess(Bitmap& rBitmap, BitmapAccessMode nMode = BitmapAccessMode::Info); | ||||
39 | virtual ~BitmapInfoAccess(); | ||||
40 | |||||
41 | bool operator!() const | ||||
42 | { | ||||
43 | return mpBuffer == nullptr; | ||||
44 | } | ||||
45 | |||||
46 | long Width() const | ||||
47 | { | ||||
48 | return mpBuffer ? mpBuffer->mnWidth : 0L; | ||||
49 | } | ||||
50 | |||||
51 | long Height() const | ||||
52 | { | ||||
53 | return mpBuffer ? mpBuffer->mnHeight : 0L; | ||||
54 | } | ||||
55 | |||||
56 | bool IsTopDown() const | ||||
57 | { | ||||
58 | assert(mpBuffer && "Access is not valid!")(static_cast <bool> (mpBuffer && "Access is not valid!" ) ? void (0) : __assert_fail ("mpBuffer && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 58, __extension__ __PRETTY_FUNCTION__)); | ||||
59 | |||||
60 | return mpBuffer && (mpBuffer->mnFormat & ScanlineFormat::TopDown); | ||||
61 | } | ||||
62 | |||||
63 | bool IsBottomUp() const | ||||
64 | { | ||||
65 | return !IsTopDown(); | ||||
66 | } | ||||
67 | |||||
68 | ScanlineFormat GetScanlineFormat() const | ||||
69 | { | ||||
70 | assert(mpBuffer && "Access is not valid!")(static_cast <bool> (mpBuffer && "Access is not valid!" ) ? void (0) : __assert_fail ("mpBuffer && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 70, __extension__ __PRETTY_FUNCTION__)); | ||||
71 | |||||
72 | return mpBuffer ? RemoveScanline(mpBuffer->mnFormat) : ScanlineFormat::NONE; | ||||
73 | } | ||||
74 | |||||
75 | sal_uInt32 GetScanlineSize() const | ||||
76 | { | ||||
77 | assert(mpBuffer && "Access is not valid!")(static_cast <bool> (mpBuffer && "Access is not valid!" ) ? void (0) : __assert_fail ("mpBuffer && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 77, __extension__ __PRETTY_FUNCTION__)); | ||||
78 | |||||
79 | return mpBuffer ? mpBuffer->mnScanlineSize : 0; | ||||
80 | } | ||||
81 | |||||
82 | sal_uInt16 GetBitCount() const | ||||
83 | { | ||||
84 | assert(mpBuffer && "Access is not valid!")(static_cast <bool> (mpBuffer && "Access is not valid!" ) ? void (0) : __assert_fail ("mpBuffer && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 84, __extension__ __PRETTY_FUNCTION__)); | ||||
85 | |||||
86 | return mpBuffer ? mpBuffer->mnBitCount : 0; | ||||
87 | } | ||||
88 | |||||
89 | BitmapColor GetBestMatchingColor(const BitmapColor& rBitmapColor) | ||||
90 | { | ||||
91 | if (HasPalette()) | ||||
92 | return BitmapColor(static_cast<sal_uInt8>(GetBestPaletteIndex(rBitmapColor))); | ||||
93 | else | ||||
94 | return rBitmapColor; | ||||
95 | } | ||||
96 | |||||
97 | bool HasPalette() const | ||||
98 | { | ||||
99 | assert(mpBuffer && "Access is not valid!")(static_cast <bool> (mpBuffer && "Access is not valid!" ) ? void (0) : __assert_fail ("mpBuffer && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 99, __extension__ __PRETTY_FUNCTION__)); | ||||
100 | |||||
101 | return mpBuffer
| ||||
102 | } | ||||
103 | |||||
104 | const BitmapPalette& GetPalette() const | ||||
105 | { | ||||
106 | assert(mpBuffer && "Access is not valid!")(static_cast <bool> (mpBuffer && "Access is not valid!" ) ? void (0) : __assert_fail ("mpBuffer && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 106, __extension__ __PRETTY_FUNCTION__)); | ||||
107 | |||||
108 | return mpBuffer->maPalette; | ||||
109 | } | ||||
110 | |||||
111 | sal_uInt16 GetPaletteEntryCount() const | ||||
112 | { | ||||
113 | assert(HasPalette() && "Bitmap has no palette!")(static_cast <bool> (HasPalette() && "Bitmap has no palette!" ) ? void (0) : __assert_fail ("HasPalette() && \"Bitmap has no palette!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 113, __extension__ __PRETTY_FUNCTION__)); | ||||
114 | |||||
115 | return HasPalette() ? mpBuffer->maPalette.GetEntryCount() : 0; | ||||
116 | } | ||||
117 | |||||
118 | const BitmapColor& GetPaletteColor( sal_uInt16 nColor ) const | ||||
119 | { | ||||
120 | assert(mpBuffer && "Access is not valid!")(static_cast <bool> (mpBuffer && "Access is not valid!" ) ? void (0) : __assert_fail ("mpBuffer && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 120, __extension__ __PRETTY_FUNCTION__)); | ||||
121 | assert(HasPalette() && "Bitmap has no palette!")(static_cast <bool> (HasPalette() && "Bitmap has no palette!" ) ? void (0) : __assert_fail ("HasPalette() && \"Bitmap has no palette!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 121, __extension__ __PRETTY_FUNCTION__)); | ||||
122 | |||||
123 | return mpBuffer->maPalette[nColor]; | ||||
124 | } | ||||
125 | |||||
126 | const BitmapColor& GetBestPaletteColor(const BitmapColor& rBitmapColor) const | ||||
127 | { | ||||
128 | return GetPaletteColor(GetBestPaletteIndex(rBitmapColor)); | ||||
129 | } | ||||
130 | |||||
131 | sal_uInt16 GetBestPaletteIndex(const BitmapColor& rBitmapColor) const; | ||||
132 | |||||
133 | ColorMask& GetColorMask() const | ||||
134 | { | ||||
135 | assert(mpBuffer && "Access is not valid!")(static_cast <bool> (mpBuffer && "Access is not valid!" ) ? void (0) : __assert_fail ("mpBuffer && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 135, __extension__ __PRETTY_FUNCTION__)); | ||||
136 | |||||
137 | return mpBuffer->maColorMask; | ||||
138 | } | ||||
139 | |||||
140 | private: | ||||
141 | BitmapInfoAccess(const BitmapInfoAccess&) = delete; | ||||
142 | BitmapInfoAccess& operator=(const BitmapInfoAccess&) = delete; | ||||
143 | |||||
144 | protected: | ||||
145 | Bitmap maBitmap; | ||||
146 | BitmapBuffer* mpBuffer; | ||||
147 | ColorMask maColorMask; | ||||
148 | BitmapAccessMode mnAccessMode; | ||||
149 | }; | ||||
150 | |||||
151 | |||||
152 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) BitmapReadAccess : public BitmapInfoAccess | ||||
153 | { | ||||
154 | friend class BitmapWriteAccess; | ||||
155 | |||||
156 | public: | ||||
157 | BitmapReadAccess(Bitmap& rBitmap, BitmapAccessMode nMode = BitmapAccessMode::Read); | ||||
158 | virtual ~BitmapReadAccess() override; | ||||
159 | |||||
160 | Scanline GetBuffer() const | ||||
161 | { | ||||
162 | assert(mpBuffer && "Access is not valid!")(static_cast <bool> (mpBuffer && "Access is not valid!" ) ? void (0) : __assert_fail ("mpBuffer && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 162, __extension__ __PRETTY_FUNCTION__)); | ||||
163 | |||||
164 | return mpBuffer ? mpBuffer->mpBits : nullptr; | ||||
165 | } | ||||
166 | |||||
167 | Scanline GetScanline(long nY) const | ||||
168 | { | ||||
169 | assert(mpBuffer && "Access is not valid!")(static_cast <bool> (mpBuffer && "Access is not valid!" ) ? void (0) : __assert_fail ("mpBuffer && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 169, __extension__ __PRETTY_FUNCTION__)); | ||||
170 | assert(nY < mpBuffer->mnHeight && "y-coordinate out of range!")(static_cast <bool> (nY < mpBuffer->mnHeight && "y-coordinate out of range!") ? void (0) : __assert_fail ("nY < mpBuffer->mnHeight && \"y-coordinate out of range!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 170, __extension__ __PRETTY_FUNCTION__)); | ||||
171 | |||||
172 | if (mpBuffer->mnFormat & ScanlineFormat::TopDown) | ||||
173 | { | ||||
174 | return mpBuffer->mpBits + (nY * mpBuffer->mnScanlineSize); | ||||
175 | } | ||||
176 | return mpBuffer->mpBits + ((mpBuffer->mnHeight - 1 - nY) * mpBuffer->mnScanlineSize); | ||||
177 | } | ||||
178 | |||||
179 | BitmapColor GetPixelFromData(const sal_uInt8* pData, long nX) const | ||||
180 | { | ||||
181 | assert(pData && "Access is not valid!")(static_cast <bool> (pData && "Access is not valid!" ) ? void (0) : __assert_fail ("pData && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 181, __extension__ __PRETTY_FUNCTION__)); | ||||
182 | |||||
183 | return mFncGetPixel( pData, nX, maColorMask ); | ||||
184 | } | ||||
185 | |||||
186 | sal_uInt8 GetIndexFromData(const sal_uInt8* pData, long nX) const | ||||
187 | { | ||||
188 | return GetPixelFromData( pData, nX ).GetIndex(); | ||||
189 | } | ||||
190 | |||||
191 | void SetPixelOnData(sal_uInt8* pData, long nX, const BitmapColor& rBitmapColor) | ||||
192 | { | ||||
193 | assert(pData && "Access is not valid!")(static_cast <bool> (pData && "Access is not valid!" ) ? void (0) : __assert_fail ("pData && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 193, __extension__ __PRETTY_FUNCTION__)); | ||||
194 | |||||
195 | mFncSetPixel(pData, nX, rBitmapColor, maColorMask); | ||||
196 | } | ||||
197 | |||||
198 | BitmapColor GetPixel(long nY, long nX) const | ||||
199 | { | ||||
200 | assert(mpBuffer && "Access is not valid!")(static_cast <bool> (mpBuffer && "Access is not valid!" ) ? void (0) : __assert_fail ("mpBuffer && \"Access is not valid!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 200, __extension__ __PRETTY_FUNCTION__)); | ||||
201 | assert(nX < mpBuffer->mnWidth && "x-coordinate out of range!")(static_cast <bool> (nX < mpBuffer->mnWidth && "x-coordinate out of range!") ? void (0) : __assert_fail ("nX < mpBuffer->mnWidth && \"x-coordinate out of range!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 201, __extension__ __PRETTY_FUNCTION__)); | ||||
202 | assert(nY < mpBuffer->mnHeight && "y-coordinate out of range!")(static_cast <bool> (nY < mpBuffer->mnHeight && "y-coordinate out of range!") ? void (0) : __assert_fail ("nY < mpBuffer->mnHeight && \"y-coordinate out of range!\"" , "/home/maarten/src/libreoffice/core/include/vcl/bitmapaccess.hxx" , 202, __extension__ __PRETTY_FUNCTION__)); | ||||
203 | |||||
204 | return mFncGetPixel(GetScanline(nY), nX, maColorMask ); | ||||
205 | } | ||||
206 | |||||
207 | BitmapColor GetColor(long nY, long nX) const | ||||
208 | { | ||||
209 | if (HasPalette()) | ||||
210 | return mpBuffer->maPalette[GetPixelIndex(nY, nX)]; | ||||
211 | else | ||||
212 | return GetPixel(nY, nX); | ||||
213 | } | ||||
214 | |||||
215 | sal_uInt8 GetPixelIndex(long nY, long nX) const | ||||
216 | { | ||||
217 | return GetPixel(nY, nX).GetIndex(); | ||||
218 | } | ||||
219 | |||||
220 | /** Get the interpolated color at coordinates fY, fX; if outside, return rFallback */ | ||||
221 | BitmapColor GetInterpolatedColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const; | ||||
222 | |||||
223 | /** Get the color at coordinates fY, fX; if outside, return rFallback. Automatically does the correct | ||||
224 | inside/outside checks, e.g. static_cast< sal_uInt32 >(-0.25) *is* 0, not -1 and has to be outside */ | ||||
225 | BitmapColor GetColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const; | ||||
226 | |||||
227 | private: | ||||
228 | BitmapReadAccess(const BitmapReadAccess&) = delete; | ||||
229 | BitmapReadAccess& operator=(const BitmapReadAccess&) = delete; | ||||
230 | |||||
231 | protected: | ||||
232 | FncGetPixel mFncGetPixel; | ||||
233 | FncSetPixel mFncSetPixel; | ||||
234 | |||||
235 | public: | ||||
236 | |||||
237 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) BitmapBuffer* ImplGetBitmapBuffer() const | ||||
238 | { | ||||
239 | return mpBuffer; | ||||
240 | } | ||||
241 | |||||
242 | static BitmapColor GetPixelForN1BitMsbPal(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
243 | static BitmapColor GetPixelForN1BitLsbPal(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
244 | static BitmapColor GetPixelForN4BitMsnPal(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
245 | static BitmapColor GetPixelForN4BitLsnPal(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
246 | static BitmapColor GetPixelForN8BitPal(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
247 | static BitmapColor GetPixelForN8BitTcMask(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
248 | static BitmapColor GetPixelForN24BitTcBgr(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
249 | static BitmapColor GetPixelForN24BitTcRgb(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
250 | static BitmapColor GetPixelForN32BitTcAbgr(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
251 | static BitmapColor GetPixelForN32BitTcXbgr(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
252 | static BitmapColor GetPixelForN32BitTcArgb(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
253 | static BitmapColor GetPixelForN32BitTcXrgb(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
254 | static BitmapColor GetPixelForN32BitTcBgra(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
255 | static BitmapColor GetPixelForN32BitTcBgrx(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
256 | static BitmapColor GetPixelForN32BitTcRgba(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
257 | static BitmapColor GetPixelForN32BitTcRgbx(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
258 | static BitmapColor GetPixelForN32BitTcMask(ConstScanline pScanline, long nX, const ColorMask& rMask); | ||||
259 | |||||
260 | static void SetPixelForN1BitMsbPal(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
261 | static void SetPixelForN1BitLsbPal(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
262 | static void SetPixelForN4BitMsnPal(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
263 | static void SetPixelForN4BitLsnPal(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
264 | static void SetPixelForN8BitPal(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
265 | static void SetPixelForN8BitTcMask(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
266 | static void SetPixelForN24BitTcBgr(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
267 | static void SetPixelForN24BitTcRgb(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
268 | static void SetPixelForN32BitTcAbgr(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
269 | static void SetPixelForN32BitTcXbgr(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
270 | static void SetPixelForN32BitTcArgb(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
271 | static void SetPixelForN32BitTcXrgb(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
272 | static void SetPixelForN32BitTcBgra(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
273 | static void SetPixelForN32BitTcBgrx(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
274 | static void SetPixelForN32BitTcRgba(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
275 | static void SetPixelForN32BitTcRgbx(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
276 | static void SetPixelForN32BitTcMask(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask); | ||||
277 | |||||
278 | static FncGetPixel GetPixelFunction( ScanlineFormat nFormat ); | ||||
279 | static FncSetPixel SetPixelFunction( ScanlineFormat nFormat ); | ||||
280 | }; | ||||
281 | |||||
282 | |||||
283 | #endif // INCLUDED_VCL_BMPACC_HXX | ||||
284 | |||||
285 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |