static void _JpegEncode(const CFX_DIBSource* pSource, FX_LPBYTE& dest_buf, FX_STRSIZE& dest_size, int quality, FX_LPCBYTE icc_buf, FX_DWORD icc_length) { struct jpeg_error_mgr jerr; jerr.error_exit = _error_do_nothing; jerr.emit_message = _error_do_nothing1; jerr.output_message = _error_do_nothing; jerr.format_message = _error_do_nothing2; jerr.reset_error_mgr = _error_do_nothing; struct jpeg_compress_struct cinfo; memset(&cinfo, 0, sizeof(cinfo)); cinfo.err = &jerr; jpeg_create_compress(&cinfo); int Bpp = pSource->GetBPP() / 8; FX_DWORD nComponents = Bpp >= 3 ? (pSource->IsCmykImage() ? 4 : 3) : 1; FX_DWORD pitch = pSource->GetPitch(); FX_DWORD width = pdfium::base::checked_cast<FX_DWORD>(pSource->GetWidth()); FX_DWORD height = pdfium::base::checked_cast<FX_DWORD>(pSource->GetHeight()); FX_SAFE_DWORD safe_buf_len = width; safe_buf_len *= height; safe_buf_len *= nComponents; safe_buf_len += 1024; if (icc_length) { safe_buf_len += 255 * 18; safe_buf_len += icc_length; } FX_DWORD dest_buf_length = 0; if (!safe_buf_len.IsValid()) { dest_buf = nullptr; } else { dest_buf_length = safe_buf_len.ValueOrDie(); dest_buf = FX_TryAlloc(FX_BYTE, dest_buf_length); const int MIN_TRY_BUF_LEN = 1024; while (!dest_buf && dest_buf_length > MIN_TRY_BUF_LEN) { dest_buf_length >>= 1; dest_buf = FX_TryAlloc(FX_BYTE, dest_buf_length); } } if (!dest_buf) { FX_OutOfMemoryTerminate(); } struct jpeg_destination_mgr dest; dest.init_destination = _dest_do_nothing; dest.term_destination = _dest_do_nothing; dest.empty_output_buffer = _dest_empty; dest.next_output_byte = dest_buf; dest.free_in_buffer = dest_buf_length; cinfo.dest = &dest; cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = nComponents; if (nComponents == 1) { cinfo.in_color_space = JCS_GRAYSCALE; } else if (nComponents == 3) { cinfo.in_color_space = JCS_RGB; } else { cinfo.in_color_space = JCS_CMYK; } FX_LPBYTE line_buf = NULL; if (nComponents > 1) { line_buf = FX_Alloc2D(FX_BYTE, width, nComponents); } jpeg_set_defaults(&cinfo); if(quality != 75) { jpeg_set_quality(&cinfo, quality, TRUE); } jpeg_start_compress(&cinfo, TRUE); _JpegEmbedIccProfile(&cinfo, icc_buf, icc_length); JSAMPROW row_pointer[1]; JDIMENSION row; while (cinfo.next_scanline < cinfo.image_height) { FX_LPCBYTE src_scan = pSource->GetScanline(cinfo.next_scanline); if (nComponents > 1) { FX_LPBYTE dest_scan = line_buf; if (nComponents == 3) { for (int i = 0; i < width; i ++) { dest_scan[0] = src_scan[2]; dest_scan[1] = src_scan[1]; dest_scan[2] = src_scan[0]; dest_scan += 3; src_scan += Bpp; } } else { for (int i = 0; i < pitch; i ++) { *dest_scan++ = ~*src_scan++; } } row_pointer[0] = line_buf; } else { row_pointer[0] = (FX_LPBYTE)src_scan; } row = cinfo.next_scanline; jpeg_write_scanlines(&cinfo, row_pointer, 1); if (cinfo.next_scanline == row) { dest_buf = FX_Realloc(FX_BYTE, dest_buf, dest_buf_length + JPEG_BLOCK_SIZE); dest.next_output_byte = dest_buf + dest_buf_length - dest.free_in_buffer; dest_buf_length += JPEG_BLOCK_SIZE; dest.free_in_buffer += JPEG_BLOCK_SIZE; } } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); if (line_buf) { FX_Free(line_buf); } dest_size = dest_buf_length - (FX_STRSIZE)dest.free_in_buffer; }
static void _JpegEncode(const CFX_DIBSource* pSource, FX_LPBYTE& dest_buf, FX_STRSIZE& dest_size, int quality, FX_LPCBYTE icc_buf, FX_DWORD icc_length) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; jerr.error_exit = _error_do_nothing; jerr.emit_message = _error_do_nothing1; jerr.output_message = _error_do_nothing; jerr.format_message = _error_do_nothing2; jerr.reset_error_mgr = _error_do_nothing; cinfo.err = &jerr; jpeg_create_compress(&cinfo); int Bpp = pSource->GetBPP() / 8; int nComponents = Bpp >= 3 ? (pSource->IsCmykImage() ? 4 : 3) : 1; int pitch = pSource->GetPitch(); int width = pSource->GetWidth(); int height = pSource->GetHeight(); FX_DWORD dest_buf_length = width * height * nComponents + 1024 + (icc_length ? (icc_length + 255 * 18) : 0); dest_buf = FX_Alloc(FX_BYTE, dest_buf_length); while (dest_buf == NULL) { dest_buf_length >>= 1; dest_buf = FX_Alloc(FX_BYTE, dest_buf_length); } FXSYS_memset32(dest_buf, 0, dest_buf_length); struct jpeg_destination_mgr dest; dest.init_destination = _dest_do_nothing; dest.term_destination = _dest_do_nothing; dest.empty_output_buffer = _dest_empty; dest.next_output_byte = dest_buf; dest.free_in_buffer = dest_buf_length; cinfo.dest = &dest; cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = nComponents; if (nComponents == 1) { cinfo.in_color_space = JCS_GRAYSCALE; } else if (nComponents == 3) { cinfo.in_color_space = JCS_RGB; } else { cinfo.in_color_space = JCS_CMYK; } FX_LPBYTE line_buf = NULL; if (nComponents > 1) { line_buf = FX_Alloc(FX_BYTE, width * nComponents); if (line_buf == NULL) { return; } } jpeg_set_defaults(&cinfo); if(quality != 75) { jpeg_set_quality(&cinfo, quality, TRUE); } jpeg_start_compress(&cinfo, TRUE); _JpegEmbedIccProfile(&cinfo, icc_buf, icc_length); JSAMPROW row_pointer[1]; JDIMENSION row; while (cinfo.next_scanline < cinfo.image_height) { FX_LPCBYTE src_scan = pSource->GetScanline(cinfo.next_scanline); if (nComponents > 1) { FX_LPBYTE dest_scan = line_buf; if (nComponents == 3) { for (int i = 0; i < width; i ++) { dest_scan[0] = src_scan[2]; dest_scan[1] = src_scan[1]; dest_scan[2] = src_scan[0]; dest_scan += 3; src_scan += Bpp; } } else { for (int i = 0; i < pitch; i ++) { *dest_scan++ = ~*src_scan++; } } row_pointer[0] = line_buf; } else { row_pointer[0] = (FX_LPBYTE)src_scan; } row = cinfo.next_scanline; jpeg_write_scanlines(&cinfo, row_pointer, 1); if (cinfo.next_scanline == row) { dest_buf = FX_Realloc(FX_BYTE, dest_buf, dest_buf_length + JPEG_BLOCK_SIZE); if (dest_buf == NULL) { FX_Free(line_buf); return; } dest.next_output_byte = dest_buf + dest_buf_length - dest.free_in_buffer; dest_buf_length += JPEG_BLOCK_SIZE; dest.free_in_buffer += JPEG_BLOCK_SIZE; } } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); if (line_buf) { FX_Free(line_buf); } dest_size = dest_buf_length - (FX_STRSIZE)dest.free_in_buffer; }