186 int32_t BitmapWidth = pBitmap->GetWidth();
187 int32_t BitmapHeight = pBitmap->GetHeight();
188 if (BitmapWidth < 1 || BitmapHeight < 1)
192 CreateXObjectImageDict(BitmapWidth, BitmapHeight);
193 const int32_t bpp = pBitmap->GetBPP();
194 size_t dest_pitch = 0;
195 bool bCopyWithoutAlpha =
true;
199 if (!pBitmap->IsMaskFormat()) {
200 reset_bgra = ArgbToBGRAStruct(pBitmap->GetPaletteArgb(0));
201 set_bgra = ArgbToBGRAStruct(pBitmap->GetPaletteArgb(1));
203 if (set_bgra.alpha == 0 || reset_bgra.alpha == 0) {
204 pDict->SetNewFor<CPDF_Boolean>(
"ImageMask",
true);
205 if (reset_bgra.alpha == 0) {
206 auto pArray = pDict->SetNewFor<
CPDF_Array>(
"Decode");
207 pArray->AppendNew<CPDF_Number>(1);
208 pArray->AppendNew<CPDF_Number>(0);
211 auto pCS = pDict->SetNewFor<
CPDF_Array>(
"ColorSpace");
212 pCS->AppendNew<CPDF_Name>(
"Indexed");
213 pCS->AppendNew<CPDF_Name>(
"DeviceRGB");
214 pCS->AppendNew<CPDF_Number>(1);
215 const uint8_t ct[6] = {reset_bgra.red, reset_bgra.green, reset_bgra.blue,
216 set_bgra.red, set_bgra.green, set_bgra.blue};
219 pDict->SetNewFor<CPDF_Number>(
"BitsPerComponent", 1);
220 dest_pitch = (BitmapWidth + 7) / 8;
221 }
else if (bpp == 8) {
222 size_t palette_size = pBitmap->GetRequiredPaletteSize();
223 if (palette_size > 0) {
224 DCHECK(palette_size <= 256);
225 auto pCS = m_pDocument->NewIndirect<CPDF_Array>();
226 pCS->AppendNew<CPDF_Name>(
"Indexed");
227 pCS->AppendNew<CPDF_Name>(
"DeviceRGB");
228 pCS->AppendNew<CPDF_Number>(
static_cast<
int>(palette_size - 1));
229 DataVector<uint8_t> color_table(Fx2DSizeOrDie(palette_size, 3));
230 auto color_table_span = pdfium::make_span(color_table);
231 for (size_t i = 0; i < palette_size; i++) {
232 uint32_t argb = pBitmap->GetPaletteArgb(i);
233 color_table_span[0] =
FXARGB_R(argb);
234 color_table_span[1] =
FXARGB_G(argb);
235 color_table_span[2] =
FXARGB_B(argb);
236 color_table_span = color_table_span.subspan(3);
238 auto pNewDict = m_pDocument->New<CPDF_Dictionary>();
239 auto pCTS = m_pDocument->NewIndirect<CPDF_Stream>(std::move(color_table),
240 std::move(pNewDict));
241 pCS->AppendNew<CPDF_Reference>(m_pDocument, pCTS->GetObjNum());
242 pDict->SetNewFor<CPDF_Reference>(
"ColorSpace", m_pDocument,
245 pDict->SetNewFor<CPDF_Name>(
"ColorSpace",
"DeviceGray");
247 pDict->SetNewFor<CPDF_Number>(
"BitsPerComponent", 8);
248 dest_pitch = BitmapWidth;
250 pDict->SetNewFor<CPDF_Name>(
"ColorSpace",
"DeviceRGB");
251 pDict->SetNewFor<CPDF_Number>(
"BitsPerComponent", 8);
252 dest_pitch = BitmapWidth * 3;
253 bCopyWithoutAlpha =
false;
257 if (pBitmap->IsAlphaFormat())
258 pMaskBitmap = pBitmap->CloneAlphaMask();
261 const int32_t mask_width = pMaskBitmap->GetWidth();
262 const int32_t mask_height = pMaskBitmap->GetHeight();
263 DataVector<uint8_t> mask_buf;
265 CreateXObjectImageDict(mask_width, mask_height);
266 pMaskDict->SetNewFor<CPDF_Name>(
"ColorSpace",
"DeviceGray");
267 pMaskDict->SetNewFor<CPDF_Number>(
"BitsPerComponent", 8);
269 mask_buf.resize(Fx2DSizeOrDie(mask_width, mask_height));
270 for (int32_t a = 0; a < mask_height; a++) {
271 fxcrt::Copy(pMaskBitmap->GetScanline(a).first(mask_width),
272 pdfium::make_span(mask_buf).subspan(a * mask_width));
275 pMaskDict->SetNewFor<CPDF_Number>(
276 "Length",
pdfium::checked_cast<
int>(mask_buf.size()));
277 auto pNewStream = m_pDocument->NewIndirect<CPDF_Stream>(
278 std::move(mask_buf), std::move(pMaskDict));
279 pDict->SetNewFor<CPDF_Reference>(
"SMask", m_pDocument,
280 pNewStream->GetObjNum());
283 DataVector<uint8_t> dest_buf(Fx2DSizeOrDie(dest_pitch, BitmapHeight));
284 pdfium::span<uint8_t> dest_span = pdfium::make_span(dest_buf);
285 pdfium::span<
const uint8_t> src_span = pBitmap->GetBuffer();
286 const int32_t src_pitch = pBitmap->GetPitch();
287 if (bCopyWithoutAlpha) {
288 for (int32_t i = 0; i < BitmapHeight; i++) {
289 dest_span =
fxcrt::spancpy(dest_span, src_span.first(dest_pitch));
290 src_span = src_span.subspan(src_pitch);
293 const size_t src_step = bpp == 24 ? 3 : 4;
294 for (int32_t row = 0; row < BitmapHeight; row++) {
295 uint8_t* dest_ptr = dest_span.data();
296 const uint8_t* src_ptr = src_span.data();
297 for (int32_t column = 0; column < BitmapWidth; column++) {
299 dest_ptr[0] = src_ptr[2];
300 dest_ptr[1] = src_ptr[1];
301 dest_ptr[2] = src_ptr[0];
306 dest_span = dest_span.subspan(dest_pitch);
307 src_span = src_span.subspan(src_pitch);
312 pdfium::MakeRetain<CPDF_Stream>(std::move(dest_buf), std::move(pDict));
313 m_bIsMask = pBitmap->IsMaskFormat();
314 m_Width = BitmapWidth;
315 m_Height = BitmapHeight;