Commit 18adb421 authored by Elen.Subbotina's avatar Elen.Subbotina Committed by Alexander Trofimov

PdfWriter with JBig2 linux build

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62538 954022d7-b5bf-4e40-9824-e11837661b57
parent c790d7af
......@@ -808,7 +808,7 @@ CString RtfCharProperty::RenderToOOX(RenderParameter oRenderParameter)
sResult.Append( m_poShading.RenderToOOX( oRenderParameter ));
return sResult;
}
#include <langinfo.h>
CString RtfListLevelProperty::RenderToRtf(RenderParameter oRenderParameter)
{
RtfDocument* poRtfDocument = static_cast<RtfDocument*>( oRenderParameter.poDocument);
......
......@@ -432,8 +432,7 @@ SOURCES += \
../../../cximage/CxImage/ximawmf.cpp \
../../../cximage/CxImage/ximawnd.cpp \
../../../cximage/CxImage/xmemfile.cpp \
../../../raster/BgraFrame.cpp \
../../../raster/ImageFileFormatChecker.cpp
../../../raster/BgraFrame.cpp
HEADERS += \
../../../graphics/AggPlusEnums.h \
......
......@@ -114,7 +114,7 @@ jbig2enc_init(struct jbig2enc_ctx *ctx) {
ctx->bp = -1;
ctx->b = 0;
ctx->outbuf_used = 0;
ctx->outbuf = (u8 *) malloc(JBIG2_OUTPUTBUFFER_SIZE);
ctx->outbuf = (u8 *) new u8 [JBIG2_OUTPUTBUFFER_SIZE];
ctx->output_chunks = new std::vector<uint8_t *>;
ctx->iaidctx = NULL;
}
......@@ -127,7 +127,7 @@ jbig2enc_reset(struct jbig2enc_ctx *ctx) {
ctx->ct = 12;
ctx->bp = -1;
ctx->b = 0;
free(ctx->iaidctx);
delete []ctx->iaidctx;
ctx->iaidctx = NULL;
memset(ctx->context, 0, JBIG2_MAX_CTX);
memset(ctx->intctx, 0, 13 * 512);
......@@ -139,8 +139,9 @@ jbig2enc_flush(struct jbig2enc_ctx *ctx) {
ctx->outbuf_used = 0;
for (std::vector<uint8_t *>::iterator i = ctx->output_chunks->begin();
i != ctx->output_chunks->end(); ++i) {
free(*i);
i != ctx->output_chunks->end(); ++i)
{
delete [](*i);
}
ctx->output_chunks->clear();
ctx->bp = -1;
......@@ -150,12 +151,14 @@ jbig2enc_flush(struct jbig2enc_ctx *ctx) {
void
jbig2enc_dealloc(struct jbig2enc_ctx *ctx) {
for (std::vector<uint8_t *>::iterator i = ctx->output_chunks->begin();
i != ctx->output_chunks->end(); ++i) {
free(*i);
i != ctx->output_chunks->end(); ++i)
{
delete [](*i);
}
delete ctx->output_chunks;
free(ctx->outbuf);
free(ctx->iaidctx);
delete []ctx->outbuf;
delete []ctx->iaidctx;
}
// -----------------------------------------------------------------------------
......@@ -166,7 +169,7 @@ static void inline
emit(struct jbig2enc_ctx *restrict ctx) {
if (unlikely(ctx->outbuf_used == JBIG2_OUTPUTBUFFER_SIZE)) {
ctx->output_chunks->push_back(ctx->outbuf);
ctx->outbuf = (u8 *) malloc(JBIG2_OUTPUTBUFFER_SIZE);
ctx->outbuf = new u8[JBIG2_OUTPUTBUFFER_SIZE];
ctx->outbuf_used = 0;
}
......@@ -359,11 +362,12 @@ jbig2enc_oob(struct jbig2enc_ctx *restrict ctx, int proc) {
// see comments in .h file
void
jbig2enc_int(struct jbig2enc_ctx *restrict ctx, int proc, int value) {
jbig2enc_int(struct jbig2enc_ctx *restrict ctx, int proc, int value)
{
u8 *const context = ctx->intctx[proc];
int i;
if (value > 2000000000 || value < -2000000000) abort();
// if (value > 2000000000 || value < -2000000000) assert();
u32 prev = 1;
......@@ -404,10 +408,12 @@ jbig2enc_int(struct jbig2enc_ctx *restrict ctx, int proc, int value) {
// see comments in .h file
void
jbig2enc_iaid(struct jbig2enc_ctx *restrict ctx, int symcodelen, int value) {
if (!ctx->iaidctx) {
jbig2enc_iaid(struct jbig2enc_ctx *restrict ctx, int symcodelen, int value)
{
if (!ctx->iaidctx)
{
// we've not yet allocated the context index buffer for this
ctx->iaidctx = (u8 *) malloc(1 << symcodelen);
ctx->iaidctx = (u8 *) new u8[1 << symcodelen];
memset(ctx->iaidctx, 0, 1 << symcodelen);
}
const u32 mask = (1 << (symcodelen + 1)) - 1;
......
......@@ -286,7 +286,8 @@ jbig2_pages_complete(struct jbig2ctx *ctx, int *const length) {
jbig2enc_init(&ectx);
struct jbig2_file_header header;
if (ctx->full_headers) {
if (ctx->full_headers)
{
memset(&header, 0, sizeof(header));
header.n_pages = htonl(ctx->classer->npages);
header.organisation_type = 1;
......
#ifndef _JBIG2_ENCODER_H
#define _JBIG2_ENCODER_H
#include <vector>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include "../LeptonLib/allheaders.h"
#include "../LeptonLib/pix.h"
#include "jbig2enc.h"
#include "io.h"
#if defined(_WIN32) || defined (_WIN64)
// -----------------------------------------------------------------------------
// Windows, sadly, lacks asprintf
// -----------------------------------------------------------------------------
#include <stdarg.h>
int asprintf(char **strp, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
const int required = vsnprintf(NULL, 0, fmt, va);
char *const buffer = (char *) malloc(required + 1);
const int ret = vsnprintf(buffer, required + 1, fmt, va);
*strp = buffer;
va_end(va);
return ret;
}
#endif
// -----------------------------------------------------------------------------
// Morphological operations for segmenting an image into text regions
// -----------------------------------------------------------------------------
static const char *segment_mask_sequence = "r11";
static const char *segment_seed_sequence = "r1143 + o4.4 + x4"; /* maybe o6.6 */
static const char *segment_dilation_sequence = "d3.3";
// -----------------------------------------------------------------------------
// Takes two pix as input, generated from the same original image:
// 1. pixb - a binary thresholded image
// 2. piximg - a full color or grayscale image
// and segments them by finding the areas that contain color or grayscale
// graphics, removing those areas from the binary image, and doing the
// opposite for the full color/grayscale image. The upshot is that after
// this routine has been run, the binary image contains only text and the
// full color image contains only the graphics.
//
// Both input images are modified by this procedure. If no text is found,
// pixb is set to NULL. If no graphics is found, piximg is set to NULL.
//
// Thanks to Dan Bloomberg for this
// -----------------------------------------------------------------------------
static PIX*
segment_image(PIX *pixb, PIX *piximg) {
// Make seed and mask, and fill seed into mask
PIX *pixmask4 = pixMorphSequence(pixb, (char *) segment_mask_sequence, 0);
PIX *pixseed4 = pixMorphSequence(pixb, (char *) segment_seed_sequence, 0);
PIX *pixsf4 = pixSeedfillBinary(NULL, pixseed4, pixmask4, 8);
PIX *pixd4 = pixMorphSequence(pixsf4, (char *) segment_dilation_sequence, 0);
// we want to force the binary mask to be the same size as the
// input color image, so we have to do it this way...
// is there a better way?
// PIX *pixd = pixExpandBinary(pixd4, 4);
PIX *pixd = pixCreate(piximg->w, piximg->h, 1);
pixCopyResolution(pixd, piximg);
expandBinaryPower2Low(pixd->data, pixd->w, pixd->h, pixd->wpl,
pixd4->data, pixd4->w, pixd4->h, pixd4->wpl, 4);
pixDestroy(&pixd4);
pixDestroy(&pixsf4);
pixDestroy(&pixseed4);
pixDestroy(&pixmask4);
pixSubtract(pixb, pixb, pixd);
// now see what we got from the segmentation
static l_int32 *tab = NULL;
if (tab == NULL) tab = makePixelSumTab8();
// if no image portion was found, set the image pointer to NULL and return
l_int32 pcount;
pixCountPixels(pixd, &pcount, tab);
if (pcount < 100) {
pixDestroy(&pixd);
return NULL;
}
// if no text portion found, set the binary pointer to NULL
pixCountPixels(pixb, &pcount, tab);
if (pcount < 100) {
pixDestroy(&pixb);
}
PIX *piximg1;
if (piximg->d == 1 || piximg->d == 8 || piximg->d == 32) {
piximg1 = pixClone(piximg);
} else if (piximg->d > 8) {
piximg1 = pixConvertTo32(piximg);
} else {
piximg1 = pixConvertTo8(piximg, FALSE);
}
PIX *pixd1;
if (piximg1->d == 32) {
pixd1 = pixConvertTo32(pixd);
} else if (piximg1->d == 8) {
pixd1 = pixConvertTo8(pixd, FALSE);
} else {
pixd1 = pixClone(pixd);
}
pixDestroy(&pixd);
pixRasteropFullImage(pixd1, piximg1, PIX_SRC | PIX_DST);
pixDestroy(&piximg1);
return pixd1;
#include <vector>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include "../LeptonLib/allheaders.h"
#include "../LeptonLib/pix.h"
#include "jbig2enc.h"
#include "../../../Common/DocxFormat/Source/SystemUtility/File.h"
#if defined(_WIN32) || defined (_WIN64)
// -----------------------------------------------------------------------------
// Windows, sadly, lacks asprintf
// -----------------------------------------------------------------------------
#include <stdarg.h>
int asprintf(char **strp, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
const int required = vsnprintf(NULL, 0, fmt, va);
char *const buffer = (char *) malloc(required + 1);
const int ret = vsnprintf(buffer, required + 1, fmt, va);
*strp = buffer;
va_end(va);
return ret;
}
#endif
// -----------------------------------------------------------------------------
// Morphological operations for segmenting an image into text regions
// -----------------------------------------------------------------------------
static const char *segment_mask_sequence = "r11";
static const char *segment_seed_sequence = "r1143 + o4.4 + x4"; /* maybe o6.6 */
static const char *segment_dilation_sequence = "d3.3";
// -----------------------------------------------------------------------------
// Takes two pix as input, generated from the same original image:
// 1. pixb - a binary thresholded image
// 2. piximg - a full color or grayscale image
// and segments them by finding the areas that contain color or grayscale
// graphics, removing those areas from the binary image, and doing the
// opposite for the full color/grayscale image. The upshot is that after
// this routine has been run, the binary image contains only text and the
// full color image contains only the graphics.
//
// Both input images are modified by this procedure. If no text is found,
// pixb is set to NULL. If no graphics is found, piximg is set to NULL.
//
// Thanks to Dan Bloomberg for this
// -----------------------------------------------------------------------------
static PIX*
segment_image(PIX *pixb, PIX *piximg) {
// Make seed and mask, and fill seed into mask
PIX *pixmask4 = pixMorphSequence(pixb, (char *) segment_mask_sequence, 0);
PIX *pixseed4 = pixMorphSequence(pixb, (char *) segment_seed_sequence, 0);
PIX *pixsf4 = pixSeedfillBinary(NULL, pixseed4, pixmask4, 8);
PIX *pixd4 = pixMorphSequence(pixsf4, (char *) segment_dilation_sequence, 0);
// we want to force the binary mask to be the same size as the
// input color image, so we have to do it this way...
// is there a better way?
// PIX *pixd = pixExpandBinary(pixd4, 4);
PIX *pixd = pixCreate(piximg->w, piximg->h, 1);
pixCopyResolution(pixd, piximg);
expandBinaryPower2Low(pixd->data, pixd->w, pixd->h, pixd->wpl,
pixd4->data, pixd4->w, pixd4->h, pixd4->wpl, 4);
pixDestroy(&pixd4);
pixDestroy(&pixsf4);
pixDestroy(&pixseed4);
pixDestroy(&pixmask4);
pixSubtract(pixb, pixb, pixd);
// now see what we got from the segmentation
static l_int32 *tab = NULL;
if (tab == NULL) tab = makePixelSumTab8();
// if no image portion was found, set the image pointer to NULL and return
l_int32 pcount;
pixCountPixels(pixd, &pcount, tab);
if (pcount < 100) {
pixDestroy(&pixd);
return NULL;
}
// if no text portion found, set the binary pointer to NULL
pixCountPixels(pixb, &pcount, tab);
if (pcount < 100) {
pixDestroy(&pixb);
}
PIX *piximg1;
if (piximg->d == 1 || piximg->d == 8 || piximg->d == 32) {
piximg1 = pixClone(piximg);
} else if (piximg->d > 8) {
piximg1 = pixConvertTo32(piximg);
} else {
piximg1 = pixConvertTo8(piximg, FALSE);
}
PIX *pixd1;
if (piximg1->d == 32) {
pixd1 = pixConvertTo32(pixd);
} else if (piximg1->d == 8) {
pixd1 = pixConvertTo8(pixd, FALSE);
} else {
pixd1 = pixClone(pixd);
}
pixDestroy(&pixd);
pixRasteropFullImage(pixd1, piximg1, PIX_SRC | PIX_DST);
pixDestroy(&piximg1);
return pixd1;
}
#endif /* _JBIG2_ENCODER_H */
\ No newline at end of file
#endif /* _JBIG2_ENCODER_H */
......@@ -11,6 +11,8 @@
#include <netinet/in.h>
#endif
#include <string.h>
// -----------------------------------------------------------------------------
// See comments in jbig2structs.h about the bit packing in this structure.
// -----------------------------------------------------------------------------
......
......@@ -32,9 +32,9 @@ bool CJBig2File::MemoryToJBig2(unsigned char* pBufferBGRA ,int BufferSize, int n
int lBufferSize = BufferSize;
unsigned char *pSourceBuffer = pBufferBGRA;
PIX *pSource = pixCreate( nWidth, nHeight, 32 );
if ( !pSource ) return false;
PIX *pSource = pixCreate( nWidth, nHeight, 32 );
if ( !pSource ) return false;
for ( int nY = 0; nY < nHeight; nY++ )
{
......@@ -44,158 +44,158 @@ bool CJBig2File::MemoryToJBig2(unsigned char* pBufferBGRA ,int BufferSize, int n
}
}
jbig2ctx *pContext = jbig2_init( m_dTreshold, 0.5, 0, 0, ! m_bPDFMode, m_bRefine ? 10 : -1 );
// JBig2
// TO DO: 1 JBig2
// ColorMap
PIX *pPixL = NULL;
if ( NULL == ( pPixL = pixRemoveColormap( pSource, REMOVE_CMAP_BASED_ON_SRC ) ) )
{
pixDestroy( &pSource );
jbig2_destroy( pContext );
return false;
}
pixDestroy( &pSource );
PIX *pPixT = NULL;
if ( pPixL->d > 1 )
{
PIX *pGray = NULL;
if ( pPixL->d > 8 )
{
pGray = pixConvertRGBToGrayFast( pPixL );
if ( !pGray )
{
pixDestroy( &pSource );
jbig2_destroy( pContext );
return false;
}
}
else
{
pGray = pixClone( pPixL );
}
if ( m_bUpscale2x )
{
pPixT = pixScaleGray2xLIThresh( pGray, m_nBwTreshold );
}
else if ( m_bUpscale4x )
{
pPixT = pixScaleGray4xLIThresh( pGray, m_nBwTreshold );
}
else
{
pPixT = pixThresholdToBinary( pGray, m_nBwTreshold );
}
pixDestroy( &pGray );
}
else
{
pPixT = pixClone( pPixL );
}
if ( m_sOutputTreshold.length() > 0 )
{
pixWrite( m_sOutputTreshold.c_str(), pPixT, IFF_BMP );
}
if ( m_bSegment && pPixL->d > 1 )
{
PIX *pGraphics = segment_image( pPixT, pPixL );
if ( pGraphics )
{
char *sFilename;
asprintf( &sFilename, "%s.%04d.%s", m_sBaseName.c_str(), 0, ".bmp" );
pixWrite( sFilename, pGraphics, IFF_BMP );
free( sFilename );
}
if ( !pPixT )
{
//
return true;
}
}
pixDestroy( &pPixL );
if ( !m_bSymbolMode )
{
int nLength = 0;
uint8_t *pBuffer = jbig2_encode_generic( pPixT, !m_bPDFMode, 0, 0, m_bDuplicateLineRemoval, &nLength );
bool bRes = true;
FILE *pFile = _wfopen( sDstFileName.c_str(), _T("wb") );
if ( pFile && pBuffer )
{
::fwrite( pBuffer, nLength, 1, pFile );
::fclose( pFile );
bRes = true;
}
else
bRes = false;
pixDestroy( &pPixT );
if ( pBuffer ) free( pBuffer );
jbig2_destroy( pContext );
return bRes;
}
int nNumPages = 1;
jbig2_add_page( pContext, pPixT );
pixDestroy( &pPixT );
int nLength = 0;
uint8_t *pBuffer = jbig2_pages_complete( pContext, &nLength );
if ( !pBuffer )
{
jbig2_destroy( pContext );
return false;
}
if ( m_bPDFMode )
{
std::wstring sFileName = sDstFileName;//m_sBaseName + _T(".sym");
const int nFileD = _wopen( sFileName.c_str(), O_WRONLY | O_TRUNC | O_CREAT /*| WINBINARY*/, 0600 );
if ( nFileD < 0 )
{
free( pBuffer );
jbig2_destroy( pContext );
return false;
}
write( nFileD, pBuffer, nLength );
close( nFileD );
}
free( pBuffer );
for ( int nIndex = 0; nIndex < nNumPages; ++nIndex )
{
pBuffer = jbig2_produce_page( pContext, nIndex, -1, -1, &nLength );
if ( m_bPDFMode )
{
std::wstring sFileName = m_sBaseName + _T(".0000");
const int nFileD = _wopen( sFileName.c_str(), O_WRONLY | O_TRUNC | O_CREAT /*| WINBINARY*/, 0600 );
if ( nFileD < 0 )
{
free( pBuffer );
jbig2_destroy( pContext );
return false;
}
write( nFileD, pBuffer, nLength );
close( nFileD );
}
free( pBuffer );
}
jbig2_destroy( pContext );
jbig2ctx *pContext = jbig2_init( m_dTreshold, 0.5, 0, 0, ! m_bPDFMode, m_bRefine ? 10 : -1 );
// JBig2
// TO DO: 1 JBig2
// ColorMap
PIX *pPixL = NULL;
if ( NULL == ( pPixL = pixRemoveColormap( pSource, REMOVE_CMAP_BASED_ON_SRC ) ) )
{
pixDestroy( &pSource );
jbig2_destroy( pContext );
return false;
}
pixDestroy( &pSource );
PIX *pPixT = NULL;
if ( pPixL->d > 1 )
{
PIX *pGray = NULL;
if ( pPixL->d > 8 )
{
pGray = pixConvertRGBToGrayFast( pPixL );
if ( !pGray )
{
pixDestroy( &pSource );
jbig2_destroy( pContext );
return false;
}
}
else
{
pGray = pixClone( pPixL );
}
if ( m_bUpscale2x )
{
pPixT = pixScaleGray2xLIThresh( pGray, m_nBwTreshold );
}
else if ( m_bUpscale4x )
{
pPixT = pixScaleGray4xLIThresh( pGray, m_nBwTreshold );
}
else
{
pPixT = pixThresholdToBinary( pGray, m_nBwTreshold );
}
pixDestroy( &pGray );
}
else
{
pPixT = pixClone( pPixL );
}
if ( m_sOutputTreshold.length() > 0 )
{
pixWrite( m_sOutputTreshold.c_str(), pPixT, IFF_BMP );
}
if ( m_bSegment && pPixL->d > 1 )
{
PIX *pGraphics = segment_image( pPixT, pPixL );
if ( pGraphics )
{
char *sFilename;
asprintf( &sFilename, "%s.%04d.%s", m_sBaseName.c_str(), 0, ".bmp" );
pixWrite( sFilename, pGraphics, IFF_BMP );
free( sFilename );
}
if ( !pPixT )
{
//
return true;
}
}
pixDestroy( &pPixL );
if ( !m_bSymbolMode )
{
int nLength = 0;
uint8_t *pBuffer = jbig2_encode_generic( pPixT, !m_bPDFMode, 0, 0, m_bDuplicateLineRemoval, &nLength );
bool bRes = true;
CFile file;
if (file.CreateFile(sDstFileName.c_str() ) == S_OK )
{
file.WriteFile(pBuffer, nLength);
file.CloseFile();
bRes = true;
}
else
bRes = false;
pixDestroy( &pPixT );
if ( pBuffer ) free( pBuffer );
jbig2_destroy( pContext );
return bRes;
}
int nNumPages = 1;
jbig2_add_page( pContext, pPixT );
pixDestroy( &pPixT );
int nLength = 0;
uint8_t *pBuffer = jbig2_pages_complete( pContext, &nLength );
if ( !pBuffer )
{
jbig2_destroy( pContext );
return false;
}
if ( m_bPDFMode )
{
std::wstring sFileName = sDstFileName;//m_sBaseName + _T(".sym");
CFile file;
if ( file.CreateFile(sFileName.c_str()) != S_OK)
{
free( pBuffer );
jbig2_destroy( pContext );
return false;
}
file.WriteFile( pBuffer, nLength );
file.CloseFile();
}
free( pBuffer );
for ( int nIndex = 0; nIndex < nNumPages; ++nIndex )
{
pBuffer = jbig2_produce_page( pContext, nIndex, -1, -1, &nLength );
if ( m_bPDFMode )
{
std::wstring sFileName = m_sBaseName + _T(".0000");
CFile file;
if ( file.CreateFile(sFileName.c_str()) != S_OK)
{
free( pBuffer );
jbig2_destroy( pContext );
return false;
}
file.WriteFile( pBuffer, nLength );
file.CloseFile();
}
free( pBuffer );
}
jbig2_destroy( pContext );
return true;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment