OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GUI::anonymous_namespace{AnimatedTexture.cpp} Namespace Reference

Classes

struct  DecodedFrame

Functions

std::vector< unsigned char > read_file_bytes (const std::string &path)
bool has_gif_signature (const std::vector< unsigned char > &bytes)
std::vector< unsigned char > image_to_rgba (const wxImage &image)
bool decode_gif (const std::vector< unsigned char > &bytes, int &width, int &height, std::vector< DecodedFrame > &out)

Class Documentation

◆ Slic3r::GUI::anonymous_namespace{AnimatedTexture.cpp}::DecodedFrame

struct Slic3r::GUI::anonymous_namespace{AnimatedTexture.cpp}::DecodedFrame
Collaboration diagram for Slic3r::GUI::anonymous_namespace{AnimatedTexture.cpp}::DecodedFrame:
Class Members
double delay
vector< unsigned char > rgba

Function Documentation

◆ decode_gif()

bool Slic3r::GUI::anonymous_namespace{AnimatedTexture.cpp}::decode_gif ( const std::vector< unsigned char > & bytes,
int & width,
int & height,
std::vector< DecodedFrame > & out )
76{
77 wxMemoryInputStream stream(bytes.data(), bytes.size());
78 wxGIFDecoder decoder;
79
80 // A truncated file still decodes everything up to the cut, which is worth showing.
81 const wxGIFErrorCode err = decoder.LoadGIF(stream);
82 if ((err != wxGIF_OK && err != wxGIF_TRUNCATED) || decoder.GetFrameCount() == 0)
83 return false;
84
85 const wxSize size = decoder.GetAnimationSize();
86 width = size.GetWidth();
87 height = size.GetHeight();
88 if (width <= 0 || height <= 0)
89 return false;
90
91 std::vector<unsigned char> canvas(size_t(width) * size_t(height) * 4, 0);
92 std::vector<unsigned char> saved;
93
94 for (unsigned int i = 0; i < decoder.GetFrameCount(); ++i) {
95 const wxSize frame_size = decoder.GetFrameSize(i);
96 const wxPoint frame_pos = decoder.GetFramePosition(i);
97 const wxAnimationDisposal disposal = decoder.GetDisposalMethod(i);
98 const unsigned char *indices = decoder.GetData(i);
99 const unsigned char *palette = decoder.GetPalette(i);
100 const int transparent = decoder.GetTransparentColourIndex(i);
101
102 if (disposal == wxANIM_TOPREVIOUS)
103 saved = canvas;
104
105 if (indices != nullptr && palette != nullptr)
106 for (int y = 0; y < frame_size.GetHeight(); ++y) {
107 const int cy = frame_pos.y + y;
108 if (cy < 0 || cy >= height)
109 continue;
110 for (int x = 0; x < frame_size.GetWidth(); ++x) {
111 const int cx = frame_pos.x + x;
112 if (cx < 0 || cx >= width)
113 continue;
114 const unsigned char index = indices[size_t(y) * size_t(frame_size.GetWidth()) + size_t(x)];
115 if (int(index) == transparent)
116 continue;
117 unsigned char *dst = &canvas[(size_t(cy) * size_t(width) + size_t(cx)) * 4];
118 dst[0] = palette[3 * size_t(index) + 0];
119 dst[1] = palette[3 * size_t(index) + 1];
120 dst[2] = palette[3 * size_t(index) + 2];
121 dst[3] = 255;
122 }
123 }
124
125 // Browsers treat 0 and 1 hundredths of a second as "as fast as the file can mean", and settle
126 // on 100 ms; an animation authored against that convention plays at the intended speed only if
127 // this does the same.
128 const long delay_ms = decoder.GetDelay(i);
129 out.push_back({ canvas, (delay_ms <= 10 ? 100.0 : double(delay_ms)) / 1000.0 });
130
131 if (disposal == wxANIM_TOBACKGROUND) {
132 for (int y = 0; y < frame_size.GetHeight(); ++y) {
133 const int cy = frame_pos.y + y;
134 if (cy < 0 || cy >= height)
135 continue;
136 const int x0 = std::max(0, frame_pos.x);
137 const int x1 = std::min(width, frame_pos.x + frame_size.GetWidth());
138 if (x1 > x0)
139 std::fill_n(&canvas[(size_t(cy) * size_t(width) + size_t(x0)) * 4], size_t(x1 - x0) * 4, 0);
140 }
141 } else if (disposal == wxANIM_TOPREVIOUS) {
142 canvas = saved;
143 }
144 }
145 return !out.empty();
146}

References decode_gif().

Referenced by decode_gif().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_gif_signature()

bool Slic3r::GUI::anonymous_namespace{AnimatedTexture.cpp}::has_gif_signature ( const std::vector< unsigned char > & bytes)
39{
40 return bytes.size() > 6 && bytes[0] == 'G' && bytes[1] == 'I' && bytes[2] == 'F';
41}

References has_gif_signature().

Referenced by has_gif_signature().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ image_to_rgba()

std::vector< unsigned char > Slic3r::GUI::anonymous_namespace{AnimatedTexture.cpp}::image_to_rgba ( const wxImage & image)
46{
47 const size_t n = size_t(image.GetWidth()) * size_t(image.GetHeight());
48 const unsigned char *rgb = image.GetData();
49 const unsigned char *a = image.HasAlpha() ? image.GetAlpha() : nullptr;
50
51 std::vector<unsigned char> out(n * 4);
52 for (size_t i = 0; i < n; ++i) {
53 out[i * 4 + 0] = rgb[i * 3 + 0];
54 out[i * 4 + 1] = rgb[i * 3 + 1];
55 out[i * 4 + 2] = rgb[i * 3 + 2];
56 out[i * 4 + 3] = a != nullptr ? a[i] : 255;
57 }
58 return out;
59}

References image_to_rgba().

Referenced by image_to_rgba().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_file_bytes()

std::vector< unsigned char > Slic3r::GUI::anonymous_namespace{AnimatedTexture.cpp}::read_file_bytes ( const std::string & path)
33{
34 std::ifstream ifs(path, std::ios::binary);
35 return std::vector<unsigned char>(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>());
36}

References read_file_bytes().

Referenced by read_file_bytes().

Here is the call graph for this function:
Here is the caller graph for this function: