1// Aseprite Document Library
2// Copyright (c) 2022 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/cel_data_io.h"
13
14#include "base/serialization.h"
15#include "doc/cel_data.h"
16#include "doc/subobjects_io.h"
17#include "doc/user_data_io.h"
18#include "fixmath/fixmath.h"
19
20#include <iostream>
21#include <memory>
22
23namespace doc {
24
25#define HAS_BOUNDS_F 1
26
27using namespace base::serialization;
28using namespace base::serialization::little_endian;
29
30void write_celdata(std::ostream& os, const CelData* celdata)
31{
32 write32(os, celdata->id());
33 write32(os, celdata->bounds().x);
34 write32(os, celdata->bounds().y);
35 write32(os, celdata->bounds().w);
36 write32(os, celdata->bounds().h);
37 write8(os, celdata->opacity());
38 write32(os, celdata->image()->id());
39 write_user_data(os, celdata->userData());
40
41 if (celdata->hasBoundsF()) { // Reference layer
42 write32(os, HAS_BOUNDS_F);
43 write32(os, fixmath::ftofix(celdata->boundsF().x));
44 write32(os, fixmath::ftofix(celdata->boundsF().y));
45 write32(os, fixmath::ftofix(celdata->boundsF().w));
46 write32(os, fixmath::ftofix(celdata->boundsF().h));
47 }
48 else {
49 write32(os, 0);
50 }
51}
52
53CelData* read_celdata(std::istream& is, SubObjectsIO* subObjects, bool setId)
54{
55 ObjectId id = read32(is);
56 int x = read32(is);
57 int y = read32(is);
58 int w = read32(is);
59 int h = read32(is);
60 int opacity = read8(is);
61 ObjectId imageId = read32(is);
62 UserData userData = read_user_data(is);
63 gfx::RectF boundsF;
64
65 // Extra fields
66 int flags = read32(is);
67 if (flags & HAS_BOUNDS_F) {
68 fixmath::fixed x = read32(is);
69 fixmath::fixed y = read32(is);
70 fixmath::fixed w = read32(is);
71 fixmath::fixed h = read32(is);
72 if (w && h) {
73 boundsF = gfx::RectF(fixmath::fixtof(x),
74 fixmath::fixtof(y),
75 fixmath::fixtof(w),
76 fixmath::fixtof(h));
77 }
78 }
79
80 ImageRef image(subObjects->getImageRef(imageId));
81 if (!image)
82 return nullptr;
83
84 std::unique_ptr<CelData> celdata(new CelData(image));
85 celdata->setBounds(gfx::Rect(x, y, w, h));
86 celdata->setOpacity(opacity);
87 celdata->setUserData(userData);
88 if (setId)
89 celdata->setId(id);
90 if (!boundsF.isEmpty())
91 celdata->setBoundsF(boundsF);
92 return celdata.release();
93}
94
95}
96