// Copyright 2018 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "testing/helpers/write.h"

#include <limits.h>

#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "core/fxcrt/check.h"
#include "core/fxcrt/notreached.h"
#include "public/cpp/fpdf_scopers.h"
#include "public/fpdf_annot.h"
#include "public/fpdf_attachment.h"
#include "public/fpdf_edit.h"
#include "public/fpdf_thumbnail.h"
#include "testing/fx_string_testhelpers.h"
#include "testing/image_diff/image_diff_png.h"

#ifdef PDF_ENABLE_SKIA
#include "third_party/skia/include/core/SkImage.h"        // nogncheck
#include "third_party/skia/include/core/SkPicture.h"      // nogncheck
#include "third_party/skia/include/core/SkPixmap.h"       // nogncheck
#include "third_party/skia/include/core/SkSerialProcs.h"  // nogncheck
#include "third_party/skia/include/core/SkStream.h"       // nogncheck
#ifdef PDF_ENABLE_RUST_PNG
#include "third_party/skia/include/encode/SkPngRustEncoder.h"  // nogncheck
#else
#include "third_party/skia/include/encode/SkPngEncoder.h"  // nogncheck
#endif  // PDF_ENABLE_RUST_PNG
#endif  // PDF_ENABLE_SKIA

namespace {

bool CheckDimensions(int stride, int width, int height) {
  if (stride < 0 || width < 0 || height < 0) {
    return false;
  }
  if (height > 0 && stride > INT_MAX / height) {
    return false;
  }
  return true;
}

const char* AnnotSubtypeToCString(FPDF_ANNOTATION_SUBTYPE subtype) {
  if (subtype == FPDF_ANNOT_TEXT) {
    return "Text";
  }
  if (subtype == FPDF_ANNOT_LINK) {
    return "Link";
  }
  if (subtype == FPDF_ANNOT_FREETEXT) {
    return "FreeText";
  }
  if (subtype == FPDF_ANNOT_LINE) {
    return "Line";
  }
  if (subtype == FPDF_ANNOT_SQUARE) {
    return "Square";
  }
  if (subtype == FPDF_ANNOT_CIRCLE) {
    return "Circle";
  }
  if (subtype == FPDF_ANNOT_POLYGON) {
    return "Polygon";
  }
  if (subtype == FPDF_ANNOT_POLYLINE) {
    return "PolyLine";
  }
  if (subtype == FPDF_ANNOT_HIGHLIGHT) {
    return "Highlight";
  }
  if (subtype == FPDF_ANNOT_UNDERLINE) {
    return "Underline";
  }
  if (subtype == FPDF_ANNOT_SQUIGGLY) {
    return "Squiggly";
  }
  if (subtype == FPDF_ANNOT_STRIKEOUT) {
    return "StrikeOut";
  }
  if (subtype == FPDF_ANNOT_STAMP) {
    return "Stamp";
  }
  if (subtype == FPDF_ANNOT_CARET) {
    return "Caret";
  }
  if (subtype == FPDF_ANNOT_INK) {
    return "Ink";
  }
  if (subtype == FPDF_ANNOT_POPUP) {
    return "Popup";
  }
  if (subtype == FPDF_ANNOT_FILEATTACHMENT) {
    return "FileAttachment";
  }
  if (subtype == FPDF_ANNOT_SOUND) {
    return "Sound";
  }
  if (subtype == FPDF_ANNOT_MOVIE) {
    return "Movie";
  }
  if (subtype == FPDF_ANNOT_WIDGET) {
    return "Widget";
  }
  if (subtype == FPDF_ANNOT_SCREEN) {
    return "Screen";
  }
  if (subtype == FPDF_ANNOT_PRINTERMARK) {
    return "PrinterMark";
  }
  if (subtype == FPDF_ANNOT_TRAPNET) {
    return "TrapNet";
  }
  if (subtype == FPDF_ANNOT_WATERMARK) {
    return "Watermark";
  }
  if (subtype == FPDF_ANNOT_THREED) {
    return "3D";
  }
  if (subtype == FPDF_ANNOT_RICHMEDIA) {
    return "RichMedia";
  }
  if (subtype == FPDF_ANNOT_XFAWIDGET) {
    return "XFAWidget";
  }
  NOTREACHED();
}

void AppendFlagString(const char* flag, std::string* output) {
  if (!output->empty()) {
    *output += ", ";
  }
  *output += flag;
}

std::string AnnotFlagsToString(int flags) {
  std::string str;
  if (flags & FPDF_ANNOT_FLAG_INVISIBLE) {
    AppendFlagString("Invisible", &str);
  }
  if (flags & FPDF_ANNOT_FLAG_HIDDEN) {
    AppendFlagString("Hidden", &str);
  }
  if (flags & FPDF_ANNOT_FLAG_PRINT) {
    AppendFlagString("Print", &str);
  }
  if (flags & FPDF_ANNOT_FLAG_NOZOOM) {
    AppendFlagString("NoZoom", &str);
  }
  if (flags & FPDF_ANNOT_FLAG_NOROTATE) {
    AppendFlagString("NoRotate", &str);
  }
  if (flags & FPDF_ANNOT_FLAG_NOVIEW) {
    AppendFlagString("NoView", &str);
  }
  if (flags & FPDF_ANNOT_FLAG_READONLY) {
    AppendFlagString("ReadOnly", &str);
  }
  if (flags & FPDF_ANNOT_FLAG_LOCKED) {
    AppendFlagString("Locked", &str);
  }
  if (flags & FPDF_ANNOT_FLAG_TOGGLENOVIEW) {
    AppendFlagString("ToggleNoView", &str);
  }
  return str;
}

const char* PageObjectTypeToCString(int type) {
  if (type == FPDF_PAGEOBJ_TEXT) {
    return "Text";
  }
  if (type == FPDF_PAGEOBJ_PATH) {
    return "Path";
  }
  if (type == FPDF_PAGEOBJ_IMAGE) {
    return "Image";
  }
  if (type == FPDF_PAGEOBJ_SHADING) {
    return "Shading";
  }
  if (type == FPDF_PAGEOBJ_FORM) {
    return "Form";
  }
  NOTREACHED();
}

std::vector<uint8_t> EncodePng(pdfium::span<const uint8_t> input,
                               int width,
                               int height,
                               int stride,
                               int format) {
  std::vector<uint8_t> png;
  switch (format) {
    case FPDFBitmap_Unknown:
      break;
    case FPDFBitmap_Gray:
      png = image_diff_png::EncodeGrayPNG(input, width, height, stride);
      break;
    case FPDFBitmap_BGR:
      png = image_diff_png::EncodeBGRPNG(input, width, height, stride);
      break;
    case FPDFBitmap_BGRx:
      png = image_diff_png::EncodeBGRAPNG(input, width, height, stride,
                                          /*discard_transparency=*/true);
      break;
    case FPDFBitmap_BGRA:
      png = image_diff_png::EncodeBGRAPNG(input, width, height, stride,
                                          /*discard_transparency=*/false);
      break;
    default:
      NOTREACHED();
  }
  return png;
}

#ifdef _WIN32
int CALLBACK EnhMetaFileProc(HDC hdc,
                             HANDLETABLE* handle_table,
                             const ENHMETARECORD* record,
                             int objects_count,
                             LPARAM param) {
  std::vector<const ENHMETARECORD*>& items =
      *reinterpret_cast<std::vector<const ENHMETARECORD*>*>(param);
  items.push_back(record);
  return 1;
}
#endif  // _WIN32

std::string GeneratePageOutputFilename(const char* pdf_name,
                                       int page_num,
                                       const char* extension) {
  std::ostringstream stream;
  stream << pdf_name << "." << page_num << "." << extension;
  std::string filename = stream.str();
  if (filename.size() >= 256) {
    fprintf(stderr, "Filename %s is too long\n", filename.c_str());
    return std::string();
  }

  return filename;
}

std::string GenerateImageOutputFilename(const char* pdf_name,
                                        int page_num,
                                        int image_num,
                                        const char* extension) {
  std::ostringstream stream;
  stream << pdf_name << "." << page_num << "." << image_num << "." << extension;
  std::string filename = stream.str();
  if (filename.size() >= 256) {
    fprintf(stderr, "Filename %s for saving image is too long.\n",
            filename.c_str());
    return std::string();
  }

  return filename;
}

}  // namespace

