1// Aseprite Document Library
2// Copyright (c) 2019 Igara Studio S.A.
3// Copyright (c) 2001-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#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif
11
12#include "doc/layer_io.h"
13
14#include "base/serialization.h"
15#include "doc/cel.h"
16#include "doc/cel_data.h"
17#include "doc/cel_data_io.h"
18#include "doc/cel_io.h"
19#include "doc/image_io.h"
20#include "doc/layer.h"
21#include "doc/layer_io.h"
22#include "doc/layer_tilemap.h"
23#include "doc/sprite.h"
24#include "doc/string_io.h"
25#include "doc/subobjects_io.h"
26#include "doc/user_data_io.h"
27
28#include <iostream>
29#include <memory>
30#include <vector>
31
32namespace doc {
33
34using namespace base::serialization;
35using namespace base::serialization::little_endian;
36
37// Serialized Layer data:
38
39void write_layer(std::ostream& os, const Layer* layer)
40{
41 write32(os, layer->id());
42 write_string(os, layer->name());
43
44 write32(os, static_cast<int>(layer->flags())); // Flags
45 write16(os, static_cast<int>(layer->type())); // Type
46
47 switch (layer->type()) {
48
49 case ObjectType::LayerImage:
50 case ObjectType::LayerTilemap: {
51 const LayerImage* imgLayer = static_cast<const LayerImage*>(layer);
52 CelConstIterator it, begin = imgLayer->getCelBegin();
53 CelConstIterator end = imgLayer->getCelEnd();
54
55 // Blend mode & opacity
56 write16(os, (int)imgLayer->blendMode());
57 write8(os, imgLayer->opacity());
58
59 // Images
60 int images = 0;
61 int celdatas = 0;
62 for (it=begin; it != end; ++it) {
63 const Cel* cel = *it;
64 if (!cel->link()) {
65 ++images;
66 ++celdatas;
67 }
68 }
69
70 write16(os, images);
71 for (it=begin; it != end; ++it) {
72 const Cel* cel = *it;
73 if (!cel->link())
74 write_image(os, cel->image());
75 }
76
77 write16(os, celdatas);
78 for (it=begin; it != end; ++it) {
79 const Cel* cel = *it;
80 if (!cel->link())
81 write_celdata(os, cel->dataRef().get());
82 }
83
84 // Cels
85 write16(os, imgLayer->getCelsCount());
86 for (it=begin; it != end; ++it) {
87 const Cel* cel = *it;
88 write_cel(os, cel);
89 }
90
91 // Save tilemap data
92 if (layer->type() == ObjectType::LayerTilemap) {
93 // Tileset index
94 write32(os, static_cast<const LayerTilemap*>(layer)->tilesetIndex());
95 }
96 break;
97 }
98
99 case ObjectType::LayerGroup: {
100 // Number of sub-layers
101 write16(os, static_cast<const LayerGroup*>(layer)->layersCount());
102
103 for (const Layer* child : static_cast<const LayerGroup*>(layer)->layers())
104 write_layer(os, child);
105 break;
106 }
107
108 }
109
110 write_user_data(os, layer->userData());
111}
112
113Layer* read_layer(std::istream& is, SubObjectsFromSprite* subObjects)
114{
115 ObjectId id = read32(is);
116 std::string name = read_string(is);
117 uint32_t flags = read32(is); // Flags
118 uint16_t layer_type = read16(is); // Type
119 std::unique_ptr<Layer> layer;
120
121 switch (static_cast<ObjectType>(layer_type)) {
122
123 case ObjectType::LayerImage:
124 case ObjectType::LayerTilemap: {
125 LayerImage* imgLayer;
126 if ((static_cast<ObjectType>(layer_type)) == ObjectType::LayerTilemap) {
127 imgLayer = new LayerTilemap(subObjects->sprite(), 0);
128 }
129 else {
130 imgLayer = new LayerImage(subObjects->sprite());
131 }
132
133 // Create layer
134 layer.reset(imgLayer);
135
136 // Blend mode & opacity
137 imgLayer->setBlendMode((BlendMode)read16(is));
138 imgLayer->setOpacity(read8(is));
139
140 // Read images
141 int images = read16(is); // Number of images
142 for (int c=0; c<images; ++c) {
143 ImageRef image(read_image(is));
144 subObjects->addImageRef(image);
145 }
146
147 // Read celdatas
148 int celdatas = read16(is);
149 for (int c=0; c<celdatas; ++c) {
150 CelDataRef celdata(read_celdata(is, subObjects));
151 subObjects->addCelDataRef(celdata);
152 }
153
154 // Read cels
155 int cels = read16(is); // Number of cels
156 for (int c=0; c<cels; ++c) {
157 // Read the cel
158 Cel* cel = read_cel(is, subObjects);
159
160 // Add the cel in the layer
161 imgLayer->addCel(cel);
162 }
163
164 // Create the layer tilemap
165 if (imgLayer->isTilemap()) {
166 doc::tileset_index tsi = read32(is); // Tileset index
167 static_cast<LayerTilemap*>(imgLayer)->setTilesetIndex(tsi);
168 }
169 break;
170 }
171
172 case ObjectType::LayerGroup: {
173 // Create the layer group
174 layer.reset(new LayerGroup(subObjects->sprite()));
175
176 // Number of sub-layers
177 int layers = read16(is);
178 for (int c=0; c<layers; c++) {
179 Layer* child = read_layer(is, subObjects);
180 if (child)
181 static_cast<LayerGroup*>(layer.get())->addLayer(child);
182 else
183 break;
184 }
185 break;
186 }
187
188 default:
189 throw InvalidLayerType("Invalid layer type found in stream");
190
191 }
192
193 UserData userData = read_user_data(is);
194
195 if (layer) {
196 layer->setName(name);
197 layer->setFlags(static_cast<LayerFlags>(flags));
198 layer->setId(id);
199 layer->setUserData(userData);
200 }
201
202 return layer.release();
203}
204
205}
206