// 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/SkPicture.h"       // nogncheck
#include "third_party/skia/include/core/SkSerialProcs.h"   // nogncheck
#include "third_party/skia/include/core/SkStream.h"        // nogncheck
#include "third_party/skia/include/encode/SkPngEncoder.h"  // nogncheck
#endif

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::make_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> {
      return SkPngEncoder::Encode(nullptr, img, SkPngEncoder::Options{});
  };

  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::make_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");
}