std::string WritePpm(const char* pdf_name,
                     int num,
                     void* buffer_void,
                     int stride,
                     int width,
                     int height) {
  if (!CheckDimensions(stride, width, height)) {
    return "";
  }

  int out_len = width * height;
  if (out_len > INT_MAX / 3) {
    return "";
  }

  out_len *= 3;

  std::string filename = GeneratePageOutputFilename(pdf_name, num, "ppm");
  if (filename.empty()) {
    return std::string();
  }
  FILE* fp = fopen(filename.c_str(), "wb");
  if (!fp) {
    return std::string();
  }

  fprintf(fp, "P6\n# PDF test render\n%d %d\n255\n", width, height);
  // Source data is B, G, R, unused.
  // Dest data is R, G, B.
  const uint8_t* buffer = reinterpret_cast<const uint8_t*>(buffer_void);
  std::vector<uint8_t> result(out_len);
  for (int h = 0; h < height; ++h) {
    const uint8_t* src_line = buffer + (stride * h);
    uint8_t* dest_line = result.data() + (width * h * 3);
    for (int w = 0; w < width; ++w) {
      // R
      dest_line[w * 3] = src_line[(w * 4) + 2];
      // G
      dest_line[(w * 3) + 1] = src_line[(w * 4) + 1];
      // B
      dest_line[(w * 3) + 2] = src_line[w * 4];
    }
  }
  if (fwrite(result.data(), out_len, 1, fp) != 1) {
    fprintf(stderr, "Failed to write to %s\n", filename.c_str());
  }

  fclose(fp);
  return filename;
}

