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
17namespace dio {
18
19template<typename ImageTraits>
20class PixelIO {
21public:
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
30template<>
31class PixelIO<doc::RgbTraits> {
32 int r, g, b, a;
33public:
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
68template<>
69class PixelIO<doc::GrayscaleTraits> {
70 int k, a;
71public:
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
100template<>
101class PixelIO<doc::IndexedTraits> {
102public:
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
119template<>
120class PixelIO<doc::TilemapTraits> {
121 int b1, b2, b3, b4;
122public:
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