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