void WriteText(FPDF_TEXTPAGE textpage, const char* pdf_name, int num) {
  std::string filename = GeneratePageOutputFilename(pdf_name, num, "txt");
  if (filename.empty()) {
    return;
  }
  FILE* fp = fopen(filename.c_str(), "w");
  if (!fp) {
    fprintf(stderr, "Failed to open %s for output\n", filename.c_str());
    return;
  }

  // Output in UTF32-LE.
  uint32_t bom = 0x0000FEFF;
  if (fwrite(&bom, sizeof(bom), 1, fp) != 1) {
    fprintf(stderr, "Failed to write to %s\n", filename.c_str());
    (void)fclose(fp);
    return;
  }

  for (int i = 0; i < FPDFText_CountChars(textpage); i++) {
    uint32_t c = FPDFText_GetUnicode(textpage, i);
    if (fwrite(&c, sizeof(c), 1, fp) != 1) {
      fprintf(stderr, "Failed to write to %s\n", filename.c_str());
      break;
    }
  }
  (void)fclose(fp);
}

void WriteAnnot(FPDF_PAGE page, const char* pdf_name, int num) {
  // Open the output text file.
  std::string filename = GeneratePageOutputFilename(pdf_name, num, "annot.txt");
  if (filename.empty()) {
    return;
  }
  FILE* fp = fopen(filename.c_str(), "w");
  if (!fp) {
    fprintf(stderr, "Failed to open %s for output\n", filename.c_str());
    return;
  }

  int annot_count = FPDFPage_GetAnnotCount(page);
  fprintf(fp, "Number of annotations: %d\n\n", annot_count);

  // Iterate through all annotations on this page.
  for (int i = 0; i < annot_count; ++i) {
    // Retrieve the annotation object and its subtype.
    fprintf(fp, "Annotation #%d:\n", i + 1);
    ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, i));
    if (!annot) {
      fprintf(fp, "Failed to retrieve annotation!\n\n");
      continue;
    }

    FPDF_ANNOTATION_SUBTYPE subtype = FPDFAnnot_GetSubtype(annot.get());
    fprintf(fp, "Subtype: %s\n", AnnotSubtypeToCString(subtype));

    // Retrieve the annotation flags.
    fprintf(fp, "Flags set: %s\n",
            AnnotFlagsToString(FPDFAnnot_GetFlags(annot.get())).c_str());

    // Retrieve the annotation's object count and object types.
    const int obj_count = FPDFAnnot_GetObjectCount(annot.get());
    fprintf(fp, "Number of objects: %d\n", obj_count);
    if (obj_count > 0) {
      fprintf(fp, "Object types: ");
      for (int j = 0; j < obj_count; ++j) {
        const char* type = PageObjectTypeToCString(
            FPDFPageObj_GetType(FPDFAnnot_GetObject(annot.get(), j)));
        fprintf(fp, "%s  ", type);
      }
      fprintf(fp, "\n");
    }

    // Retrieve the annotation's color and interior color.
    unsigned int R;
    unsigned int G;
    unsigned int B;
    unsigned int A;
    if (FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_Color, &R, &G, &B,
                           &A)) {
      fprintf(fp, "Color in RGBA: %d %d %d %d\n", R, G, B, A);
    } else {
      fprintf(fp, "Failed to retrieve color.\n");
    }
    if (FPDFAnnot_GetColor(annot.get(), FPDFANNOT_COLORTYPE_InteriorColor, &R,
                           &G, &B, &A)) {
      fprintf(fp, "Interior color in RGBA: %d %d %d %d\n", R, G, B, A);
    } else {
      fprintf(fp, "Failed to retrieve interior color.\n");
    }

    // Retrieve the annotation's contents and author.
    static constexpr char kContentsKey[] = "Contents";
    static constexpr char kAuthorKey[] = "T";
    unsigned long length_bytes =
        FPDFAnnot_GetStringValue(annot.get(), kContentsKey, nullptr, 0);
    std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
    FPDFAnnot_GetStringValue(annot.get(), kContentsKey, buf.data(),
                             length_bytes);
    fprintf(fp, "Content: %ls\n", GetPlatformWString(buf.data()).c_str());
    length_bytes =
        FPDFAnnot_GetStringValue(annot.get(), kAuthorKey, nullptr, 0);
    buf = GetFPDFWideStringBuffer(length_bytes);
    FPDFAnnot_GetStringValue(annot.get(), kAuthorKey, buf.data(), length_bytes);
    fprintf(fp, "Author: %ls\n", GetPlatformWString(buf.data()).c_str());

    // Retrieve the annotation's quadpoints if it is a markup annotation.
    if (FPDFAnnot_HasAttachmentPoints(annot.get())) {
      size_t qp_count = FPDFAnnot_CountAttachmentPoints(annot.get());
      fprintf(fp, "Number of quadpoints sets: %zu\n", qp_count);

      // Iterate through all quadpoints of the current annotation
      for (size_t j = 0; j < qp_count; ++j) {
        FS_QUADPOINTSF quadpoints;
        if (FPDFAnnot_GetAttachmentPoints(annot.get(), j, &quadpoints)) {
          fprintf(fp,
                  "Quadpoints set #%zu: (%.3f, %.3f), (%.3f, %.3f), "
                  "(%.3f, %.3f), (%.3f, %.3f)\n",
                  j + 1, quadpoints.x1, quadpoints.y1, quadpoints.x2,
                  quadpoints.y2, quadpoints.x3, quadpoints.y3, quadpoints.x4,
                  quadpoints.y4);
        } else {
          fprintf(fp, "Failed to retrieve quadpoints set #%zu.\n", j + 1);
        }
      }
    }

    // Retrieve the annotation's rectangle coordinates.
    FS_RECTF rect;
    if (FPDFAnnot_GetRect(annot.get(), &rect)) {
      fprintf(fp, "Rectangle: l - %.3f, b - %.3f, r - %.3f, t - %.3f\n\n",
              rect.left, rect.bottom, rect.right, rect.top);
    } else {
      fprintf(fp, "Failed to retrieve annotation rectangle.\n");
    }
  }

  (void)fclose(fp);
}

