181 int32_t BitmapWidth = pBitmap->GetWidth();
182 int32_t BitmapHeight = pBitmap->GetHeight();
183 if (BitmapWidth < 1 || BitmapHeight < 1)
187 CreateXObjectImageDict(BitmapWidth, BitmapHeight);
188 const int32_t bpp = pBitmap->GetBPP();
189 size_t dest_pitch = 0;
190 bool bCopyWithoutAlpha =
true;
200 if (!pBitmap->IsMaskFormat()) {
201 std::tie(reset_a, reset_r, reset_g, reset_b) =
202 ArgbDecode(pBitmap->GetPaletteArgb(0));
203 std::tie(set_a, set_r, set_g, set_b) =
204 ArgbDecode(pBitmap->GetPaletteArgb(1));
206 if (set_a == 0 || reset_a == 0) {
207 pDict->SetNewFor<CPDF_Boolean>(
"ImageMask",
true);
209 auto pArray = pDict->SetNewFor<CPDF_Array>(
"Decode");
210 pArray->AppendNew<CPDF_Number>(1);
211 pArray->AppendNew<CPDF_Number>(0);
214 auto pCS = pDict->SetNewFor<CPDF_Array>(
"ColorSpace");
215 pCS->AppendNew<CPDF_Name>(
"Indexed");
216 pCS->AppendNew<CPDF_Name>(
"DeviceRGB");
217 pCS->AppendNew<CPDF_Number>(1);
221 pdfium::span<
char> pBuf = ct.GetBuffer(6);
222 pBuf[0] =
static_cast<
char>(reset_r);
223 pBuf[1] =
static_cast<
char>(reset_g);
224 pBuf[2] =
static_cast<
char>(reset_b);
225 pBuf[3] =
static_cast<
char>(set_r);
226 pBuf[4] =
static_cast<
char>(set_g);
227 pBuf[5] =
static_cast<
char>(set_b);
230 pCS->AppendNew<CPDF_String>(ct,
true);
232 pDict->SetNewFor<CPDF_Number>(
"BitsPerComponent", 1);
233 dest_pitch = (BitmapWidth + 7) / 8;
234 }
else if (bpp == 8) {
235 size_t palette_size = pBitmap->GetRequiredPaletteSize();
236 if (palette_size > 0) {
237 DCHECK(palette_size <= 256);
238 auto pCS = m_pDocument->NewIndirect<CPDF_Array>();
239 pCS->AppendNew<CPDF_Name>(
"Indexed");
240 pCS->AppendNew<CPDF_Name>(
"DeviceRGB");
241 pCS->AppendNew<CPDF_Number>(
static_cast<
int>(palette_size - 1));
242 DataVector<uint8_t> color_table(Fx2DSizeOrDie(palette_size, 3));
243 auto color_table_span = pdfium::make_span(color_table);
244 for (size_t i = 0; i < palette_size; i++) {
245 uint32_t argb = pBitmap->GetPaletteArgb(i);
246 color_table_span[0] =
FXARGB_R(argb);
247 color_table_span[1] =
FXARGB_G(argb);
248 color_table_span[2] =
FXARGB_B(argb);
249 color_table_span = color_table_span.subspan(3);
251 auto pNewDict = m_pDocument->New<CPDF_Dictionary>();
252 auto pCTS = m_pDocument->NewIndirect<CPDF_Stream>(std::move(color_table),
253 std::move(pNewDict));
254 pCS->AppendNew<CPDF_Reference>(m_pDocument, pCTS->GetObjNum());
255 pDict->SetNewFor<CPDF_Reference>(
"ColorSpace", m_pDocument,
258 pDict->SetNewFor<CPDF_Name>(
"ColorSpace",
"DeviceGray");
260 pDict->SetNewFor<CPDF_Number>(
"BitsPerComponent", 8);
261 dest_pitch = BitmapWidth;
263 pDict->SetNewFor<CPDF_Name>(
"ColorSpace",
"DeviceRGB");
264 pDict->SetNewFor<CPDF_Number>(
"BitsPerComponent", 8);
265 dest_pitch = BitmapWidth * 3;
266 bCopyWithoutAlpha =
false;
270 if (pBitmap->IsAlphaFormat())
271 pMaskBitmap = pBitmap->CloneAlphaMask();
274 const int32_t mask_width = pMaskBitmap->GetWidth();
275 const int32_t mask_height = pMaskBitmap->GetHeight();
276 DataVector<uint8_t> mask_buf;
278 CreateXObjectImageDict(mask_width, mask_height);
279 pMaskDict->SetNewFor<CPDF_Name>(
"ColorSpace",
"DeviceGray");
280 pMaskDict->SetNewFor<CPDF_Number>(
"BitsPerComponent", 8);
282 mask_buf.resize(Fx2DSizeOrDie(mask_width, mask_height));
283 for (int32_t a = 0; a < mask_height; a++) {
284 fxcrt::spancpy(pdfium::make_span(mask_buf).subspan(a * mask_width),
285 pMaskBitmap->GetScanline(a).first(mask_width));
288 pMaskDict->SetNewFor<CPDF_Number>(
289 "Length", pdfium::base::checked_cast<
int>(mask_buf.size()));
290 auto pNewStream = m_pDocument->NewIndirect<CPDF_Stream>(
291 std::move(mask_buf), std::move(pMaskDict));
292 pDict->SetNewFor<CPDF_Reference>(
"SMask", m_pDocument,
293 pNewStream->GetObjNum());
296 DataVector<uint8_t> dest_buf(Fx2DSizeOrDie(dest_pitch, BitmapHeight));
297 pdfium::span<uint8_t> dest_span = pdfium::make_span(dest_buf);
298 pdfium::span<
const uint8_t> src_span = pBitmap->GetBuffer();
299 const int32_t src_pitch = pBitmap->GetPitch();
300 if (bCopyWithoutAlpha) {
301 for (int32_t i = 0; i < BitmapHeight; i++) {
302 fxcrt::spancpy(dest_span, src_span.first(dest_pitch));
303 dest_span = dest_span.subspan(dest_pitch);
304 src_span = src_span.subspan(src_pitch);
307 const size_t src_step = bpp == 24 ? 3 : 4;
308 for (int32_t row = 0; row < BitmapHeight; row++) {
309 uint8_t* dest_ptr = dest_span.data();
310 const uint8_t* src_ptr = src_span.data();
311 for (int32_t column = 0; column < BitmapWidth; column++) {
312 dest_ptr[0] = src_ptr[2];
313 dest_ptr[1] = src_ptr[1];
314 dest_ptr[2] = src_ptr[0];
318 dest_span = dest_span.subspan(dest_pitch);
319 src_span = src_span.subspan(src_pitch);
324 pdfium::MakeRetain<CPDF_Stream>(std::move(dest_buf), std::move(pDict));
325 m_bIsMask = pBitmap->IsMaskFormat();
326 m_Width = BitmapWidth;
327 m_Height = BitmapHeight;