static CFX_DIBitmap* Transform1bppBitmap(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix) { ASSERT(pSrc->GetFormat() == FXDIB_1bppRgb || pSrc->GetFormat() == FXDIB_1bppMask || pSrc->GetFormat() == FXDIB_1bppCmyk); CFX_DIBExtractor src_bitmap(pSrc); CFX_DIBitmap* pSrcBitmap = src_bitmap; if (pSrcBitmap == NULL) { return NULL; } int src_width = pSrcBitmap->GetWidth(), src_height = pSrcBitmap->GetHeight(); uint8_t* src_buf = pSrcBitmap->GetBuffer(); FX_DWORD src_pitch = pSrcBitmap->GetPitch(); FX_FLOAT dest_area = pDestMatrix->GetUnitArea(); FX_FLOAT area_scale = FXSYS_Div((FX_FLOAT)(src_width * src_height), dest_area); FX_FLOAT size_scale = FXSYS_sqrt(area_scale); CFX_AffineMatrix adjusted_matrix(*pDestMatrix); adjusted_matrix.Scale(size_scale, size_scale); CFX_FloatRect result_rect_f = adjusted_matrix.GetUnitRect(); FX_RECT result_rect = result_rect_f.GetOutterRect(); CFX_AffineMatrix src2result; src2result.e = adjusted_matrix.c + adjusted_matrix.e; src2result.f = adjusted_matrix.d + adjusted_matrix.f; src2result.a = adjusted_matrix.a / pSrcBitmap->GetWidth(); src2result.b = adjusted_matrix.b / pSrcBitmap->GetWidth(); src2result.c = -adjusted_matrix.c / pSrcBitmap->GetHeight(); src2result.d = -adjusted_matrix.d / pSrcBitmap->GetHeight(); src2result.TranslateI(-result_rect.left, -result_rect.top); CFX_AffineMatrix result2src; result2src.SetReverse(src2result); CPDF_FixedMatrix result2src_fix(result2src, 8); int result_width = result_rect.Width(); int result_height = result_rect.Height(); CFX_DIBitmap* pTempBitmap = new CFX_DIBitmap; if (!pTempBitmap->Create(result_width, result_height, pSrc->GetFormat())) { delete pTempBitmap; if (pSrcBitmap != src_bitmap) { delete pSrcBitmap; } return NULL; } pTempBitmap->CopyPalette(pSrc->GetPalette()); uint8_t* dest_buf = pTempBitmap->GetBuffer(); int dest_pitch = pTempBitmap->GetPitch(); FXSYS_memset(dest_buf, pSrc->IsAlphaMask() ? 0 : 0xff, dest_pitch * result_height); if (pSrcBitmap->IsAlphaMask()) { for (int dest_y = 0; dest_y < result_height; dest_y++) { uint8_t* dest_scan = dest_buf + dest_y * dest_pitch; for (int dest_x = 0; dest_x < result_width; dest_x++) { int src_x, src_y; result2src_fix.Transform(dest_x, dest_y, src_x, src_y); if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) { continue; } if (!((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8)))) { continue; } dest_scan[dest_x / 8] |= 1 << (7 - dest_x % 8); } } } else { for (int dest_y = 0; dest_y < result_height; dest_y++) { uint8_t* dest_scan = dest_buf + dest_y * dest_pitch; for (int dest_x = 0; dest_x < result_width; dest_x++) { int src_x, src_y; result2src_fix.Transform(dest_x, dest_y, src_x, src_y); if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) { continue; } if ((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8))) { continue; } dest_scan[dest_x / 8] &= ~(1 << (7 - dest_x % 8)); } } } if (pSrcBitmap != src_bitmap) { delete pSrcBitmap; } return pTempBitmap; }
CFX_DIBitmap* CFX_DIBSource::SwapXY(FX_BOOL bXFlip, FX_BOOL bYFlip, const FX_RECT* pDestClip) const { FX_RECT dest_clip(0, 0, m_Height, m_Width); if (pDestClip) { dest_clip.Intersect(*pDestClip); } if (dest_clip.IsEmpty()) { return nullptr; } CFX_DIBitmap* pTransBitmap = new CFX_DIBitmap; int result_height = dest_clip.Height(), result_width = dest_clip.Width(); if (!pTransBitmap->Create(result_width, result_height, GetFormat())) { delete pTransBitmap; return nullptr; } pTransBitmap->CopyPalette(m_pPalette.get()); int dest_pitch = pTransBitmap->GetPitch(); uint8_t* dest_buf = pTransBitmap->GetBuffer(); int row_start = bXFlip ? m_Height - dest_clip.right : dest_clip.left; int row_end = bXFlip ? m_Height - dest_clip.left : dest_clip.right; int col_start = bYFlip ? m_Width - dest_clip.bottom : dest_clip.top; int col_end = bYFlip ? m_Width - dest_clip.top : dest_clip.bottom; if (GetBPP() == 1) { FXSYS_memset(dest_buf, 0xff, dest_pitch * result_height); for (int row = row_start; row < row_end; row++) { const uint8_t* src_scan = GetScanline(row); int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - dest_clip.left; uint8_t* dest_scan = dest_buf; if (bYFlip) { dest_scan += (result_height - 1) * dest_pitch; } int dest_step = bYFlip ? -dest_pitch : dest_pitch; for (int col = col_start; col < col_end; col++) { if (!(src_scan[col / 8] & (1 << (7 - col % 8)))) { dest_scan[dest_col / 8] &= ~(1 << (7 - dest_col % 8)); } dest_scan += dest_step; } } } else { int nBytes = GetBPP() / 8; int dest_step = bYFlip ? -dest_pitch : dest_pitch; if (nBytes == 3) { dest_step -= 2; } for (int row = row_start; row < row_end; row++) { int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - dest_clip.left; uint8_t* dest_scan = dest_buf + dest_col * nBytes; if (bYFlip) { dest_scan += (result_height - 1) * dest_pitch; } if (nBytes == 4) { uint32_t* src_scan = (uint32_t*)GetScanline(row) + col_start; for (int col = col_start; col < col_end; col++) { *(uint32_t*)dest_scan = *src_scan++; dest_scan += dest_step; } } else { const uint8_t* src_scan = GetScanline(row) + col_start * nBytes; if (nBytes == 1) { for (int col = col_start; col < col_end; col++) { *dest_scan = *src_scan++; dest_scan += dest_step; } } else { for (int col = col_start; col < col_end; col++) { *dest_scan++ = *src_scan++; *dest_scan++ = *src_scan++; *dest_scan = *src_scan++; dest_scan += dest_step; } } } } } if (m_pAlphaMask) { dest_pitch = pTransBitmap->m_pAlphaMask->GetPitch(); dest_buf = pTransBitmap->m_pAlphaMask->GetBuffer(); int dest_step = bYFlip ? -dest_pitch : dest_pitch; for (int row = row_start; row < row_end; row++) { int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - dest_clip.left; uint8_t* dest_scan = dest_buf + dest_col; if (bYFlip) { dest_scan += (result_height - 1) * dest_pitch; } const uint8_t* src_scan = m_pAlphaMask->GetScanline(row) + col_start; for (int col = col_start; col < col_end; col++) { *dest_scan = *src_scan++; dest_scan += dest_step; } } } return pTransBitmap; }
CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, HBITMAP hBitmap, FX_DWORD* pPalette, FX_DWORD palsize) { FX_BOOL bCreatedDC = hDC == NULL; if (hDC == NULL) { hDC = CreateCompatibleDC(NULL); } BITMAPINFOHEADER bmih; FXSYS_memset(&bmih, 0, sizeof bmih); bmih.biSize = sizeof bmih; GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS); int width = bmih.biWidth; int height = abs(bmih.biHeight); bmih.biHeight = -height; bmih.biCompression = BI_RGB; CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; int ret = 0; if (bmih.biBitCount == 1 || bmih.biBitCount == 8) { int size = sizeof (BITMAPINFOHEADER) + 8; if (bmih.biBitCount == 8) { size += sizeof (FX_DWORD) * 254; } BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(uint8_t, size); pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmih->bmiHeader.biBitCount = bmih.biBitCount; pbmih->bmiHeader.biCompression = BI_RGB; pbmih->bmiHeader.biHeight = -height; pbmih->bmiHeader.biPlanes = 1; pbmih->bmiHeader.biWidth = bmih.biWidth; if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 ? FXDIB_1bppRgb : FXDIB_8bppRgb)) { delete pDIBitmap; FX_Free(pbmih); if (bCreatedDC) { DeleteDC(hDC); } return NULL; } ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)pbmih, DIB_RGB_COLORS); FX_Free(pbmih); pbmih = NULL; pDIBitmap->CopyPalette(pPalette, palsize); } else { if (bmih.biBitCount <= 24) { bmih.biBitCount = 24; } else { bmih.biBitCount = 32; } if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) { delete pDIBitmap; if (bCreatedDC) { DeleteDC(hDC); } return NULL; } ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)&bmih, DIB_RGB_COLORS); if (ret != 0 && bmih.biBitCount == 32) { int pitch = pDIBitmap->GetPitch(); for (int row = 0; row < height; row ++) { uint8_t* dest_scan = (uint8_t*)(pDIBitmap->GetBuffer() + row * pitch); for (int col = 0; col < width; col++) { dest_scan[3] = 255; dest_scan += 4; } } } } if (ret == 0) { delete pDIBitmap; pDIBitmap = NULL; } if (bCreatedDC) { DeleteDC(hDC); } return pDIBitmap; }