std::string WritePng(const char* pdf_name,
                     int num,
                     void* buffer,
                     int stride,
                     int width,
                     int height) {
  if (!CheckDimensions(stride, width, height)) {
    return "";
  }

  auto input = pdfium::span(static_cast<uint8_t*>(buffer),
                            static_cast<size_t>(stride) * height);
  std::vector<uint8_t> png_encoding =
      EncodePng(input, width, height, stride, FPDFBitmap_BGRA);
  if (png_encoding.empty()) {
    fprintf(stderr, "Failed to convert bitmap to PNG\n");
    return "";
  }

  std::string filename = GeneratePageOutputFilename(pdf_name, num, "png");
  if (filename.empty()) {
    return std::string();
  }
  FILE* fp = fopen(filename.c_str(), "wb");
  if (!fp) {
    fprintf(stderr, "Failed to open %s for output\n", filename.c_str());
    return std::string();
  }

  size_t bytes_written =
      fwrite(&png_encoding.front(), 1, png_encoding.size(), fp);
  if (bytes_written != png_encoding.size()) {
    fprintf(stderr, "Failed to write to %s\n", filename.c_str());
  }

  (void)fclose(fp);
  return filename;
}

#ifdef _WIN32
std::string WriteBmp(const char* pdf_name,
                     int num,
                     void* buffer,
                     int stride,
                     int width,
                     int height) {
  if (!CheckDimensions(stride, width, height)) {
    return std::string();
  }

  int out_len = stride * height;
  if (out_len > INT_MAX / 3) {
    return std::string();
  }

  std::string filename = GeneratePageOutputFilename(pdf_name, num, "bmp");
  if (filename.empty()) {
    return std::string();
  }
  FILE* fp = fopen(filename.c_str(), "wb");
  if (!fp) {
    return std::string();
  }

  BITMAPINFO bmi = {};
  bmi.bmiHeader.biSize = sizeof(bmi) - sizeof(RGBQUAD);
  bmi.bmiHeader.biWidth = width;
  bmi.bmiHeader.biHeight = -height;  // top-down image
  bmi.bmiHeader.biPlanes = 1;
  bmi.bmiHeader.biBitCount = 32;
  bmi.bmiHeader.biCompression = BI_RGB;
  bmi.bmiHeader.biSizeImage = 0;

  BITMAPFILEHEADER file_header = {};
  file_header.bfType = 0x4d42;
  file_header.bfSize = sizeof(file_header) + bmi.bmiHeader.biSize + out_len;
  file_header.bfOffBits = file_header.bfSize - out_len;

  if (fwrite(&file_header, sizeof(file_header), 1, fp) != 1 ||
      fwrite(&bmi, bmi.bmiHeader.biSize, 1, fp) != 1 ||
      fwrite(buffer, out_len, 1, fp) != 1) {
    fprintf(stderr, "Failed to write to %s\n", filename.c_str());
  }
  fclose(fp);
  return filename;
}

