1 | // Aseprite Document IO Library |
2 | // Copyright (c) 2019 Igara Studio S.A. |
3 | // Copyright (c) 2017-2018 David Capello |
4 | // |
5 | // This file is released under the terms of the MIT license. |
6 | // Read LICENSE.txt for more information. |
7 | |
8 | #ifndef DIO_PIXEL_IO_H_INCLUDED |
9 | #define DIO_PIXEL_IO_H_INCLUDED |
10 | #pragma once |
11 | |
12 | #include "dio/file_interface.h" |
13 | #include "doc/image_traits.h" |
14 | |
15 | #include <cstring> |
16 | |
17 | namespace dio { |
18 | |
19 | template<typename ImageTraits> |
20 | class PixelIO { |
21 | public: |
22 | typename ImageTraits::pixel_t read_pixel(FileInterface* fi); |
23 | void write_pixel(FileInterface* fi, typename ImageTraits::pixel_t c); |
24 | void read_scanline(typename ImageTraits::address_t address, |
25 | int w, uint8_t* buffer); |
26 | void write_scanline(typename ImageTraits::address_t address, |
27 | int w, uint8_t* buffer); |
28 | }; |
29 | |
30 | template<> |
31 | class PixelIO<doc::RgbTraits> { |
32 | int r, g, b, a; |
33 | public: |
34 | doc::RgbTraits::pixel_t read_pixel(FileInterface* f) { |
35 | r = f->read8(); |
36 | g = f->read8(); |
37 | b = f->read8(); |
38 | a = f->read8(); |
39 | return doc::rgba(r, g, b, a); |
40 | } |
41 | void write_pixel(FileInterface* f, doc::RgbTraits::pixel_t c) { |
42 | f->write8(doc::rgba_getr(c)); |
43 | f->write8(doc::rgba_getg(c)); |
44 | f->write8(doc::rgba_getb(c)); |
45 | f->write8(doc::rgba_geta(c)); |
46 | } |
47 | void read_scanline(doc::RgbTraits::address_t address, |
48 | int w, uint8_t* buffer) { |
49 | for (int x=0; x<w; ++x, ++address) { |
50 | r = *(buffer++); |
51 | g = *(buffer++); |
52 | b = *(buffer++); |
53 | a = *(buffer++); |
54 | *address = doc::rgba(r, g, b, a); |
55 | } |
56 | } |
57 | void write_scanline(doc::RgbTraits::address_t address, |
58 | int w, uint8_t* buffer) { |
59 | for (int x=0; x<w; ++x, ++address) { |
60 | *(buffer++) = doc::rgba_getr(*address); |
61 | *(buffer++) = doc::rgba_getg(*address); |
62 | *(buffer++) = doc::rgba_getb(*address); |
63 | *(buffer++) = doc::rgba_geta(*address); |
64 | } |
65 | } |
66 | }; |
67 | |
68 | template<> |
69 | class PixelIO<doc::GrayscaleTraits> { |
70 | int k, a; |
71 | public: |
72 | doc::GrayscaleTraits::pixel_t read_pixel(FileInterface* f) { |
73 | k = f->read8(); |
74 | a = f->read8(); |
75 | return doc::graya(k, a); |
76 | } |
77 | void write_pixel(FileInterface* f, doc::GrayscaleTraits::pixel_t c) { |
78 | f->write8(doc::graya_getv(c)); |
79 | f->write8(doc::graya_geta(c)); |
80 | } |
81 | void read_scanline(doc::GrayscaleTraits::address_t address, |
82 | int w, uint8_t* buffer) |
83 | { |
84 | for (int x=0; x<w; ++x, ++address) { |
85 | k = *(buffer++); |
86 | a = *(buffer++); |
87 | *address = doc::graya(k, a); |
88 | } |
89 | } |
90 | void write_scanline(doc::GrayscaleTraits::address_t address, |
91 | int w, uint8_t* buffer) |
92 | { |
93 | for (int x=0; x<w; ++x, ++address) { |
94 | *(buffer++) = doc::graya_getv(*address); |
95 | *(buffer++) = doc::graya_geta(*address); |
96 | } |
97 | } |
98 | }; |
99 | |
100 | template<> |
101 | class PixelIO<doc::IndexedTraits> { |
102 | public: |
103 | doc::IndexedTraits::pixel_t read_pixel(FileInterface* f) { |
104 | return f->read8(); |
105 | } |
106 | void write_pixel(FileInterface* f, doc::IndexedTraits::pixel_t c) { |
107 | f->write8(c); |
108 | } |
109 | void read_scanline(doc::IndexedTraits::address_t address, |
110 | int w, uint8_t* buffer) { |
111 | std::memcpy(address, buffer, w); |
112 | } |
113 | void write_scanline(doc::IndexedTraits::address_t address, |
114 | int w, uint8_t* buffer) { |
115 | std::memcpy(buffer, address, w); |
116 | } |
117 | }; |
118 | |
119 | template<> |
120 | class PixelIO<doc::TilemapTraits> { |
121 | int b1, b2, b3, b4; |
122 | public: |
123 | doc::TilemapTraits::pixel_t read_pixel(FileInterface* f) { |
124 | int b1 = f->read8(); |
125 | int b2 = f->read8(); |
126 | int b3 = f->read8(); |
127 | int b4 = f->read8(); |
128 | |
129 | if (f->ok()) { |
130 | // Little endian |
131 | return ((b4 << 24) | (b3 << 16) | (b2 << 8) | b1); |
132 | } |
133 | else |
134 | return 0; |
135 | } |
136 | void read_scanline(doc::TilemapTraits::address_t address, |
137 | int w, uint8_t* buffer) { |
138 | for (int x=0; x<w; ++x, ++address) { |
139 | b1 = *(buffer++); |
140 | b2 = *(buffer++); |
141 | b3 = *(buffer++); |
142 | b4 = *(buffer++); |
143 | *address = ((b4 << 24) | (b3 << 16) | (b2 << 8) | b1); |
144 | } |
145 | } |
146 | }; |
147 | |
148 | } // namespace dio |
149 | |
150 | #endif |
151 | |