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  {
68  return GetPixelForN8BitPal;
76  else
81  else
86  else
91  else
95 
96  default:
97  return nullptr;
98  }
99 }
100 
102 {
103  switch (RemoveScanline(nFormat))
104  {
106  return SetPixelForN1BitMsbPal;
108  return SetPixelForN1BitLsbPal;
110  return SetPixelForN8BitPal;
112  return SetPixelForN24BitTcBgr;
114  return SetPixelForN24BitTcRgb;
118  else
123  else
128  else
133  else
137 
138  default:
139  return nullptr;
140  }
141 }
142 
144  const BitmapColor& rFallback) const
145 {
146  // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
147  // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
148  if (mpBuffer && fX >= 0.0 && fY >= 0.0)
149  {
150  const sal_Int64 nX(static_cast<sal_Int64>(fX));
151  const sal_Int64 nY(static_cast<sal_Int64>(fY));
152 
153  if (nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
154  {
155  // get base-return value from inside pixel
156  BitmapColor aRetval(GetColor(nY, nX));
157 
158  // calculate deltas and indices for neighbour accesses
159  sal_Int16 nDeltaX((fX - (nX + 0.5)) * 255.0); // [-255 .. 255]
160  sal_Int16 nDeltaY((fY - (nY + 0.5)) * 255.0); // [-255 .. 255]
161  sal_Int16 nIndX(0);
162  sal_Int16 nIndY(0);
163 
164  if (nDeltaX > 0)
165  {
166  nIndX = nX + 1;
167  }
168  else
169  {
170  nIndX = nX - 1;
171  nDeltaX = -nDeltaX;
172  }
173 
174  if (nDeltaY > 0)
175  {
176  nIndY = nY + 1;
177  }
178  else
179  {
180  nIndY = nY - 1;
181  nDeltaY = -nDeltaY;
182  }
183 
184  // get right/left neighbour
185  BitmapColor aXCol(rFallback);
186 
187  if (nDeltaX && nIndX >= 0 && nIndX < mpBuffer->mnWidth)
188  {
189  aXCol = GetColor(nY, nIndX);
190  }
191 
192  // get top/bottom neighbour
193  BitmapColor aYCol(rFallback);
194 
195  if (nDeltaY && nIndY >= 0 && nIndY < mpBuffer->mnHeight)
196  {
197  aYCol = GetColor(nIndY, nX);
198  }
199 
200  // get one of four edge neighbours
201  BitmapColor aXYCol(rFallback);
202 
203  if (nDeltaX && nDeltaY && nIndX >= 0 && nIndY >= 0 && nIndX < mpBuffer->mnWidth
204  && nIndY < mpBuffer->mnHeight)
205  {
206  aXYCol = GetColor(nIndY, nIndX);
207  }
208 
209  // merge return value with right/left neighbour
210  if (aXCol != aRetval)
211  {
212  aRetval.Merge(aXCol, 255 - nDeltaX);
213  }
214 
215  // merge top/bottom neighbour with edge
216  if (aYCol != aXYCol)
217  {
218  aYCol.Merge(aXYCol, 255 - nDeltaX);
219  }
220 
221  // merge return value with already merged top/bottom neighbour
222  if (aRetval != aYCol)
223  {
224  aRetval.Merge(aYCol, 255 - nDeltaY);
225  }
226 
227  return aRetval;
228  }
229  }
230 
231  return rFallback;
232 }
233 
235  const BitmapColor& rFallback) const
236 {
237  // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
238  // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
239  if (mpBuffer && fX >= 0.0 && fY >= 0.0)
240  {
241  const sal_Int32 nX(static_cast<sal_Int32>(fX));
242  const sal_Int32 nY(static_cast<sal_Int32>(fY));
243 
244  if (nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
245  {
246  return GetColor(nY, nX);
247  }
248  }
249 
250  return rFallback;
251 }
252 
254  const ColorMask&)
255 {
256  return BitmapColor(pScanline[nX >> 3] & (1 << (7 - (nX & 7))) ? 1 : 0);
257 }
258 
260  const BitmapColor& rBitmapColor, const ColorMask&)
261 {
262  sal_uInt8& rByte = pScanline[nX >> 3];
263 
264  if (rBitmapColor.GetIndex() & 1)
265  rByte |= 1 << (7 - (nX & 7));
266  else
267  rByte &= ~(1 << (7 - (nX & 7)));
268 }
269 
271  const ColorMask&)
272 {
273  return BitmapColor(pScanline[nX >> 3] & (1 << (nX & 7)) ? 1 : 0);
274 }
275 
277  const BitmapColor& rBitmapColor, const ColorMask&)
278 {
279  sal_uInt8& rByte = pScanline[nX >> 3];
280 
281  if (rBitmapColor.GetIndex() & 1)
282  rByte |= 1 << (nX & 7);
283  else
284  rByte &= ~(1 << (nX & 7));
285 }
286 
288  const ColorMask&)
289 {
290  return BitmapColor(pScanline[nX]);
291 }
292 
294  const BitmapColor& rBitmapColor, const ColorMask&)
295 {
296  pScanline[nX] = rBitmapColor.GetIndex();
297 }
298 
300  const ColorMask&)
301 {
302  BitmapColor aBitmapColor;
303 
304  pScanline = pScanline + nX * 3;
305  aBitmapColor.SetBlue(*pScanline++);
306  aBitmapColor.SetGreen(*pScanline++);
307  aBitmapColor.SetRed(*pScanline);
308 
309  return aBitmapColor;
310 }
311 
313  const BitmapColor& rBitmapColor, const ColorMask&)
314 {
315  pScanline = pScanline + nX * 3;
316  *pScanline++ = rBitmapColor.GetBlue();
317  *pScanline++ = rBitmapColor.GetGreen();
318  *pScanline = rBitmapColor.GetRed();
319 }
320 
322  const ColorMask&)
323 {
324  BitmapColor aBitmapColor;
325 
326  pScanline = pScanline + nX * 3;
327  aBitmapColor.SetRed(*pScanline++);
328  aBitmapColor.SetGreen(*pScanline++);
329  aBitmapColor.SetBlue(*pScanline);
330 
331  return aBitmapColor;
332 }
333 
335  const BitmapColor& rBitmapColor, const ColorMask&)
336 {
337  pScanline = pScanline + nX * 3;
338  *pScanline++ = rBitmapColor.GetRed();
339  *pScanline++ = rBitmapColor.GetGreen();
340  *pScanline = rBitmapColor.GetBlue();
341 }
342 
344  const ColorMask&)
345 {
346  pScanline = pScanline + nX * 4;
347 
348  sal_uInt8 a = *pScanline++;
349  sal_uInt8 b = *pScanline++;
350  sal_uInt8 g = *pScanline++;
351  sal_uInt8 r = *pScanline;
352 
355 }
356 
358  const ColorMask&)
359 {
360  BitmapColor aBitmapColor;
361 
362  pScanline = pScanline + (nX << 2) + 1;
363  aBitmapColor.SetBlue(*pScanline++);
364  aBitmapColor.SetGreen(*pScanline++);
365  aBitmapColor.SetRed(*pScanline);
366 
367  return aBitmapColor;
368 }
369 
371  const BitmapColor& rBitmapColor, const ColorMask&)
372 {
373  pScanline = pScanline + nX * 4;
374 
375  sal_uInt8 alpha = rBitmapColor.GetAlpha();
376  *pScanline++ = alpha;
377  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
378  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
379  *pScanline = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
380 }
381 
383  const BitmapColor& rBitmapColor, const ColorMask&)
384 {
385  pScanline = pScanline + (nX << 2);
386  *pScanline++ = 0xFF;
387  *pScanline++ = rBitmapColor.GetBlue();
388  *pScanline++ = rBitmapColor.GetGreen();
389  *pScanline = rBitmapColor.GetRed();
390 }
391 
393  const ColorMask&)
394 {
395  pScanline = pScanline + nX * 4;
396 
397  sal_uInt8 a = *pScanline++;
398  sal_uInt8 r = *pScanline++;
399  sal_uInt8 g = *pScanline++;
400  sal_uInt8 b = *pScanline;
401 
404 }
405 
407  const ColorMask&)
408 {
409  BitmapColor aBitmapColor;
410 
411  pScanline = pScanline + (nX << 2) + 1;
412  aBitmapColor.SetRed(*pScanline++);
413  aBitmapColor.SetGreen(*pScanline++);
414  aBitmapColor.SetBlue(*pScanline);
415 
416  return aBitmapColor;
417 }
418 
420  const BitmapColor& rBitmapColor, const ColorMask&)
421 {
422  pScanline = pScanline + nX * 4;
423 
424  sal_uInt8 alpha = rBitmapColor.GetAlpha();
425  *pScanline++ = alpha;
426  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
427  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
428  *pScanline = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
429 }
430 
432  const BitmapColor& rBitmapColor, const ColorMask&)
433 {
434  pScanline = pScanline + (nX << 2);
435  *pScanline++ = 0xFF;
436  *pScanline++ = rBitmapColor.GetRed();
437  *pScanline++ = rBitmapColor.GetGreen();
438  *pScanline = rBitmapColor.GetBlue();
439 }
440 
442  const ColorMask&)
443 {
444  pScanline = pScanline + nX * 4;
445 
446  sal_uInt8 b = *pScanline++;
447  sal_uInt8 g = *pScanline++;
448  sal_uInt8 r = *pScanline++;
449  sal_uInt8 a = *pScanline;
450 
453 }
454 
456  const ColorMask&)
457 {
458  BitmapColor aBitmapColor;
459 
460  pScanline = pScanline + (nX << 2);
461  aBitmapColor.SetBlue(*pScanline++);
462  aBitmapColor.SetGreen(*pScanline++);
463  aBitmapColor.SetRed(*pScanline);
464 
465  return aBitmapColor;
466 }
467 
469  const BitmapColor& rBitmapColor, const ColorMask&)
470 {
471  pScanline = pScanline + nX * 4;
472 
473  sal_uInt8 alpha = rBitmapColor.GetAlpha();
474  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
475  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
476  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
477  *pScanline = alpha;
478 }
479 
481  const BitmapColor& rBitmapColor, const ColorMask&)
482 {
483  pScanline = pScanline + (nX << 2);
484  *pScanline++ = rBitmapColor.GetBlue();
485  *pScanline++ = rBitmapColor.GetGreen();
486  *pScanline++ = rBitmapColor.GetRed();
487  *pScanline = 0xFF;
488 }
489 
491  const ColorMask&)
492 {
493  pScanline = pScanline + nX * 4;
494 
495  sal_uInt8 r = *pScanline++;
496  sal_uInt8 g = *pScanline++;
497  sal_uInt8 b = *pScanline++;
498  sal_uInt8 a = *pScanline;
499 
502 }
503 
505  const ColorMask&)
506 {
507  BitmapColor aBitmapColor;
508 
509  pScanline = pScanline + (nX << 2);
510  aBitmapColor.SetRed(*pScanline++);
511  aBitmapColor.SetGreen(*pScanline++);
512  aBitmapColor.SetBlue(*pScanline);
513 
514  return aBitmapColor;
515 }
516 
518  const BitmapColor& rBitmapColor, const ColorMask&)
519 {
520  pScanline = pScanline + nX * 4;
521 
522  sal_uInt8 alpha = rBitmapColor.GetAlpha();
523  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
524  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
525  *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
526  *pScanline = alpha;
527 }
528 
530  const BitmapColor& rBitmapColor, const ColorMask&)
531 {
532  pScanline = pScanline + (nX << 2);
533  *pScanline++ = rBitmapColor.GetRed();
534  *pScanline++ = rBitmapColor.GetGreen();
535  *pScanline++ = rBitmapColor.GetBlue();
536  *pScanline = 0xFF;
537 }
538 
540  const ColorMask& rMask)
541 {
542  BitmapColor aColor;
543  rMask.GetColorFor32Bit(aColor, pScanline + (nX << 2));
544  return aColor;
545 }
546 
548  const BitmapColor& rBitmapColor,
549  const ColorMask& rMask)
550 {
551  rMask.SetColorFor32Bit(rBitmapColor, pScanline + (nX << 2));
552 }
553 
554 /* 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
Definition: bitmap.hxx:522
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:74
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
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: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: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