void WriteEmf(FPDF_PAGE page, const char* pdf_name, int num) {
  std::string filename = GeneratePageOutputFilename(pdf_name, num, "emf");
  if (filename.empty()) {
    return;
  }

  HDC dc = CreateEnhMetaFileA(nullptr, filename.c_str(), nullptr, nullptr);

  int width = static_cast<int>(FPDF_GetPageWidthF(page));
  int height = static_cast<int>(FPDF_GetPageHeightF(page));
  HRGN rgn = CreateRectRgn(0, 0, width, height);
  SelectClipRgn(dc, rgn);
  DeleteObject(rgn);

  SelectObject(dc, GetStockObject(NULL_PEN));
  SelectObject(dc, GetStockObject(WHITE_BRUSH));
  // If a PS_NULL pen is used, the dimensions of the rectangle are 1 pixel less.
  Rectangle(dc, 0, 0, width + 1, height + 1);

  CHECK(FPDF_RenderPage(dc, page, 0, 0, width, height, 0,
                        FPDF_ANNOT | FPDF_PRINTING));

  DeleteEnhMetaFile(CloseEnhMetaFile(dc));
}

void WritePS(FPDF_PAGE page, const char* pdf_name, int num) {
  std::string filename = GeneratePageOutputFilename(pdf_name, num, "ps");
  if (filename.empty()) {
    return;
  }
  FILE* fp = fopen(filename.c_str(), "wb");
  if (!fp) {
    return;
  }

  HDC dc = CreateEnhMetaFileA(nullptr, nullptr, nullptr, nullptr);

  int width = static_cast<int>(FPDF_GetPageWidthF(page));
  int height = static_cast<int>(FPDF_GetPageHeightF(page));
  CHECK(FPDF_RenderPage(dc, page, 0, 0, width, height, 0,
                        FPDF_ANNOT | FPDF_PRINTING));

  HENHMETAFILE emf = CloseEnhMetaFile(dc);
  std::vector<const ENHMETARECORD*> items;
  EnumEnhMetaFile(nullptr, emf, &EnhMetaFileProc, &items, nullptr);
  for (const ENHMETARECORD* record : items) {
    if (record->iType != EMR_GDICOMMENT) {
      continue;
    }

    const auto* comment = reinterpret_cast<const EMRGDICOMMENT*>(record);
    const char* data = reinterpret_cast<const char*>(comment->Data);
    uint16_t size = *reinterpret_cast<const uint16_t*>(data);
    if (fwrite(data + sizeof(uint16_t), size, 1, fp) != 1) {
      fprintf(stderr, "Failed to write to %s\n", filename.c_str());
      break;
    }
  }
  fclose(fp);
  DeleteEnhMetaFile(emf);
}
#endif  // _WIN32

