ADTF Display Toolbox
Loading...
Searching...
No Matches
image.h
Go to the documentation of this file.
1
7#pragma once
8
9#include <adtf_base.h>
13
14#ifdef WIN32
15 #include <windows.h>
16#endif
17
18#ifdef max
19 #undef max
20#endif
21#include <algorithm>
22
23#ifdef GetObject
24 #undef GetObject
25#endif
26
27namespace adtf
28{
29
30namespace disptb
31{
32
33namespace graphicslib
34{
35
36namespace dengar
37{
38class cColor;
39
40#ifndef WIN32
41typedef tUInt32 DWORD_PTR;
42#endif // WIN32
43
44#define ALPHA_DEFAULT 0
45
46// Converts 8-bit R, G, and B values to 16-bit RGB565 color depth
47#define RGB565(R, G, B) (tUInt16)(((((tUInt16) B) >> 3) << 11) | ((((tUInt16) G) >> 2) << 5) | (((tUInt16) R) >> 3))
48#define GetRed_RGB565(RGB) (((RGB) & 0x1F) << 3)
49#define GetGreen_RGB565(RGB) ((((RGB) >> 5) & 0x3F) << 2)
50#define GetBlue_RGB565(RGB) (((RGB) >> 11) << 3)
51
52#define BGR565(R, G, B) (tUInt16)(((((tUInt16) R) >> 3) << 11) | ((((tUInt16) G) >> 2) << 5) | (((tUInt16) B) >> 3))
53#define GetRed_BGR565(RGB) (((RGB) >> 11) << 3)
54#define GetGreen_BGR565(RGB) ((((RGB) >> 5) & 0x3F) << 2)
55#define GetBlue_BGR565(RGB) (((RGB) & 0x1F) << 3)
56
57#define RGB555(R, G, B) (tUInt16)(((((tUInt16) B) >> 3) << 10) | ((((tUInt16) G) >> 3) << 5) | (((tUInt16) R) >> 3))
58#define GetRed_RGB555(RGB) (((RGB) & 0x1F) << 3)
59#define GetGreen_RGB555(RGB) ((((RGB) >> 5) & 0x1F) << 3)
60#define GetBlue_RGB555(RGB) (((RGB) >> 10) << 3)
61
62#define BGR555(R, G, B) (tUInt16)(((((tUInt16) R) >> 3) << 10) | ((((tUInt16) G) >> 3) << 5) | (((tUInt16) B) >> 3))
63#define GetRed_BGR555(RGB) (((RGB) >> 10) << 3)
64#define GetGreen_BGR555(RGB) ((((RGB) >> 5) & 0x1F) << 3)
65#define GetBlue_BGR555(RGB) (((RGB) & 0x1F) << 3)
66
67#define RGBA4444(R, G, B, A) \
68 (tUInt16)(((((tUInt16) A) >> 4) << 12) | ((((tUInt16) B) >> 4) << 8) | ((((tUInt16) G) >> 4) << 4) | \
69 (((tUInt16) R) >> 4))
70#define GetRed_RGBA4444(RGB) (((RGB) & 0xf) << 4)
71#define GetGreen_RGBA4444(RGB) ((RGB) & 0xf0)
72#define GetBlue_RGBA4444(RGB) (((RGB) & 0xf00) >> 4)
73#define GetAlpha_RGBA4444(RGB) (((RGB) & 0xf000) >> 8)
74
75#define ABGR4444(R, G, B, A) \
76 (tUInt16)(((((tUInt16) R) >> 4) << 12) | ((((tUInt16) G) >> 4) << 8) | ((((tUInt16) B) >> 4) << 4) | \
77 (((tUInt16) A) >> 4))
78#define GetRed_ABGR4444(RGB) (((RGB) & 0xf000) >> 8)
79#define GetGreen_ABGR4444(RGB) (((RGB) & 0xf00) >> 4)
80#define GetBlue_ABGR4444(RGB) ((RGB) & 0xf0)
81#define GetAlpha_ABGR4444(RGB) (((RGB) & 0xf) << 4)
82
83#define GET_REMAINDER(v, v1, v2, max) ((((max) + 1) * (v) * (v2)) / (v1) - ((max) + 1) * (((v) * (v2)) / (v1)))
84
85#pragma pack(push)
86#pragma pack(1)
90typedef struct
91{
92 tUInt16 ui16Type;
94 tUInt32 ui32Size;
95 tUInt16 ui16Reserved1;
96 tUInt16 ui16Reserved2;
99
100#pragma pack(pop)
101
107class cImage : public IImage
108{
109public:
112
113protected:
115
119
120 tColor* m_pPalette;
121 tUInt8* m_pBitmap;
123
125
126public:
131 {
132 Initialize();
133 }
134
139 cImage(const cImage& oImage): cImage(static_cast<const IImage&>(oImage))
140 {
141 }
142
147 cImage(const IImage& oImage)
148 {
149 Initialize();
150 Create(oImage.GetWidth(), oImage.GetHeight(), oImage.GetBitsPerPixel(), oImage.GetBytesPerLine(),
151 oImage.GetBitmap(), oImage.GetPixelFormat());
152 }
153
157 virtual ~cImage()
158 {
159 Free();
160 }
161
165 tVoid Destroy()
166 {
167 delete this;
168 }
169
186 tResult Create(tInt nWidth,
187 tInt nHeight,
188 tInt nBitsPerPixel,
189 tInt nBytesPerLine = 0,
190 const tUInt8* pBitmap = nullptr,
191 tInt nPixelFormat = 0)
192 {
193 Release();
194
195 tBitmapFormat l_sFormat;
196
197 l_sFormat.nPixelFormat = (nPixelFormat != 0) ? static_cast<int16_t>(nPixelFormat) :
198 static_cast<int16_t>(GetDefaultFormatFromBpp(nBitsPerPixel));
199 l_sFormat.nWidth = nWidth;
200 l_sFormat.nHeight = nHeight;
201 l_sFormat.nBitsPerPixel = static_cast<int16_t>(nBitsPerPixel);
202 l_sFormat.nBytesPerLine = nBytesPerLine;
203 if (l_sFormat.nBytesPerLine == 0)
204 {
205 l_sFormat.nBytesPerLine =
207 }
208 l_sFormat.nSize = l_sFormat.nBytesPerLine * l_sFormat.nHeight;
209 l_sFormat.nPaletteSize = 0;
210
211 RETURN_IF_FAILED(Create(&l_sFormat, NULL, pBitmap));
212
213 RETURN_NOERROR;
214 }
215
230 tResult Create(const tBitmapFormat* psFormat, const tColor* pPalette = nullptr, const tUInt8* pBitmap = nullptr)
231 {
232 Release();
233
234 RETURN_IF_POINTER_NULL(psFormat);
235
236 RETURN_IF_FAILED(Alloc(psFormat));
237
238 if (pPalette != NULL)
239 {
240 RETURN_IF_FAILED(SetPalette(psFormat->nPaletteSize, pPalette));
241 }
242 else if (psFormat->nBitsPerPixel <= 8)
243 {
244 // create greyscale palette
245 m_sFormat.nPixelFormat = PF_GREYSCALE_8;
246
247 RETURN_IF_FAILED(SetPalette((1 << 8), NULL));
248 }
249 else if (m_sFormat.nPixelFormat == PF_UNKNOWN)
250 {
251 m_sFormat.nPixelFormat = static_cast<int16_t>(GetDefaultFormatFromBpp(psFormat->nBitsPerPixel));
252 }
253
254 if (pBitmap != NULL)
255 {
256 SetBits(pBitmap, psFormat);
257 }
258
259 RETURN_NOERROR;
260 }
261
276 tResult Attach(tUInt8* pBitmap, tInt nWidth, tInt nHeight, tInt nBitsPerPixel, tInt nBytesPerLine = 0)
277 {
278 Release();
279
280 RETURN_IF_POINTER_NULL(pBitmap);
281
282 tBitmapFormat l_sFormat;
283
284 l_sFormat.nPixelFormat = static_cast<int16_t>(GetDefaultFormatFromBpp(nBitsPerPixel));
285 l_sFormat.nWidth = nWidth;
286 l_sFormat.nHeight = nHeight;
287 l_sFormat.nBitsPerPixel = static_cast<int16_t>(nBitsPerPixel);
288 l_sFormat.nBytesPerLine = nBytesPerLine;
289 if (l_sFormat.nBytesPerLine == 0)
290 {
291 l_sFormat.nBytesPerLine = l_sFormat.nWidth * l_sFormat.nBitsPerPixel / 8;
292 }
293 l_sFormat.nSize = l_sFormat.nBytesPerLine * l_sFormat.nHeight;
294 l_sFormat.nPaletteSize = 0;
295
296 RETURN_IF_FAILED(Attach(pBitmap, &l_sFormat, NULL));
297
298 RETURN_NOERROR;
299 }
300
315 tResult Attach(tUInt8* pBitmap, const tBitmapFormat* psFormat, const tColor* pPalette = nullptr)
316 {
317 Release();
318
319 RETURN_IF_POINTER_NULL(pBitmap);
320 RETURN_IF_POINTER_NULL(psFormat);
321
322 adtf::util::cMemoryBlock::MemCopy(&m_sFormat, psFormat, sizeof(m_sFormat));
323 m_pBitmap = pBitmap;
324 m_bReference = tTrue;
325
326 if (pPalette != NULL)
327 {
328 RETURN_IF_FAILED(SetPalette(psFormat->nPaletteSize, pPalette));
329 }
330 else if (psFormat->nBitsPerPixel <= 8)
331 {
332 // greyscale palette
333 m_sFormat.nPixelFormat = PF_GREYSCALE_8;
334
335 RETURN_IF_FAILED(SetPalette((1 << 8), NULL));
336 }
337 else if (m_sFormat.nPixelFormat == 0)
338 {
339 m_sFormat.nPixelFormat = static_cast<int16_t>(GetDefaultFormatFromBpp(m_sFormat.nBitsPerPixel));
340 }
341
342 RETURN_NOERROR;
343 }
344
364 tResult Load(const tChar* strFile, tUInt32 nFlags = 0)
365 {
366 Release();
367 RETURN_IF_POINTER_NULL(strFile)
368 // File Format:
369 // 1) tBitmapFileHeader
370 // 2) tWin32BitmapInfoHeader
371 // 3) Palette
372 // 4) Bitmap Data
373
374 adtf::util::cFile oFile;
375 RETURN_IF_FAILED(oFile.Open(strFile, adtf::util::cFile::OM_Read))
376
377 tBitmapFileHeader sFileHeader;
378 RETURN_IF_FAILED(oFile.ReadAll(&sFileHeader, sizeof(sFileHeader)))
379
380 if (sFileHeader.ui16Type != 0x4D42) // always "BM"
381 {
382 RETURN_ERROR(ERR_INVALID_FILE);
383 }
384
385 tWin32BitmapInfoHeader sBitmapHeader;
386 RETURN_IF_FAILED(oFile.ReadAll(&sBitmapHeader, sizeof(sBitmapHeader)));
387
388 if (sBitmapHeader.nBitCount < 8)
389 {
390 // file formats with a bit depth less than 8 are not supported, yet.
391 RETURN_ERROR(ERR_NOT_SUPPORTED);
392 }
393
394 // bitmaps are always DWORD-aligned
395 tUInt16 nBytesPerLine =
396 static_cast<uint16_t>(CalcAlignedMemSize((sBitmapHeader.nWidth * sBitmapHeader.nBitCount) / 8, 4));
397
398 RETURN_IF_FAILED(
399 Create(sBitmapHeader.nWidth, sBitmapHeader.nHeight, sBitmapHeader.nBitCount, nBytesPerLine, NULL));
400
401 if (sBitmapHeader.nBitCount == 8)
402 {
403 tInt nPaletteBytes = std::max<tInt>(m_nGreyPaletteSize, GetPaletteSize()) * sizeof(tColor);
404 RETURN_IF_FAILED(oFile.ReadAll(m_pPalette, nPaletteBytes));
405 }
406
407 if (oFile.SetFilePos(sFileHeader.ui32DataOffset, adtf::util::cFile::FP_Begin) == -1)
408 {
409 RETURN_ERROR(ERR_INVALID_FILE);
410 }
411
412 RETURN_IF_FAILED(oFile.ReadAll(m_pBitmap, m_sFormat.nSize));
413
414 // windows bitmaps are always R
415 if (m_sFormat.nBitsPerPixel >= 24)
416 {
417 if (m_sFormat.nBitsPerPixel == 24)
418 {
419 m_sFormat.nPixelFormat = PF_BGR_888;
420 RETURN_IF_FAILED(Convert(PF_RGB_888));
421 }
422 if (m_sFormat.nBitsPerPixel == 32)
423 {
424 m_sFormat.nPixelFormat = PF_BGRA_8888;
425 RETURN_IF_FAILED(Convert(PF_RGBA_8888));
426 }
427
428 // this flag is ignored, since it is not longer needed
429 // the bitmap is loaded now with the correct format
430 // if (LF_SWAP_RGB == (nFlags & LF_SWAP_RGB))
431 //{
432 // FlipRGB();
433 //}
434 }
435
436 if (0 == (nFlags & LF_FLIP_VERTICAL))
437 {
438 RETURN_IF_FAILED(Flip());
439 }
440
441 RETURN_NOERROR;
442 }
443
458 tResult Save(const tChar* strFile)
459 {
460 RETURN_IF_POINTER_NULL(m_pBitmap);
461
462 if (m_sFormat.nBitsPerPixel == 32)
463 {
464 if (m_sFormat.nPixelFormat == IImage::PF_32BIT)
465 {
466 m_sFormat.nPixelFormat = static_cast<int16_t>(GetDefaultFormatFromBpp(32));
467 }
468
469 if (m_sFormat.nPixelFormat != IImage::PF_BGRA_8888)
470 {
471 cImage oImg;
472 oImg.Create(m_sFormat.nWidth, m_sFormat.nHeight, m_sFormat.nBitsPerPixel, m_sFormat.nBytesPerLine,
473 GetBitmap(), m_sFormat.nPixelFormat);
474
475 RETURN_IF_FAILED(oImg.Convert(IImage::PF_BGRA_8888));
476 return oImg.Save(strFile);
477 }
478 }
479 else if (m_sFormat.nBitsPerPixel == 24)
480 {
481 if (m_sFormat.nPixelFormat == IImage::PF_24BIT)
482 {
483 m_sFormat.nPixelFormat = static_cast<int16_t>(GetDefaultFormatFromBpp(24));
484 }
485
486 if (m_sFormat.nPixelFormat != IImage::PF_BGR_888)
487 {
488 cImage oImg;
489 oImg.Create(m_sFormat.nWidth, m_sFormat.nHeight, m_sFormat.nBitsPerPixel, m_sFormat.nBytesPerLine,
490 GetBitmap(), m_sFormat.nPixelFormat);
491
492 if (m_sFormat.nPixelFormat == IImage::PF_YUV420P_888)
493 {
494 RETURN_IF_FAILED(oImg.ChangePixelFormat(IImage::PF_RGB_888));
495 RETURN_IF_FAILED(oImg.Convert(IImage::PF_BGR_888));
496 }
497 else
498 {
499 RETURN_IF_FAILED(oImg.Convert(IImage::PF_BGR_888));
500 }
501 return oImg.Save(strFile);
502 }
503 }
504 else
505 {
506 if (m_sFormat.nPixelFormat == IImage::PF_16BIT)
507 {
508 m_sFormat.nPixelFormat = static_cast<int16_t>(GetDefaultFormatFromBpp(16));
509 }
510 else if (m_sFormat.nPixelFormat == IImage::PF_8BIT)
511 {
512 m_sFormat.nPixelFormat = static_cast<int16_t>(GetDefaultFormatFromBpp(8));
513 }
514
515 cImage oImg;
516 oImg.Create(m_sFormat.nWidth, m_sFormat.nHeight, m_sFormat.nBitsPerPixel, m_sFormat.nBytesPerLine,
517 GetBitmap(), m_sFormat.nPixelFormat);
518
519 RETURN_IF_FAILED(oImg.ChangePixelFormat(IImage::PF_BGR_888));
520 return oImg.Save(strFile);
521 }
522
523 adtf::util::cFile oFile;
524 tResult nResult = oFile.Open(strFile, adtf::util::cFile::OM_Write);
525 if (IS_FAILED(nResult))
526 {
527 return nResult;
528 }
529
530 tInt l_nPaletteSize = m_sFormat.nPaletteSize;
531 if (l_nPaletteSize == 0 && m_pPalette)
532 {
533 l_nPaletteSize = m_nGreyPaletteSize;
534 }
535
536 tInt nPaletteBytes = l_nPaletteSize * sizeof(tColor);
537 tInt nBitmapBytes = m_sFormat.nSize;
538
539 tBitmapFileHeader sFileHeader;
540 sFileHeader.ui16Type = 0x4D42;
541 sFileHeader.ui32Size =
542 sizeof(tBitmapFileHeader) + sizeof(tWin32BitmapInfoHeader) + nPaletteBytes + nBitmapBytes;
543 sFileHeader.ui16Reserved1 = 0;
544 sFileHeader.ui16Reserved2 = 0;
545 sFileHeader.ui32DataOffset = sizeof(tBitmapFileHeader) + sizeof(tWin32BitmapInfoHeader) + nPaletteBytes;
546
547 nResult = oFile.WriteAll(&sFileHeader, sizeof(sFileHeader));
548 if (IS_FAILED(nResult))
549 {
550 oFile.Close();
551 return nResult;
552 }
553
554 tWin32BitmapInfo* pBitmapInfo = GetBitmapInfo();
555 nResult = oFile.WriteAll(&pBitmapInfo->sHeader, sizeof(tWin32BitmapInfoHeader));
556 if (IS_FAILED(nResult))
557 {
558 oFile.Close();
559 return nResult;
560 }
561
562 if (m_pPalette)
563 {
564 nResult = oFile.WriteAll(m_pPalette, nPaletteBytes);
565 if (IS_FAILED(nResult))
566 {
567 oFile.Close();
568 return nResult;
569 }
570 }
571
572 Flip();
573 nResult = oFile.WriteAll(m_pBitmap, nBitmapBytes);
574 Flip();
575
576 oFile.Close();
577 return nResult;
578 }
579
585 tResult Release()
586 {
587 Free();
588
589 RETURN_NOERROR;
590 }
591
599 tResult SetPixelFormat(tInt nPixelFormat)
600 {
601 m_sFormat.nPixelFormat = static_cast<int16_t>(nPixelFormat);
602
603 RETURN_NOERROR;
604 }
605
611 tInt GetPixelFormat() const
612 {
613 return m_sFormat.nPixelFormat;
614 }
615
623 char const* GetPixelFormatStr() const
624 {
626 }
627
635 static tInt FlipRGBFormat(tInt nPixelFormat)
636 {
637 switch (nPixelFormat)
638 {
639 case PF_RGBA_4444: return PF_ABGR_4444;
640 case PF_ABGR_4444: return PF_RGBA_4444;
641 case PF_RGB_555: return PF_BGR_555;
642 case PF_RGB_565: return PF_BGR_565;
643 case PF_BGR_555: return PF_RGB_555;
644 case PF_BGR_565: return PF_RGB_565;
645 case PF_RGB_888: return PF_BGR_888;
646 case PF_BGR_888: return PF_RGB_888;
647 case PF_ARGB_8888: return PF_ABGR_8888;
648 case PF_ABGR_8888: return PF_ARGB_8888;
649 case PF_RGBA_8888: return PF_BGRA_8888;
650 case PF_BGRA_8888: return PF_RGBA_8888;
651 case PF_UNKNOWN: return PF_BGR_888;
652 }
653 return nPixelFormat;
654 }
655
664 static tInt FlipToBGRFormat(tInt nPixelFormat)
665 {
666 switch (nPixelFormat)
667 {
668 case PF_RGBA_4444: return PF_ABGR_4444;
669 case PF_RGB_555: return PF_BGR_555;
670 case PF_RGB_565: return PF_BGR_565;
671 case PF_RGB_888: return PF_BGR_888;
672 case PF_ARGB_8888: return PF_ABGR_8888;
673 case PF_RGBA_8888: return PF_BGRA_8888;
674 case PF_UNKNOWN: return PF_BGR_888;
675 }
676 return nPixelFormat;
677 }
678
687 static tInt FlipToRGBFormat(tInt nPixelFormat)
688 {
689 switch (nPixelFormat)
690 {
691 case PF_ABGR_4444: return PF_RGBA_4444;
692 case PF_BGR_555: return PF_RGB_555;
693 case PF_BGR_565: return PF_RGB_565;
694 case PF_BGR_888: return PF_RGB_888;
695 case PF_ABGR_8888: return PF_ARGB_8888;
696 case PF_BGRA_8888: return PF_RGBA_8888;
697 case PF_UNKNOWN: return PF_RGB_888;
698 }
699 return nPixelFormat;
700 }
701
707 tInt GetWidth() const
708 {
709 return m_sFormat.nWidth;
710 }
711
717 tInt GetHeight() const
718 {
719 return m_sFormat.nHeight;
720 }
721
727 tInt GetBitsPerPixel() const
728 {
729 return m_sFormat.nBitsPerPixel;
730 }
731
739 tInt GetBytesPerLine() const
740 {
741 return m_sFormat.nBytesPerLine;
742 }
743
749 tInt GetSize() const
750 {
751 return m_sFormat.nSize;
752 }
753
759 tFloat64 GetRatio() const
760 {
761 tFloat64 l_fImageRatio = 1.0;
762 if (m_sFormat.nHeight != 0)
763 {
764 l_fImageRatio = (tFloat64) m_sFormat.nWidth / m_sFormat.nHeight;
765 }
766
767 return l_fImageRatio;
768 }
769
776 const tBitmapFormat* GetFormat() const override
777 {
778 return &m_sFormat;
779 }
780
791 tResult SetPalette(tInt nPaletteSize, const tColor* pPalette)
792 {
793 FreePalette();
794
795 if (m_sFormat.nBitsPerPixel != 8)
796 {
797 RETURN_ERROR(ERR_NOT_SUPPORTED);
798 }
799
800 if (nPaletteSize > 0)
801 {
802 RETURN_IF_FAILED(AllocPalette(nPaletteSize));
803
804 if (pPalette != NULL)
805 {
806 adtf::util::cMemoryBlock::MemCopy(m_pPalette, pPalette, nPaletteSize * sizeof(*pPalette));
807
808 m_sFormat.nPixelFormat = PF_RGB_8;
809 m_sFormat.nPaletteSize = nPaletteSize;
811 }
812 else
813 {
814 // initialize greyscale palette
815 tUInt8 l_nColValue;
816 for (tInt l_nIdx = 0; l_nIdx < nPaletteSize; l_nIdx++)
817 {
818 l_nColValue = (tUInt8) ((l_nIdx * 255) / nPaletteSize);
819 m_pPalette[l_nIdx].nRed = m_pPalette[l_nIdx].nGreen = m_pPalette[l_nIdx].nBlue =
820 (tUInt8) l_nColValue;
821 m_pPalette[l_nIdx].nAlpha = 0;
822 }
823
824 m_sFormat.nPixelFormat = PF_GREYSCALE_8;
825 m_sFormat.nPaletteSize = 0;
826 m_nGreyPaletteSize = nPaletteSize;
827 }
828 }
829
830 RETURN_NOERROR;
831 }
832
838 tColor* GetPalette() const
839 {
840 return m_pPalette;
841 }
842
848 tInt GetPaletteSize() const
849 {
850 return m_sFormat.nPaletteSize;
851 }
852
860 tColor GetPaletteEntry(tInt nIdx) const
861 {
862 if (nIdx >= 0 && nIdx < m_sFormat.nPaletteSize)
863 {
864 return m_pPalette[nIdx];
865 }
866
867 tColor l_sCol = {0, 0, 0, 0};
868 return l_sCol;
869 }
870
880 tResult SetPaletteEntry(tInt nIdx, const tColor& sColor)
881 {
882 if (nIdx >= 0 && nIdx < m_sFormat.nPaletteSize)
883 {
884 m_pPalette[nIdx] = sColor;
885
886 RETURN_NOERROR;
887 }
888
889 RETURN_ERROR(ERR_INVALID_ARG);
890 }
891
897 tUInt8* GetBitmap() const
898 {
899 return m_pBitmap;
900 }
901
911 tUInt8* GetBitmapLine(tInt y) const
912 {
913 return m_pBitmap + (y * m_sFormat.nBytesPerLine);
914 }
915
924 {
925 if (m_psBitmapInfo == NULL)
926 {
927 if (IS_FAILED(AllocBitmapInfo()))
928 {
929 return NULL;
930 }
931 }
932
933 return m_psBitmapInfo;
934 }
935
942 {
943 if (0 == m_nBitmapInfoSize)
944 {
946 }
947 return m_nBitmapInfoSize;
948 }
949
955 operator IImage*()
956 {
957 return dynamic_cast<IImage*>(this);
958 }
959
960public: // image manipulation
969 tResult Flip()
970 {
971 RETURN_IF_POINTER_NULL(m_pBitmap);
972 if (m_sFormat.nHeight < 1)
973 {
974 RETURN_ERROR(ERR_UNEXPECTED);
975 }
976
977 tUInt8* pLineBuffer = new tUInt8[m_sFormat.nBytesPerLine];
978 if (pLineBuffer == NULL)
979 {
980 RETURN_ERROR(ERR_MEMORY);
981 }
982
983 tInt nBytesPerLine = m_sFormat.nBytesPerLine;
984
985 tUInt8* pSrc = m_pBitmap;
986 tUInt8* pDest = m_pBitmap + (m_sFormat.nHeight - 1) * nBytesPerLine;
987
988 while (pSrc < pDest)
989 {
990 // swap lines...
991 adtf::util::cMemoryBlock::MemCopy(pLineBuffer, pSrc, nBytesPerLine);
992 adtf::util::cMemoryBlock::MemCopy(pSrc, pDest, nBytesPerLine);
993 adtf::util::cMemoryBlock::MemCopy(pDest, pLineBuffer, nBytesPerLine);
994
995 pSrc += m_sFormat.nBytesPerLine;
996 pDest -= m_sFormat.nBytesPerLine;
997 }
998
999 delete[] pLineBuffer;
1000 RETURN_NOERROR;
1001 }
1002
1010 tResult Mirror()
1011 {
1012 RETURN_IF_POINTER_NULL(m_pBitmap);
1013 if (m_sFormat.nWidth < 2)
1014 {
1015 RETURN_ERROR(ERR_UNEXPECTED);
1016 }
1017
1018 tUInt8 ui8Buf;
1019 tUInt16 ui16Buf;
1020 tUInt32 ui32Buf;
1021
1022 tUInt8* pLeft;
1023 tUInt8* pRight;
1024 tUInt8* pLine = m_pBitmap;
1025 for (tInt y = 0; y < m_sFormat.nHeight; y++)
1026 {
1027 pLeft = pLine;
1028 pRight = pLine + ((m_sFormat.nWidth - 1) * m_sFormat.nBitsPerPixel) / 8;
1029
1030 switch (m_sFormat.nBitsPerPixel)
1031 {
1032 case 8:
1033 {
1034 while (pLeft < pRight)
1035 {
1036 ui8Buf = *pLeft;
1037 *pLeft = *pRight;
1038 *pRight = ui8Buf;
1039 pLeft++;
1040 pRight--;
1041 }
1042 break;
1043 }
1044 case 16:
1045 {
1046 tUInt16* pui16Left = (tUInt16*) pLeft;
1047 tUInt16* pui16Right = (tUInt16*) pRight;
1048 while (pui16Left < pui16Right)
1049 {
1050 ui16Buf = *pui16Left;
1051 *pui16Left = *pui16Right;
1052 *pui16Right = ui16Buf;
1053
1054 pui16Left++;
1055 pui16Right--;
1056 }
1057 break;
1058 }
1059 case 24:
1060 {
1061 while (pLeft < pRight)
1062 {
1063 ui8Buf = *pLeft;
1064 *pLeft = *pRight;
1065 *pRight = ui8Buf;
1066 pLeft++;
1067 pRight++;
1068
1069 ui8Buf = *pLeft;
1070 *pLeft = *pRight;
1071 *pRight = ui8Buf;
1072 pLeft++;
1073 pRight++;
1074
1075 ui8Buf = *pLeft;
1076 *pLeft = *pRight;
1077 *pRight = ui8Buf;
1078 pLeft++;
1079 pRight++;
1080
1081 pRight -= 6;
1082 }
1083 break;
1084 }
1085 case 32:
1086 {
1087 tUInt32* pui32Left = (tUInt32*) pLeft;
1088 tUInt32* pui32Right = (tUInt32*) pRight;
1089 while (pui32Left < pui32Right)
1090 {
1091 ui32Buf = *pui32Left;
1092 *pui32Left = *pui32Right;
1093 *pui32Right = ui32Buf;
1094
1095 pui32Left++;
1096 pui32Right--;
1097 }
1098 break;
1099 }
1100 default:
1101 {
1102 RETURN_ERROR(ERR_NOT_SUPPORTED);
1103 break;
1104 }
1105 }
1106
1107 pLine += m_sFormat.nBytesPerLine;
1108 }
1109 RETURN_NOERROR;
1110 }
1111
1128 tResult Resize(tInt nWidth, tInt nHeight)
1129 {
1130 if ((nWidth < 1) || (nHeight < 1))
1131 {
1132 RETURN_ERROR(ERR_INVALID_ARG);
1133 }
1134
1135 if (this->GetWidth() == nWidth && this->GetHeight() == nHeight)
1136 {
1137 // Nothing to do here
1138 RETURN_NOERROR;
1139 }
1140
1141 RETURN_IF_POINTER_NULL(m_pBitmap);
1142
1143 RETURN_IF_FAILED(Convert(nWidth, nHeight, m_sFormat.nBitsPerPixel));
1144
1145 RETURN_NOERROR;
1146 }
1147
1164 tResult ChangeDepth(tInt nBitsPerPixel, tInt nBytesPerLine = 0, tUInt32 ui32Mask = 0x0)
1165 {
1166 RETURN_IF_FAILED(Convert(m_sFormat.nWidth, m_sFormat.nHeight, nBitsPerPixel, nBytesPerLine, ui32Mask));
1167
1168 RETURN_NOERROR;
1169 }
1170
1185 tResult Convert(tInt nWidth, tInt nHeight, tInt nBitsPerPixel, tInt nBytesPerLine = 0, tUInt32 ui32Mask = 0x0)
1186 {
1187 tBitmapFormat sNewFormat;
1188 adtf::util::cMemoryBlock::MemSet(&sNewFormat, 0, sizeof(sNewFormat));
1189 sNewFormat.nWidth = nWidth;
1190 sNewFormat.nHeight = nHeight;
1191 sNewFormat.nBitsPerPixel = static_cast<int16_t>(nBitsPerPixel);
1192 sNewFormat.nBytesPerLine = nBytesPerLine;
1193 return Convert(&sNewFormat, ui32Mask);
1194 }
1195
1210 tResult Convert(const tBitmapFormat* psFormat, tUInt32 ui32Mask = 0x0)
1211 {
1212 RETURN_IF_POINTER_NULL(psFormat);
1213 RETURN_IF_POINTER_NULL(m_pBitmap);
1214
1215 tBitmapFormat sNewFormat = *psFormat;
1216
1217 if (sNewFormat.nWidth == m_sFormat.nWidth && sNewFormat.nHeight == m_sFormat.nHeight &&
1218 sNewFormat.nBitsPerPixel == m_sFormat.nBitsPerPixel && sNewFormat.nPixelFormat == m_sFormat.nPixelFormat &&
1219 (sNewFormat.nBytesPerLine == 0 || sNewFormat.nBytesPerLine == m_sFormat.nBytesPerLine))
1220 {
1221 RETURN_NOERROR;
1222 }
1223
1224 if (sNewFormat.nWidth <= 0 || sNewFormat.nHeight <= 0)
1225 {
1226 RETURN_ERROR(ERR_INVALID_ARG);
1227 }
1228
1229 if (sNewFormat.nBytesPerLine == 0)
1230 {
1231 sNewFormat.nBytesPerLine =
1232 CalcAlignedMemSize((sNewFormat.nWidth * sNewFormat.nBitsPerPixel) / 8, m_nDefaultLineAlignment);
1233 sNewFormat.nSize = sNewFormat.nHeight * sNewFormat.nBytesPerLine;
1234 }
1235
1236 cImage oTempImage;
1237 RETURN_IF_FAILED(oTempImage.Create(&sNewFormat));
1238 tResult nResult = ERR_NOERROR;
1239
1240 if (sNewFormat.nPixelFormat == m_sFormat.nPixelFormat && ui32Mask == 0x0)
1241 {
1242 // just resize image
1243 nResult = StretchBlit(m_pBitmap, &m_sFormat, oTempImage.GetBitmap(), oTempImage.GetFormat());
1244 }
1245 else
1246 {
1247 // do bit conversions
1248 if (sNewFormat.nWidth == m_sFormat.nWidth && sNewFormat.nHeight == m_sFormat.nHeight)
1249 {
1250 nResult =
1251 Convert_impl(m_pBitmap, &m_sFormat, oTempImage.GetBitmap(), oTempImage.GetFormat(), 0, ui32Mask);
1252 }
1253 else
1254 {
1255 nResult =
1256 StretchBlit_impl(m_pBitmap, &m_sFormat, oTempImage.GetBitmap(), oTempImage.GetFormat(), ui32Mask);
1257 }
1258 }
1259
1260 RETURN_IF_FAILED(nResult);
1261 if (GetSize() != oTempImage.GetSize())
1262 {
1263 Release();
1264 RETURN_IF_FAILED(Create(oTempImage.GetFormat()));
1265 }
1266 else
1267 {
1268 adtf::util::cMemoryBlock::MemCopy(&m_sFormat, oTempImage.GetFormat(), sizeof(m_sFormat));
1269 }
1270 adtf::util::cMemoryBlock::MemCopy(GetBitmap(), oTempImage.GetBitmap(), GetSize());
1271 RETURN_NOERROR;
1272 }
1273
1282 tResult Convert(tInt oPixelFormat)
1283 {
1285 fmt.nPixelFormat = tInt16(oPixelFormat);
1286 fmt.nBitsPerPixel = tInt16(CalcBitsPerPixelFromPixelFormat(oPixelFormat));
1287 fmt.nPaletteSize = 0;
1288 fmt.nBytesPerLine = 0;
1289 fmt.nSize = 0;
1290 return Convert(&fmt, 0U);
1291 }
1292
1306 tResult ChangePixelFormat(tInt nFormat, tUInt32 ui32Flags = 0)
1307 {
1308 if ((m_sFormat.nPixelFormat == IImage::PF_8BIT) || (m_sFormat.nPixelFormat == IImage::PF_16BIT) ||
1309 (m_sFormat.nPixelFormat == IImage::PF_24BIT) || (m_sFormat.nPixelFormat == IImage::PF_32BIT))
1310 {
1311 auto const bpp = GetBitsPerPixel();
1312 auto const fmt = GetDefaultFormatFromBpp(bpp);
1313 m_sFormat.nPixelFormat = static_cast<int16_t>(fmt);
1314 }
1315
1316 if (m_sFormat.nPixelFormat == IImage::PF_UNKNOWN)
1317 {
1318 LOG_ERROR("Got PF_UNKNOWN");
1319 RETURN_ERROR(ERR_UNKNOWN_FORMAT);
1320 }
1321
1322 if (nFormat == m_sFormat.nPixelFormat)
1323 {
1324 RETURN_NOERROR;
1325 }
1326
1327 auto nBpp = static_cast<int32_t>(CalcBitsPerPixelFromPixelFormat(nFormat));
1328 if (nBpp < 1)
1329 {
1330 RETURN_ERROR(ERR_NOT_SUPPORTED);
1331 }
1332
1333 cImage oTempImage;
1334 oTempImage.Create(m_sFormat.nWidth, m_sFormat.nHeight, nBpp);
1335 oTempImage.SetPixelFormat(nFormat);
1336
1337 if (IS_OK(
1338 Convert_impl(GetBitmap(), GetFormat(), oTempImage.GetBitmap(), oTempImage.GetFormat(), ui32Flags, 0x0)))
1339 {
1340 Create(m_sFormat.nWidth, m_sFormat.nHeight, nBpp);
1341 SetPixelFormat(nFormat);
1342 adtf::util::cMemoryBlock::MemCopy(GetBitmap(), oTempImage.GetBitmap(), oTempImage.GetSize());
1343 RETURN_NOERROR;
1344 }
1345
1346 if (m_sFormat.nPixelFormat == PF_YUV420P_888 && m_sFormat.nBitsPerPixel == 24)
1347 {
1348 if (nFormat == PF_RGB_888)
1349 {
1351 m_sFormat.nSize = m_sFormat.nBytesPerLine * m_sFormat.nHeight;
1352
1353 tUInt8* pRGB;
1354 tHandle hRGBMem;
1355 RETURN_IF_FAILED(AllocImpl(m_sFormat.nSize, &hRGBMem, (tVoid**) &pRGB));
1356
1357 tInt nYUPlaneSize = ((m_sFormat.nWidth + 1) / 2) * ((m_sFormat.nHeight + 1) / 2);
1358 tUInt8* pY = m_pBitmap;
1359 tUInt8* pV = pY + m_sFormat.nWidth * m_sFormat.nHeight;
1360 tUInt8* pU = pV + nYUPlaneSize;
1361 tInt nLineWidthUV = (m_sFormat.nWidth + 1) / 2;
1362 tInt nLineWidthRGB = m_sFormat.nBytesPerLine;
1363 tUInt8* pPixel = pRGB;
1364 for (tInt32 nY = 0; nY < m_sFormat.nHeight; ++nY)
1365 {
1366 for (tInt32 nX = 0; nX < m_sFormat.nWidth; ++nX)
1367 {
1368 Yuv2Rgb(pY[nX], pU[nX / 2], pV[nX / 2], pPixel + nX * 3);
1369 }
1370
1371 pPixel += nLineWidthRGB;
1372 pY += m_sFormat.nWidth;
1373 if (nY % 2)
1374 {
1375 pV += nLineWidthUV;
1376 pU += nLineWidthUV;
1377 }
1378 }
1379
1380 if (m_hBitmapMemory != NULL)
1381 {
1383 }
1384
1385 m_hBitmapMemory = hRGBMem;
1386
1387 m_bReference = tFalse;
1388 m_pBitmap = pRGB;
1389
1390 m_sFormat.nPixelFormat = static_cast<int16_t>(nFormat);
1391
1392 RETURN_NOERROR;
1393 }
1394 }
1395
1396 if (m_sFormat.nPixelFormat == PF_RGB_888 && m_sFormat.nBitsPerPixel == 24)
1397 {
1398 if (nFormat == PF_YUV420P_888)
1399 {
1400 tInt nYUPlaneSize = ((m_sFormat.nWidth + 1) / 2) * ((m_sFormat.nHeight + 1) / 2);
1401
1402 m_sFormat.nSize = m_sFormat.nWidth * m_sFormat.nHeight + 2 * nYUPlaneSize;
1403
1404 tUInt8* pYUV;
1405 tHandle hYUVMem;
1406 RETURN_IF_FAILED(AllocImpl(m_sFormat.nSize, &hYUVMem, (tVoid**) &pYUV));
1407
1408 tInt nLineWidthRGB = m_sFormat.nBytesPerLine;
1409 tUInt8* pY = pYUV;
1410 tUInt8* pRGBLine = m_pBitmap;
1411 for (tInt32 nY = 0; nY < m_sFormat.nHeight; ++nY)
1412 {
1413 for (tInt32 nX = 0; nX < m_sFormat.nWidth; ++nX)
1414 {
1415 pY[nX] = YFromRGB(pRGBLine + nX * 3);
1416 }
1417 pRGBLine += nLineWidthRGB;
1418 pY += m_sFormat.nWidth;
1419 }
1420
1421 pRGBLine = m_pBitmap;
1422 tUInt8* pV = pY;
1423 tUInt8* pU = pV + nYUPlaneSize;
1424 tInt nLineWidth = (m_sFormat.nWidth + 1) / 2;
1425 nLineWidthRGB += nLineWidthRGB;
1426 for (tInt32 nY = 0; nY < m_sFormat.nHeight; nY += 2)
1427 {
1428 for (tInt32 nX = 0; nX < m_sFormat.nWidth; nX += 2)
1429 {
1430 tUInt8* pPixel = pRGBLine + nX * 3;
1431 pU[nX / 2] = UFromRGB(pPixel);
1432 pV[nX / 2] = VFromRGB(pPixel);
1433 }
1434 pRGBLine += nLineWidthRGB;
1435 pU += nLineWidth;
1436 pV += nLineWidth;
1437 }
1438
1439 if (m_hBitmapMemory != NULL)
1440 {
1442 }
1443
1444 m_hBitmapMemory = hYUVMem;
1445 m_bReference = tFalse;
1446 m_pBitmap = pYUV;
1447 m_sFormat.nPixelFormat = static_cast<int16_t>(nFormat);
1448
1449 RETURN_NOERROR;
1450 }
1451 }
1452
1453 RETURN_ERROR(ERR_NOT_SUPPORTED);
1454 }
1455
1468 tResult FlipRGB()
1469 {
1470 RETURN_IF_POINTER_NULL(m_pBitmap);
1471 tBitmapFormat sFormat = m_sFormat;
1472
1473 switch (m_sFormat.nPixelFormat)
1474 {
1475 case PF_RGB_888: sFormat.nPixelFormat = PF_BGR_888; break;
1476 case PF_BGR_888: sFormat.nPixelFormat = PF_RGB_888; break;
1477 case PF_ABGR_8888: sFormat.nPixelFormat = PF_ARGB_8888; break;
1478 case PF_ARGB_8888: sFormat.nPixelFormat = PF_ABGR_8888; break;
1479 case PF_BGRA_8888: sFormat.nPixelFormat = PF_RGBA_8888; break;
1480 case PF_RGBA_8888: sFormat.nPixelFormat = PF_BGRA_8888; break;
1481 default: RETURN_NOERROR;
1482 }
1483
1484 return Convert(&sFormat);
1485 }
1486
1494 tResult FlipAlpha()
1495 {
1496 if (0 == GetBytesPerLine())
1497 {
1498 RETURN_ERROR(ERR_UNEXPECTED);
1499 }
1500
1501 tBool bAlphaFromHighToLow = tFalse;
1502
1503 switch (m_sFormat.nPixelFormat)
1504 {
1505 case PF_ABGR_8888:
1506 {
1507 m_sFormat.nPixelFormat = PF_BGRA_8888;
1508 bAlphaFromHighToLow = tTrue;
1509 }
1510 break;
1511 case PF_ARGB_8888:
1512 {
1513 m_sFormat.nPixelFormat = PF_RGBA_8888;
1514 bAlphaFromHighToLow = tTrue;
1515 }
1516 break;
1517 case PF_BGRA_8888:
1518 {
1519 m_sFormat.nPixelFormat = PF_ABGR_8888;
1520 bAlphaFromHighToLow = tFalse;
1521 }
1522 break;
1523 case PF_RGBA_8888:
1524 {
1525 m_sFormat.nPixelFormat = PF_ARGB_8888;
1526 bAlphaFromHighToLow = tFalse;
1527 }
1528 break;
1529 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
1530 }
1531
1532 tUInt32* pLine = (tUInt32*) GetBitmap();
1533
1534 if (bAlphaFromHighToLow)
1535 {
1536 // ARGB => RGBA, ABGR => BGRA
1537 for (tInt nLine = 0; nLine < m_sFormat.nHeight; nLine++)
1538 {
1539 for (tInt nPos = 0; nPos < m_sFormat.nWidth; nPos++)
1540 {
1541 pLine[nPos] = (pLine[nPos] >> 24) | (pLine[nPos] << 8);
1542 }
1543 pLine += GetBytesPerLine() / 4;
1544 }
1545 }
1546 else
1547 {
1548 // RGBA => ARGB, BGRA => ABGR
1549 for (tInt nLine = 0; nLine < m_sFormat.nHeight; nLine++)
1550 {
1551 for (tInt nPos = 0; nPos < m_sFormat.nWidth; nPos++)
1552 {
1553 pLine[nPos] = (pLine[nPos] << 24) | (pLine[nPos] >> 8);
1554 }
1555 pLine += GetBytesPerLine() / 4;
1556 }
1557 }
1558 RETURN_NOERROR;
1559 }
1560
1574 tResult MakeAlphaChannel(const tColor& sColorKey, tBool bClearTransparent = tFalse)
1575 {
1576 tInt nOrgPixelFormat = GetPixelFormat();
1577 if (nOrgPixelFormat != PF_RGBA_8888)
1578 {
1579 RETURN_IF_FAILED(ChangePixelFormat(PF_RGBA_8888));
1580 }
1581
1582 tUInt8* pBitmap = GetBitmap();
1583 RETURN_IF_POINTER_NULL(pBitmap);
1584
1585 tUInt8* pLine = pBitmap;
1586 tUInt32* ptr;
1587 tUInt8* pPixelAlpha;
1588
1589 tInt nHeight = GetHeight();
1590 tInt nBytesPerLine = GetBytesPerLine();
1591 tInt nSteps = nBytesPerLine / 4;
1592
1593 tUInt32 ui32CompValue = (tUInt32) sColorKey.nBlue | ((tUInt32) sColorKey.nGreen << 8) |
1594 ((tUInt32) sColorKey.nRed << 16) | ((tUInt32) sColorKey.nAlpha << 24);
1595 ui32CompValue = ui32CompValue & 0x00FFFFFF; // removing the alphavalue
1596
1597 for (tInt nLine = 0; nLine < nHeight; nLine++)
1598 {
1599 ptr = (tUInt32*) pLine;
1600 pPixelAlpha = pLine + 3;
1601
1602 for (tInt nStep = 0; nStep < nSteps; nStep++)
1603 {
1604 if ((*ptr & 0x00FFFFFF) == ui32CompValue)
1605 {
1606 *pPixelAlpha = 0;
1607 if (bClearTransparent)
1608 {
1609 *ptr = 0;
1610 }
1611 }
1612 else
1613 {
1614 *pPixelAlpha = 0xFF;
1615 }
1616
1617 ptr++;
1618 pPixelAlpha += 4;
1619 }
1620
1621 pLine += nBytesPerLine;
1622 }
1623
1624 RETURN_NOERROR;
1625 }
1626
1627public: // blit functions
1641 tResult Blit(const cImage& oDestImage, tInt nFlags = 0)
1642 {
1643 return Blit(GetBitmap(), GetFormat(), oDestImage.GetBitmap(), oDestImage.GetFormat(), nFlags);
1644 }
1645
1660 tResult SetBits(const tUInt8* pSrcBitmapData, const tBitmapFormat* psSrcBitmapFormat)
1661 {
1662 RETURN_IF_POINTER_NULL(pSrcBitmapData);
1663 RETURN_IF_POINTER_NULL(psSrcBitmapFormat);
1664 const tBitmapFormat* m_pMyFormat = GetFormat();
1665 if (0 != adtf::util::cMemoryBlock::MemCmp(psSrcBitmapFormat, m_pMyFormat, sizeof(*pSrcBitmapData)) ||
1666 m_pBitmap == NULL)
1667 {
1668 RETURN_IF_FAILED(Release());
1669 RETURN_IF_FAILED(Create(psSrcBitmapFormat));
1670 }
1671
1672 adtf::util::cMemoryBlock::MemCopy(m_pBitmap, pSrcBitmapData, GetSize());
1673 RETURN_NOERROR;
1674 }
1675
1688 tResult GetBits(tUInt8* pDestBitmapData, const tBitmapFormat* psDestBitmapFormat, tInt nFlags = 0)
1689 {
1690 return Blit(GetBitmap(), GetFormat(), pDestBitmapData, psDestBitmapFormat, nFlags);
1691 }
1692
1693public: // static blit functions
1708 static tResult Blit(const disptb::graphicslib::dengar::cImage& oSrcImage,
1709 const disptb::graphicslib::dengar::cImage& oDestImage,
1710 tInt nFlags = 0)
1711 {
1712 return Blit(oSrcImage.GetBitmap(), oSrcImage.GetFormat(), oDestImage.GetBitmap(), oDestImage.GetFormat(),
1713 nFlags);
1714 }
1715
1731 static tResult Blit(const tUInt8* pSrcBitmapData,
1732 const tBitmapFormat* psSrcBitmapFormat,
1733 tUInt8* pDestBitmapData,
1734 const tBitmapFormat* psDestBitmapFormat,
1735 tInt nFlags = 0)
1736 {
1737 return Blit_impl(pSrcBitmapData, psSrcBitmapFormat, pDestBitmapData, psDestBitmapFormat, nFlags);
1738 }
1739
1755 static tResult StretchBlit(const disptb::graphicslib::dengar::cImage& oSrcImage,
1756 const disptb::graphicslib::dengar::cImage& oDestImage,
1757 tInt nFlags = 0)
1758 {
1759 return StretchBlit(oSrcImage.GetBitmap(), oSrcImage.GetFormat(), oDestImage.GetBitmap(), oDestImage.GetFormat(),
1760 nFlags);
1761 }
1762
1780 static tResult StretchBlit(const tUInt8* pSrcBitmapData,
1781 const tBitmapFormat* psSrcBitmapFormat,
1782 tUInt8* pDestBitmapData,
1783 const tBitmapFormat* psDestBitmapFormat,
1784 tInt nFlags = 0)
1785 {
1786 return StretchBlit_impl(pSrcBitmapData, psSrcBitmapFormat, pDestBitmapData, psDestBitmapFormat, nFlags);
1787 }
1788
1822 static tResult Convert(const tUInt8* pSrcBitmapData,
1823 const tBitmapFormat* psSrcBitmapFormat,
1824 tUInt8* pDestBitmapData,
1825 const tBitmapFormat* psDestBitmapFormat,
1826 tInt nFlags,
1827 tUInt32 ui32Mask)
1828 {
1829 RETURN_IF_POINTER_NULL(pSrcBitmapData);
1830 RETURN_IF_POINTER_NULL(psSrcBitmapFormat);
1831 RETURN_IF_POINTER_NULL(pDestBitmapData);
1832 RETURN_IF_POINTER_NULL(psDestBitmapFormat);
1833 if (psSrcBitmapFormat->nWidth != psDestBitmapFormat->nWidth ||
1834 psSrcBitmapFormat->nHeight != psDestBitmapFormat->nHeight)
1835 {
1836 return StretchBlit_impl(pSrcBitmapData, psSrcBitmapFormat, pDestBitmapData, psDestBitmapFormat, nFlags,
1837 ui32Mask);
1838 }
1839 else
1840 {
1841 return Convert_impl(pSrcBitmapData, psSrcBitmapFormat, pDestBitmapData, psDestBitmapFormat, nFlags,
1842 ui32Mask);
1843 }
1844 }
1845
1860 {
1861 RETURN_IF_POINTER_NULL(pSourceImage);
1862 RETURN_IF_POINTER_NULL(pDestImage);
1863 RETURN_IF_POINTER_NULL(pMaskImage);
1864 RETURN_IF_POINTER_NULL(pSourceImage->GetBitmap());
1865 RETURN_IF_POINTER_NULL(pDestImage->GetBitmap());
1866 RETURN_IF_POINTER_NULL(pMaskImage->GetBitmap());
1867
1868 if ((pMaskImage->GetWidth() < pSourceImage->GetWidth()) ||
1869 (pMaskImage->GetHeight() < pSourceImage->GetHeight()) ||
1870 (pDestImage->GetHeight() < pSourceImage->GetHeight()) ||
1871 (pDestImage->GetWidth() < pSourceImage->GetWidth()))
1872 {
1873 RETURN_ERROR(ERR_UNEXPECTED);
1874 }
1875 if ((PF_RGB_888 != pSourceImage->GetPixelFormat()) && (PF_BGR_888 != pSourceImage->GetPixelFormat()) &&
1876 (PF_BGRA_8888 != pSourceImage->GetPixelFormat()) && (PF_RGBA_8888 != pSourceImage->GetPixelFormat()))
1877 {
1878 RETURN_ERROR(ERR_NOT_SUPPORTED);
1879 }
1880
1881 if ((PF_RGB_888 != pDestImage->GetPixelFormat()) && (PF_BGR_888 != pDestImage->GetPixelFormat()) &&
1882 (PF_BGRA_8888 != pDestImage->GetPixelFormat()) && (PF_RGBA_8888 != pDestImage->GetPixelFormat()))
1883 {
1884 RETURN_ERROR(ERR_NOT_SUPPORTED);
1885 }
1886
1887 tUInt8* pSourceBuffer = pSourceImage->GetBitmap();
1888 tUInt8* pDestBuffer = pDestImage->GetBitmap();
1889 tUInt8* pMaskBuffer = pMaskImage->GetBitmap();
1890
1891 tUInt8* pSrcLine = pSourceBuffer;
1892 tUInt8* pDestLine = pDestBuffer;
1893 tUInt8* pMaskLine = pMaskBuffer;
1894
1895 tUInt8* pSrc;
1896 tUInt8* pDest;
1897 tUInt8* pMask;
1898
1899 tInt nHeight = pSourceImage->GetHeight();
1900 tInt nWidth = pSourceImage->GetWidth();
1901 tInt nAlpha;
1902
1903 for (tInt y = 0; y < nHeight; y++)
1904 {
1905 pSrc = pSrcLine;
1906 pDest = pDestLine;
1907 pMask = pMaskLine;
1908
1909 for (tInt x = 0; x < nWidth; x++)
1910 {
1911 nAlpha = *(pMask++);
1912 *(pDest) = (tUInt8) (((*pDest * nAlpha) + (*pSrc * (255 - nAlpha))) / 255);
1913 pSrc++;
1914 pDest++;
1915 *(pDest) = (tUInt8) (((*pDest * nAlpha) + (*pSrc * (255 - nAlpha))) / 255);
1916 pSrc++;
1917 pDest++;
1918 *(pDest) = (tUInt8) (((*pDest * nAlpha) + (*pSrc * (255 - nAlpha))) / 255);
1919 pSrc++;
1920 pDest++;
1921 }
1922
1923 pSrcLine += pSourceImage->GetBytesPerLine();
1924 pDestLine += pDestImage->GetBytesPerLine();
1925 pMaskLine += pMaskImage->GetBytesPerLine();
1926 }
1927
1928 RETURN_NOERROR;
1929 }
1930
1944 {
1945 if (oSrc.GetPixelFormat() != oDest.GetPixelFormat())
1946 {
1947 RETURN_ERROR(ERR_NOT_IMPL);
1948 }
1949
1950 if ((PF_RGB_888 != oSrc.GetPixelFormat()) && (PF_RGBA_8888 != oSrc.GetPixelFormat()))
1951 {
1952 RETURN_ERROR(ERR_NOT_SUPPORTED);
1953 }
1954 tUInt8* pSrcBitmapData = oSrc.GetBitmap();
1955 tUInt8* pDestBitmapData = oDest.GetBitmap();
1956
1957 RETURN_IF_POINTER_NULL(pSrcBitmapData);
1958 RETURN_IF_POINTER_NULL(pDestBitmapData);
1959
1960 const tBitmapFormat* psSrcBitmapFormat = oSrc.GetFormat();
1961 const tBitmapFormat* psDestBitmapFormat = oDest.GetFormat();
1962
1963 RETURN_IF_POINTER_NULL(psSrcBitmapFormat);
1964 RETURN_IF_POINTER_NULL(psDestBitmapFormat);
1965
1966 tInt l_nCopyWidth = psDestBitmapFormat->nWidth;
1967 tInt l_nCopyHeight = psDestBitmapFormat->nHeight;
1968
1969 const tUInt8* l_pSrcLine = pSrcBitmapData;
1970 const tUInt8* l_pSrcLine2 = pSrcBitmapData;
1971
1972 tUInt8* l_pDestLine = pDestBitmapData;
1973 tInt l_nBytesPerPixel = psSrcBitmapFormat->nBitsPerPixel / 8;
1974
1975 tInt nCopySrcStep = psSrcBitmapFormat->nWidth;
1976 tInt nCopySrcMax = l_nCopyWidth * nCopySrcStep;
1977
1978 tInt y2, y3;
1979 tInt y_weight;
1980
1981 for (tInt y = 0; y < l_nCopyHeight; y++)
1982 {
1983 y_weight = GET_REMAINDER(y, psSrcBitmapFormat->nHeight, psDestBitmapFormat->nHeight, 256);
1984
1985 y2 = (y * psSrcBitmapFormat->nHeight) / l_nCopyHeight;
1986 y3 = y2 + 1;
1987 if (y3 >= psSrcBitmapFormat->nHeight)
1988 y3 = y2;
1989
1990 l_pSrcLine = pSrcBitmapData + y2 * psSrcBitmapFormat->nBytesPerLine;
1991 l_pSrcLine2 = pSrcBitmapData + y3 * psSrcBitmapFormat->nBytesPerLine;
1992
1993 l_pDestLine = pDestBitmapData + y * psDestBitmapFormat->nBytesPerLine;
1994
1995 if (l_nBytesPerPixel == 4)
1996 {
1997 tUInt32* l_pui32SrcLine = (tUInt32*) l_pSrcLine;
1998 tUInt32* l_pui32SrcLine2 = (tUInt32*) l_pSrcLine2;
1999 tUInt32* l_pui32DestLine = (tUInt32*) l_pDestLine;
2000
2001 tUInt32 v, v1, v2, v3, v4;
2002 tInt x2;
2003 tInt x_weight;
2004 for (tInt x = 0; x < nCopySrcMax; x += nCopySrcStep)
2005 {
2006 x_weight =
2007 GET_REMAINDER(x / nCopySrcStep, psSrcBitmapFormat->nWidth, psDestBitmapFormat->nWidth, 256);
2008
2009 x2 = x + nCopySrcStep;
2010 if (x2 >= nCopySrcMax)
2011 x2 = x;
2012
2013 v1 = *(l_pui32SrcLine + x / l_nCopyWidth);
2014 v2 = *(l_pui32SrcLine2 + x / l_nCopyWidth);
2015 v3 = *(l_pui32SrcLine + x2 / l_nCopyWidth);
2016 v4 = *(l_pui32SrcLine2 + x2 / l_nCopyWidth);
2017
2018 v = BlendRGB32(v1, v2, v3, v4, y_weight, x_weight);
2019
2020 *(l_pui32DestLine++) = v;
2021 }
2022 }
2023 else if (l_nBytesPerPixel == 3)
2024 {
2025 tUInt8* l_pui8SrcLine = (tUInt8*) l_pSrcLine;
2026 tUInt8* l_pui8SrcLine2 = (tUInt8*) l_pSrcLine2;
2027 tUInt8* l_pui8DestLine = (tUInt8*) l_pDestLine;
2028
2029 tUInt8 v, v1, v2, v3, v4;
2030 tInt x2;
2031 tInt x_weight;
2032 for (tInt x = 0; x < nCopySrcMax; x += nCopySrcStep)
2033 {
2034 x_weight =
2035 GET_REMAINDER(x / nCopySrcStep, psSrcBitmapFormat->nWidth, psDestBitmapFormat->nWidth, 256);
2036
2037 x2 = x + nCopySrcStep;
2038 if (x2 >= nCopySrcMax)
2039 x2 = x;
2040
2041 v1 = *(l_pui8SrcLine + (x / l_nCopyWidth) * 3);
2042 v2 = *(l_pui8SrcLine2 + (x / l_nCopyWidth) * 3);
2043 v3 = *(l_pui8SrcLine + (x2 / l_nCopyWidth) * 3);
2044 v4 = *(l_pui8SrcLine2 + (x2 / l_nCopyWidth) * 3);
2045 v = BlendPixel(v1, v2, v3, v4, y_weight, x_weight);
2046
2047 *(l_pui8DestLine++) = v;
2048
2049 v1 = *(l_pui8SrcLine + (x / l_nCopyWidth) * 3 + 1);
2050 v2 = *(l_pui8SrcLine2 + (x / l_nCopyWidth) * 3 + 1);
2051 v3 = *(l_pui8SrcLine + (x2 / l_nCopyWidth) * 3 + 1);
2052 v4 = *(l_pui8SrcLine2 + (x2 / l_nCopyWidth) * 3 + 1);
2053 v = BlendPixel(v1, v2, v3, v4, y_weight, x_weight);
2054
2055 *(l_pui8DestLine++) = v;
2056
2057 v1 = *(l_pui8SrcLine + (x / l_nCopyWidth) * 3 + 2);
2058 v2 = *(l_pui8SrcLine2 + (x / l_nCopyWidth) * 3 + 2);
2059 v3 = *(l_pui8SrcLine + (x2 / l_nCopyWidth) * 3 + 2);
2060 v4 = *(l_pui8SrcLine2 + (x2 / l_nCopyWidth) * 3 + 2);
2061 v = BlendPixel(v1, v2, v3, v4, y_weight, x_weight);
2062
2063 *(l_pui8DestLine++) = v;
2064 }
2065 }
2066 }
2067
2068 RETURN_NOERROR;
2069 }
2070
2083 {
2084 RETURN_IF_POINTER_NULL(pImage);
2085 RETURN_IF_POINTER_NULL(pImage->GetBitmap());
2086 RETURN_IF_POINTER_NULL(pImage->GetBitmapInfo());
2087
2088 switch (pImage->GetPixelFormat())
2089 {
2091 case IImage::PF_BGRA_8888: break;
2092 default:
2093 {
2094 tBitmapFormat oFormat = *pImage->GetFormat();
2095 oFormat.nBitsPerPixel = 32;
2097 oFormat.nBytesPerLine = 0;
2098 RETURN_IF_FAILED(pImage->Convert(&oFormat));
2099 break;
2100 }
2101 }
2102
2103 auto pPixel = (tUInt32*) pImage->GetBitmap();
2104 tUInt32 nTranspColor = oColor.GetRGBA(pImage->GetPixelFormat()) & 0x00ffffff;
2105 tInt nWidth = pImage->GetWidth();
2106 tInt nHeight = pImage->GetHeight();
2107 tInt nBPL = pImage->GetBytesPerLine();
2108
2109 for (tInt nY = 0; nY < nHeight; nY++)
2110 {
2111 for (tInt nX = 0; nX < nWidth; nX++)
2112 {
2113 if ((pPixel[nX] & 0x00ffffff) == nTranspColor)
2114 {
2115 pPixel[nX] = 0x00000000;
2116 }
2117 else
2118 {
2119 pPixel[nX] = pPixel[nX] | 0xff000000;
2120 }
2121 }
2122 pPixel += nBPL / 4;
2123 }
2124 RETURN_NOERROR;
2125 }
2126
2127public: // color functions
2135 static inline tUInt8 RedValue(tUInt32 nColor)
2136 {
2137 return ((tUInt8) (nColor));
2138 };
2139
2147 static inline tUInt8 GreenValue(tUInt32 nColor)
2148 {
2149 return ((tUInt8) (((tUInt16) (nColor)) >> 8));
2150 };
2151
2159 static inline tUInt8 BlueValue(tUInt32 nColor)
2160 {
2161 return ((tUInt8) ((nColor) >> 16));
2162 };
2163
2173 static inline tFloat64 Brightness(tFloat64 fRed, tFloat64 fGreen, tFloat64 fBlue)
2174 {
2175 return (0.114 * fRed + 0.587 * fGreen + 0.299 * fBlue);
2176 }
2177
2187 static inline tInt BrightnessValue(tInt nRed, tInt nGreen, tInt nBlue)
2188 {
2189 return 116 * nRed + 602 * nGreen + 306 * nBlue;
2190 }
2191
2201 static inline tUInt8 Brightness(tInt nRed, tInt nGreen, tInt nBlue)
2202 {
2203 return (tUInt8) (disptb::graphicslib::dengar::cImage::BrightnessValue(nRed, nGreen, nBlue) >> 10);
2204 }
2205
2213 static inline tUInt8 Brightness(tColor nColor)
2214 {
2215 return (
2216 tUInt8) (disptb::graphicslib::dengar::cImage::BrightnessValue(nColor.nRed, nColor.nGreen, nColor.nBlue) >>
2217 10);
2218 }
2219
2227 static inline tUInt8 Brightness(tUInt32 nColor)
2228 {
2230 BlueValue(nColor)) >>
2231 10);
2232 }
2233
2234public: // helper functions
2235#ifdef WIN32
2248 tResult LoadResource(tInt nResourceId, tHandle hModule = NULL, tUInt32 nFlags = 0)
2249 {
2250 Release();
2251
2252 HRSRC hResource = ::FindResource((HMODULE) hModule, MAKEINTRESOURCE(nResourceId), RT_BITMAP);
2253 if (NULL == hResource)
2254 {
2255 RETURN_ERROR(ERR_NOT_FOUND);
2256 }
2257
2258 HGLOBAL hResourceData = ::LoadResource((HMODULE) hModule, hResource);
2259 if (NULL == hResourceData)
2260 {
2261 RETURN_ERROR(ERR_NOACCESS);
2262 }
2263
2264 BITMAPINFOHEADER* pBitmap = (BITMAPINFOHEADER*) ::LockResource(hResourceData);
2265 if (NULL == pBitmap)
2266 {
2267 ::FreeResource(hResourceData);
2268 RETURN_ERROR(ERR_NOACCESS);
2269 }
2270
2271 tVoid* pPalette;
2272 tInt nPaletteSize;
2273 if (pBitmap->biBitCount <= 8)
2274 {
2275 BITMAPINFO* pBitmapHeader = (BITMAPINFO*) pBitmap;
2276
2277 nPaletteSize = (1 << pBitmap->biBitCount);
2278 pPalette = (tVoid*) &pBitmapHeader->bmiColors[0];
2279 }
2280 else
2281 {
2282 nPaletteSize = 0;
2283 pPalette = NULL;
2284 }
2285
2286 tUInt8* pBitmapData = (tUInt8*) pBitmap + pBitmap->biSize + nPaletteSize * sizeof(tUInt32);
2287
2288 tResult nResult = Create(pBitmap->biWidth, pBitmap->biHeight, pBitmap->biBitCount, 0, pBitmapData);
2289 if (IS_OK(nResult) && NULL != pPalette)
2290 {
2291 nResult = SetPalette(nPaletteSize, (tColor*) pPalette);
2292 }
2293
2294 UnlockResource(hResourceData);
2295 ::FreeResource(hResourceData);
2296
2297 if (IS_FAILED(nResult))
2298 {
2299 return nResult;
2300 }
2301
2302 // windows bitmaps are always BGR
2303 if (m_sFormat.nBitsPerPixel == 24)
2304 {
2306 }
2307 else if (m_sFormat.nBitsPerPixel == 32)
2308 {
2310 }
2311
2312 if (m_sFormat.nBitsPerPixel >= 24 && ((nFlags & LF_SWAP_RGB) != 0))
2313 {
2314 FlipRGB();
2315 }
2316
2317 if (((nFlags & LF_FLIP_VERTICAL) == 0))
2318 {
2319 Flip();
2320 }
2321
2322 RETURN_NOERROR;
2323 }
2338 tResult CaptureScreen(tInt x, tInt y, tInt nWidth, tInt nHeight)
2339 {
2340 RETURN_IF_FAILED(Create(nWidth, nHeight, 24));
2341 if ((nWidth < 1) || (nHeight < 1) || (x < 0) || (y < 0))
2342 {
2343 RETURN_ERROR(ERR_INVALID_ARG);
2344 }
2345 HDC hdcScreen = ::GetDC(NULL);
2346 HDC hdcCapture = ::CreateCompatibleDC(hdcScreen);
2347 HBITMAP bmCapture = ::CreateCompatibleBitmap(hdcScreen, nWidth, nHeight);
2348
2349 ::SetStretchBltMode(hdcCapture, COLORONCOLOR);
2350 ::SelectObject(hdcCapture, bmCapture);
2351
2352 ::StretchBlt(hdcCapture, 0, 0, nWidth, nHeight, hdcScreen, x, y, nWidth, nHeight, SRCCOPY);
2353
2354 ::GetDIBits(hdcCapture, bmCapture, 0, nHeight, GetBitmap(), (BITMAPINFO*) GetBitmapInfo(), DIB_RGB_COLORS);
2355
2356 ::DeleteObject(bmCapture);
2357 ::DeleteDC(hdcCapture);
2358
2359 ::ReleaseDC(NULL, hdcScreen);
2360
2361 RETURN_NOERROR;
2362 }
2371 tHandle CreateRegion()
2372 {
2373 switch (GetPixelFormat())
2374 {
2375 case PF_8BIT:
2376 case PF_RGB_8:
2377 case PF_GREYSCALE_8:
2378 case PF_RGB_888:
2379 case PF_RGBA_8888: break;
2380 default: return NULL;
2381 }
2382
2383 HRGN hRgn = ::CreateRectRgn(0, 0, GetWidth(), GetHeight());
2384
2385 tBool bVFlip = tTrue;
2386 tInt nBytesPerLine = GetBytesPerLine();
2387 tInt nBytesPerPixel = GetBitsPerPixel() / 8;
2388
2389 tUInt8* pImage = GetBitmap();
2390 tUInt8* pLine = pImage;
2391 if (bVFlip)
2392 {
2393 pLine += nBytesPerLine * (GetHeight() - 1);
2394 }
2395
2396 tUInt8* ptr;
2397 tUInt8 r, g, b = 0;
2398
2399 tInt rgn_start = -1;
2400 tBool bTransparent;
2401
2402 for (tInt y = 0; y < GetHeight(); y++)
2403 {
2404 ptr = pLine;
2405 for (tInt x = 0; x < GetWidth(); x++)
2406 {
2407 bTransparent = tFalse;
2408
2409 if (nBytesPerPixel >= 3)
2410 {
2411 r = *(ptr);
2412 g = *(ptr + 1);
2413 b = *(ptr + 2);
2414
2415 if (r == 0xFF && g == 0x00 && b == 0xFF)
2416 {
2417 bTransparent = tTrue;
2418 }
2419 }
2420 else // 8 bit
2421 {
2422 if (*ptr == 0x00)
2423 {
2424 bTransparent = tTrue;
2425 }
2426 }
2427
2428 if (bTransparent)
2429 {
2430 if (rgn_start < 0)
2431 {
2432 rgn_start = x;
2433 }
2434 }
2435 else
2436 {
2437 if (rgn_start >= 0)
2438 {
2439 HRGN hLocalRgn = ::CreateRectRgn(rgn_start, y, x, y + 1);
2440 ::CombineRgn(hRgn, hRgn, hLocalRgn, RGN_DIFF);
2441 ::DeleteObject(hLocalRgn);
2442
2443 rgn_start = -1;
2444 }
2445 }
2446
2447 ptr += nBytesPerPixel;
2448 }
2449
2450 if (rgn_start >= 0)
2451 {
2452 HRGN hLocalRgn = ::CreateRectRgn(rgn_start, y, GetWidth(), y + 1);
2453 ::CombineRgn(hRgn, hRgn, hLocalRgn, RGN_DIFF);
2454 ::DeleteObject(hLocalRgn);
2455
2456 rgn_start = -1;
2457 }
2458
2459 if (bVFlip)
2460 {
2461 pLine -= nBytesPerLine;
2462 }
2463 else
2464 {
2465 pLine += nBytesPerLine;
2466 }
2467 }
2468
2469 return (tHandle) hRgn;
2470 }
2471#endif // WIN32
2472
2482 {
2483 if (this == &oImage)
2484 {
2485 return tTrue;
2486 }
2487
2488 if ((oImage.m_sFormat.nWidth != m_sFormat.nWidth) || (oImage.m_sFormat.nHeight != m_sFormat.nHeight) ||
2489 (oImage.m_sFormat.nPixelFormat != m_sFormat.nPixelFormat) ||
2490 (oImage.m_sFormat.nBitsPerPixel != m_sFormat.nBitsPerPixel))
2491 {
2492 return tFalse;
2493 }
2494
2495 if (oImage.GetBitmap() == GetBitmap())
2496 {
2497 return tTrue;
2498 }
2499
2500 tInt nBytesToCompare = m_sFormat.nWidth * m_sFormat.nBitsPerPixel / 8;
2501
2502 for (tInt nLine = 0; nLine < m_sFormat.nHeight; nLine++)
2503 {
2504 tInt nOffset = nLine * m_sFormat.nBytesPerLine;
2505 if (adtf::util::cMemoryBlock::MemCmp(GetBitmap() + nOffset, oImage.GetBitmap() + nOffset,
2506 nBytesToCompare) != 0)
2507 {
2508 return tFalse;
2509 }
2510 }
2511
2512 return tTrue;
2513 }
2514
2523 {
2524 if (this == &oImage)
2525 {
2526 return 0;
2527 }
2528
2529 if ((oImage.m_sFormat.nWidth != m_sFormat.nWidth) || (oImage.m_sFormat.nHeight != m_sFormat.nHeight) ||
2530 (oImage.m_sFormat.nPixelFormat != m_sFormat.nPixelFormat) ||
2531 (oImage.m_sFormat.nBitsPerPixel != m_sFormat.nBitsPerPixel))
2532 {
2533 return -1;
2534 }
2535
2536 if (oImage.GetBitmap() == GetBitmap())
2537 {
2538 return 0;
2539 }
2540
2541 tInt nResult = 0;
2542 tInt nBytesPerPixel = m_sFormat.nBitsPerPixel / 8;
2543 tInt nBytesToCompare = m_sFormat.nWidth * nBytesPerPixel;
2544
2545 for (tInt nLine = 0; nLine < m_sFormat.nHeight; nLine++)
2546 {
2547 tInt nOffset = nLine * m_sFormat.nBytesPerLine;
2548
2549 tUInt8* pLine = GetBitmap() + nOffset;
2550 tUInt8* pRefLine = oImage.GetBitmap() + nOffset;
2551
2552 for (tInt i = 0; i < nBytesToCompare; i += nBytesPerPixel)
2553 {
2554 for (tInt p = 0; p < nBytesPerPixel; p++)
2555 {
2556 if (pLine[i + p] != pRefLine[i + p])
2557 {
2558 nResult++;
2559 break;
2560 }
2561 }
2562 }
2563 }
2564
2565 return nResult;
2566 }
2567
2577 static tInt CalcAlignedMemSize(tInt nBytes, tInt nAlignment)
2578 {
2579 if (nBytes < 0)
2580 {
2581 return 0;
2582 }
2583
2584 if (nAlignment < 1)
2585 {
2586 return nBytes;
2587 }
2588
2589 if (nBytes % nAlignment)
2590 {
2591 return (nBytes + (nAlignment - (nBytes % nAlignment)));
2592 }
2593
2594 return nBytes;
2595 }
2596
2603 static tInt GuessPixelFormat(const tBitmapFormat* pFormat)
2604 {
2605 if (pFormat->nPixelFormat != cImage::PF_UNKNOWN)
2606 {
2607 // nothing to guess
2608 return pFormat->nPixelFormat;
2609 }
2610
2611 tUInt nExpectedSize = (pFormat->nBitsPerPixel / 8) * pFormat->nWidth * pFormat->nHeight;
2612 if (nExpectedSize > static_cast<tUInt>(pFormat->nSize))
2613 {
2614 // Size does not match our default formats
2615 return cImage::PF_UNKNOWN;
2616 }
2617
2618 switch (pFormat->nBitsPerPixel)
2619 {
2620 case 8: return cImage::PF_GREYSCALE_8;
2621 case 16: return cImage::PF_RGB_555;
2622 case 24: return cImage::PF_RGB_888;
2623 case 32: return cImage::PF_RGBA_8888;
2624 default: return cImage::PF_UNKNOWN;
2625 }
2626 }
2627
2635 static tInt GetBitsPerPixelFromFormat(tInt nFormat)
2636 {
2637 return CalcBitsPerPixelFromPixelFormat(nFormat);
2638 }
2639
2647 static tInt GetDefaultFormatFromBpp(tInt nBpp)
2648 {
2649 switch (nBpp)
2650 {
2651 case 32: return PF_RGBA_8888;
2652 case 24: return PF_RGB_888;
2653 case 16: return PF_RGB_555;
2654 case 8: return PF_GREYSCALE_8;
2655 default: return PF_UNKNOWN;
2656 }
2657 }
2658
2666 static tChar const* GetPixelFormatIdentifier(const tInt nImage)
2667 {
2668 switch (nImage)
2669 {
2670 case PF_UNKNOWN:
2671 {
2672 return "UNKNOWN";
2673 }
2674 case PF_8BIT:
2675 {
2676 return "8 bit";
2677 }
2678 case PF_GREYSCALE_8:
2679 {
2680 return "8 bit greyscale";
2681 }
2682 case PF_RGB_8:
2683 {
2684 return "8 bit RGB";
2685 }
2686 case PF_16BIT:
2687 {
2688 return "16 bit";
2689 }
2690 case PF_GREYSCALE_10:
2691 {
2692 return "10 bit greyscale";
2693 }
2694 case PF_GREYSCALE_12:
2695 {
2696 return "12 bit greyscale";
2697 }
2698 case PF_GREYSCALE_14:
2699 {
2700 return "14 bit greyscale";
2701 }
2702 case PF_GREYSCALE_16:
2703 {
2704 return "16 bit greyscale";
2705 }
2706 case PF_RGB_444:
2707 {
2708 return "12 bit RGB";
2709 }
2710 case PF_RGB_555:
2711 {
2712 return "15 bit RGB";
2713 }
2714 case PF_RGB_565:
2715 {
2716 return "16 bit RGB";
2717 }
2718 case PF_RGBA_4444:
2719 {
2720 return "16 bit RGBA";
2721 }
2722 case PF_ABGR_4444:
2723 {
2724 return "16 bit ABGR";
2725 }
2726 case PF_RIII_10:
2727 {
2728 return "10 bit RIII";
2729 }
2730 case PF_RIII_12:
2731 {
2732 return "12 bit RIII";
2733 }
2734 case PF_RIII_14:
2735 {
2736 return "14 bit RIII";
2737 }
2738 case PF_RIII_16:
2739 {
2740 return "16 bit RIII";
2741 }
2742 case PF_BGR_555:
2743 {
2744 return "15 bit BGR";
2745 }
2746 case PF_BGR_565:
2747 {
2748 return "16 bit BGR";
2749 }
2750 case PF_RGBA_5551:
2751 {
2752 return "16 bit RGBA 5551";
2753 }
2754 case PF_BGRA_5551:
2755 {
2756 return "16 bit BGRA 5551";
2757 }
2758 case PF_ARGB_1555:
2759 {
2760 return "16 bit ARGB 1555";
2761 }
2762 case PF_ABGR_1555:
2763 {
2764 return "16 bit ABGR 1555";
2765 }
2766 case PF_24BIT:
2767 {
2768 return "24 bit";
2769 }
2770 case PF_GREYSCALE_18:
2771 {
2772 return "18 bit greyscale";
2773 }
2774 case PF_GREYSCALE_20:
2775 {
2776 return "20 bit greyscale";
2777 }
2778 case PF_GREYSCALE_22:
2779 {
2780 return "22 bit greyscale";
2781 }
2782 case PF_GREYSCALE_24:
2783 {
2784 return "24 bit greyscale";
2785 }
2786 case PF_RGB_888:
2787 {
2788 return "24 bit RGB";
2789 }
2790 case PF_BGR_888:
2791 {
2792 return "24 bit BGR";
2793 }
2794 case PF_32BIT:
2795 {
2796 return "32 bit";
2797 }
2798 case PF_ARGB_8888:
2799 {
2800 return "32 bit ARGB";
2801 }
2802 case PF_ABGR_8888:
2803 {
2804 return "32 bit ABGR";
2805 }
2806 case PF_RGBA_8888:
2807 {
2808 return "32 bit RGBA";
2809 }
2810 case PF_BGRA_8888:
2811 {
2812 return "32 bit BGRA";
2813 }
2814 case PF_xRGB_8888:
2815 {
2816 return "32 bit xRGB";
2817 }
2818 case PF_xBGR_8888:
2819 {
2820 return "32 bit xBGR";
2821 }
2822 case PF_RGBx_8888:
2823 {
2824 return "32 bit RGBx";
2825 }
2826 case PF_BGRx_8888:
2827 {
2828 return "32 bit BGRx";
2829 }
2830 case PF_GREYSCALE_32:
2831 {
2832 return "32bit greyscale";
2833 }
2835 {
2836 return "32 bit float greyscale";
2837 }
2838 case PF_YUV420P_888:
2839 {
2840 return "24 bit YUV420P";
2841 }
2842 case PF_CUSTOM:
2843 {
2844 return "CUSTOM";
2845 }
2846 default:
2847 {
2848 return "NOT DEFINED";
2849 }
2850 }
2851 }
2852
2853protected: // internal
2859 tResult Initialize()
2860 {
2861 adtf::util::cMemoryBlock::MemSet(&m_sFormat, 0, sizeof(m_sFormat));
2862
2863 m_bReference = tFalse;
2864 m_pBitmap = NULL;
2865 m_hBitmapMemory = NULL;
2866 m_pPalette = NULL;
2867 m_psBitmapInfo = NULL;
2870
2871 RETURN_NOERROR;
2872 }
2873
2881 tResult Alloc(const tBitmapFormat* psFormat)
2882 {
2883 if (m_bReference)
2884 {
2885 m_pBitmap = NULL;
2886 m_bReference = tFalse;
2887 }
2888
2889 if (m_pBitmap != NULL && psFormat->nSize == m_sFormat.nSize)
2890 {
2891 RETURN_NOERROR;
2892 }
2893
2894 Free();
2895 if (m_sFormat.nBytesPerLine == 0)
2896 {
2897 m_sFormat.nBytesPerLine =
2899 }
2900
2901 if (psFormat->nSize > 0)
2902 {
2903 RETURN_IF_FAILED(AllocImpl(psFormat->nSize, &m_hBitmapMemory, (tVoid**) &m_pBitmap));
2904 }
2905
2906 adtf::util::cMemoryBlock::MemCopy(&m_sFormat, psFormat, sizeof(m_sFormat));
2907
2908 RETURN_NOERROR;
2909 }
2910
2916 tResult Free()
2917 {
2919 FreePalette();
2920 adtf::util::cMemoryBlock::MemSet(&m_sFormat, 0, sizeof(m_sFormat));
2921
2922 if (!m_bReference)
2923 {
2924 if (m_hBitmapMemory != NULL)
2925 {
2927 m_hBitmapMemory = NULL;
2928 }
2929 else if (m_pBitmap != NULL)
2930 {
2931 delete[] m_pBitmap;
2932 }
2933 }
2934
2935 m_pBitmap = NULL;
2936 m_bReference = tFalse;
2937
2938 RETURN_NOERROR;
2939 }
2940
2950 tResult AllocImpl(tInt nSize, tHandle* hMemory, tVoid** pBuffer)
2951 {
2952 *hMemory = NULL;
2953 *pBuffer = NULL;
2954
2955 tInt nMemBlockSize = nSize + m_nDefaultMemoryAlignment - 1;
2956
2957 *hMemory = (tHandle) new tUInt8[nMemBlockSize];
2958 if (*hMemory == NULL)
2959 {
2960 RETURN_ERROR(ERR_MEMORY);
2961 }
2962
2963 *pBuffer = (tUInt8*) ((reinterpret_cast<tMemoryAddress>(*hMemory) + m_nDefaultMemoryAlignment - 1) &
2965
2966 RETURN_NOERROR;
2967 }
2968
2976 tResult FreeImpl(tHandle hMemory)
2977 {
2978 delete[] ((tUInt8*) hMemory);
2979
2980 RETURN_NOERROR;
2981 }
2982
2990 tResult AllocPalette(tInt nPaletteSize)
2991 {
2992 if (m_pPalette != NULL && nPaletteSize == m_sFormat.nPaletteSize)
2993 {
2994 RETURN_NOERROR;
2995 }
2996
2997 FreePalette();
2998
2999 if (nPaletteSize != 0)
3000 {
3001 m_pPalette = new tColor[nPaletteSize];
3002 if (m_pPalette == NULL)
3003 {
3004 RETURN_ERROR(ERR_MEMORY);
3005 }
3006 }
3007
3008 RETURN_NOERROR;
3009 }
3010
3016 tResult FreePalette()
3017 {
3018 if (m_pPalette != NULL)
3019 {
3020 delete[] m_pPalette;
3021 m_pPalette = NULL;
3022 }
3023
3025 m_sFormat.nPaletteSize = 0;
3026
3027 RETURN_NOERROR;
3028 }
3029
3036 {
3038
3039 tInt l_nPaletteSize = m_sFormat.nPaletteSize;
3040 if (l_nPaletteSize == 0 && m_pPalette != NULL)
3041 {
3042 l_nPaletteSize = m_nGreyPaletteSize;
3043 }
3044
3045 tInt nBitmapInfoSize = sizeof(tWin32BitmapInfo) + sizeof(tColor) * l_nPaletteSize;
3046
3047 m_psBitmapInfo = (tWin32BitmapInfo*) new tUInt8[nBitmapInfoSize];
3048 if (m_psBitmapInfo == NULL)
3049 {
3050 RETURN_ERROR(ERR_MEMORY);
3051 }
3052
3053 adtf::util::cMemoryBlock::MemSet(m_psBitmapInfo, 0, nBitmapInfoSize);
3054
3055 m_nBitmapInfoSize = nBitmapInfoSize;
3056
3057 tWin32BitmapInfoHeader* l_pHdr = &m_psBitmapInfo->sHeader;
3058 l_pHdr->nSize = sizeof(tWin32BitmapInfoHeader);
3059 l_pHdr->nWidth = m_sFormat.nWidth;
3060 l_pHdr->nHeight = m_sFormat.nHeight;
3061 l_pHdr->nPlanes = 1;
3062#ifdef WIN32
3063 l_pHdr->nBitCount = (WORD) m_sFormat.nBitsPerPixel;
3064 l_pHdr->nCompression = BI_RGB;
3065#else
3066 l_pHdr->nBitCount = (tUInt8) m_sFormat.nBitsPerPixel;
3067 l_pHdr->nCompression = 0L;
3068#endif
3069 l_pHdr->nSizeImage = m_sFormat.nSize;
3070 l_pHdr->nXPelsPerMeter = 0;
3071 l_pHdr->nYPelsPerMeter = 0;
3072 l_pHdr->nClrUsed = l_nPaletteSize;
3073 l_pHdr->nClrImportant = 0;
3074
3075 if (l_nPaletteSize > 0 && m_pPalette != NULL)
3076 {
3077 tColor* l_aPalette = (tColor*) ((tUInt8*) m_psBitmapInfo + sizeof(tWin32BitmapInfoHeader));
3078 adtf::util::cMemoryBlock::MemCopy(l_aPalette, m_pPalette, l_nPaletteSize * sizeof(tColor));
3079 }
3080
3081 RETURN_NOERROR;
3082 }
3083
3090 {
3091 if (m_psBitmapInfo != NULL)
3092 {
3093 delete[] ((tUInt8*) m_psBitmapInfo);
3094 m_psBitmapInfo = NULL;
3095 }
3096
3098
3099 RETURN_NOERROR;
3100 }
3101
3102protected: // internal blitting operations
3114 static tResult Blit_impl(const tUInt8* pSrcBitmapData,
3115 const tBitmapFormat* psSrcBitmapFormat,
3116 tUInt8* pDestBitmapData,
3117 const tBitmapFormat* psDestBitmapFormat,
3118 tInt nFlags)
3119 {
3120 RETURN_IF_POINTER_NULL(pSrcBitmapData);
3121 RETURN_IF_POINTER_NULL(psSrcBitmapFormat);
3122 RETURN_IF_POINTER_NULL(pDestBitmapData);
3123 RETURN_IF_POINTER_NULL(psDestBitmapFormat);
3124
3125 if (psSrcBitmapFormat->nPixelFormat != psDestBitmapFormat->nPixelFormat)
3126 {
3127 return Convert_impl(pSrcBitmapData, psSrcBitmapFormat, pDestBitmapData, psDestBitmapFormat, nFlags, 0x0);
3128 }
3129
3130 tInt l_nCopyWidth = std::min<tInt>(psSrcBitmapFormat->nBytesPerLine, psDestBitmapFormat->nBytesPerLine);
3131 tInt l_nCopyHeight = std::min<tInt>(psSrcBitmapFormat->nHeight, psDestBitmapFormat->nHeight);
3132
3133 const tUInt8* l_pSrcLine = pSrcBitmapData;
3134 tUInt8* l_pDestLine = pDestBitmapData;
3135
3136 if ((nFlags & BLIT_VerticalFlip) != 0)
3137 {
3138 l_pDestLine += psDestBitmapFormat->nBytesPerLine * (l_nCopyHeight - 1);
3139
3140 for (tInt y = 0; y < l_nCopyHeight; y++)
3141 {
3142 adtf::util::cMemoryBlock::MemCopy(l_pDestLine, l_pSrcLine, l_nCopyWidth);
3143
3144 l_pSrcLine += psSrcBitmapFormat->nBytesPerLine;
3145 l_pDestLine -= psDestBitmapFormat->nBytesPerLine;
3146 }
3147 }
3148 else
3149 {
3150 if (psSrcBitmapFormat->nBytesPerLine == psDestBitmapFormat->nBytesPerLine)
3151 {
3152 adtf::util::cMemoryBlock::MemCopy(l_pDestLine, l_pSrcLine,
3153 l_nCopyHeight * psSrcBitmapFormat->nBytesPerLine);
3154 }
3155 else
3156 {
3157 for (tInt y = 0; y < l_nCopyHeight; y++)
3158 {
3159 adtf::util::cMemoryBlock::MemCopy(l_pDestLine, l_pSrcLine, l_nCopyWidth);
3160
3161 l_pSrcLine += psSrcBitmapFormat->nBytesPerLine;
3162 l_pDestLine += psDestBitmapFormat->nBytesPerLine;
3163 }
3164 }
3165 }
3166
3167 RETURN_NOERROR;
3168 }
3169
3182 static tResult StretchBlit_impl(const tUInt8* pSrcBitmapData,
3183 const tBitmapFormat* psSrcBitmapFormat,
3184 tUInt8* pDestBitmapData,
3185 const tBitmapFormat* psDestBitmapFormat,
3186 tInt nFlags,
3187 tUInt32 ui32Mask = 0x0)
3188 {
3189 RETURN_IF_POINTER_NULL(pSrcBitmapData);
3190 RETURN_IF_POINTER_NULL(psSrcBitmapFormat);
3191 RETURN_IF_POINTER_NULL(pDestBitmapData);
3192 RETURN_IF_POINTER_NULL(psDestBitmapFormat);
3193
3194 cImage oTempImage;
3195 if (psSrcBitmapFormat->nBitsPerPixel != psDestBitmapFormat->nBitsPerPixel)
3196 {
3197 if (psSrcBitmapFormat->nWidth == psDestBitmapFormat->nWidth &&
3198 psSrcBitmapFormat->nHeight == psDestBitmapFormat->nHeight)
3199 {
3200 return Convert_impl(pSrcBitmapData, psSrcBitmapFormat, pDestBitmapData, psDestBitmapFormat, nFlags,
3201 ui32Mask);
3202 }
3203 else
3204 {
3205 tBitmapFormat oNewFormat;
3206 adtf::util::cMemoryBlock::MemCopy(&oNewFormat, psSrcBitmapFormat, sizeof(tBitmapFormat));
3207 oNewFormat.nBitsPerPixel = psDestBitmapFormat->nBitsPerPixel;
3208 oNewFormat.nBytesPerLine = CalcAlignedMemSize(oNewFormat.nWidth * oNewFormat.nBitsPerPixel / 8,
3210 oNewFormat.nPixelFormat = psDestBitmapFormat->nPixelFormat;
3211
3212 RETURN_IF_FAILED(oTempImage.Create(psSrcBitmapFormat->nWidth, psSrcBitmapFormat->nHeight,
3213 psDestBitmapFormat->nBitsPerPixel, 0, NULL,
3214 psDestBitmapFormat->nPixelFormat));
3215 RETURN_IF_FAILED(
3216 Convert_impl(pSrcBitmapData, psSrcBitmapFormat, oTempImage.GetBitmap(), &oNewFormat, nFlags, 0x0));
3217 pSrcBitmapData = oTempImage.GetBitmap();
3218 psSrcBitmapFormat = oTempImage.GetFormat();
3219 }
3220 }
3221
3222 if (psSrcBitmapFormat->nWidth == psDestBitmapFormat->nWidth &&
3223 psSrcBitmapFormat->nHeight == psDestBitmapFormat->nHeight)
3224 {
3225 return Blit(pSrcBitmapData, psSrcBitmapFormat, pDestBitmapData, psDestBitmapFormat, nFlags);
3226 }
3227
3228 tInt l_nCopyWidth = psDestBitmapFormat->nWidth;
3229 tInt l_nCopyHeight = psDestBitmapFormat->nHeight;
3230
3231 const tUInt8* l_pSrcLine = pSrcBitmapData;
3232 tUInt8* l_pDestLine = pDestBitmapData;
3233 tInt l_nBytesPerPixel = psSrcBitmapFormat->nBitsPerPixel / 8;
3234
3235 tInt nCopySrcStep = psSrcBitmapFormat->nWidth;
3236 tInt nCopySrcMax = l_nCopyWidth * nCopySrcStep;
3237
3238 tInt y2;
3239 tInt x2;
3240
3241 for (tInt y = 0; y < l_nCopyHeight; y++)
3242 {
3243 y2 = tInt(y * tFloat(psSrcBitmapFormat->nHeight) / l_nCopyHeight);
3244
3245 l_pSrcLine = pSrcBitmapData + y2 * psSrcBitmapFormat->nBytesPerLine;
3246 l_pDestLine = pDestBitmapData + y * psDestBitmapFormat->nBytesPerLine;
3247
3248 if (l_nBytesPerPixel == 1)
3249 {
3250 for (tInt x = 0; x < nCopySrcMax; x += nCopySrcStep)
3251 {
3252 *(l_pDestLine++) = *(l_pSrcLine + x / l_nCopyWidth);
3253 }
3254 }
3255 else if (l_nBytesPerPixel == 2)
3256 {
3257 tUInt16* l_pui16SrcLine = (tUInt16*) l_pSrcLine;
3258 tUInt16* l_pui16DestLine = (tUInt16*) l_pDestLine;
3259
3260 for (tInt x = 0; x < nCopySrcMax; x += nCopySrcStep)
3261 {
3262 *(l_pui16DestLine++) = *(l_pui16SrcLine + x / l_nCopyWidth);
3263 }
3264 }
3265 else if (l_nBytesPerPixel == 3)
3266 {
3267 const tUInt8* l_pSrc;
3268 tUInt8* l_pDest;
3269 for (tInt x = 0; x < l_nCopyWidth; x++)
3270 {
3271 x2 = tInt(x * tFloat(psSrcBitmapFormat->nWidth) / l_nCopyWidth);
3272
3273 l_pDest = l_pDestLine + x * l_nBytesPerPixel;
3274 l_pSrc = l_pSrcLine + x2 * l_nBytesPerPixel;
3275
3276 *l_pDest++ = *l_pSrc++;
3277 *l_pDest++ = *l_pSrc++;
3278 *l_pDest++ = *l_pSrc++;
3279 }
3280 }
3281 else if (l_nBytesPerPixel == 4)
3282 {
3283 tUInt32* l_pui32SrcLine = (tUInt32*) l_pSrcLine;
3284 tUInt32* l_pui32DestLine = (tUInt32*) l_pDestLine;
3285
3286 for (tInt x = 0; x < nCopySrcMax; x += nCopySrcStep)
3287 {
3288 *(l_pui32DestLine++) = *(l_pui32SrcLine + x / l_nCopyWidth);
3289 }
3290 }
3291 }
3292
3293 RETURN_NOERROR;
3294 }
3295
3309 static tResult Convert_impl(const tUInt8* pSrcBitmapData,
3310 const tBitmapFormat* psSrcBitmapFormat,
3311 tUInt8* pDestBitmapData,
3312 const tBitmapFormat* psDestBitmapFormat,
3313 tInt nFlags,
3314 tUInt32 ui32Mask)
3315 {
3316 if (psSrcBitmapFormat->nPixelFormat == IImage::PF_UNKNOWN ||
3317 psDestBitmapFormat->nPixelFormat == IImage::PF_UNKNOWN)
3318 {
3319 RETURN_ERROR(ERR_UNKNOWN_FORMAT);
3320 }
3321
3322 if (psSrcBitmapFormat->nPixelFormat == IImage::PF_CUSTOM ||
3323 psDestBitmapFormat->nPixelFormat == IImage::PF_CUSTOM)
3324 {
3325 RETURN_ERROR(ERR_UNKNOWN_FORMAT);
3326 }
3327
3328 if (psSrcBitmapFormat->nPixelFormat == PF_YUV420P_888 || psDestBitmapFormat->nPixelFormat == PF_YUV420P_888)
3329 {
3330 RETURN_ERROR(ERR_NOT_SUPPORTED);
3331 }
3332
3333 const tUInt8* l_pSrcLine = pSrcBitmapData;
3334 tUInt8* l_pDestLine = pDestBitmapData;
3335
3336 tInt l_nSrcBytesPerPixel = psSrcBitmapFormat->nBitsPerPixel / 8;
3337 tInt l_nDestBytesPerPixel = psDestBitmapFormat->nBitsPerPixel / 8;
3338
3339 tInt l_nCopyWidth = std::min<tInt>(psSrcBitmapFormat->nWidth, psDestBitmapFormat->nWidth);
3340 tInt l_nCopyHeight = std::min<tInt>(psSrcBitmapFormat->nHeight, psDestBitmapFormat->nHeight);
3341 tUInt16 c16;
3342 tUInt8 nRed, nGreen, nBlue;
3343
3344 // this is removed because it makes no sense to copy the smaller image onto the lower end
3345 // of the destination image
3346 // if (psSrcBitmapFormat->nHeight >= psDestBitmapFormat->nHeight)
3347 //{
3348 // l_pSrcLine += (psSrcBitmapFormat->nHeight - psDestBitmapFormat->nHeight) *
3349 // psSrcBitmapFormat->nBytesPerLine;
3350 //}
3351 // else
3352 //{
3353 // l_pDestLine += (psDestBitmapFormat->nHeight - psSrcBitmapFormat->nHeight) *
3354 // psDestBitmapFormat->nBytesPerLine;
3355 //}
3356
3357 tInt nShiftBits = 0;
3358 if (ui32Mask != 0x0)
3359 {
3360 tUInt32 ui32TempMask;
3361 for (ui32TempMask = ui32Mask; !(ui32TempMask & 0x01); ui32TempMask >>= 1)
3362 {
3363 ++nShiftBits;
3364 }
3365
3366 tInt nDataBits = 0;
3367 for (; (ui32TempMask & 0x01); ui32TempMask >>= 1)
3368 {
3369 ++nDataBits;
3370 }
3371
3372 nShiftBits -=
3373 std::min<tInt>(psSrcBitmapFormat->nBitsPerPixel, psDestBitmapFormat->nBitsPerPixel) - nDataBits;
3374 if (nShiftBits < 0)
3375 {
3376 nShiftBits = 0;
3377 }
3378 }
3379
3380 tBool bVFlip = ((nFlags & BLIT_VerticalFlip) != 0);
3381
3382 if (bVFlip)
3383 {
3384 l_pDestLine += (l_nCopyHeight - 1) * psDestBitmapFormat->nBytesPerLine;
3385 }
3386
3387 // conversion
3388 for (tInt y = 0; y < l_nCopyHeight; y++)
3389 {
3390 // no conversion is needed
3391 if (psDestBitmapFormat->nPixelFormat == psSrcBitmapFormat->nPixelFormat)
3392 {
3393 adtf::util::cMemoryBlock::MemCopy(l_pDestLine, l_pSrcLine, l_nCopyWidth * l_nSrcBytesPerPixel);
3394 }
3395 else if (l_nSrcBytesPerPixel == 1)
3396 {
3397 if (0 != psSrcBitmapFormat->nPaletteSize)
3398 {
3399 RETURN_ERROR(ERR_NOT_SUPPORTED);
3400 }
3401
3402 const tUInt8* l_pSrc = l_pSrcLine;
3403 tUInt8 c8;
3404
3405 if (l_nDestBytesPerPixel == 3)
3406 {
3407 tUInt8* l_pDest = l_pDestLine;
3408 for (tInt x = 0; x < l_nCopyWidth; x++)
3409 {
3410 c8 = *(l_pSrc++);
3411
3412 *(l_pDest++) = c8;
3413 *(l_pDest++) = c8;
3414 *(l_pDest++) = c8;
3415 }
3416 }
3417 else if (l_nDestBytesPerPixel == 4)
3418 {
3419 tUInt32* l_pDest = (tUInt32*) l_pDestLine;
3420 tInt rs = 0, gs = 0, bs = 0;
3421
3422 switch (psDestBitmapFormat->nPixelFormat)
3423 {
3424 case PF_RGBA_8888:
3425 case PF_BGRA_8888:
3426 {
3427 rs = 0;
3428 gs = 8;
3429 bs = 16;
3430 }
3431 break;
3432
3433 case PF_ARGB_8888:
3434 case PF_ABGR_8888:
3435 {
3436 rs = 8;
3437 gs = 16;
3438 bs = 24;
3439 }
3440 break;
3441
3442 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
3443 }
3444
3445 for (tInt x = 0; x < l_nCopyWidth; x++)
3446 {
3447 tUInt32 k8 = *(l_pSrc++);
3448 *l_pDest++ = (k8 << bs) | (k8 << gs) | (k8 << rs);
3449 }
3450 }
3451 else if (l_nDestBytesPerPixel == 2)
3452 {
3453 tUInt16* l_pDest = (tUInt16*) l_pDestLine;
3454
3455 if (psDestBitmapFormat->nPixelFormat == PF_RGB_555)
3456 {
3457 for (tInt x = 0; x < l_nCopyWidth; x++)
3458 {
3459 c8 = *(l_pSrc++);
3460 *(l_pDest++) = RGB555(c8, c8, c8);
3461 }
3462 }
3463 else if (psDestBitmapFormat->nPixelFormat == PF_RGB_565)
3464 {
3465 for (tInt x = 0; x < l_nCopyWidth; x++)
3466 {
3467 c8 = *(l_pSrc++);
3468 *(l_pDest++) = RGB565(c8, c8, c8);
3469 }
3470 }
3471 else
3472 {
3473 if (ui32Mask == 0)
3474 {
3475 for (tInt x = 0; x < l_nCopyWidth; x++)
3476 {
3477 c8 = *(l_pSrc++);
3478 *(l_pDest++) = (((tUInt16) c8) << 8);
3479 }
3480 }
3481 else
3482 {
3483 for (tInt x = 0; x < l_nCopyWidth; x++)
3484 {
3485 c8 = *(l_pSrc++);
3486 *(l_pDest++) = (tUInt16) ((((tUInt32) c8) << nShiftBits) & ui32Mask);
3487 }
3488 }
3489 }
3490 }
3491 }
3492 else if (l_nSrcBytesPerPixel == 2)
3493 {
3494 if (l_nDestBytesPerPixel == 1)
3495 {
3496 tUInt16* l_pSrc = (tUInt16*) l_pSrcLine;
3497 tUInt8* l_pDest = l_pDestLine;
3498 if (psSrcBitmapFormat->nPixelFormat == PF_RGB_555)
3499 {
3500 for (tInt x = 0; x < l_nCopyWidth; x++)
3501 {
3502 c16 = *(l_pSrc++);
3503 nRed = GetRed_RGB555(c16);
3504 nGreen = GetGreen_RGB555(c16);
3505 nBlue = GetBlue_RGB555(c16);
3506 *(l_pDest++) = Brightness((tInt) nRed, (tInt) nGreen, (tInt) nBlue);
3507 }
3508 }
3509 else if (psSrcBitmapFormat->nPixelFormat == PF_RGB_565)
3510 {
3511 for (tInt x = 0; x < l_nCopyWidth; x++)
3512 {
3513 c16 = *(l_pSrc++);
3514 nRed = GetRed_RGB565(c16);
3515 nGreen = GetGreen_RGB565(c16);
3516 nBlue = GetBlue_RGB565(c16);
3517 *(l_pDest++) = Brightness((tInt) nRed, (tInt) nGreen, (tInt) nBlue);
3518 }
3519 }
3520 else
3521 {
3522 if (ui32Mask == 0)
3523 {
3524 for (tInt x = 0; x < l_nCopyWidth; x++)
3525 {
3526 *(l_pDest++) = (tUInt8) (*(l_pSrc++) >> 8);
3527 }
3528 }
3529 else
3530 {
3531 for (tInt x = 0; x < l_nCopyWidth; x++)
3532 {
3533 *(l_pDest++) = (tUInt8) (((*(l_pSrc++)) & ui32Mask) >> nShiftBits);
3534 }
3535 }
3536 }
3537 }
3538 else if (l_nDestBytesPerPixel == 2)
3539 {
3540 tUInt16* l_pDest = (tUInt16*) l_pDestLine;
3541 tUInt16* l_pSrc = (tUInt16*) l_pSrcLine;
3542
3543 tInt iSRPos, iSGPos, iSBPos, iSAPos = 16;
3544 tInt iDRPos, iDGPos, iDBPos, iDAPos = 16;
3545 tUInt16 iSMask, iSGMask, iSAMask = 0;
3546 tUInt16 iDMask, iDGMask, iDAMask = 0;
3547
3548 switch (psSrcBitmapFormat->nPixelFormat)
3549 {
3550 case PF_RGB_444:
3551 iSRPos = 0;
3552 iSGPos = 4;
3553 iSBPos = 8;
3554 iSMask = iSGMask = 0xf;
3555 break;
3556 case PF_RGB_555:
3557 iSRPos = 0;
3558 iSGPos = 5;
3559 iSBPos = 10;
3560 iSMask = iSGMask = 0x1f;
3561 break;
3562 case PF_BGR_555:
3563 iSRPos = 10;
3564 iSGPos = 5;
3565 iSBPos = 0;
3566 iSMask = iSGMask = 0x1f;
3567 break;
3568 case PF_RGB_565:
3569 iSRPos = 0;
3570 iSGPos = 5;
3571 iSBPos = 11;
3572 iSMask = 0x1f;
3573 iSGMask = 0x3f;
3574 break;
3575 case PF_BGR_565:
3576 iSRPos = 11;
3577 iSGPos = 5;
3578 iSBPos = 0;
3579 iSMask = 0x1f;
3580 iSGMask = 0x3f;
3581 break;
3582 case PF_RGBA_4444:
3583 iSRPos = 0;
3584 iSGPos = 4;
3585 iSBPos = 8;
3586 iSAPos = 12;
3587 iSMask = iSGMask = 0xf;
3588 iSAMask = 0xf;
3589 break;
3590 case PF_ABGR_4444:
3591 iSAPos = 0;
3592 iSBPos = 4;
3593 iSGPos = 8;
3594 iSRPos = 12;
3595 iSMask = iSGMask = 0xf;
3596 iSAMask = 0xf;
3597 break;
3598 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
3599 }
3600
3601 switch (psDestBitmapFormat->nPixelFormat)
3602 {
3603 case PF_RGB_444:
3604 iDRPos = 0;
3605 iDGPos = 4;
3606 iDBPos = 8;
3607 iDMask = iDGMask = 0xf;
3608 break;
3609 case PF_RGB_555:
3610 iDRPos = 0;
3611 iDGPos = 5;
3612 iDBPos = 10;
3613 iDMask = iDGMask = 0x1f;
3614 break;
3615 case PF_BGR_555:
3616 iDRPos = 10;
3617 iDGPos = 5;
3618 iDBPos = 0;
3619 iDMask = iDGMask = 0x1f;
3620 break;
3621 case PF_RGB_565:
3622 iDRPos = 0;
3623 iDGPos = 5;
3624 iDBPos = 11;
3625 iDMask = 0x1f;
3626 iDGMask = 0x3f;
3627 break;
3628 case PF_BGR_565:
3629 iDRPos = 11;
3630 iDGPos = 5;
3631 iDBPos = 0;
3632 iDMask = 0x1f;
3633 iDGMask = 0x3f;
3634 break;
3635 case PF_RGBA_4444:
3636 iDRPos = 0;
3637 iDGPos = 4;
3638 iDBPos = 8;
3639 iDAPos = 12;
3640 iDMask = iDGMask = 0xf;
3641 iDAMask = 0xf;
3642 break;
3643 case PF_ABGR_4444:
3644 iDAPos = 0;
3645 iDBPos = 4;
3646 iDGPos = 8;
3647 iDRPos = 12;
3648 iDMask = iDGMask = 0xf;
3649 iDAMask = 0xf;
3650 break;
3651 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
3652 }
3653
3654 tUInt16 iDRMask = iDMask;
3655 tUInt16 iDBMask = iDMask;
3656 tUInt16 iSRMask = iSMask;
3657 tUInt16 iSBMask = iSMask;
3658
3659 iDRMask = AdjustMasks(iSRMask, iDRMask, iSRPos);
3660 iDBMask = AdjustMasks(iSBMask, iDBMask, iSBPos);
3661 iDGMask = AdjustMasks(iSGMask, iDGMask, iSGPos);
3662 iSAMask = AdjustMasks(iSAMask, iDAMask, iSAPos);
3663
3664 if (iSRPos < 0)
3665 {
3666 iDRPos -= iSRPos;
3667 iDRMask >>= -iSRPos;
3668 iSRPos = 0;
3669 }
3670
3671 for (tInt x = 0; x < l_nCopyWidth; x++)
3672 {
3673 tUInt16 c = *l_pSrc++;
3674
3675 *l_pDest++ = (((c >> iSRPos) & iDRMask) << iDRPos) | (((c >> iSGPos) & iDGMask) << iDGPos) |
3676 (((c >> iSBPos) & iDBMask) << iDBPos) | (((c >> iSAPos) & iSAMask) << iDAPos);
3677 }
3678 }
3679 else if (l_nDestBytesPerPixel == 3)
3680 {
3681 tUInt8* l_pDest = l_pDestLine;
3682 tUInt16* l_pSrc = (tUInt16*) l_pSrcLine;
3683
3684 tInt iSl, iSRr, iSGl, iSGr, iSBr;
3685 tInt iDR, iDB;
3686
3687 switch (psSrcBitmapFormat->nPixelFormat)
3688 {
3689 case PF_RGB_555:
3690 iSRr = 0;
3691 iSGr = 5;
3692 iSBr = 10;
3693 iSl = iSGl = 3;
3694 break;
3695 case PF_RGB_565:
3696 iSRr = 0;
3697 iSGr = 5;
3698 iSBr = 11;
3699 iSl = 3;
3700 iSGl = 2;
3701 break;
3702 case PF_BGR_555:
3703 iSRr = 10;
3704 iSGr = 5;
3705 iSBr = 0;
3706 iSl = iSGl = 3;
3707 break;
3708 case PF_BGR_565:
3709 iSRr = 11;
3710 iSGr = 5;
3711 iSBr = 0;
3712 iSl = 3;
3713 iSGl = 2;
3714 break;
3715 case PF_RGB_444:
3716 iSRr = 0;
3717 iSGr = 4;
3718 iSBr = 8;
3719 iSl = iSGl = 4;
3720 break;
3721 case PF_RGBA_4444:
3722 iSRr = 0;
3723 iSGr = 4;
3724 iSBr = 8;
3725 iSl = iSGl = 4;
3726 break;
3727 case PF_ABGR_4444:
3728 iSRr = 12;
3729 iSGr = 8;
3730 iSBr = 4;
3731 iSl = iSGl = 4;
3732 break;
3733 case PF_GREYSCALE_16:
3734 iSRr = 8;
3735 iSGr = 8;
3736 iSBr = 8;
3737 iSl = iSGl = 0;
3738 break;
3739 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
3740 }
3741
3742 switch (psDestBitmapFormat->nPixelFormat)
3743 {
3744 case PF_RGB_888:
3745 iDR = 0;
3746 iDB = 2;
3747 break;
3748 case PF_BGR_888:
3749 iDR = 2;
3750 iDB = 0;
3751 break;
3752 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
3753 }
3754
3755 for (tInt x = 0; x < l_nCopyWidth; x++)
3756 {
3757 tUInt16 const k16 = *l_pSrc++;
3758 l_pDest[iDR] = static_cast<uint8_t>((k16 >> iSRr) << iSl);
3759 l_pDest[1] = static_cast<uint8_t>((k16 >> iSGr) << iSGl);
3760 l_pDest[iDB] = static_cast<uint8_t>((k16 >> iSBr) << iSl);
3761 l_pDest += 3;
3762 }
3763 }
3764 else if (l_nDestBytesPerPixel == 4)
3765 {
3766 tUInt8* l_pDest = l_pDestLine;
3767 tUInt16* l_pSrc = (tUInt16*) l_pSrcLine;
3768
3769 tInt iSl, iSRr, iSGl, iSGr, iSBr, iSAr = 16;
3770
3771 switch (psSrcBitmapFormat->nPixelFormat)
3772 {
3773 case PF_RGB_555:
3774 iSRr = 0;
3775 iSGr = 5;
3776 iSBr = 10;
3777 iSl = iSGl = 3;
3778 break;
3779 case PF_RGB_565:
3780 iSRr = 0;
3781 iSGr = 5;
3782 iSBr = 11;
3783 iSl = 3;
3784 iSGl = 2;
3785 break;
3786 case PF_BGR_555:
3787 iSRr = 10;
3788 iSGr = 5;
3789 iSBr = 0;
3790 iSl = iSGl = 3;
3791 break;
3792 case PF_BGR_565:
3793 iSRr = 11;
3794 iSGr = 5;
3795 iSBr = 0;
3796 iSl = 3;
3797 iSGl = 2;
3798 break;
3799 case PF_RGB_444:
3800 iSRr = 0;
3801 iSGr = 4;
3802 iSBr = 8;
3803 iSl = iSGl = 4;
3804 break;
3805 case PF_RGBA_4444:
3806 iSRr = 0;
3807 iSGr = 4;
3808 iSBr = 8;
3809 iSl = iSGl = 4;
3810 iSAr = 12;
3811 break;
3812 case PF_ABGR_4444:
3813 iSRr = 12;
3814 iSGr = 8;
3815 iSBr = 4;
3816 iSl = iSGl = 4;
3817 iSAr = 0;
3818 break;
3819 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
3820 }
3821
3822 tInt iDR, iDG, iDB, iDA;
3823
3824 switch (psDestBitmapFormat->nPixelFormat)
3825 {
3826 case PF_ARGB_8888:
3827 iDA = 0;
3828 iDR = 1;
3829 iDG = 2;
3830 iDB = 3;
3831 break;
3832 case PF_ABGR_8888:
3833 iDA = 0;
3834 iDR = 3;
3835 iDG = 2;
3836 iDB = 1;
3837 break;
3838 case PF_RGBA_8888:
3839 iDA = 3;
3840 iDR = 0;
3841 iDG = 1;
3842 iDB = 2;
3843 break;
3844 case PF_BGRA_8888:
3845 iDA = 3;
3846 iDR = 2;
3847 iDG = 1;
3848 iDB = 0;
3849 break;
3850 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
3851 }
3852
3853 for (tInt x = 0; x < l_nCopyWidth; x++)
3854 {
3855 tUInt16 const k16 = *l_pSrc++;
3856 l_pDest[iDR] = static_cast<uint8_t>((k16 >> iSRr) << iSl);
3857 l_pDest[iDG] = static_cast<uint8_t>((k16 >> iSGr) << iSGl);
3858 l_pDest[iDB] = static_cast<uint8_t>((k16 >> iSBr) << iSl);
3859 l_pDest[iDA] = static_cast<uint8_t>((k16 >> iSAr) << iSl);
3860 l_pDest += 4;
3861 }
3862 }
3863 }
3864 else if (l_nSrcBytesPerPixel == 3)
3865 {
3866 const tUInt8* l_pSrc = l_pSrcLine;
3867 if (l_nDestBytesPerPixel == 1)
3868 {
3869 if (PF_GREYSCALE_8 != psDestBitmapFormat->nPixelFormat)
3870 {
3871 RETURN_ERROR(ERR_NOT_SUPPORTED);
3872 }
3873
3874 tUInt8* l_pDest = l_pDestLine;
3875 tInt ri = 0, gi = 0, bi = 0;
3876
3877 switch (psSrcBitmapFormat->nPixelFormat)
3878 {
3879 case PF_RGB_888:
3880 ri = 0;
3881 gi = 1;
3882 bi = 2;
3883 break;
3884 case PF_BGR_888:
3885 ri = 2;
3886 gi = 1;
3887 bi = 0;
3888 break;
3889 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
3890 }
3891
3892 for (tInt x = 0; x < l_nCopyWidth; x++)
3893 {
3894 *(l_pDest++) = Brightness(l_pSrc[ri], l_pSrc[gi], l_pSrc[bi]);
3895 l_pSrc += 3;
3896 }
3897 }
3898 else if (l_nDestBytesPerPixel == 2)
3899 {
3900 tUInt16* l_pDest = (tUInt16*) l_pDestLine;
3901 tInt iSR, iSB;
3902
3903 switch (psSrcBitmapFormat->nPixelFormat)
3904 {
3905 case PF_RGB_888:
3906 iSR = 0;
3907 iSB = 2;
3908 break;
3909 case PF_BGR_888:
3910 iSR = 2;
3911 iSB = 0;
3912 break;
3913 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
3914 }
3915
3916 tInt iDr, iDRl, iDGr, iDGl, iDBl, iDAl = 16;
3917 tBool bDestGrey = tFalse;
3918
3919 switch (psDestBitmapFormat->nPixelFormat)
3920 {
3921 case PF_RGB_555:
3922 iDRl = 0;
3923 iDGl = 5;
3924 iDBl = 10;
3925 iDr = iDGr = 3;
3926 break;
3927 case PF_RGB_565:
3928 iDRl = 0;
3929 iDGl = 5;
3930 iDBl = 11;
3931 iDr = 3;
3932 iDGr = 2;
3933 break;
3934 case PF_BGR_555:
3935 iDRl = 10;
3936 iDGl = 5;
3937 iDBl = 0;
3938 iDr = iDGr = 3;
3939 break;
3940 case PF_BGR_565:
3941 iDRl = 11;
3942 iDGl = 5;
3943 iDBl = 0;
3944 iDr = 3;
3945 iDGr = 2;
3946 break;
3947 case PF_RGB_444:
3948 iDRl = 0;
3949 iDGl = 4;
3950 iDBl = 8;
3951 iDr = iDGr = 4;
3952 break;
3953 case PF_RGBA_4444:
3954 iDRl = 0;
3955 iDGl = 4;
3956 iDBl = 8;
3957 iDr = iDGr = 4;
3958 iDAl = 12;
3959 break;
3960 case PF_ABGR_4444:
3961 iDRl = 12;
3962 iDGl = 8;
3963 iDBl = 4;
3964 iDr = iDGr = 4;
3965 iDAl = 0;
3966 break;
3967 case PF_GREYSCALE_16: bDestGrey = tTrue; break;
3968 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
3969 }
3970
3971 if (bDestGrey)
3972 {
3973 for (tInt x = 0; x < l_nCopyWidth; x++)
3974 {
3975 *l_pDest++ = static_cast<uint16_t>(
3976 cImage::BrightnessValue(l_pSrc[iSR], l_pSrc[1], l_pSrc[iSB]) >> 2);
3977 l_pSrc += 3;
3978 }
3979 }
3980 else
3981 {
3982 for (tInt x = 0; x < l_nCopyWidth; x++)
3983 {
3984 *l_pDest++ =
3985 (((tUInt16) l_pSrc[iSR] >> iDr) << iDRl) | (((tUInt16) l_pSrc[1] >> iDGr) << iDGl) |
3986 (((tUInt16) l_pSrc[iSB] >> iDr) << iDBl) | (((tUInt16) ALPHA_DEFAULT >> iDr) << iDAl);
3987 l_pSrc += 3;
3988 }
3989 }
3990 }
3991 else if (l_nDestBytesPerPixel == 3)
3992 {
3993 tUInt8* l_pDest = l_pDestLine;
3994
3995 tInt iDR, iDB, iSR, iSB;
3996
3997 switch (psSrcBitmapFormat->nPixelFormat)
3998 {
3999 case PF_RGB_888:
4000 iSR = 0;
4001 iSB = 2;
4002 break;
4003 case PF_BGR_888:
4004 iSR = 2;
4005 iSB = 0;
4006 break;
4007 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
4008 }
4009
4010 switch (psDestBitmapFormat->nPixelFormat)
4011 {
4012 case PF_RGB_888:
4013 iDR = 0;
4014 iDB = 2;
4015 break;
4016 case PF_BGR_888:
4017 iDR = 2;
4018 iDB = 0;
4019 break;
4020 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
4021 }
4022
4023 for (tInt x = 0; x < l_nCopyWidth; x++)
4024 {
4025 l_pDest[iDR] = l_pSrc[iSR];
4026 l_pDest[1] = l_pSrc[1];
4027 l_pDest[iDB] = l_pSrc[iSB];
4028 l_pDest += 3;
4029 l_pSrc += 3;
4030 }
4031 }
4032 else if (l_nDestBytesPerPixel == 4)
4033 {
4034 tUInt8* l_pDest = l_pDestLine;
4035
4036 tInt iSR, iSG, iSB;
4037 tInt iDR, iDG, iDB, iDA;
4038
4039 switch (psSrcBitmapFormat->nPixelFormat)
4040 {
4041 case PF_RGB_888:
4042 iSR = 0;
4043 iSG = 1;
4044 iSB = 2;
4045 break;
4046 case PF_BGR_888:
4047 iSR = 2;
4048 iSG = 1;
4049 iSB = 0;
4050 break;
4051 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
4052 }
4053
4054 switch (psDestBitmapFormat->nPixelFormat)
4055 {
4056 case PF_ARGB_8888:
4057 iDA = 0;
4058 iDR = 1;
4059 iDG = 2;
4060 iDB = 3;
4061 break;
4062 case PF_ABGR_8888:
4063 iDA = 0;
4064 iDR = 3;
4065 iDG = 2;
4066 iDB = 1;
4067 break;
4068 case PF_RGBA_8888:
4069 iDA = 3;
4070 iDR = 0;
4071 iDG = 1;
4072 iDB = 2;
4073 break;
4074 case PF_BGRA_8888:
4075 iDA = 3;
4076 iDR = 2;
4077 iDG = 1;
4078 iDB = 0;
4079 break;
4080 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
4081 }
4082
4083 for (tInt x = 0; x < l_nCopyWidth; x++)
4084 {
4085 l_pDest[iDR] = l_pSrc[iSR];
4086 l_pDest[iDG] = l_pSrc[iSG];
4087 l_pDest[iDB] = l_pSrc[iSB];
4088 l_pDest[iDA] = ALPHA_DEFAULT;
4089 l_pDest += 4;
4090 l_pSrc += 3;
4091 }
4092 }
4093 }
4094 else if (l_nSrcBytesPerPixel == 4)
4095 {
4096 if (l_nDestBytesPerPixel == 1)
4097 {
4098 if (PF_GREYSCALE_8 != psDestBitmapFormat->nPixelFormat)
4099 {
4100 RETURN_ERROR(ERR_NOT_SUPPORTED);
4101 }
4102
4103 tUInt8* l_pSrc = (tUInt8*) l_pSrcLine;
4104 tUInt8* l_pDest = l_pDestLine;
4105 tInt ri = 0, gi = 0, bi = 0;
4106
4107 switch (psSrcBitmapFormat->nPixelFormat)
4108 {
4109 case PF_RGBA_8888:
4110 ri = 0;
4111 gi = 1;
4112 bi = 2;
4113 break;
4114 case PF_BGRA_8888:
4115 ri = 2;
4116 gi = 1;
4117 bi = 0;
4118 break;
4119 case PF_ARGB_8888:
4120 ri = 1;
4121 gi = 2;
4122 bi = 3;
4123 break;
4124 case PF_ABGR_8888:
4125 ri = 3;
4126 gi = 2;
4127 bi = 1;
4128 break;
4129 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
4130 }
4131
4132 for (tInt x = 0; x < l_nCopyWidth; x++)
4133 {
4134 *(l_pDest++) = Brightness(l_pSrc[ri], l_pSrc[gi], l_pSrc[bi]);
4135 l_pSrc += 4;
4136 }
4137 }
4138 else if (l_nDestBytesPerPixel == 2)
4139 {
4140 tUInt16* l_pDest = (tUInt16*) l_pDestLine;
4141 tUInt8* l_pSrc = (tUInt8*) l_pSrcLine;
4142
4143 tInt iSR, iSG, iSB, iSA;
4144
4145 switch (psSrcBitmapFormat->nPixelFormat)
4146 {
4147 case PF_RGBA_8888:
4148 iSR = 0;
4149 iSG = 1;
4150 iSB = 2;
4151 iSA = 3;
4152 break;
4153 case PF_BGRA_8888:
4154 iSR = 2;
4155 iSG = 1;
4156 iSB = 0;
4157 iSA = 3;
4158 break;
4159 case PF_ARGB_8888:
4160 iSR = 1;
4161 iSG = 2;
4162 iSB = 3;
4163 iSA = 0;
4164 break;
4165 case PF_ABGR_8888:
4166 iSR = 3;
4167 iSG = 2;
4168 iSB = 1;
4169 iSA = 0;
4170 break;
4171 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
4172 }
4173
4174 tInt iDr, iDRl, iDGr, iDGl, iDBl, iDAl = 16;
4175
4176 switch (psDestBitmapFormat->nPixelFormat)
4177 {
4178 case PF_RGB_555:
4179 iDRl = 0;
4180 iDGl = 5;
4181 iDBl = 10;
4182 iDr = iDGr = 3;
4183 break;
4184 case PF_RGB_565:
4185 iDRl = 0;
4186 iDGl = 5;
4187 iDBl = 11;
4188 iDr = 3;
4189 iDGr = 2;
4190 break;
4191 case PF_BGR_555:
4192 iDRl = 10;
4193 iDGl = 5;
4194 iDBl = 0;
4195 iDr = iDGr = 3;
4196 break;
4197 case PF_BGR_565:
4198 iDRl = 11;
4199 iDGl = 5;
4200 iDBl = 0;
4201 iDr = 3;
4202 iDGr = 2;
4203 break;
4204 case PF_RGB_444:
4205 iDRl = 0;
4206 iDGl = 4;
4207 iDBl = 8;
4208 iDr = iDGr = 4;
4209 break;
4210 case PF_RGBA_4444:
4211 iDRl = 0;
4212 iDGl = 4;
4213 iDBl = 8;
4214 iDr = iDGr = 4;
4215 iDAl = 12;
4216 break;
4217 case PF_ABGR_4444:
4218 iDRl = 12;
4219 iDGl = 8;
4220 iDBl = 4;
4221 iDr = iDGr = 4;
4222 iDAl = 0;
4223 break;
4224 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
4225 }
4226
4227 for (tInt x = 0; x < l_nCopyWidth; x++)
4228 {
4229 *l_pDest++ =
4230 (((tUInt16) l_pSrc[iSR] >> iDr) << iDRl) | (((tUInt16) l_pSrc[iSG] >> iDGr) << iDGl) |
4231 (((tUInt16) l_pSrc[iSB] >> iDr) << iDBl) | (((tUInt16) l_pSrc[iSA] >> iDr) << iDAl);
4232 l_pSrc += 4;
4233 }
4234 }
4235 else if (l_nDestBytesPerPixel == 3)
4236 {
4237 const tUInt8* l_pSrc = l_pSrcLine;
4238 tUInt8* l_pDest = l_pDestLine;
4239
4240 tInt iDR, iDG, iDB;
4241 tInt iSR, iSG, iSB;
4242
4243 switch (psSrcBitmapFormat->nPixelFormat)
4244 {
4245 case PF_ARGB_8888:
4246 iSR = 1;
4247 iSG = 2;
4248 iSB = 3;
4249 break;
4250 case PF_ABGR_8888:
4251 iSR = 3;
4252 iSG = 2;
4253 iSB = 1;
4254 break;
4255 case PF_RGBA_8888:
4256 iSR = 0;
4257 iSG = 1;
4258 iSB = 2;
4259 break;
4260 case PF_BGRA_8888:
4261 iSR = 2;
4262 iSG = 1;
4263 iSB = 0;
4264 break;
4265 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
4266 }
4267
4268 switch (psDestBitmapFormat->nPixelFormat)
4269 {
4270 case PF_RGB_888:
4271 iDR = 0;
4272 iDG = 1;
4273 iDB = 2;
4274 break;
4275 case PF_BGR_888:
4276 iDR = 2;
4277 iDG = 1;
4278 iDB = 0;
4279 break;
4280 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
4281 }
4282
4283 for (tInt x = 0; x < l_nCopyWidth; x++)
4284 {
4285 l_pDest[iDR] = l_pSrc[iSR];
4286 l_pDest[iDG] = l_pSrc[iSG];
4287 l_pDest[iDB] = l_pSrc[iSB];
4288 l_pSrc += 4;
4289 l_pDest += 3;
4290 }
4291 }
4292 else if (l_nDestBytesPerPixel == 4)
4293 {
4294 const tUInt8* l_pSrc = l_pSrcLine;
4295 tUInt8* l_pDest = (tUInt8*) l_pDestLine;
4296
4297 tInt iSA, iSR, iSG, iSB;
4298 switch (psSrcBitmapFormat->nPixelFormat)
4299 {
4300 case PF_ARGB_8888:
4301 iSA = 0;
4302 iSR = 1;
4303 iSG = 2;
4304 iSB = 3;
4305 break;
4306 case PF_ABGR_8888:
4307 iSA = 0;
4308 iSR = 3;
4309 iSG = 2;
4310 iSB = 1;
4311 break;
4312 case PF_RGBA_8888:
4313 iSA = 3;
4314 iSR = 0;
4315 iSG = 1;
4316 iSB = 2;
4317 break;
4318 case PF_BGRA_8888:
4319 iSA = 3;
4320 iSR = 2;
4321 iSG = 1;
4322 iSB = 0;
4323 break;
4324 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
4325 }
4326
4327 tInt iDA, iDR, iDG, iDB;
4328 switch (psDestBitmapFormat->nPixelFormat)
4329 {
4330 case PF_ARGB_8888:
4331 iDA = 0;
4332 iDR = 1;
4333 iDG = 2;
4334 iDB = 3;
4335 break;
4336 case PF_ABGR_8888:
4337 iDA = 0;
4338 iDR = 3;
4339 iDG = 2;
4340 iDB = 1;
4341 break;
4342 case PF_RGBA_8888:
4343 iDA = 3;
4344 iDR = 0;
4345 iDG = 1;
4346 iDB = 2;
4347 break;
4348 case PF_BGRA_8888:
4349 iDA = 3;
4350 iDR = 2;
4351 iDG = 1;
4352 iDB = 0;
4353 break;
4354 default: RETURN_ERROR(ERR_NOT_SUPPORTED);
4355 }
4356
4357 for (tInt x = 0; x < l_nCopyWidth; x++)
4358 {
4359 l_pDest[iDA] = l_pSrc[iSA];
4360 l_pDest[iDR] = l_pSrc[iSR];
4361 l_pDest[iDG] = l_pSrc[iSG];
4362 l_pDest[iDB] = l_pSrc[iSB];
4363 l_pDest += 4;
4364 l_pSrc += 4;
4365 }
4366 }
4367 else
4368 {
4369 RETURN_ERROR(ERR_NOT_SUPPORTED);
4370 }
4371 }
4372
4373 l_pSrcLine += psSrcBitmapFormat->nBytesPerLine;
4374
4375 if (bVFlip)
4376 {
4377 l_pDestLine -= psDestBitmapFormat->nBytesPerLine;
4378 }
4379 else
4380 {
4381 l_pDestLine += psDestBitmapFormat->nBytesPerLine;
4382 }
4383 }
4384
4385 RETURN_NOERROR;
4386 }
4387
4388protected:
4389 /*static tResult StretchConvert_impl(const tUInt8* pSrcBitmapData,
4390 const tBitmapFormat* psSrcBitmapFormat,
4391 tUInt8* pDestBitmapData,
4392 const tBitmapFormat* psDestBitmapFormat,
4393 tInt nFlags,
4394 tUInt32 ui32Mask);*/
4395public:
4404 {
4405 if (this == &oImage)
4406 {
4407 return *this;
4408 }
4410 oImage.m_sFormat.nBytesPerLine, oImage.GetBitmap(), oImage.m_sFormat.nPixelFormat);
4411 return *this;
4412 }
4413
4414public:
4415 static int32_t GetNextPowerOfTwo(int32_t const a)
4416 {
4417 // if a <= 0, 1 will be returned
4418 int32_t rval = (a > 0) ? a - 1 : 0; // if a <= 0, rval is 0, otherwise rval = a-1
4419 rval |= rval >> 1;
4420 rval |= rval >> 2;
4421 rval |= rval >> 4;
4422 rval |= rval >> 8;
4423 rval |= rval >> 16;
4424 return ++rval;
4425 }
4426
4427 static int32_t CalcBitsPerPixelFromPixelFormat(int32_t const oPixelFormat)
4428 {
4429 switch (oPixelFormat)
4430 {
4431 case IImage::PF_8BIT: return 8;
4432 case IImage::PF_GREYSCALE_8: return 8;
4433 case IImage::PF_RGB_8: return 8;
4434 case IImage::PF_16BIT:
4435 return 16;
4436 case IImage::PF_GREYSCALE_10: return 16;
4437 case IImage::PF_GREYSCALE_12: return 16;
4438 case IImage::PF_GREYSCALE_14: return 16;
4439 case IImage::PF_GREYSCALE_16: return 16;
4440 case IImage::PF_RGB_444: return 16;
4441 case IImage::PF_RGB_565: return 16;
4443 return 16;
4444 case IImage::PF_RGB_555:
4445 return 16;
4446 case IImage::PF_RGBA_5551: return 16;
4448 return 16;
4449 case IImage::PF_ABGR_1555: return 16;
4450 case IImage::PF_RIII_10: return 16;
4451 case IImage::PF_RIII_12: return 16;
4452 case IImage::PF_RIII_14: return 16;
4453 case IImage::PF_RIII_16: return 16;
4454 case IImage::PF_BGR_565: return 16;
4455 case IImage::PF_BGR_555: return 16;
4456 case IImage::PF_BGRA_5551: return 16;
4457 case IImage::PF_ARGB_1555: return 16;
4458 case IImage::PF_24BIT:
4459 return 24;
4460 case IImage::PF_GREYSCALE_18: return 24;
4461 case IImage::PF_GREYSCALE_20: return 24;
4462 case IImage::PF_GREYSCALE_22: return 24;
4463 case IImage::PF_GREYSCALE_24: return 24;
4464 case IImage::PF_RGB_888:
4465 return 24;
4466 case IImage::PF_BGR_888: return 24;
4467 case IImage::PF_32BIT:
4468 return 32;
4470 return 32;
4472 return 32;
4474 return 32;
4477 return 32;
4479 return 32;
4481 return 32;
4483 return 32;
4486 return 32;
4487 case IImage::PF_GREYSCALE_32: return 32;
4488 case IImage::PF_GREYSCALE_FLOAT32: return 32;
4490 return 24;
4491 default: return 0;
4492 }
4493 }
4494
4495 static bool NeedAlphaBlend(int32_t const oPixelFormat)
4496 {
4497 switch (oPixelFormat)
4498 {
4500 return true;
4502 return true;
4503 case IImage::PF_ARGB_1555: return true;
4504 case IImage::PF_RGBA_5551: return true;
4505 case IImage::PF_ABGR_1555: return true;
4506 case IImage::PF_BGRA_5551: return true;
4507 case IImage::PF_32BIT:
4508 return true;
4510 return true;
4512 return true;
4514 return true;
4517 return true;
4519 default: return false;
4520 }
4521 }
4522
4523protected:
4524 inline void Yuv2Rgb(tUInt8 y, tUInt8 u, tUInt8 v, tUInt8* pPixel)
4525 {
4526 int32_t const c = y - 16;
4527 int32_t const d = u - 128;
4528 int32_t const e = v - 128;
4529 int32_t const r = (298 * c + 409 * e + 128) >> 8;
4530 int32_t const g = (298 * c - 100 * d - 208 * e + 128) >> 8;
4531 int32_t const b = (298 * c + 516 * d + 128) >> 8;
4532 pPixel[0] = static_cast<uint8_t>(std::clamp(r, 0, 255));
4533 pPixel[1] = static_cast<uint8_t>(std::clamp(g, 0, 255));
4534 pPixel[2] = static_cast<uint8_t>(std::clamp(b, 0, 255));
4535 }
4536
4537 inline tUInt8 YFromRGB(tUInt8* pPixel)
4538 {
4539 return ((66 * pPixel[0] + 129 * pPixel[1] + 25 * pPixel[2] + 128) >> 8) + 16;
4540 }
4541
4542 inline tUInt8 UFromRGB(tUInt8* pPixel)
4543 {
4544 return ((-38 * pPixel[0] - 74 * pPixel[1] + 112 * pPixel[2] + 128) >> 8) + 128;
4545 }
4546
4547 inline tUInt8 VFromRGB(tUInt8* pPixel)
4548 {
4549 return ((112 * pPixel[0] - 94 * pPixel[1] - 18 * pPixel[2] + 128) >> 8) + 128;
4550 }
4551
4552 static tUInt8 BlendPixel(tUInt8 c1, tUInt8 c2, tUInt8 c3, tUInt8 c4, tInt alpha_y, tInt alpha_x)
4553 {
4554 tInt a1 = alpha_x * alpha_y;
4555 tInt a2 = alpha_x * (256 - alpha_y);
4556 tInt a3 = (256 - alpha_x) * alpha_y;
4557 tInt a4 = (256 - alpha_x) * (256 - alpha_y);
4558
4559 return (tUInt8) (((tInt) c1 * a1 + (tInt) c2 * a2 + (tInt) c3 * a3 + (tInt) c4 * a4) >> 16);
4560 }
4561
4562 static tUInt32 BlendRGB32(tUInt32 c1, tUInt32 c2, tUInt32 c3, tUInt32 c4, tInt alpha_y, tInt alpha_x)
4563 {
4564 tInt a1 = alpha_x * alpha_y;
4565 tInt a2 = alpha_x * (256 - alpha_y);
4566 tInt a3 = (256 - alpha_x) * alpha_y;
4567 tInt a4 = (256 - alpha_x) * (256 - alpha_y);
4568
4569 tUInt8* pb1 = (tUInt8*) &c1;
4570 tUInt8* pb2 = (tUInt8*) &c2;
4571 tUInt8* pb3 = (tUInt8*) &c3;
4572 tUInt8* pb4 = (tUInt8*) &c4;
4573
4574 tUInt32 c = 0;
4575 tUInt8* pb = (tUInt8*) &c;
4576
4577 pb[1] = (tUInt8) (((tInt) pb1[0] * a1 + (tInt) pb2[0] * a2 + (tInt) pb3[0] * a3 + (tInt) pb4[0] * a4) >> 16);
4578 pb[2] = (tUInt8) (((tInt) pb1[1] * a1 + (tInt) pb2[1] * a2 + (tInt) pb3[1] * a3 + (tInt) pb4[1] * a4) >> 16);
4579 pb[3] = (tUInt8) (((tInt) pb1[2] * a1 + (tInt) pb2[2] * a2 + (tInt) pb3[2] * a3 + (tInt) pb4[2] * a4) >> 16);
4580 pb[0] = (tUInt8) (((tInt) pb1[3] * a1 + (tInt) pb2[3] * a2 + (tInt) pb3[3] * a3 + (tInt) pb4[3] * a4) >> 16);
4581
4582 return c;
4583 }
4584
4585 static tUInt16 AdjustMasks(tUInt16 iSMask, tUInt16 iDMask, tInt& iPos)
4586 {
4587 if (iSMask == 0 || iDMask == 0)
4588 {
4589 return 0;
4590 }
4591
4592 if (iSMask == iDMask)
4593 {
4594 return iDMask;
4595 }
4596
4597 while (iSMask > iDMask)
4598 {
4599 iSMask >>= 1;
4600 iPos++;
4601 }
4602
4603 tInt iMoveCount = 0;
4604 while ((iSMask | (iSMask - 1)) < iDMask)
4605 {
4606 iSMask <<= 1;
4607 iPos--;
4608 iMoveCount++;
4609 }
4610 return (iDMask >> iMoveCount) << iMoveCount;
4611 }
4612};
4613
4614inline tInt cImage::m_nDefaultLineAlignment = 4;
4615inline tInt cImage::m_nDefaultMemoryAlignment = 16;
4616
4617} // namespace dengar
4618
4619using dengar::cImage;
4620} // namespace graphicslib
4621
4622} // namespace disptb
4623
4624} // namespace adtf
@ PF_BGRA_5551
16 bit BGRA (R: 5 bit, G: 5 bit, B: 5 bit, Alpha:1bit)
Definition image_intf.h:152
@ PF_32BIT
32 bit This definition is a placeholder a 32 Bit format, bitorder is undefined.
Definition image_intf.h:117
@ PF_RGB_888
24 bit RGB (R: 8 bit, G: 8 bit, B: 8 bit) - default format for 24 bpp
Definition image_intf.h:111
@ PF_GREYSCALE_FLOAT32
32 bit greyscale float value
Definition image_intf.h:129
@ PF_GREYSCALE_10
10 bit greyscale To setup Format use tBitmapFormat::nBitsPerPixel = 16 !
Definition image_intf.h:72
@ PF_YUV420P_888
24 bit YUV (Y: 8 bit, U: 8 bit, V: 8 bit) - Y = luminance, U+V = chrominance If using this format in ...
Definition image_intf.h:134
@ PF_16BIT
16 bit This definition is a placeholder a 16 Bit format, bitorder is undefined.
Definition image_intf.h:67
@ PF_GREYSCALE_24
24 bit greyscale
Definition image_intf.h:109
@ PF_RGBA_8888
32 bit RGBA (R: 8 bit, G: 8 bit, B: 8 bit, A: 8 bit) with alpha value - default format for 32 bpp
Definition image_intf.h:123
@ PF_RGB_555
15 bit RGB (R: 5 bit, G: 5 bit, B: 5 bit) - default format for 16 bpp
Definition image_intf.h:88
@ PF_xRGB_8888
32 bit aligned memory with only 24 Bit valid RGB data. A=255.
Definition image_intf.h:137
@ PF_RGB_565
16 bit RGB (R: 5 bit, G: 6 bit, B: 5 bit)
Definition image_intf.h:90
@ PF_BGRA_8888
32 bit BGRA (B: 8 bit, G: 8 bit, R: 8 bit, A: 8 bit) with alpha value - inverted RGB + A
Definition image_intf.h:125
@ PF_ARGB_1555
16 bit ARGB (R: 5 bit, G: 5 bit, B: 5 bit, Alpha:1bit)
Definition image_intf.h:146
@ PF_24BIT
24 bit This definition is a placeholder a 24 Bit format, bitorder is undefined.
Definition image_intf.h:104
@ PF_ABGR_1555
16 bit ABGR (R: 5 bit, G: 5 bit, B: 5 bit, Alpha:1bit)
Definition image_intf.h:150
@ PF_BGRx_8888
32 bit aligned memory with only 24 Bit valid RGB data. A=255.
Definition image_intf.h:143
@ PF_RGBx_8888
32 bit aligned memory with only 24 Bit valid RGB data. A=255.
Definition image_intf.h:141
@ PF_ARGB_8888
32 bit ARGB (A: 8 bit, R: 8 bit, G: 8 bit, B: 8 bit) with alpha value
Definition image_intf.h:119
@ PF_GREYSCALE_16
16 bit greyscale
Definition image_intf.h:84
@ PF_ABGR_8888
32 bit ABGR (A: 8 bit, B: 8 bit, G: 8 bit, R: 8 bit) with alpha value - inverted RGBA
Definition image_intf.h:121
@ PF_RGB_444
12 bit RGB (R: 4 bit, G: 4 bit, B: 4 bit)
Definition image_intf.h:86
@ PF_BGR_888
24 bit BGR (B: 8 bit, G: 8 bit, R: 8 bit) - inverted RGB
Definition image_intf.h:113
@ PF_GREYSCALE_8
8 bit greyscale - default format for 8 bpp
Definition image_intf.h:61
@ PF_xBGR_8888
32 bit aligned memory with only 24 Bit valid RGB data. A=255.
Definition image_intf.h:139
@ PF_GREYSCALE_12
12 bit greyscale To setup Format use tBitmapFormat::nBitsPerPixel = 16 !
Definition image_intf.h:77
@ PF_RGBA_5551
16 bit RGBA (R: 5 bit, G: 5 bit, B: 5 bit, Alpha:1bit)
Definition image_intf.h:148
@ PF_GREYSCALE_14
14 bit greyscale To setup Format use tBitmapFormat::nBitsPerPixel = 16 !
Definition image_intf.h:82
@ PF_ABGR_4444
16 bit ABGR (A: 4 bit, B: 4 bit, G: 4 bit, R: 4 bit) with alpha value - inverted RGBA
Definition image_intf.h:94
@ PF_RGB_8
8 bit RGB (R: 3 bit, G: 3 bit, B: 2 Bit) - palletized 8 bpp format
Definition image_intf.h:63
@ PF_RGBA_4444
16 bit RGBA (R: 4 bit, G: 4 bit, B: 4 bit, A: 4 bit) with alpha value
Definition image_intf.h:92
@ PF_GREYSCALE_32
32 bit greyscale
Definition image_intf.h:127
cImage()
Default constructor.
Definition image.h:130
virtual tUInt8 * GetBitmap() const =0
Returns a pointer to the raw data.
virtual tInt GetWidth() const =0
Returns the width of the image.
@ PF_BGRA_5551
16 bit BGRA (R: 5 bit, G: 5 bit, B: 5 bit, Alpha:1bit)
Definition image_intf.h:152
@ PF_32BIT
32 bit This definition is a placeholder a 32 Bit format, bitorder is undefined.
Definition image_intf.h:117
@ PF_RGB_888
24 bit RGB (R: 8 bit, G: 8 bit, B: 8 bit) - default format for 24 bpp
Definition image_intf.h:111
@ PF_GREYSCALE_FLOAT32
32 bit greyscale float value
Definition image_intf.h:129
@ PF_GREYSCALE_10
10 bit greyscale To setup Format use tBitmapFormat::nBitsPerPixel = 16 !
Definition image_intf.h:72
@ PF_YUV420P_888
24 bit YUV (Y: 8 bit, U: 8 bit, V: 8 bit) - Y = luminance, U+V = chrominance If using this format in ...
Definition image_intf.h:134
@ PF_16BIT
16 bit This definition is a placeholder a 16 Bit format, bitorder is undefined.
Definition image_intf.h:67
@ PF_RGBA_8888
32 bit RGBA (R: 8 bit, G: 8 bit, B: 8 bit, A: 8 bit) with alpha value - default format for 32 bpp
Definition image_intf.h:123
@ PF_RGB_555
15 bit RGB (R: 5 bit, G: 5 bit, B: 5 bit) - default format for 16 bpp
Definition image_intf.h:88
@ PF_xRGB_8888
32 bit aligned memory with only 24 Bit valid RGB data. A=255.
Definition image_intf.h:137
@ PF_RGB_565
16 bit RGB (R: 5 bit, G: 6 bit, B: 5 bit)
Definition image_intf.h:90
@ PF_BGRA_8888
32 bit BGRA (B: 8 bit, G: 8 bit, R: 8 bit, A: 8 bit) with alpha value - inverted RGB + A
Definition image_intf.h:125
@ PF_ARGB_1555
16 bit ARGB (R: 5 bit, G: 5 bit, B: 5 bit, Alpha:1bit)
Definition image_intf.h:146
@ PF_24BIT
24 bit This definition is a placeholder a 24 Bit format, bitorder is undefined.
Definition image_intf.h:104
@ PF_ABGR_1555
16 bit ABGR (R: 5 bit, G: 5 bit, B: 5 bit, Alpha:1bit)
Definition image_intf.h:150
@ PF_BGRx_8888
32 bit aligned memory with only 24 Bit valid RGB data. A=255.
Definition image_intf.h:143
@ PF_RGBx_8888
32 bit aligned memory with only 24 Bit valid RGB data. A=255.
Definition image_intf.h:141
@ PF_ARGB_8888
32 bit ARGB (A: 8 bit, R: 8 bit, G: 8 bit, B: 8 bit) with alpha value
Definition image_intf.h:119
@ PF_ABGR_8888
32 bit ABGR (A: 8 bit, B: 8 bit, G: 8 bit, R: 8 bit) with alpha value - inverted RGBA
Definition image_intf.h:121
@ PF_RGB_444
12 bit RGB (R: 4 bit, G: 4 bit, B: 4 bit)
Definition image_intf.h:86
@ PF_BGR_888
24 bit BGR (B: 8 bit, G: 8 bit, R: 8 bit) - inverted RGB
Definition image_intf.h:113
@ PF_GREYSCALE_8
8 bit greyscale - default format for 8 bpp
Definition image_intf.h:61
@ PF_xBGR_8888
32 bit aligned memory with only 24 Bit valid RGB data. A=255.
Definition image_intf.h:139
@ PF_GREYSCALE_12
12 bit greyscale To setup Format use tBitmapFormat::nBitsPerPixel = 16 !
Definition image_intf.h:77
@ PF_RGBA_5551
16 bit RGBA (R: 5 bit, G: 5 bit, B: 5 bit, Alpha:1bit)
Definition image_intf.h:148
@ PF_GREYSCALE_14
14 bit greyscale To setup Format use tBitmapFormat::nBitsPerPixel = 16 !
Definition image_intf.h:82
@ PF_ABGR_4444
16 bit ABGR (A: 4 bit, B: 4 bit, G: 4 bit, R: 4 bit) with alpha value - inverted RGBA
Definition image_intf.h:94
@ PF_RGB_8
8 bit RGB (R: 3 bit, G: 3 bit, B: 2 Bit) - palletized 8 bpp format
Definition image_intf.h:63
@ PF_RGBA_4444
16 bit RGBA (R: 4 bit, G: 4 bit, B: 4 bit, A: 4 bit) with alpha value
Definition image_intf.h:92
virtual tInt GetPixelFormat() const =0
Returns the pixel format.
virtual tInt GetBytesPerLine() const =0
Returns the bytes per line of the image.
@ LF_FLIP_VERTICAL
perform a vertical flip
Definition image_intf.h:168
@ LF_SWAP_RGB
this flag is ignored, since it is not longer needed
Definition image_intf.h:167
virtual tInt GetBitsPerPixel() const =0
Returns the bits per pixel of the image.
@ BLIT_VerticalFlip
Blit with vertical flip.
Definition image_intf.h:179
virtual tInt GetHeight() const =0
Returns the height of the image.
tUInt32 GetRGBA() const
Gets a four Byte value containing the 3 color channels and the alphachannel.
Definition color.h:312
Image and bitmap handling.
Definition image.h:108
static tInt m_nDefaultLineAlignment
the default line alignment, currently power of 2
Definition image.h:111
static tResult SetTransparency(disptb::graphicslib::dengar::cImage *pImage, disptb::graphicslib::dengar::cColor oColor)
Helper method for setting transparency in bitmaps.
Definition image.h:2081
tWin32BitmapInfo * GetBitmapInfo() override
Generates a Win32 image descriptor.
Definition image.h:923
tResult SetPalette(tInt nPaletteSize, const tColor *pPalette)
Sets a color palette.
Definition image.h:791
static tInt CalcAlignedMemSize(tInt nBytes, tInt nAlignment)
Calculate the size of a given number of bytes to match a given alignment.
Definition image.h:2577
tResult FreeBitmapInfo()
Free space from bitmap info.
Definition image.h:3089
tResult Convert(tInt nWidth, tInt nHeight, tInt nBitsPerPixel, tInt nBytesPerLine=0, tUInt32 ui32Mask=0x0)
Converts the image to new dimensions and color depth.
Definition image.h:1185
tResult Save(const tChar *strFile)
Saves the image to a file.
Definition image.h:458
const tBitmapFormat * GetFormat() const override
Returns the current bitmap format of the image.
Definition image.h:776
static tInt GuessPixelFormat(const tBitmapFormat *pFormat)
Tries to guess the PixelFormat based on the other parameters of a bitmap format.
Definition image.h:2603
tInt GetBitmapInfoSize()
Returns the size of the Win32 image descriptor.
Definition image.h:941
tResult Alloc(const tBitmapFormat *psFormat)
Allocates the image's bitmap buffer.
Definition image.h:2881
tBool Compare(const disptb::graphicslib::dengar::cImage &oImage)
Compares the bitmaps of two images.
Definition image.h:2481
static tInt GetDefaultFormatFromBpp(tInt nBpp)
Retrieve image format based on image resolution.
Definition image.h:2647
tColor * GetPalette() const
Returns the color palette.
Definition image.h:838
static tResult BilinearStretchBlit(disptb::graphicslib::dengar::cImage &oSrc, disptb::graphicslib::dengar::cImage &oDest)
Copies an image to another using the bilinear algorithm.
Definition image.h:1942
tResult Resize(tInt nWidth, tInt nHeight)
Resizes the image to the new height nHeight and width nWidth.
Definition image.h:1128
static tResult Convert(const tUInt8 *pSrcBitmapData, const tBitmapFormat *psSrcBitmapFormat, tUInt8 *pDestBitmapData, const tBitmapFormat *psDestBitmapFormat, tInt nFlags, tUInt32 ui32Mask)
Converts an image to another format.
Definition image.h:1822
static tInt FlipToBGRFormat(tInt nPixelFormat)
Returns the pixel format flipped to BGR.
Definition image.h:664
tInt GetPixelFormat() const
Returns the pixel format.
Definition image.h:611
tResult FlipAlpha()
Flips the alpha part from left to right and back:ARGB <-> RGBA and ABGR <-> BGRA.
Definition image.h:1494
tUInt8 * m_pBitmap
actual pixel data, may be reference to data of other pic
Definition image.h:121
tInt m_nBitmapInfoSize
size of windows bitmap info
Definition image.h:118
tResult Attach(tUInt8 *pBitmap, const tBitmapFormat *psFormat, const tColor *pPalette=nullptr)
Attaches an image reference.
Definition image.h:315
tWin32BitmapInfo * m_psBitmapInfo
current bitmap info, windows style
Definition image.h:117
tResult Free()
Frees the image's bitmap buffer.
Definition image.h:2916
static tFloat64 Brightness(tFloat64 fRed, tFloat64 fGreen, tFloat64 fBlue)
Calculates the bringhtness value of a color.
Definition image.h:2173
tInt m_nGreyPaletteSize
size of palette
Definition image.h:124
static tResult StretchBlit_impl(const tUInt8 *pSrcBitmapData, const tBitmapFormat *psSrcBitmapFormat, tUInt8 *pDestBitmapData, const tBitmapFormat *psDestBitmapFormat, tInt nFlags, tUInt32 ui32Mask=0x0)
Internal blitting operation.
Definition image.h:3182
static tChar const * GetPixelFormatIdentifier(const tInt nImage)
Returns the image format as string (enum to string)
Definition image.h:2666
tResult FlipRGB()
Flips RGB to BGR and the other way around.
Definition image.h:1468
tUInt8 * GetBitmapLine(tInt y) const
Returns a pointer to raw data of a line.
Definition image.h:911
cImage(const cImage &oImage)
Copy constructor.
Definition image.h:139
tResult Attach(tUInt8 *pBitmap, tInt nWidth, tInt nHeight, tInt nBitsPerPixel, tInt nBytesPerLine=0)
Attaches an image reference.
Definition image.h:276
tResult SetPixelFormat(tInt nPixelFormat)
Sets the pixel format used.
Definition image.h:599
tInt GetBytesPerLine() const
Returns the bytes per line of the image.
Definition image.h:739
static tResult Blit(const tUInt8 *pSrcBitmapData, const tBitmapFormat *psSrcBitmapFormat, tUInt8 *pDestBitmapData, const tBitmapFormat *psDestBitmapFormat, tInt nFlags=0)
Copies bitmap data from one image to another.
Definition image.h:1731
static tInt GetBitsPerPixelFromFormat(tInt nFormat)
Retrieve image resolution from image format.
Definition image.h:2635
static tResult Blit_impl(const tUInt8 *pSrcBitmapData, const tBitmapFormat *psSrcBitmapFormat, tUInt8 *pDestBitmapData, const tBitmapFormat *psDestBitmapFormat, tInt nFlags)
Internal blitting operation.
Definition image.h:3114
static tUInt8 RedValue(tUInt32 nColor)
Returns the red component of a color.
Definition image.h:2135
tResult AllocPalette(tInt nPaletteSize)
Allocate space for a palette.
Definition image.h:2990
static tResult StretchBlit(const tUInt8 *pSrcBitmapData, const tBitmapFormat *psSrcBitmapFormat, tUInt8 *pDestBitmapData, const tBitmapFormat *psDestBitmapFormat, tInt nFlags=0)
Copies bitmap data from one image (with height H1 and width W1) to another image, stretching the scr ...
Definition image.h:1780
tInt GetWidth() const
Returns the width of the image.
Definition image.h:707
cImage(const IImage &oImage)
Copy constructor.
Definition image.h:147
tResult GetBits(tUInt8 *pDestBitmapData, const tBitmapFormat *psDestBitmapFormat, tInt nFlags=0)
Retrieves the image's bitmap data.
Definition image.h:1688
disptb::graphicslib::dengar::cImage & operator=(const disptb::graphicslib::dengar::cImage &oImage)
Set the current image to the image oImage.
Definition image.h:4403
tResult FreePalette()
Frees space from palette.
Definition image.h:3016
tResult Create(tInt nWidth, tInt nHeight, tInt nBitsPerPixel, tInt nBytesPerLine=0, const tUInt8 *pBitmap=nullptr, tInt nPixelFormat=0)
Creates a new image.
Definition image.h:186
static tInt FlipToRGBFormat(tInt nPixelFormat)
Returns the pixel format flipped to RGB.
Definition image.h:687
tColor GetPaletteEntry(tInt nIdx) const
Returns a color palette entry.
Definition image.h:860
tInt GetPaletteSize() const
Returns the color palette size.
Definition image.h:848
static tUInt8 Brightness(tUInt32 nColor)
Calculates the bringhtness value of a color.
Definition image.h:2227
char const * GetPixelFormatStr() const
Retrieves the image's pixel format as string.
Definition image.h:623
static tInt BrightnessValue(tInt nRed, tInt nGreen, tInt nBlue)
Calculates the bringhtness value of a color without scaling it down.
Definition image.h:2187
tResult Create(const tBitmapFormat *psFormat, const tColor *pPalette=nullptr, const tUInt8 *pBitmap=nullptr)
Creates a new image from a bitmap format description.
Definition image.h:230
tResult Release()
Frees all allocated resources.
Definition image.h:585
tResult Flip()
Flips the image upside down.
Definition image.h:969
tResult AllocBitmapInfo()
Allocate space for bitmap info.
Definition image.h:3035
tResult ChangeDepth(tInt nBitsPerPixel, tInt nBytesPerLine=0, tUInt32 ui32Mask=0x0)
Changes the color depth.
Definition image.h:1164
tUInt8 * GetBitmap() const
Returns a pointer to the raw data.
Definition image.h:897
static tResult Blit(const disptb::graphicslib::dengar::cImage &oSrcImage, const disptb::graphicslib::dengar::cImage &oDestImage, tInt nFlags=0)
Copies bitmap data from one image to another.
Definition image.h:1708
tResult Mirror()
Mirrors the image.
Definition image.h:1010
static tResult AlphaBlend(disptb::graphicslib::dengar::cImage *pSourceImage, disptb::graphicslib::dengar::cImage *pDestImage, disptb::graphicslib::dengar::cImage *pMaskImage)
Alpha blends an image to a destination image.
Definition image.h:1857
tResult SetBits(const tUInt8 *pSrcBitmapData, const tBitmapFormat *psSrcBitmapFormat)
Sets the image's bitmap data.
Definition image.h:1660
tInt CountDifferences(const disptb::graphicslib::dengar::cImage &oImage)
Compares the bitmaps of two images and counts the amount of different pixels.
Definition image.h:2522
static tUInt8 GreenValue(tUInt32 nColor)
Returns the green component of a color.
Definition image.h:2147
tResult FreeImpl(tHandle hMemory)
Internal implementation of the free function.
Definition image.h:2976
tVoid Destroy()
Destroy the instance.
Definition image.h:165
tResult AllocImpl(tInt nSize, tHandle *hMemory, tVoid **pBuffer)
Internal implementation of the allocation function.
Definition image.h:2950
tResult Convert(tInt oPixelFormat)
Converts the image to a new image format.
Definition image.h:1282
tBool m_bReference
flag indicating the m_pBitmap pointer is used as a reference
Definition image.h:114
static tInt m_nDefaultMemoryAlignment
the default memory alignment used, currently 16
Definition image.h:110
static tResult StretchBlit(const disptb::graphicslib::dengar::cImage &oSrcImage, const disptb::graphicslib::dengar::cImage &oDestImage, tInt nFlags=0)
Copies bitmap data from one image (with height H1 and width W1) to another image, stretching the scr ...
Definition image.h:1755
static tInt FlipRGBFormat(tInt nPixelFormat)
Returns the format with flipped RGB.
Definition image.h:635
tResult Initialize()
Initialize the image.
Definition image.h:2859
static tUInt8 Brightness(tColor nColor)
Calculates the bringhtness value of a color.
Definition image.h:2213
tColor * m_pPalette
array of colors making up the palette
Definition image.h:120
tHandle m_hBitmapMemory
Handle for bitmap memory.
Definition image.h:122
tResult Blit(const cImage &oDestImage, tInt nFlags=0)
Copies bitmap data from one image to another.
Definition image.h:1641
tResult Load(const tChar *strFile, tUInt32 nFlags=0)
Loads an image from a file.
Definition image.h:364
static tUInt8 BlueValue(tUInt32 nColor)
Returns the blue component of a color.
Definition image.h:2159
tResult Convert(const tBitmapFormat *psFormat, tUInt32 ui32Mask=0x0)
Converts the image to a new image format.
Definition image.h:1210
static tResult Convert_impl(const tUInt8 *pSrcBitmapData, const tBitmapFormat *psSrcBitmapFormat, tUInt8 *pDestBitmapData, const tBitmapFormat *psDestBitmapFormat, tInt nFlags, tUInt32 ui32Mask)
will convert the bitmap from one format to another one.
Definition image.h:3309
tInt GetHeight() const
Returns the height of the image.
Definition image.h:717
tInt GetSize() const
Returns the size of the image in bytes.
Definition image.h:749
static tUInt8 Brightness(tInt nRed, tInt nGreen, tInt nBlue)
Calculates the bringhtness value of a color.
Definition image.h:2201
tResult SetPaletteEntry(tInt nIdx, const tColor &sColor)
Sets an entry of the color palette.
Definition image.h:880
tResult MakeAlphaChannel(const tColor &sColorKey, tBool bClearTransparent=tFalse)
Creates an alpha channel.
Definition image.h:1574
tResult ChangePixelFormat(tInt nFormat, tUInt32 ui32Flags=0)
Changes the pixel format used.
Definition image.h:1306
tFloat64 GetRatio() const
Returns the aspect ratio of the image.
Definition image.h:759
tInt GetBitsPerPixel() const
Returns the bits per pixel of the image.
Definition image.h:727
tBitmapFormat m_sFormat
current format of bitmap
Definition image.h:116
Copyright © Audi Electronics Venture GmbH.
Copyright © Audi Electronics Venture GmbH.
Copyright © Audi Electronics Venture GmbH.
Namespace for functionality provided by the Display Toolbox.
Main namespace.
This structure defines the file header used to load and save a bitmap.
Definition image.h:91
tUInt16 ui16Type
always 0x4D42, for more information have a look at http://msdn.microsoft.com/en-us/library/AA930979....
Definition image.h:92
tUInt32 ui32Size
actual size of data + this header + windows bitmap header + palette
Definition image.h:94
Struct to specifie a bitmap.
tInt32 nWidth
Specifies the width (in pixels) of the image.
tInt16 nBitsPerPixel
Specifies the number of bits used to represent the color of a single pixel.
tInt32 nSize
Size of bitmap in bytes (nBytesPerLine * nHeight)
tInt32 nHeight
Specifies the width (in pixels) of the image.
tInt16 nPixelFormat
Pixel format specified in tPixelFormat. More information ca be found at.
tInt32 nBytesPerLine
Specifies the number of bytes used per line (nWidth * nBitsPerPixel / 8 + n PaddingBytes) normally th...
tInt32 nPaletteSize
Size of colour palette.
Struct to get informations about a bitmap.
tInt32 nWidth
Specifies the width of the bitmap, in pixels.
tUInt16 nBitCount
Specifies the number of bits in a bitmap.
tUInt32 nCompression
Specifies the compression rate of the bitmap.
tUInt16 nPlanes
Specifies the number of planes for the target device. This value must be set to 1.
tInt32 nXPelsPerMeter
Specifies the horizontal resolution, in pixels-per-meter, of the target device for the bitmap.
tInt32 nHeight
Specifies the height of the bitmap, in pixels.
tUInt32 nClrImportant
Specifies the number of color indexes that are required for displaying the bitmap.
tUInt32 nSizeImage
Specifies the size, in bytes, of the image. This may be set to zero for uncompressed bitmaps.
tInt32 nYPelsPerMeter
Specifies the vertical resolution, in pixels-per-meter, of the target device for the bitmap.
tUInt32 nSize
Specifies the number of bytes required by the structure.
tUInt32 nClrUsed
Specifies the number of color indexes in the color table that are actually used by the bitmap.
Struct to get the informations and the color about a bitmap.