Change PNG functions to return std::vector.
Currently, PNG functions pass the std::vector containing the data an an
out parameters, with a separate bool return value to indicate success or
failure. Instead of doing this, just return the std::vector and check
whether it contains data or not.
For affected functions that return std::vector, use the same variable in
all return paths to make it obvious to the compiler that it can apply
RVO and not create a copy.
Change-Id: Ia1f84a6be29fe2d86df800607a258747999b311f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/56653
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/samples/pdfium_test_write_helper.cc b/samples/pdfium_test_write_helper.cc
index f18a791..c6f630a 100644
--- a/samples/pdfium_test_write_helper.cc
+++ b/samples/pdfium_test_write_helper.cc
@@ -130,38 +130,33 @@
return "";
}
-bool EncodePng(const unsigned char* buffer,
- int width,
- int height,
- int stride,
- int format,
- std::vector<unsigned char>* png_encoding) {
- bool ret = false;
+std::vector<unsigned char> EncodePng(const unsigned char* buffer,
+ int width,
+ int height,
+ int stride,
+ int format) {
+ std::vector<unsigned char> png;
switch (format) {
case FPDFBitmap_Unknown:
- ret = false;
break;
case FPDFBitmap_Gray:
- ret = image_diff_png::EncodeGrayPNG(buffer, width, height, stride,
- png_encoding);
+ png = image_diff_png::EncodeGrayPNG(buffer, width, height, stride);
break;
case FPDFBitmap_BGR:
- ret = image_diff_png::EncodeBGRPNG(buffer, width, height, stride,
- png_encoding);
+ png = image_diff_png::EncodeBGRPNG(buffer, width, height, stride);
break;
case FPDFBitmap_BGRx:
- ret = image_diff_png::EncodeBGRAPNG(buffer, width, height, stride, true,
- png_encoding);
+ png = image_diff_png::EncodeBGRAPNG(buffer, width, height, stride,
+ /*discard_transparency=*/true);
break;
case FPDFBitmap_BGRA:
- ret = image_diff_png::EncodeBGRAPNG(buffer, width, height, stride, false,
- png_encoding);
+ png = image_diff_png::EncodeBGRAPNG(buffer, width, height, stride,
+ /*discard_transparency=*/false);
break;
default:
NOTREACHED();
}
-
- return ret;
+ return png;
}
#ifdef _WIN32
@@ -386,11 +381,11 @@
if (!CheckDimensions(stride, width, height))
return "";
- std::vector<unsigned char> png_encoding;
const auto* buffer = static_cast<const unsigned char*>(buffer_void);
- if (!EncodePng(buffer, width, height, stride, FPDFBitmap_BGRA,
- &png_encoding)) {
+ std::vector<unsigned char> png_encoding =
+ EncodePng(buffer, width, height, stride, FPDFBitmap_BGRA);
+ if (png_encoding.empty()) {
fprintf(stderr, "Failed to convert bitmap to PNG\n");
return "";
}
@@ -628,14 +623,15 @@
continue;
}
- std::vector<unsigned char> png_encoding;
const unsigned char* buffer =
static_cast<const unsigned char*>(FPDFBitmap_GetBuffer(bitmap.get()));
int width = FPDFBitmap_GetWidth(bitmap.get());
int height = FPDFBitmap_GetHeight(bitmap.get());
int stride = FPDFBitmap_GetStride(bitmap.get());
- if (!EncodePng(buffer, width, height, stride, format, &png_encoding)) {
+ std::vector<unsigned char> png_encoding =
+ EncodePng(buffer, width, height, stride, format);
+ if (png_encoding.empty()) {
fprintf(stderr,
"Failed to convert image object #%d on page #%d to png.\n", i + 1,
page_num + 1);
diff --git a/testing/image_diff/image_diff.cpp b/testing/image_diff/image_diff.cpp
index f9d70f3..3da138b 100644
--- a/testing/image_diff/image_diff.cpp
+++ b/testing/image_diff/image_diff.cpp
@@ -63,8 +63,9 @@
fclose(f);
- if (!image_diff_png::DecodePNG(compressed.data(), compressed.size(), &data_,
- &w_, &h_)) {
+ data_ = image_diff_png::DecodePNG(compressed.data(), compressed.size(), &w_,
+ &h_);
+ if (data_.empty()) {
Clear();
return false;
}
@@ -278,12 +279,10 @@
if (same)
return kStatusSame;
- std::vector<unsigned char> png_encoding;
- if (!image_diff_png::EncodeRGBAPNG(diff_image.data(), diff_image.w(),
- diff_image.h(), diff_image.w() * 4,
- &png_encoding)) {
+ std::vector<unsigned char> png_encoding = image_diff_png::EncodeRGBAPNG(
+ diff_image.data(), diff_image.w(), diff_image.h(), diff_image.w() * 4);
+ if (png_encoding.empty())
return kStatusError;
- }
FILE* f = fopen(out_file.c_str(), "wb");
if (!f)
diff --git a/testing/image_diff/image_diff_png.cpp b/testing/image_diff/image_diff_png.cpp
index 09fb34f..9825e28 100644
--- a/testing/image_diff/image_diff_png.cpp
+++ b/testing/image_diff/image_diff_png.cpp
@@ -362,26 +362,26 @@
} // namespace
// static
-bool Decode(const unsigned char* input,
- size_t input_size,
- ColorFormat format,
- std::vector<unsigned char>* output,
- int* w,
- int* h) {
+std::vector<unsigned char> Decode(const unsigned char* input,
+ size_t input_size,
+ ColorFormat format,
+ int* w,
+ int* h) {
+ std::vector<unsigned char> output;
png_struct* png_ptr = NULL;
png_info* info_ptr = NULL;
if (!BuildPNGStruct(input, input_size, &png_ptr, &info_ptr))
- return false;
+ return output;
PngReadStructDestroyer destroyer(&png_ptr, &info_ptr);
if (setjmp(png_jmpbuf(png_ptr))) {
// The destroyer will ensure that the structures are cleaned up in this
// case, even though we may get here as a jump from random parts of the
// PNG library called below.
- return false;
+ return output;
}
- PngDecoderState state(format, output);
+ PngDecoderState state(format, &output);
png_set_progressive_read_fn(png_ptr, &state, &DecodeInfoCallback,
&DecodeRowCallback, &DecodeEndCallback);
@@ -391,13 +391,13 @@
if (!state.done) {
// Fed it all the data but the library didn't think we got all the data, so
// this file must be truncated.
- output->clear();
- return false;
+ output.clear();
+ return output;
}
*w = state.width;
*h = state.height;
- return true;
+ return output;
}
// Encoder
@@ -569,20 +569,23 @@
} // namespace
// static
-bool EncodeWithCompressionLevel(const unsigned char* input,
- ColorFormat format,
- const int width,
- const int height,
- int row_byte_width,
- bool discard_transparency,
- const std::vector<Comment>& comments,
- int compression_level,
- std::vector<unsigned char>* output) {
+std::vector<unsigned char> EncodeWithCompressionLevel(
+ const unsigned char* input,
+ ColorFormat format,
+ const int width,
+ const int height,
+ int row_byte_width,
+ bool discard_transparency,
+ const std::vector<Comment>& comments,
+ int compression_level) {
+ std::vector<unsigned char> output;
+
// Run to convert an input row into the output row format, NULL means no
// conversion is necessary.
FormatConverter converter = nullptr;
- int input_color_components, output_color_components;
+ int input_color_components;
+ int output_color_components;
int png_output_color_type;
switch (format) {
case FORMAT_BGR:
@@ -629,95 +632,86 @@
default:
NOTREACHED();
- return false;
+ return output;
}
// Row stride should be at least as long as the length of the data.
if (row_byte_width < input_color_components * width)
- return false;
+ return output;
png_struct* png_ptr =
png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
- return false;
+ return output;
png_info* info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_write_struct(&png_ptr, NULL);
- return false;
+ return output;
}
- PngEncoderState state(output);
+ PngEncoderState state(&output);
bool success =
DoLibpngWrite(png_ptr, info_ptr, &state, width, height, row_byte_width,
input, compression_level, png_output_color_type,
output_color_components, converter, comments);
png_destroy_write_struct(&png_ptr, &info_ptr);
- return success;
+ if (!success)
+ output.clear();
+ return output;
}
// static
-bool Encode(const unsigned char* input,
- ColorFormat format,
- const int width,
- const int height,
- int row_byte_width,
- bool discard_transparency,
- const std::vector<Comment>& comments,
- std::vector<unsigned char>* output) {
+std::vector<unsigned char> Encode(const unsigned char* input,
+ ColorFormat format,
+ const int width,
+ const int height,
+ int row_byte_width,
+ bool discard_transparency,
+ const std::vector<Comment>& comments) {
return EncodeWithCompressionLevel(input, format, width, height,
row_byte_width, discard_transparency,
- comments, Z_DEFAULT_COMPRESSION, output);
+ comments, Z_DEFAULT_COMPRESSION);
}
-// Decode a PNG into an RGBA pixel array.
-bool DecodePNG(const unsigned char* input,
- size_t input_size,
- std::vector<unsigned char>* output,
- int* width,
- int* height) {
- return Decode(input, input_size, FORMAT_RGBA, output, width, height);
+std::vector<unsigned char> DecodePNG(const unsigned char* input,
+ size_t input_size,
+ int* width,
+ int* height) {
+ return Decode(input, input_size, FORMAT_RGBA, width, height);
}
-// Encode a BGR pixel array into a PNG.
-bool EncodeBGRPNG(const unsigned char* input,
- int width,
- int height,
- int row_byte_width,
- std::vector<unsigned char>* output) {
+std::vector<unsigned char> EncodeBGRPNG(const unsigned char* input,
+ int width,
+ int height,
+ int row_byte_width) {
return Encode(input, FORMAT_BGR, width, height, row_byte_width, false,
- std::vector<Comment>(), output);
+ std::vector<Comment>());
}
-// Encode an RGBA pixel array into a PNG.
-bool EncodeRGBAPNG(const unsigned char* input,
- int width,
- int height,
- int row_byte_width,
- std::vector<unsigned char>* output) {
+std::vector<unsigned char> EncodeRGBAPNG(const unsigned char* input,
+ int width,
+ int height,
+ int row_byte_width) {
return Encode(input, FORMAT_RGBA, width, height, row_byte_width, false,
- std::vector<Comment>(), output);
+ std::vector<Comment>());
}
-// Encode an BGRA pixel array into a PNG.
-bool EncodeBGRAPNG(const unsigned char* input,
- int width,
- int height,
- int row_byte_width,
- bool discard_transparency,
- std::vector<unsigned char>* output) {
+std::vector<unsigned char> EncodeBGRAPNG(const unsigned char* input,
+ int width,
+ int height,
+ int row_byte_width,
+ bool discard_transparency) {
return Encode(input, FORMAT_BGRA, width, height, row_byte_width,
- discard_transparency, std::vector<Comment>(), output);
+ discard_transparency, std::vector<Comment>());
}
-// Encode a grayscale pixel array into a PNG.
-bool EncodeGrayPNG(const unsigned char* input,
- int width,
- int height,
- int row_byte_width,
- std::vector<unsigned char>* output) {
+std::vector<unsigned char> EncodeGrayPNG(const unsigned char* input,
+ int width,
+ int height,
+ int row_byte_width) {
return Encode(input, FORMAT_GRAY, width, height, row_byte_width, false,
- std::vector<Comment>(), output);
+ std::vector<Comment>());
}
} // namespace image_diff_png
diff --git a/testing/image_diff/image_diff_png.h b/testing/image_diff/image_diff_png.h
index b334b20..380e6dc 100644
--- a/testing/image_diff/image_diff_png.h
+++ b/testing/image_diff/image_diff_png.h
@@ -12,40 +12,35 @@
namespace image_diff_png {
// Decode a PNG into an RGBA pixel array.
-bool DecodePNG(const unsigned char* input,
- size_t input_size,
- std::vector<unsigned char>* output,
- int* width,
- int* height);
+std::vector<unsigned char> DecodePNG(const unsigned char* input,
+ size_t input_size,
+ int* width,
+ int* height);
// Encode a BGR pixel array into a PNG.
-bool EncodeBGRPNG(const unsigned char* input,
- int width,
- int height,
- int row_byte_width,
- std::vector<unsigned char>* output);
+std::vector<unsigned char> EncodeBGRPNG(const unsigned char* input,
+ int width,
+ int height,
+ int row_byte_width);
// Encode an RGBA pixel array into a PNG.
-bool EncodeRGBAPNG(const unsigned char* input,
- int width,
- int height,
- int row_byte_width,
- std::vector<unsigned char>* output);
+std::vector<unsigned char> EncodeRGBAPNG(const unsigned char* input,
+ int width,
+ int height,
+ int row_byte_width);
// Encode an BGRA pixel array into a PNG.
-bool EncodeBGRAPNG(const unsigned char* input,
- int width,
- int height,
- int row_byte_width,
- bool discard_transparency,
- std::vector<unsigned char>* output);
+std::vector<unsigned char> EncodeBGRAPNG(const unsigned char* input,
+ int width,
+ int height,
+ int row_byte_width,
+ bool discard_transparency);
// Encode a grayscale pixel array into a PNG.
-bool EncodeGrayPNG(const unsigned char* input,
- int width,
- int height,
- int row_byte_width,
- std::vector<unsigned char>* output);
+std::vector<unsigned char> EncodeGrayPNG(const unsigned char* input,
+ int width,
+ int height,
+ int row_byte_width);
} // namespace image_diff_png
diff --git a/testing/utils/bitmap_saver.cpp b/testing/utils/bitmap_saver.cpp
index af13efc..bba5cd5 100644
--- a/testing/utils/bitmap_saver.cpp
+++ b/testing/utils/bitmap_saver.cpp
@@ -19,24 +19,20 @@
const auto* buffer =
static_cast<const unsigned char*>(FPDFBitmap_GetBuffer(bitmap));
- std::vector<unsigned char> png_encoding;
- bool encoded;
+ std::vector<unsigned char> png;
if (FPDFBitmap_GetFormat(bitmap) == FPDFBitmap_Gray) {
- encoded = image_diff_png::EncodeGrayPNG(buffer, width, height, stride,
- &png_encoding);
+ png = image_diff_png::EncodeGrayPNG(buffer, width, height, stride);
} else {
- encoded = image_diff_png::EncodeBGRAPNG(buffer, width, height, stride,
- /*discard_transparency=*/false,
- &png_encoding);
+ png = image_diff_png::EncodeBGRAPNG(buffer, width, height, stride,
+ /*discard_transparency=*/false);
}
- DCHECK(encoded);
+ DCHECK(!png.empty());
DCHECK(filename.size() < 256u);
std::ofstream png_file;
png_file.open(filename, std::ios_base::out | std::ios_base::binary);
- png_file.write(reinterpret_cast<char*>(&png_encoding.front()),
- png_encoding.size());
+ png_file.write(reinterpret_cast<char*>(&png.front()), png.size());
DCHECK(png_file.good());
png_file.close();
}