#ifdef PDF_ENABLE_SKIA
std::unique_ptr<SkWStream> WriteToSkWStream(const std::string& pdf_name,
                                            int num,
                                            const std::string& extension) {
  std::string discarded_filename;
  return WriteToSkWStream(pdf_name, num, extension, discarded_filename);
}

std::unique_ptr<SkWStream> WriteToSkWStream(const std::string& pdf_name,
                                            int num,
                                            const std::string& extension,
                                            std::string& filename) {
  filename =
      GeneratePageOutputFilename(pdf_name.c_str(), num, extension.c_str());
  if (filename.empty()) {
    return nullptr;
  }

  auto stream = std::make_unique<SkFILEWStream>(filename.c_str());
  if (!stream->isValid()) {
    return nullptr;
  }

  return stream;
}

std::string WriteSkp(const char* pdf_name, int num, const SkPicture& picture) {
  std::string filename;
  std::unique_ptr<SkWStream> stream =
      WriteToSkWStream(pdf_name, num, "skp", filename);
  if (!stream) {
    return "";
  }
  SkSerialProcs procs;
  procs.fImageProc = [](SkImage* img, void*) -> sk_sp<SkData> {
#ifdef PDF_ENABLE_RUST_PNG
    return SkPngRustEncoder::Encode(nullptr, img, /*options=*/{});
#else
    return SkPngEncoder::Encode(nullptr, img, /*options=*/{});
#endif
  };

  picture.serialize(stream.get(), &procs);
  return filename;
}
#endif  // PDF_ENABLE_SKIA

enum class ThumbnailDecodeType { kBitmap, kRawStream, kDecodedStream };

bool GetThumbnailFilename(char* name_buf,
                          size_t name_buf_size,
                          const char* pdf_name,
                          int page_num,
                          ThumbnailDecodeType decode_type) {
  const char* format;
  switch (decode_type) {
    case ThumbnailDecodeType::kBitmap:
      format = "%s.thumbnail.%d.png";
      break;
    case ThumbnailDecodeType::kDecodedStream:
      format = "%s.thumbnail.decoded.%d.bin";
      break;
    case ThumbnailDecodeType::kRawStream:
      format = "%s.thumbnail.raw.%d.bin";
      break;
  }

  int chars_formatted =
      snprintf(name_buf, name_buf_size, format, pdf_name, page_num);
  if (chars_formatted < 0 ||
      static_cast<size_t>(chars_formatted) >= name_buf_size) {
    fprintf(stderr, "Filename %s for saving is too long.\n", name_buf);
    return false;
  }

  return true;
}

void WriteBufferToFile(const void* buf,
                       size_t buflen,
                       const char* filename,
                       const char* filetype) {
  FILE* fp = fopen(filename, "wb");
  if (!fp) {
    fprintf(stderr, "Failed to open %s for saving %s.", filename, filetype);
    return;
  }

  size_t bytes_written = fwrite(buf, 1, buflen, fp);
  if (bytes_written == buflen) {
    fprintf(stderr, "Successfully wrote %s %s.\n", filetype, filename);
  } else {
    fprintf(stderr, "Failed to write to %s.\n", filename);
  }
  fclose(fp);
}

