| // Copyright 2019 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // ----------------------------------------------------------------------------- |
| // |
| // Image savers |
| |
| #include "imageio/image_enc.h" |
| |
| #include <cstdio> |
| #include <cstring> |
| |
| #include "imageio/file_format.h" |
| #include "imageio/imageio_util.h" |
| #include "src/utils/csp.h" |
| #include "src/utils/utils.h" |
| #include "src/wp2/base.h" |
| #include "src/wp2/format_constants.h" |
| |
| namespace WP2 { |
| |
| //------------------------------------------------------------------------------ |
| |
| WP2Status SaveImage(const ArgbBuffer& buffer, const char* const file_path, |
| bool overwrite, FileFormat format, size_t* const file_size, |
| const CSPTransform& transform) { |
| WP2_CHECK_OK(file_path != nullptr, WP2_STATUS_NULL_PARAMETER); |
| WP2_CHECK_OK(!buffer.IsEmpty(), WP2_STATUS_INVALID_PARAMETER); |
| |
| std::FILE* fout = nullptr; |
| const bool use_stdout = (strcmp(file_path, "-") == 0); |
| if (use_stdout) { // std::ftell() does not work with pipes. |
| WP2_CHECK_OK(file_size == nullptr, WP2_STATUS_INVALID_PARAMETER); |
| } |
| |
| if (format == FileFormat::AUTO) { |
| format = use_stdout ? FileFormat::PNG : GetFormatFromExtension(file_path); |
| } |
| |
| #ifdef HAVE_WINCODEC_H |
| if (format != PNG) // NOLINT |
| #endif |
| { |
| const char* const mode = (overwrite ? "wb" : "wxb"); |
| fout = |
| use_stdout ? IoUtilSetBinaryMode(stdout) : std::fopen(file_path, mode); |
| WP2_CHECK_OK(fout != nullptr, (!use_stdout && FileExists(file_path)) |
| ? WP2_STATUS_BAD_WRITE |
| : WP2_STATUS_INVALID_PARAMETER); |
| } |
| |
| WP2Status status; |
| if (format == FileFormat::PNG) { |
| status = |
| WritePNG(buffer, fout, file_path, use_stdout, overwrite, file_size); |
| } else if (format == FileFormat::TIFF) { |
| status = WriteTIFF(buffer, fout); |
| } else if (format == FileFormat::BMP) { |
| status = WriteBMP(buffer, fout); |
| } else if (format == FileFormat::PGM) { |
| status = WritePGM(buffer, fout, transform); |
| } else if (format == FileFormat::PPM) { |
| status = WritePPM(buffer, fout); |
| } else if (format == FileFormat::PAM) { |
| status = WritePAM(buffer, fout); |
| } else if (format == FileFormat::WEBP) { |
| MemoryWriter writer; |
| status = |
| CompressWebP(buffer, /*quality=*/kMaxQuality, /*effort=*/6, &writer); |
| if (status == WP2_STATUS_OK) { |
| std::fwrite(writer.mem_, writer.size_, 1, fout); |
| } |
| } else if (format == FileFormat::JPEG_XL) { |
| MemoryWriter writer; |
| // Do not choose kMaxEffort as this would lead to JPEG XL's level 10. |
| status = |
| CompressJXL(buffer, /*quality=*/kMaxQuality, /*effort=*/6, &writer); |
| if (status == WP2_STATUS_OK) { |
| std::fwrite(writer.mem_, writer.size_, 1, fout); |
| } |
| } else { |
| status = WP2_STATUS_UNSUPPORTED_FEATURE; |
| } |
| |
| if (fout != nullptr) { |
| if (file_size != nullptr) *file_size = std::ftell(fout); |
| if (fout != stdout) std::fclose(fout); |
| } |
| return status; |
| } |
| |
| //------------------------------------------------------------------------------ |
| |
| } // namespace WP2 |