Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/util/png_utils.cpp
1693 views
1
//
2
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
// png_utils: Wrapper around libpng.
7
//
8
9
#include "util/png_utils.h"
10
11
#include <array>
12
#include <cstring>
13
14
#include <png.h>
15
16
namespace angle
17
{
18
namespace
19
{
20
class ScopedFILE
21
{
22
public:
23
ScopedFILE(FILE *fp) : mFP(fp) {}
24
~ScopedFILE() { close(); }
25
26
FILE *get() const { return mFP; }
27
28
void close()
29
{
30
if (mFP)
31
{
32
fclose(mFP);
33
mFP = nullptr;
34
}
35
}
36
37
private:
38
FILE *mFP;
39
};
40
} // namespace
41
42
bool SavePNGRGB(const char *fileName,
43
const char *title,
44
uint32_t width,
45
uint32_t height,
46
const std::vector<uint8_t> &data)
47
{
48
ScopedFILE fp(fopen(fileName, "wb"));
49
if (!fp.get())
50
{
51
fprintf(stderr, "Error opening '%s'.\n", fileName);
52
return false;
53
}
54
55
png_struct *writeStruct =
56
png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
57
if (!writeStruct)
58
{
59
fprintf(stderr, "Error on png_create_write_struct.\n");
60
return false;
61
}
62
63
png_info *infoStruct = png_create_info_struct(writeStruct);
64
if (!infoStruct)
65
{
66
fprintf(stderr, "Error on png_create_info_struct.\n");
67
return false;
68
}
69
70
if (setjmp(png_jmpbuf(writeStruct)))
71
{
72
fp.close();
73
png_free_data(writeStruct, infoStruct, PNG_FREE_ALL, -1);
74
png_destroy_write_struct(&writeStruct, &infoStruct);
75
return false;
76
}
77
78
png_init_io(writeStruct, fp.get());
79
80
// Write header (8 bit colour depth)
81
png_set_IHDR(writeStruct, infoStruct, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
82
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
83
84
// Set title
85
if (title != nullptr && strlen(title) > 0)
86
{
87
std::array<char, 50> mutableKey = {};
88
strcpy(mutableKey.data(), "Title");
89
std::array<char, 200> mutableText = {};
90
strncpy(mutableText.data(), title, 199);
91
92
png_text titleText;
93
titleText.compression = PNG_TEXT_COMPRESSION_NONE;
94
titleText.key = mutableKey.data();
95
titleText.text = mutableText.data();
96
png_set_text(writeStruct, infoStruct, &titleText, 1);
97
}
98
99
png_write_info(writeStruct, infoStruct);
100
101
// RGB 3-byte stride.
102
const uint32_t rowStride = width * 3;
103
for (uint32_t row = 0; row < height; ++row)
104
{
105
uint32_t rowOffset = row * rowStride;
106
png_write_row(writeStruct, &data[rowOffset]);
107
}
108
109
png_write_end(writeStruct, infoStruct);
110
111
fp.close();
112
png_free_data(writeStruct, infoStruct, PNG_FREE_ALL, -1);
113
png_destroy_write_struct(&writeStruct, &infoStruct);
114
return true;
115
}
116
} // namespace angle
117
118