std::vector<uint8_t> EncodeBitmapToPng(ScopedFPDFBitmap bitmap) {
  std::vector<uint8_t> png_encoding;
  int format = FPDFBitmap_GetFormat(bitmap.get());
  if (format == FPDFBitmap_Unknown) {
    return png_encoding;
  }

  int width = FPDFBitmap_GetWidth(bitmap.get());
  int height = FPDFBitmap_GetHeight(bitmap.get());
  int stride = FPDFBitmap_GetStride(bitmap.get());
  if (!CheckDimensions(stride, width, height)) {
    return png_encoding;
  }

  auto input = pdfium::span(
      static_cast<const uint8_t*>(FPDFBitmap_GetBuffer(bitmap.get())),
      static_cast<size_t>(stride) * height);

  png_encoding = EncodePng(input, width, height, stride, format);
  return png_encoding;
}

void WriteAttachments(FPDF_DOCUMENT doc, const std::string& name) {
  for (int i = 0; i < FPDFDoc_GetAttachmentCount(doc); ++i) {
    FPDF_ATTACHMENT attachment = FPDFDoc_GetAttachment(doc, i);

    // Retrieve the attachment file name.
    std::string attachment_name;
    unsigned long length_bytes = FPDFAttachment_GetName(attachment, nullptr, 0);
    if (length_bytes) {
      std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
      unsigned long actual_length_bytes =
          FPDFAttachment_GetName(attachment, buf.data(), length_bytes);
      if (actual_length_bytes == length_bytes) {
        attachment_name = GetPlatformString(buf.data());
      }
    }
    if (attachment_name.empty()) {
      fprintf(stderr, "Attachment #%d has an empty file name.\n", i + 1);
      continue;
    }

    // Calculate the full attachment file name.
    char save_name[256];
    int chars_formatted =
        snprintf(save_name, sizeof(save_name), "%s.attachment.%s", name.c_str(),
                 attachment_name.c_str());
    if (chars_formatted < 0 ||
        static_cast<size_t>(chars_formatted) >= sizeof(save_name)) {
      fprintf(stderr, "Filename %s is too long.\n", save_name);
      continue;
    }

    // Retrieve the attachment.
    if (!FPDFAttachment_GetFile(attachment, nullptr, 0, &length_bytes)) {
      fprintf(stderr, "Failed to retrieve attachment \"%s\".\n",
              attachment_name.c_str());
      continue;
    }

    std::vector<char> data_buf(length_bytes);
    if (length_bytes) {
      unsigned long actual_length_bytes;
      if (!FPDFAttachment_GetFile(attachment, data_buf.data(), length_bytes,
                                  &actual_length_bytes)) {
        fprintf(stderr, "Failed to retrieve attachment \"%s\".\n",
                attachment_name.c_str());
        continue;
      }
    }

    // Write the attachment file. Since a PDF document could have 0-byte files
    // as attachments, we should allow saving the 0-byte attachments to files.
    WriteBufferToFile(data_buf.data(), length_bytes, save_name, "attachment");
  }
}

void WriteImages(FPDF_PAGE page, const char* pdf_name, int page_num) {
  for (int i = 0; i < FPDFPage_CountObjects(page); ++i) {
    FPDF_PAGEOBJECT obj = FPDFPage_GetObject(page, i);
    if (FPDFPageObj_GetType(obj) != FPDF_PAGEOBJ_IMAGE) {
      continue;
    }

    ScopedFPDFBitmap bitmap(FPDFImageObj_GetBitmap(obj));
    if (!bitmap) {
      fprintf(stderr, "Image object #%d on page #%d has an empty bitmap.\n",
              i + 1, page_num + 1);
      continue;
    }

    std::string filename =
        GenerateImageOutputFilename(pdf_name, page_num, i, "png");
    if (filename.empty()) {
      continue;
    }

    std::vector<uint8_t> png_encoding = EncodeBitmapToPng(std::move(bitmap));
    if (png_encoding.empty()) {
      fprintf(stderr,
              "Failed to convert image object #%d, on page #%d to png.\n",
              i + 1, page_num + 1);
      continue;
    }

    WriteBufferToFile(&png_encoding.front(), png_encoding.size(),
                      filename.c_str(), "image");
  }
}

