roo_display
API Documentation for roo_display
Loading...
Searching...
No Matches
png.cpp
Go to the documentation of this file.
2
3#include "roo_display.h"
5#include "roo_display/image/png/lib/png.inl"
6
8PNG_STATIC int DecodePNG(PNGIMAGE *pImage, void *pUser, int iOptions);
9// Include the C code which does the actual work
10// #include "png.inl"
11
12namespace roo_display {
13
15 PngDecoder *decoder = (PngDecoder *)pFile->fHandle;
16 return decoder->input_->read((roo::byte *)pBuf, iLen);
17}
18
20 PngDecoder *decoder = (PngDecoder *)pFile->fHandle;
21 decoder->input_->seek(iPosition);
22 // The library ignores the return value anyway.
23 return 1;
24}
25
26namespace {
27
28struct User {
29 const Surface *surface;
30 const Palette *palette;
31};
32
33} // namespace
34
36 User &user = *((User *)pDraw->pUser);
37 const Surface *surface = user.surface;
38 int16_t y = pDraw->y;
39 if (y + surface->dy() < surface->clip_box().yMin() ||
40 y + surface->dy() > surface->clip_box().yMax()) {
41 return;
42 }
43 Box box(0, y, pDraw->iWidth - 1, y);
45 switch (pDraw->iPixelType) {
48 (const roo::byte *)pDraw->pPixels);
49 surface->drawObject(raster);
50 break;
51 }
53 ConstDramRaster<Rgb888> raster(box, (const roo::byte *)pDraw->pPixels);
54 surface->drawObject(raster);
55 break;
56 }
59 (const roo::byte *)pDraw->pPixels);
60 surface->drawObject(raster);
61 break;
62 }
65 (const roo::byte *)pDraw->pPixels);
66 surface->drawObject(raster);
67 break;
68 }
69 case PNG_PIXEL_INDEXED: {
70 switch (pDraw->iBpp) {
71 case 8: {
73 (const roo::byte *)pDraw->pPixels,
74 Indexed8(user.palette));
75 surface->drawObject(raster);
76 break;
77 }
78 case 4: {
80 (const roo::byte *)pDraw->pPixels,
81 Indexed4(user.palette));
82 surface->drawObject(raster);
83 break;
84 }
85 case 2: {
87 (const roo::byte *)pDraw->pPixels,
88 Indexed2(user.palette));
89 surface->drawObject(raster);
90 break;
91 }
92 case 1: {
94 (const roo::byte *)pDraw->pPixels,
95 Indexed1(user.palette));
96 surface->drawObject(raster);
97 break;
98 }
99 }
100 }
101 }
102}
103
104PngDecoder::PngDecoder() : pngdec_(new PNGIMAGE()), input_(nullptr) {}
105
106bool PngDecoder::getDimensions(const roo_io::MultipassResource &resource,
107 int16_t &width, int16_t &height) {
108 if (!open(resource, width, height)) {
109 width = 0;
110 height = 0;
111 return false;
112 }
113 close();
114 return true;
115}
116
117bool PngDecoder::open(const roo_io::MultipassResource &resource, int16_t &width,
118 int16_t &height) {
119 input_ = resource.open();
120 if (input_ == nullptr) return false;
121 *pngdec_ = {};
122 pngdec_->pfnRead = png_read;
123 pngdec_->pfnSeek = png_seek;
124 pngdec_->pfnDraw = png_draw;
125 pngdec_->pfnOpen = nullptr;
126 pngdec_->pfnClose = nullptr;
127 pngdec_->PNGFile.iSize = input_->size();
128
129 pngdec_->PNGFile.fHandle = this;
130 if (PNGInit(pngdec_.get()) != PNG_SUCCESS) return false;
131 width = pngdec_->iWidth;
132 height = pngdec_->iHeight;
133 return true;
134}
135
136void PngDecoder::draw(const roo_io::MultipassResource &resource,
137 const Surface &s, uint8_t scale, int16_t &width,
138 int16_t &height) {
139 PauseOutput pause(s.out());
140 if (!open(resource, width, height)) {
141 return;
142 }
143 Box extents(0, 0, pngdec_->iWidth - 1, pngdec_->iHeight - 1);
144 if (Box::Intersect(s.clip_box(), extents.translate(s.dx(), s.dy())).empty()) {
145 close();
146 return;
147 }
148 if (pngdec_->ucPixelType == PNG_PIXEL_INDEXED) {
149 palette_ =
150 Palette::ReadOnly((Color *)pngdec_->ucPalette, 1 << pngdec_->ucBpp);
151 }
152 User user{.surface = &s, .palette = &palette_};
153 DecodePNG(pngdec_.get(), (void *)&user, 0);
154 close();
155}
156
157} // namespace roo_display
@ PNG_SUCCESS
Definition PNGdec.h:93
@ PNG_PIXEL_TRUECOLOR
Definition PNGdec.h:75
@ PNG_PIXEL_GRAY_ALPHA
Definition PNGdec.h:77
@ PNG_PIXEL_GRAYSCALE
Definition PNGdec.h:74
@ PNG_PIXEL_INDEXED
Definition PNGdec.h:76
@ PNG_PIXEL_TRUECOLOR_ALPHA
Definition PNGdec.h:78
#define PNG_STATIC
Definition PNGdec.h:190
Axis-aligned integer rectangle.
Definition box.h:12
int16_t yMax() const
Maximum y (inclusive).
Definition box.h:74
static Box Intersect(const Box &a, const Box &b)
Return the intersection of two boxes (may be empty).
Definition box.h:25
int16_t yMin() const
Minimum y (inclusive).
Definition box.h:68
static Palette ReadOnly(const Color *colors, int size)
Create a read-only palette backed by the given colors.
PNG decoder (stateful, reusable).
Definition png.h:21
PngDecoder()
Construct a PNG decoder instance.
Definition png.cpp:104
friend int32_t png_seek(PNGFILE *pFile, int32_t iPosition)
Definition png.cpp:19
friend int32_t png_read(PNGFILE *pFile, uint8_t *pBuf, int32_t iLen)
Definition png.cpp:14
Resumes a paused output transaction.
Low-level handle used to draw to an underlying device.
Definition drawable.h:60
int16_t dy() const
Return the y offset to apply to drawn objects.
Definition drawable.h:128
const Box & clip_box() const
Return the clip box in device coordinates (independent of offsets).
Definition drawable.h:134
void drawObject(const Drawable &object) const
Draw a drawable object to this surface.
Definition drawable.h:278
DisplayOutput & out() const
Return the device output.
Definition drawable.h:119
Defines 140 opaque HTML named colors.
internal::Indexed< 2 > Indexed2
internal::Indexed< 1 > Indexed1
internal::Indexed< 8 > Indexed8
int32_t png_seek(PNGFILE *pFile, int32_t iPosition)
Definition png.cpp:19
int32_t png_read(PNGFILE *pFile, uint8_t *pBuf, int32_t iLen)
Definition png.cpp:14
void png_draw(PNGDRAW *pDraw)
Definition png.cpp:35
internal::Indexed< 4 > Indexed4
PNG_STATIC int PNGInit(PNGIMAGE *pPNG)
const Palette * palette
Definition png.cpp:30
const Surface * surface
Definition png.cpp:29
PNG_STATIC int DecodePNG(PNGIMAGE *pImage, void *pUser, int iOptions)
Public API surface for roo_display display, touch, and drawing utilities.