LibreOffice Module vcl (master)  1
BitmapReadAccess.cxx
Go to the documentation of this file.
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 <vcl/BitmapReadAccess.hxx>
21 #include <vcl/BitmapTools.hxx>
22 
23 #include <salbmp.hxx>
24 #include <svdata.hxx>
25 #include <salinst.hxx>
26 
28  : BitmapInfoAccess(rBitmap, nMode)
29  , mFncGetPixel(nullptr)
30  , mFncSetPixel(nullptr)
31 {
32  if (!mpBuffer)
33  return;
34 
35  const std::shared_ptr<SalBitmap>& xImpBmp = rBitmap.ImplGetSalBitmap();
36  if (!xImpBmp)
37  return;
38 
40 
43 
44  if (!mFncGetPixel || !mFncSetPixel)
45  {
46  xImpBmp->ReleaseBuffer(mpBuffer, mnAccessMode);
47  mpBuffer = nullptr;
48  }
49 }
50 
52 
54 
56 {
57  switch (RemoveScanline(nFormat))
58  {
64  return GetPixelForN8BitPal;
72  else
77  else
82  else
87  else
91 
92  default:
93  return nullptr;
94  }
95 }
96 
98 {
99  switch (RemoveScanline(nFormat))
100  {
102  return SetPixelForN1BitMsbPal;
104  return SetPixelForN1BitLsbPal;
106  return SetPixelForN8BitPal;
108  return SetPixelForN24BitTcBgr;
110  return SetPixelForN24BitTcRgb;
114  else
119  else
124  else
129  else
133 
134  default:
135  return nullptr;
136  }
137 }
138 
140  const BitmapColor& rFallback) const
141 {
142  // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
143  // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
144  if (mpBuffer && fX >= 0.0 && fY >= 0.0)
145  {
146  const sal_Int64 nX(static_cast<sal_Int64>(fX));
147  const sal_Int64 nY(static_cast<sal_Int64>(fY));
148 
149  if (nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
150  {
151  // get base-return value from inside pixel
152  BitmapColor aRetval(GetColor(nY, nX));
153 
154  // calculate deltas and indices for neighbour accesses
155  sal_Int16 nDeltaX((fX - (nX + 0.5)) * 255.0); // [-255 .. 255]
156  sal_Int16 nDeltaY((fY - (nY + 0.5)) * 255.0); // [-255 .. 255]
157  sal_Int16 nIndX(0);
158  sal_Int16 nIndY(0);
159 
160  if (nDeltaX > 0)
161  {
162  nIndX = nX + 1;
163  }
164  else
165  {
166  nIndX = nX - 1;
167  nDeltaX = -nDeltaX;
168  }
169 
170  if (nDeltaY > 0)
171  {
172  nIndY = nY + 1;
173  }
174  else
175  {
176  nIndY = nY - 1;
177  nDeltaY = -nDeltaY;
178  }
179 
180  // get right/left neighbour
181  BitmapColor aXCol(rFallback);
182 
183  if (nDeltaX && nIndX >= 0 && nIndX < mpBuffer->mnWidth)
184  {
185  aXCol = GetColor(nY, nIndX);
186  }
187 
188  // get top/bottom neighbour
189  BitmapColor aYCol(rFallback);
190 
191  if (nDeltaY && nIndY >= 0 && nIndY < mpBuffer->mnHeight)
192  {
193  aYCol = GetColor(nIndY, nX);
194  }
195 
196  // get one of four edge neighbours
197  BitmapColor aXYCol(rFallback);
198 
199  if (nDeltaX && nDeltaY && nIndX >= 0 && nIndY >= 0 && nIndX < mpBuffer->mnWidth
200  && nIndY < mpBuffer->mnHeight)
201  {
202  aXYCol = GetColor(nIndY, nIndX);
203  }
204 
205  // merge return value with right/left neighbour
206  if (aXCol != aRetval)
207  {
208  aRetval.Merge(aXCol, 255 - nDeltaX);
209  }
210 
211  // merge top/bottom neighbour with edge
212  if (aYCol != aXYCol)
213  {
214  aYCol.Merge(aXYCol, 255 - nDeltaX);
215  }
216 
217  // merge return value with already merged top/bottom neighbour
218  if (aRetval != aYCol)
219  {
220  aRetval.Merge(aYCol, 255 - nDeltaY);
221  }
222 
223  return aRetval;
224  }
225  }
226 
227  return rFallback;
228 }
229 
231  const BitmapColor& rFallback) const
232 {
233  // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
234  // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
235  if (mpBuffer && fX >= 0.0 && fY >= 0.0)
236  {
237  const sal_Int32 nX(static_cast<sal_Int32>(fX));
238  const sal_Int32 nY(static_cast<sal_Int32>(fY));
239 
240  if (nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
241  {
242  return GetColor(nY, nX);
243  }
244  }
245 
246  return rFallback;
247 }
248 
250  const ColorMask&)
251 {
252  return BitmapColor(pScanline[nX >> 3] & (1 << (7 - (nX & 7))) ? 1 : 0);
253 }
254 
256  const BitmapColor& rBitmapColor, const ColorMask&)
257 {
258  sal_uInt8& rByte = pScanline[nX >> 3];
259 
260  if (rBitmapColor.GetIndex() & 1)
261  rByte |= 1 << (7 - (nX & 7));
262  else
263  rByte &= ~(1 << (7 - (nX & 7)));
264 }
265 
267  const ColorMask&)
268 {
269  return BitmapColor(pScanline[nX >> 3] & (1 << (nX & 7)) ? 1 : 0);
270 }
271 
273  const BitmapColor& rBitmapColor, const ColorMask&)
274 {
275  sal_uInt8& rByte = pScanline[nX >> 3];
276 
277  if (rBitmapColor.GetIndex() & 1)
278  rByte |= 1 << (nX & 7);
279  else
280  rByte &= ~(1 << (nX & 7));
281 }
282 
284  const ColorMask&)
285 {
286  return BitmapColor(pScanline[nX]);
287 }
288 
290  const BitmapColor& rBitmapColor, const ColorMask&)
291 {
292  pScanline[nX] = rBitmapColor.GetIndex();
293 }
294 
296  const ColorMask&)
297 {
298  BitmapColor aBitmapColor;
299 
300  pScanline = pScanline + nX * 3;
301  aBitmapColor.SetBlue(*pScanline++);
302  aBitmapColor.SetGreen(*pScanline++);
303  aBitmapColor.SetRed(*pScanline);
304 
305  return aBitmapColor;
306 }
307 
309  const BitmapColor& rBitmapColor, const ColorMask&)
310 {
311  pScanline = pScanline + nX * 3;
312  *pScanline++ = rBitmapColor.GetBlue();
313  *pScanline++ = rBitmapColor.GetGreen();
314  *pScanline = rBitmapColor.GetRed();
315 }
316 
318  const ColorMask&)
319 {
320  BitmapColor aBitmapColor;
321 
322  pScanline = pScanline + nX * 3;
323  aBitmapColor.SetRed(*pScanline++);
324  aBitmapColor.SetGreen(*pScanline++);
325  aBitmapColor.SetBlue(*pScanline);
326 
327  return aBitmapColor;
328 }
329 
331  const BitmapColor& rBitmapColor, const ColorMask&)
332 {
333  pScanline = pScanline + nX * 3;
334  *pScanline++ = rBitmapColor.GetRed();
335  *pScanline++ = rBitmapColor.GetGreen();
336  *pScanline = rBitmapColor.GetBlue();
337 }
338 
340  const ColorMask&)
341 {
342  pScanline = pScanline + nX * 4;
343 
344  sal_uInt8 a = *pScanline++;
345  sal_uInt8 b = *pScanline++;
346  sal_uInt8 g = *pScanline++;
347  sal_uInt8 r = *pScanline;
348 
351 }
352 
354  const ColorMask&)
355 {
356  BitmapColor aBitmapColor;
357 
358  pScanline = pScanline + (nX << 2) + 1;
359  aBitmapColor.SetBlue(*pScanline++);
360  aBitmapColor.SetGreen(*pScanline++);
361  aBitmapColor.SetRed(*pScanline);
362 
363  return aBitmapColor;
364 }
365 
367  const BitmapColor& rBitmapColor, const ColorMask&)
368 {
369  pScanline = pScanline + nX * 4;
370 
371  sal_uInt8 alpha = rBitmapColor.GetAlpha();
372  *pScanline++ = alpha;
373  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
374  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
375  *pScanline = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
376 }
377 
379  const BitmapColor& rBitmapColor, const ColorMask&)
380 {
381  pScanline = pScanline + (nX << 2);
382  *pScanline++ = 0xFF;
383  *pScanline++ = rBitmapColor.GetBlue();
384  *pScanline++ = rBitmapColor.GetGreen();
385  *pScanline = rBitmapColor.GetRed();
386 }
387 
389  const ColorMask&)
390 {
391  pScanline = pScanline + nX * 4;
392 
393  sal_uInt8 a = *pScanline++;
394  sal_uInt8 r = *pScanline++;
395  sal_uInt8 g = *pScanline++;
396  sal_uInt8 b = *pScanline;
397 
400 }
401 
403  const ColorMask&)
404 {
405  BitmapColor aBitmapColor;
406 
407  pScanline = pScanline + (nX << 2) + 1;
408  aBitmapColor.SetRed(*pScanline++);
409  aBitmapColor.SetGreen(*pScanline++);
410  aBitmapColor.SetBlue(*pScanline);
411 
412  return aBitmapColor;
413 }
414 
416  const BitmapColor& rBitmapColor, const ColorMask&)
417 {
418  pScanline = pScanline + nX * 4;
419 
420  sal_uInt8 alpha = rBitmapColor.GetAlpha();
421  *pScanline++ = alpha;
422  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
423  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
424  *pScanline = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
425 }
426 
428  const BitmapColor& rBitmapColor, const ColorMask&)
429 {
430  pScanline = pScanline + (nX << 2);
431  *pScanline++ = 0xFF;
432  *pScanline++ = rBitmapColor.GetRed();
433  *pScanline++ = rBitmapColor.GetGreen();
434  *pScanline = rBitmapColor.GetBlue();
435 }
436 
438  const ColorMask&)
439 {
440  pScanline = pScanline + nX * 4;
441 
442  sal_uInt8 b = *pScanline++;
443  sal_uInt8 g = *pScanline++;
444  sal_uInt8 r = *pScanline++;
445  sal_uInt8 a = *pScanline;
446 
449 }
450 
452  const ColorMask&)
453 {
454  BitmapColor aBitmapColor;
455 
456  pScanline = pScanline + (nX << 2);
457  aBitmapColor.SetBlue(*pScanline++);
458  aBitmapColor.SetGreen(*pScanline++);
459  aBitmapColor.SetRed(*pScanline);
460 
461  return aBitmapColor;
462 }
463 
465  const BitmapColor& rBitmapColor, const ColorMask&)
466 {
467  pScanline = pScanline + nX * 4;
468 
469  sal_uInt8 alpha = rBitmapColor.GetAlpha();
470  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
471  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
472  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
473  *pScanline = alpha;
474 }
475 
477  const BitmapColor& rBitmapColor, const ColorMask&)
478 {
479  pScanline = pScanline + (nX << 2);
480  *pScanline++ = rBitmapColor.GetBlue();
481  *pScanline++ = rBitmapColor.GetGreen();
482  *pScanline++ = rBitmapColor.GetRed();
483  *pScanline = 0xFF;
484 }
485 
487  const ColorMask&)
488 {
489  pScanline = pScanline + nX * 4;
490 
491  sal_uInt8 r = *pScanline++;
492  sal_uInt8 g = *pScanline++;
493  sal_uInt8 b = *pScanline++;
494  sal_uInt8 a = *pScanline;
495 
498 }
499 
501  const ColorMask&)
502 {
503  BitmapColor aBitmapColor;
504 
505  pScanline = pScanline + (nX << 2);
506  aBitmapColor.SetRed(*pScanline++);
507  aBitmapColor.SetGreen(*pScanline++);
508  aBitmapColor.SetBlue(*pScanline);
509 
510  return aBitmapColor;
511 }
512 
514  const BitmapColor& rBitmapColor, const ColorMask&)
515 {
516  pScanline = pScanline + nX * 4;
517 
518  sal_uInt8 alpha = rBitmapColor.GetAlpha();
519  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
520  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
521  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
522  *pScanline = alpha;
523 }
524 
526  const BitmapColor& rBitmapColor, const ColorMask&)
527 {
528  pScanline = pScanline + (nX << 2);
529  *pScanline++ = rBitmapColor.GetRed();
530  *pScanline++ = rBitmapColor.GetGreen();
531  *pScanline++ = rBitmapColor.GetBlue();
532  *pScanline = 0xFF;
533 }
534 
536  const ColorMask& rMask)
537 {
538  BitmapColor aColor;
539  rMask.GetColorFor32Bit(aColor, pScanline + (nX << 2));
540  return aColor;
541 }
542 
544  const BitmapColor& rBitmapColor,
545  const ColorMask& rMask)
546 {
547  rMask.SetColorFor32Bit(rBitmapColor, pScanline + (nX << 2));
548 }
549 
550 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
double mnHeight
sal_uInt8 premultiply(sal_uInt8 c, sal_uInt8 a)
static BitmapColor GetPixelForN1BitMsbPal(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
static void SetPixelForN32BitTcBgra(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
sal_uInt8 GetIndex() const
Definition: BitmapColor.hxx:70
sal_uInt8 GetAlpha() const
sal_uInt8 GetRed() const
ColorMask maColorMask
static BitmapColor GetPixelForN32BitTcRgbx(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
static BitmapColor GetPixelForN32BitTcXbgr(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
void SetBlue(sal_uInt8 nBlue)
static void SetPixelForN32BitTcArgb(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
static FncSetPixel SetPixelFunction(ScanlineFormat nFormat)
BitmapAccessMode mnAccessMode
void Merge(const Color &rMergeColor, sal_uInt8 cTransparency)
BitmapColor GetColorWithFallback(double fY, double fX, const BitmapColor &rFallback) const
Get the color at coordinates fY, fX; if outside, return rFallback.
virtual ~BitmapReadAccess() override
static void SetPixelForN32BitTcXbgr(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
sal_uInt8 unpremultiply(sal_uInt8 c, sal_uInt8 a)
const std::shared_ptr< SalBitmap > & ImplGetSalBitmap() const
long Long
void SetColorFor32Bit(const BitmapColor &rColor, sal_uInt8 *pPixel) const
Definition: ColorMask.hxx:182
static BitmapColor GetPixelForN32BitTcXrgb(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
ScanlineFormat
Definition: Scanline.hxx:29
static void SetPixelForN1BitMsbPal(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
BitmapReadAccess(Bitmap &rBitmap, BitmapAccessMode nMode=BitmapAccessMode::Read)
BitmapColor GetInterpolatedColorWithFallback(double fY, double fX, const BitmapColor &rFallback) const
Get the interpolated color at coordinates fY, fX; if outside, return rFallback.
void(* FncSetPixel)(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
BitmapBuffer * mpBuffer
static void SetPixelForN32BitTcBgrx(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
static void SetPixelForN32BitTcMask(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
sal_uInt8 GetBlue() const
ScanlineFormat mnFormat
FncGetPixel mFncGetPixel
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:75
sal_uInt8 * Scanline
Definition: Scanline.hxx:26
uno_Any a
static BitmapColor GetPixelForN24BitTcBgr(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
static void SetPixelForN1BitLsbPal(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
static BitmapColor GetPixelForN32BitTcBgrx(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
BitmapColor GetColor(tools::Long nY, tools::Long nX) const
static BitmapColor GetPixelForN32BitTcMask(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
static BitmapColor GetPixelForN32BitTcRgba(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
BitmapAccessMode
void SetRed(sal_uInt8 nRed)
static void SetPixelForN32BitTcRgbx(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
static BitmapColor GetPixelForN1BitLsbPal(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
bool Bitmap32IsPreMultipled()
static BitmapColor GetPixelForN32BitTcAbgr(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
bool supportsBitmap32() const
Definition: salinst.hxx:89
FncSetPixel mFncSetPixel
const sal_uInt8 * ConstScanline
Definition: Scanline.hxx:27
static BitmapColor GetPixelForN8BitPal(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
sal_uInt8 GetGreen() const
static FncGetPixel GetPixelFunction(ScanlineFormat nFormat)
static BitmapColor GetPixelForN32BitTcBgra(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
unsigned char sal_uInt8
static void SetPixelForN32BitTcXrgb(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
void SetGreen(sal_uInt8 nGreen)
static BitmapColor GetPixelForN24BitTcRgb(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
double mnWidth
void GetColorFor32Bit(BitmapColor &rColor, const sal_uInt8 *pPixel) const
Definition: ColorMask.hxx:165
ScanlineFormat RemoveScanline(ScanlineFormat nFormat)
Definition: Scanline.hxx:54
BitmapColor(* FncGetPixel)(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
static void SetPixelForN8BitPal(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
static void SetPixelForN24BitTcRgb(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
static void SetPixelForN24BitTcBgr(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
static BitmapColor GetPixelForN32BitTcArgb(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
SalInstance * mpDefInst
Definition: svdata.hxx:388
static void SetPixelForN32BitTcAbgr(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
static void SetPixelForN32BitTcRgba(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
ColorAlpha