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 {
55  auto pBackendCapabilities = ImplGetSVData()->mpDefInst->GetBackendCapabilities();
56  return pBackendCapabilities->mbSupportsBitmap32;
57 }
58 
60 {
61  switch (RemoveScanline(nFormat))
62  {
72  return GetPixelForN8BitPal;
80  else
85  else
90  else
95  else
99 
100  default:
101  return nullptr;
102  }
103 }
104 
106 {
107  switch (RemoveScanline(nFormat))
108  {
110  return SetPixelForN1BitMsbPal;
112  return SetPixelForN1BitLsbPal;
114  return SetPixelForN4BitMsnPal;
116  return SetPixelForN4BitLsnPal;
118  return SetPixelForN8BitPal;
120  return SetPixelForN24BitTcBgr;
122  return SetPixelForN24BitTcRgb;
126  else
131  else
136  else
141  else
145 
146  default:
147  return nullptr;
148  }
149 }
150 
152  const BitmapColor& rFallback) const
153 {
154  // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
155  // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
156  if (mpBuffer && fX >= 0.0 && fY >= 0.0)
157  {
158  const sal_Int64 nX(static_cast<sal_Int64>(fX));
159  const sal_Int64 nY(static_cast<sal_Int64>(fY));
160 
161  if (nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
162  {
163  // get base-return value from inside pixel
164  BitmapColor aRetval(GetColor(nY, nX));
165 
166  // calculate deltas and indices for neighbour accesses
167  sal_Int16 nDeltaX((fX - (nX + 0.5)) * 255.0); // [-255 .. 255]
168  sal_Int16 nDeltaY((fY - (nY + 0.5)) * 255.0); // [-255 .. 255]
169  sal_Int16 nIndX(0);
170  sal_Int16 nIndY(0);
171 
172  if (nDeltaX > 0)
173  {
174  nIndX = nX + 1;
175  }
176  else
177  {
178  nIndX = nX - 1;
179  nDeltaX = -nDeltaX;
180  }
181 
182  if (nDeltaY > 0)
183  {
184  nIndY = nY + 1;
185  }
186  else
187  {
188  nIndY = nY - 1;
189  nDeltaY = -nDeltaY;
190  }
191 
192  // get right/left neighbour
193  BitmapColor aXCol(rFallback);
194 
195  if (nDeltaX && nIndX >= 0 && nIndX < mpBuffer->mnWidth)
196  {
197  aXCol = GetColor(nY, nIndX);
198  }
199 
200  // get top/bottom neighbour
201  BitmapColor aYCol(rFallback);
202 
203  if (nDeltaY && nIndY >= 0 && nIndY < mpBuffer->mnHeight)
204  {
205  aYCol = GetColor(nIndY, nX);
206  }
207 
208  // get one of four edge neighbours
209  BitmapColor aXYCol(rFallback);
210 
211  if (nDeltaX && nDeltaY && nIndX >= 0 && nIndY >= 0 && nIndX < mpBuffer->mnWidth
212  && nIndY < mpBuffer->mnHeight)
213  {
214  aXYCol = GetColor(nIndY, nIndX);
215  }
216 
217  // merge return value with right/left neighbour
218  if (aXCol != aRetval)
219  {
220  aRetval.Merge(aXCol, 255 - nDeltaX);
221  }
222 
223  // merge top/bottom neighbour with edge
224  if (aYCol != aXYCol)
225  {
226  aYCol.Merge(aXYCol, 255 - nDeltaX);
227  }
228 
229  // merge return value with already merged top/bottom neighbour
230  if (aRetval != aYCol)
231  {
232  aRetval.Merge(aYCol, 255 - nDeltaY);
233  }
234 
235  return aRetval;
236  }
237  }
238 
239  return rFallback;
240 }
241 
243  const BitmapColor& rFallback) const
244 {
245  // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
246  // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
247  if (mpBuffer && fX >= 0.0 && fY >= 0.0)
248  {
249  const sal_Int32 nX(static_cast<sal_Int32>(fX));
250  const sal_Int32 nY(static_cast<sal_Int32>(fY));
251 
252  if (nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
253  {
254  return GetColor(nY, nX);
255  }
256  }
257 
258  return rFallback;
259 }
260 
262  const ColorMask&)
263 {
264  return BitmapColor(pScanline[nX >> 3] & (1 << (7 - (nX & 7))) ? 1 : 0);
265 }
266 
268  const BitmapColor& rBitmapColor, const ColorMask&)
269 {
270  sal_uInt8& rByte = pScanline[nX >> 3];
271 
272  if (rBitmapColor.GetIndex() & 1)
273  rByte |= 1 << (7 - (nX & 7));
274  else
275  rByte &= ~(1 << (7 - (nX & 7)));
276 }
277 
279  const ColorMask&)
280 {
281  return BitmapColor(pScanline[nX >> 3] & (1 << (nX & 7)) ? 1 : 0);
282 }
283 
285  const BitmapColor& rBitmapColor, const ColorMask&)
286 {
287  sal_uInt8& rByte = pScanline[nX >> 3];
288 
289  if (rBitmapColor.GetIndex() & 1)
290  rByte |= 1 << (nX & 7);
291  else
292  rByte &= ~(1 << (nX & 7));
293 }
294 
296  const ColorMask&)
297 {
298  return BitmapColor((pScanline[nX >> 1] >> (nX & 1 ? 0 : 4)) & 0x0f);
299 }
300 
302  const BitmapColor& rBitmapColor, const ColorMask&)
303 {
304  sal_uInt8& rByte = pScanline[nX >> 1];
305 
306  if (nX & 1)
307  {
308  rByte &= 0xf0;
309  rByte |= (rBitmapColor.GetIndex() & 0x0f);
310  }
311  else
312  {
313  rByte &= 0x0f;
314  rByte |= (rBitmapColor.GetIndex() << 4);
315  }
316 }
317 
319  const ColorMask&)
320 {
321  return BitmapColor((pScanline[nX >> 1] >> (nX & 1 ? 4 : 0)) & 0x0f);
322 }
323 
325  const BitmapColor& rBitmapColor, const ColorMask&)
326 {
327  sal_uInt8& rByte = pScanline[nX >> 1];
328 
329  if (nX & 1)
330  {
331  rByte &= 0x0f;
332  rByte |= (rBitmapColor.GetIndex() << 4);
333  }
334  else
335  {
336  rByte &= 0xf0;
337  rByte |= (rBitmapColor.GetIndex() & 0x0f);
338  }
339 }
340 
342  const ColorMask&)
343 {
344  return BitmapColor(pScanline[nX]);
345 }
346 
348  const BitmapColor& rBitmapColor, const ColorMask&)
349 {
350  pScanline[nX] = rBitmapColor.GetIndex();
351 }
352 
354  const ColorMask&)
355 {
356  BitmapColor aBitmapColor;
357 
358  pScanline = pScanline + nX * 3;
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 * 3;
370  *pScanline++ = rBitmapColor.GetBlue();
371  *pScanline++ = rBitmapColor.GetGreen();
372  *pScanline = rBitmapColor.GetRed();
373 }
374 
376  const ColorMask&)
377 {
378  BitmapColor aBitmapColor;
379 
380  pScanline = pScanline + nX * 3;
381  aBitmapColor.SetRed(*pScanline++);
382  aBitmapColor.SetGreen(*pScanline++);
383  aBitmapColor.SetBlue(*pScanline);
384 
385  return aBitmapColor;
386 }
387 
389  const BitmapColor& rBitmapColor, const ColorMask&)
390 {
391  pScanline = pScanline + nX * 3;
392  *pScanline++ = rBitmapColor.GetRed();
393  *pScanline++ = rBitmapColor.GetGreen();
394  *pScanline = rBitmapColor.GetBlue();
395 }
396 
398  const ColorMask&)
399 {
400  pScanline = pScanline + nX * 4;
401 
402  sal_uInt8 a = *pScanline++;
403  sal_uInt8 b = *pScanline++;
404  sal_uInt8 g = *pScanline++;
405  sal_uInt8 r = *pScanline;
406 
409 }
410 
412  const ColorMask&)
413 {
414  BitmapColor aBitmapColor;
415 
416  pScanline = pScanline + (nX << 2) + 1;
417  aBitmapColor.SetBlue(*pScanline++);
418  aBitmapColor.SetGreen(*pScanline++);
419  aBitmapColor.SetRed(*pScanline);
420 
421  return aBitmapColor;
422 }
423 
425  const BitmapColor& rBitmapColor, const ColorMask&)
426 {
427  pScanline = pScanline + nX * 4;
428 
429  sal_uInt8 alpha = rBitmapColor.GetAlpha();
430  *pScanline++ = alpha;
431  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
432  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
433  *pScanline = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
434 }
435 
437  const BitmapColor& rBitmapColor, const ColorMask&)
438 {
439  pScanline = pScanline + (nX << 2);
440  *pScanline++ = 0xFF;
441  *pScanline++ = rBitmapColor.GetBlue();
442  *pScanline++ = rBitmapColor.GetGreen();
443  *pScanline = rBitmapColor.GetRed();
444 }
445 
447  const ColorMask&)
448 {
449  pScanline = pScanline + nX * 4;
450 
451  sal_uInt8 a = *pScanline++;
452  sal_uInt8 r = *pScanline++;
453  sal_uInt8 g = *pScanline++;
454  sal_uInt8 b = *pScanline;
455 
458 }
459 
461  const ColorMask&)
462 {
463  BitmapColor aBitmapColor;
464 
465  pScanline = pScanline + (nX << 2) + 1;
466  aBitmapColor.SetRed(*pScanline++);
467  aBitmapColor.SetGreen(*pScanline++);
468  aBitmapColor.SetBlue(*pScanline);
469 
470  return aBitmapColor;
471 }
472 
474  const BitmapColor& rBitmapColor, const ColorMask&)
475 {
476  pScanline = pScanline + nX * 4;
477 
478  sal_uInt8 alpha = rBitmapColor.GetAlpha();
479  *pScanline++ = alpha;
480  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
481  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
482  *pScanline = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
483 }
484 
486  const BitmapColor& rBitmapColor, const ColorMask&)
487 {
488  pScanline = pScanline + (nX << 2);
489  *pScanline++ = 0xFF;
490  *pScanline++ = rBitmapColor.GetRed();
491  *pScanline++ = rBitmapColor.GetGreen();
492  *pScanline = rBitmapColor.GetBlue();
493 }
494 
496  const ColorMask&)
497 {
498  pScanline = pScanline + nX * 4;
499 
500  sal_uInt8 b = *pScanline++;
501  sal_uInt8 g = *pScanline++;
502  sal_uInt8 r = *pScanline++;
503  sal_uInt8 a = *pScanline;
504 
507 }
508 
510  const ColorMask&)
511 {
512  BitmapColor aBitmapColor;
513 
514  pScanline = pScanline + (nX << 2);
515  aBitmapColor.SetBlue(*pScanline++);
516  aBitmapColor.SetGreen(*pScanline++);
517  aBitmapColor.SetRed(*pScanline);
518 
519  return aBitmapColor;
520 }
521 
523  const BitmapColor& rBitmapColor, const ColorMask&)
524 {
525  pScanline = pScanline + nX * 4;
526 
527  sal_uInt8 alpha = rBitmapColor.GetAlpha();
528  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
529  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
530  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
531  *pScanline = alpha;
532 }
533 
535  const BitmapColor& rBitmapColor, const ColorMask&)
536 {
537  pScanline = pScanline + (nX << 2);
538  *pScanline++ = rBitmapColor.GetBlue();
539  *pScanline++ = rBitmapColor.GetGreen();
540  *pScanline++ = rBitmapColor.GetRed();
541  *pScanline = 0xFF;
542 }
543 
545  const ColorMask&)
546 {
547  pScanline = pScanline + nX * 4;
548 
549  sal_uInt8 r = *pScanline++;
550  sal_uInt8 g = *pScanline++;
551  sal_uInt8 b = *pScanline++;
552  sal_uInt8 a = *pScanline;
553 
556 }
557 
559  const ColorMask&)
560 {
561  BitmapColor aBitmapColor;
562 
563  pScanline = pScanline + (nX << 2);
564  aBitmapColor.SetRed(*pScanline++);
565  aBitmapColor.SetGreen(*pScanline++);
566  aBitmapColor.SetBlue(*pScanline);
567 
568  return aBitmapColor;
569 }
570 
572  const BitmapColor& rBitmapColor, const ColorMask&)
573 {
574  pScanline = pScanline + nX * 4;
575 
576  sal_uInt8 alpha = rBitmapColor.GetAlpha();
577  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
578  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
579  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
580  *pScanline = alpha;
581 }
582 
584  const BitmapColor& rBitmapColor, const ColorMask&)
585 {
586  pScanline = pScanline + (nX << 2);
587  *pScanline++ = rBitmapColor.GetRed();
588  *pScanline++ = rBitmapColor.GetGreen();
589  *pScanline++ = rBitmapColor.GetBlue();
590  *pScanline = 0xFF;
591 }
592 
594  const ColorMask& rMask)
595 {
596  BitmapColor aColor;
597  rMask.GetColorFor32Bit(aColor, pScanline + (nX << 2));
598  return aColor;
599 }
600 
602  const BitmapColor& rBitmapColor,
603  const ColorMask& rMask)
604 {
605  rMask.SetColorFor32Bit(rBitmapColor, pScanline + (nX << 2));
606 }
607 
608 /* 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)
static BitmapColor GetPixelForN4BitLsnPal(ConstScanline pScanline, tools::Long nX, 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
Definition: bitmap.hxx:525
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:28
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
static void SetPixelForN4BitMsnPal(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:74
sal_uInt8 * Scanline
Definition: Scanline.hxx:25
static BitmapColor GetPixelForN4BitMsnPal(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
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
virtual std::shared_ptr< vcl::BackendCapabilities > GetBackendCapabilities()
Definition: salinst.hxx:132
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)
FncSetPixel mFncSetPixel
const sal_uInt8 * ConstScanline
Definition: Scanline.hxx:26
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:56
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 SetPixelForN4BitLsnPal(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:383
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