void WriteRenderedImages(FPDF_DOCUMENT doc,
                         FPDF_PAGE page,
                         const char* pdf_name,
                         int page_num) {
  for (int i = 0; i < FPDFPage_CountObjects(page); ++i) {
    FPDF_PAGEOBJECT obj = FPDFPage_GetObject(page, i);
    if (FPDFPageObj_GetType(obj) != FPDF_PAGEOBJ_IMAGE) {
      continue;
    }

    ScopedFPDFBitmap bitmap(FPDFImageObj_GetRenderedBitmap(doc, page, obj));
    if (!bitmap) {
      fprintf(stderr, "Image object #%d on page #%d has an empty bitmap.\n",
              i + 1, page_num + 1);
      continue;
    }

    std::string filename =
        GenerateImageOutputFilename(pdf_name, page_num, i, "png");
    if (filename.empty()) {
      continue;
    }

    std::vector<uint8_t> png_encoding = EncodeBitmapToPng(std::move(bitmap));
    if (png_encoding.empty()) {
      fprintf(stderr,
              "Failed to convert image object #%d, on page #%d to png.\n",
              i + 1, page_num + 1);
      continue;
    }

    WriteBufferToFile(&png_encoding.front(), png_encoding.size(),
                      filename.c_str(), "image");
  }
}

void WriteDecodedThumbnailStream(FPDF_PAGE page,
                                 const char* pdf_name,
                                 int page_num) {
  char filename[256];
  if (!GetThumbnailFilename(filename, sizeof(filename), pdf_name, page_num,
                            ThumbnailDecodeType::kDecodedStream)) {
    return;
  }

  unsigned long decoded_data_size =
      FPDFPage_GetDecodedThumbnailData(page, nullptr, 0u);

  // Only continue if there actually is a thumbnail for this page
  if (decoded_data_size == 0) {
    fprintf(stderr, "Failed to get decoded thumbnail for page #%d.\n",
            page_num + 1);
    return;
  }

  std::vector<uint8_t> thumb_buf(decoded_data_size);
  if (FPDFPage_GetDecodedThumbnailData(
          page, thumb_buf.data(), decoded_data_size) != decoded_data_size) {
    fprintf(stderr, "Failed to get decoded thumbnail data for %s.\n", filename);
    return;
  }

  WriteBufferToFile(thumb_buf.data(), decoded_data_size, filename,
                    "decoded thumbnail");
}

void WriteRawThumbnailStream(FPDF_PAGE page,
                             const char* pdf_name,
                             int page_num) {
  char filename[256];
  if (!GetThumbnailFilename(filename, sizeof(filename), pdf_name, page_num,
                            ThumbnailDecodeType::kRawStream)) {
    return;
  }

  unsigned long raw_data_size = FPDFPage_GetRawThumbnailData(page, nullptr, 0u);

  // Only continue if there actually is a thumbnail for this page
  if (raw_data_size == 0) {
    fprintf(stderr, "Failed to get raw thumbnail data for page #%d.\n",
            page_num + 1);
    return;
  }

  std::vector<uint8_t> thumb_buf(raw_data_size);
  if (FPDFPage_GetRawThumbnailData(page, thumb_buf.data(), raw_data_size) !=
      raw_data_size) {
    fprintf(stderr, "Failed to get raw thumbnail data for %s.\n", filename);
    return;
  }

  WriteBufferToFile(thumb_buf.data(), raw_data_size, filename, "raw thumbnail");
}

void WriteThumbnail(FPDF_PAGE page, const char* pdf_name, int page_num) {
  char filename[256];
  if (!GetThumbnailFilename(filename, sizeof(filename), pdf_name, page_num,
                            ThumbnailDecodeType::kBitmap)) {
    return;
  }

  ScopedFPDFBitmap thumb_bitmap(FPDFPage_GetThumbnailAsBitmap(page));
  if (!thumb_bitmap) {
    fprintf(stderr, "Thumbnail of page #%d has an empty bitmap.\n",
            page_num + 1);
    return;
  }

  std::vector<uint8_t> png_encoding =
      EncodeBitmapToPng(std::move(thumb_bitmap));
  if (png_encoding.empty()) {
    fprintf(stderr, "Failed to convert thumbnail of page #%d to png.\n",
            page_num + 1);
    return;
  }

  WriteBufferToFile(&png_encoding.front(), png_encoding.size(), filename,
                    "thumbnail");
}
