Change CBC_DataMatrixWriter::Encode() to return a vector.

Also make out parameters pointers, instead of non-const references.

Change-Id: Idf28d1bbfce43a0c23b5aac30c78cb79ad5e5c4d
Reviewed-on: https://pdfium-review.googlesource.com/c/46515
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/fxbarcode/cbc_datamatrix.cpp b/fxbarcode/cbc_datamatrix.cpp
index c9e23fa..42679a0 100644
--- a/fxbarcode/cbc_datamatrix.cpp
+++ b/fxbarcode/cbc_datamatrix.cpp
@@ -22,6 +22,7 @@
 #include "fxbarcode/cbc_datamatrix.h"
 
 #include <memory>
+#include <vector>
 
 #include "fxbarcode/datamatrix/BC_DataMatrixWriter.h"
 #include "third_party/base/ptr_util.h"
@@ -29,17 +30,15 @@
 CBC_DataMatrix::CBC_DataMatrix()
     : CBC_CodeBase(pdfium::MakeUnique<CBC_DataMatrixWriter>()) {}
 
-CBC_DataMatrix::~CBC_DataMatrix() {}
+CBC_DataMatrix::~CBC_DataMatrix() = default;
 
 bool CBC_DataMatrix::Encode(const WideStringView& contents) {
-  int32_t outWidth = 0;
-  int32_t outHeight = 0;
+  int32_t width;
+  int32_t height;
   auto* pWriter = GetDataMatrixWriter();
-  std::unique_ptr<uint8_t, FxFreeDeleter> data(
-      pWriter->Encode(WideString(contents), outWidth, outHeight));
-  if (!data)
-    return false;
-  return pWriter->RenderResult(data.get(), outWidth, outHeight);
+  std::vector<uint8_t> data =
+      pWriter->Encode(WideString(contents), &width, &height);
+  return !data.empty() && pWriter->RenderResult(data.data(), width, height);
 }
 
 bool CBC_DataMatrix::RenderDevice(CFX_RenderDevice* device,
diff --git a/fxbarcode/datamatrix/BC_DataMatrixWriter.cpp b/fxbarcode/datamatrix/BC_DataMatrixWriter.cpp
index 86df78b..9f8b983 100644
--- a/fxbarcode/datamatrix/BC_DataMatrixWriter.cpp
+++ b/fxbarcode/datamatrix/BC_DataMatrixWriter.cpp
@@ -42,6 +42,7 @@
 #include "fxbarcode/datamatrix/BC_TextEncoder.h"
 #include "fxbarcode/datamatrix/BC_X12Encoder.h"
 #include "third_party/base/ptr_util.h"
+#include "third_party/base/stl_util.h"
 
 namespace {
 
@@ -106,22 +107,23 @@
   return true;
 }
 
-uint8_t* CBC_DataMatrixWriter::Encode(const WideString& contents,
-                                      int32_t& outWidth,
-                                      int32_t& outHeight) {
+std::vector<uint8_t> CBC_DataMatrixWriter::Encode(const WideString& contents,
+                                                  int32_t* pOutWidth,
+                                                  int32_t* pOutHeight) {
+  std::vector<uint8_t> results;
   WideString encoded = CBC_HighLevelEncoder::EncodeHighLevel(contents, false);
   if (encoded.IsEmpty())
-    return nullptr;
+    return results;
 
   const CBC_SymbolInfo* pSymbolInfo =
       CBC_SymbolInfo::Lookup(encoded.GetLength(), false);
   if (!pSymbolInfo)
-    return nullptr;
+    return results;
 
   WideString codewords =
       CBC_ErrorCorrection::EncodeECC200(encoded, pSymbolInfo);
   if (codewords.IsEmpty())
-    return nullptr;
+    return results;
 
   int32_t width = pSymbolInfo->getSymbolDataWidth();
   ASSERT(width);
@@ -133,11 +135,12 @@
   placement->place();
   auto bytematrix = encodeLowLevel(placement.get(), pSymbolInfo);
   if (!bytematrix)
-    return nullptr;
+    return results;
 
-  outWidth = bytematrix->GetWidth();
-  outHeight = bytematrix->GetHeight();
-  uint8_t* result = FX_Alloc2D(uint8_t, outWidth, outHeight);
-  memcpy(result, bytematrix->GetArray().data(), outWidth * outHeight);
-  return result;
+  *pOutWidth = bytematrix->GetWidth();
+  *pOutHeight = bytematrix->GetHeight();
+  results = pdfium::Vector2D<uint8_t>(*pOutWidth, *pOutHeight);
+  memcpy(results.data(), bytematrix->GetArray().data(),
+         *pOutWidth * *pOutHeight);
+  return results;
 }
diff --git a/fxbarcode/datamatrix/BC_DataMatrixWriter.h b/fxbarcode/datamatrix/BC_DataMatrixWriter.h
index f3dcc55..f95612e 100644
--- a/fxbarcode/datamatrix/BC_DataMatrixWriter.h
+++ b/fxbarcode/datamatrix/BC_DataMatrixWriter.h
@@ -7,6 +7,8 @@
 #ifndef FXBARCODE_DATAMATRIX_BC_DATAMATRIXWRITER_H_
 #define FXBARCODE_DATAMATRIX_BC_DATAMATRIXWRITER_H_
 
+#include <vector>
+
 #include "fxbarcode/BC_TwoDimWriter.h"
 
 class CBC_DataMatrixWriter final : public CBC_TwoDimWriter {
@@ -14,9 +16,9 @@
   CBC_DataMatrixWriter();
   ~CBC_DataMatrixWriter() override;
 
-  uint8_t* Encode(const WideString& contents,
-                  int32_t& outWidth,
-                  int32_t& outHeight);
+  std::vector<uint8_t> Encode(const WideString& contents,
+                              int32_t* pOutWidth,
+                              int32_t* pOutHeight);
 
   // CBC_TwoDimWriter
   bool SetErrorCorrectionLevel(int32_t level) override;
diff --git a/fxbarcode/datamatrix/BC_DataMatrixWriter_unittest.cpp b/fxbarcode/datamatrix/BC_DataMatrixWriter_unittest.cpp
index 10bfbbe..cf7942e 100644
--- a/fxbarcode/datamatrix/BC_DataMatrixWriter_unittest.cpp
+++ b/fxbarcode/datamatrix/BC_DataMatrixWriter_unittest.cpp
@@ -26,11 +26,6 @@
 
   {
     static constexpr int kExpectedDimension = 10;
-    std::unique_ptr<uint8_t, FxFreeDeleter> data(
-        writer.Encode(L"", width, height));
-    ASSERT_TRUE(data);
-    ASSERT_EQ(kExpectedDimension, width);
-    ASSERT_EQ(kExpectedDimension, height);
     // clang-format off
     static const char kExpectedData[kExpectedDimension * kExpectedDimension] = {
         1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
@@ -45,16 +40,15 @@
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1
     };
     // clang-format on
+    std::vector<uint8_t> data = writer.Encode(L"", &width, &height);
+    ASSERT_EQ(FX_ArraySize(kExpectedData), data.size());
+    ASSERT_EQ(kExpectedDimension, width);
+    ASSERT_EQ(kExpectedDimension, height);
     for (size_t i = 0; i < FX_ArraySize(kExpectedData); ++i)
-      EXPECT_EQ(kExpectedData[i], data.get()[i]) << i;
+      EXPECT_EQ(kExpectedData[i], data[i]) << i;
   }
   {
     static constexpr int kExpectedDimension = 14;
-    std::unique_ptr<uint8_t, FxFreeDeleter> data(
-        writer.Encode(L"helloworld", width, height));
-    ASSERT_TRUE(data);
-    ASSERT_EQ(kExpectedDimension, width);
-    ASSERT_EQ(kExpectedDimension, height);
     // clang-format off
     static const char kExpectedData[kExpectedDimension * kExpectedDimension] = {
         1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
@@ -73,16 +67,15 @@
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
     };
     // clang-format on
+    std::vector<uint8_t> data = writer.Encode(L"helloworld", &width, &height);
+    ASSERT_EQ(FX_ArraySize(kExpectedData), data.size());
+    ASSERT_EQ(kExpectedDimension, width);
+    ASSERT_EQ(kExpectedDimension, height);
     for (size_t i = 0; i < FX_ArraySize(kExpectedData); ++i)
-      EXPECT_EQ(kExpectedData[i], data.get()[i]) << i;
+      EXPECT_EQ(kExpectedData[i], data[i]) << i;
   }
   {
     static constexpr int kExpectedDimension = 10;
-    std::unique_ptr<uint8_t, FxFreeDeleter> data(
-        writer.Encode(L"12345", width, height));
-    ASSERT_TRUE(data);
-    ASSERT_EQ(kExpectedDimension, width);
-    ASSERT_EQ(kExpectedDimension, height);
     // clang-format off
     static const char kExpectedData[kExpectedDimension * kExpectedDimension] = {
         1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
@@ -97,12 +90,15 @@
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1
     };
     // clang-format on
+    std::vector<uint8_t> data = writer.Encode(L"12345", &width, &height);
+    ASSERT_EQ(FX_ArraySize(kExpectedData), data.size());
+    ASSERT_EQ(kExpectedDimension, width);
+    ASSERT_EQ(kExpectedDimension, height);
     for (size_t i = 0; i < FX_ArraySize(kExpectedData); ++i)
-      EXPECT_EQ(kExpectedData[i], data.get()[i]) << i;
+      EXPECT_EQ(kExpectedData[i], data[i]) << i;
   }
   {
-    std::unique_ptr<uint8_t, FxFreeDeleter> data(
-        writer.Encode(L"hello world", width, height));
-    ASSERT_FALSE(data);
+    std::vector<uint8_t> data = writer.Encode(L"hello world", &width, &height);
+    ASSERT_TRUE(data.empty());
   }
 }