301 lines
15 KiB
C++
301 lines
15 KiB
C++
// ==========================================================================
|
||
// Class Implementation : COXJPEGCompressor
|
||
// ==========================================================================
|
||
|
||
// Source file : OXJPGCom.cpp
|
||
|
||
// Version: 9.3
|
||
|
||
// This software along with its related components, documentation and files ("The Libraries")
|
||
// is ?1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
|
||
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
|
||
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
|
||
// to obtain this file, or directly from our office. For a copy of the license governing
|
||
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
|
||
|
||
// //////////////////////////////////////////////////////////////////////////
|
||
|
||
#include "stdafx.h"
|
||
#include "OXJPGCom.h"
|
||
|
||
#include "OXJPGFle.h"
|
||
#include "OXGphFle.h"
|
||
|
||
#include "OXJPGExp.h"
|
||
|
||
#ifdef _DEBUG
|
||
#undef THIS_FILE
|
||
static char THIS_FILE[] = __FILE__;
|
||
#endif
|
||
|
||
#define new DEBUG_NEW
|
||
|
||
#define QUALITY_DEFAULT 75
|
||
#define SIZE_ERROR_BUF 255
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// Definition of static members
|
||
|
||
|
||
// Data members -------------------------------------------------------------
|
||
// protected:
|
||
|
||
|
||
// CFile* m_pGraphFile;
|
||
// ---
|
||
|
||
// private:
|
||
|
||
// Member functions ---------------------------------------------------------
|
||
// public:
|
||
|
||
COXJPEGCompressor::COXJPEGCompressor()
|
||
:m_nQuality(QUALITY_DEFAULT),
|
||
m_bGrayScale(FALSE),
|
||
m_bOptimize(FALSE),
|
||
m_bProgressive(FALSE),
|
||
m_eDisCosTransf(DC_Undefined),
|
||
m_nSmooth(0),
|
||
m_nMaxMem(0),
|
||
m_bBaseLine(FALSE)
|
||
{
|
||
}
|
||
|
||
#ifdef _DEBUG
|
||
void COXJPEGCompressor::Dump(CDumpContext& dc) const
|
||
{
|
||
COXJPEGCodec::Dump(dc);
|
||
|
||
dc << TEXT("\nm_nQuality : ") << m_nQuality;
|
||
dc << TEXT("\nm_bGrayScale : ") << (WORD)m_bGrayScale;
|
||
dc << TEXT("\nm_bOptimize : ") << (WORD)m_bOptimize;
|
||
dc << TEXT("\nm_bBaseLine ") << (WORD)m_bBaseLine;
|
||
dc << TEXT("\nm_bProgressive ") << (WORD)m_bProgressive;
|
||
dc << TEXT("\nm_eDisCosTransf ") << (int)m_eDisCosTransf;
|
||
dc << TEXT("\nm_nSmooth ") << m_nSmooth;
|
||
dc << TEXT("\nm_nMaxMem ") << m_nMaxMem;
|
||
}
|
||
|
||
void COXJPEGCompressor::AssertValid() const
|
||
{
|
||
COXJPEGCodec::AssertValid();
|
||
}
|
||
#endif
|
||
|
||
COXJPEGCompressor::~COXJPEGCompressor()
|
||
{
|
||
}
|
||
|
||
void COXJPEGCompressor::SetQuality(UINT nQuality)
|
||
{
|
||
ASSERT(0 <= nQuality && nQuality <= 100);
|
||
|
||
m_nQuality = nQuality;
|
||
}
|
||
|
||
void COXJPEGCompressor::SetOptimize(BOOL bOptimize)
|
||
{
|
||
#ifndef ENTROPY_OPT_SUPPORTED
|
||
TRACE(_T("Entropy optimization was not compiled\n"));
|
||
#endif
|
||
m_bOptimize = bOptimize;
|
||
}
|
||
|
||
void COXJPEGCompressor::SetProgressive(BOOL bProgressive)
|
||
{
|
||
#ifndef C_PROGRESSIVE_SUPPORTED
|
||
TRACE(_T("progressive output was not compiled\n"));
|
||
#endif
|
||
m_bProgressive = bProgressive;
|
||
}
|
||
|
||
void COXJPEGCompressor::SetDisCosTranf(EDiscreteCosTransf eDisCosTransf)
|
||
{
|
||
ASSERT(DC_FIRST <= eDisCosTransf && eDisCosTransf <= DC_LAST);
|
||
|
||
m_eDisCosTransf = eDisCosTransf;
|
||
}
|
||
|
||
void COXJPEGCompressor::SetSmooth(UINT nSmooth)
|
||
{
|
||
ASSERT(1 <= nSmooth && nSmooth <= 100);
|
||
|
||
m_nSmooth = nSmooth;
|
||
}
|
||
|
||
short COXJPEGCompressor::DoCompress(COXGraphicFile* pGraphicsFile, COXJPEGFile* pJPEGFile)
|
||
{
|
||
TCHAR ErrorBuffer[SIZE_ERROR_BUF];
|
||
TRY
|
||
{
|
||
pGraphicsFile->OpenFile(CFile::modeRead | CFile::shareDenyWrite);
|
||
|
||
pJPEGFile->OpenFile(CFile::modeCreate | CFile::modeWrite);
|
||
}
|
||
CATCH(CFileException, e)
|
||
{
|
||
pGraphicsFile->AbortFile();
|
||
pJPEGFile->AbortFile();
|
||
|
||
e->GetErrorMessage(ErrorBuffer, SIZE_ERROR_BUF);
|
||
THROW(new COXJPEGException(e->m_cause, (LPCTSTR)ErrorBuffer));
|
||
}
|
||
END_CATCH
|
||
|
||
|
||
struct jpeg_compress_struct cinfo;
|
||
struct jpeg_error_mgr jerr;
|
||
JDIMENSION num_scanlines;
|
||
|
||
TRY
|
||
{
|
||
// Mapping needed to call virtual functions of right codec
|
||
m_RunningCodecsMap.SetAt(&cinfo, this);
|
||
|
||
/* Initialize the JPEG compression object with default error handling. */
|
||
SetJPEGErrorHandling(&jerr);
|
||
cinfo.err = &jerr;
|
||
|
||
jpeg_create_compress(&cinfo);
|
||
|
||
/* Initialize JPEG parameters.
|
||
* Much of this may be overridden later.
|
||
* In particular, we don't yet know the input file's color space,
|
||
* but we need to provide some value for jpeg_set_defaults() to work.
|
||
*/
|
||
|
||
cinfo.in_color_space = JCS_RGB; /* arbitrary guess */
|
||
jpeg_set_defaults(&cinfo);
|
||
|
||
// Configure the JPG Compression Manager
|
||
ProcessSwitches(&cinfo, FALSE);
|
||
|
||
pGraphicsFile->InitRead(&cinfo);
|
||
/* Read the input file header to obtain file size & colorspace. */
|
||
pGraphicsFile->StartInput(&cinfo);
|
||
|
||
/* Now that we know input colorspace, fix colorspace-dependent defaults */
|
||
jpeg_default_colorspace(&cinfo);
|
||
|
||
// Adjust default compression parameters by Re-Configuring the JPG Compression Manager
|
||
ProcessSwitches(&cinfo, TRUE);
|
||
|
||
/* Specify data destination for compression */
|
||
pJPEGFile->InitWrite(&cinfo, TRUE);
|
||
|
||
/* Start compressor */
|
||
pJPEGFile->StartOutput(&cinfo);
|
||
|
||
/* Process data */
|
||
while (cinfo.next_scanline < cinfo.image_height)
|
||
{
|
||
num_scanlines = pGraphicsFile->GetPixelRows(&cinfo);
|
||
pJPEGFile->PutPixelRows(&cinfo, pGraphicsFile->m_buffer, num_scanlines);
|
||
}
|
||
|
||
/* Finish compression and release memory */
|
||
pGraphicsFile->FinishInput(&cinfo);
|
||
pJPEGFile->FinishOutput(&cinfo);
|
||
jpeg_destroy_compress(&cinfo);
|
||
}
|
||
CATCH(COXJPEGException, e)
|
||
{
|
||
m_RunningCodecsMap.RemoveKey(&cinfo);
|
||
|
||
THROW_LAST();
|
||
}
|
||
END_CATCH
|
||
|
||
m_RunningCodecsMap.RemoveKey(&cinfo);
|
||
|
||
TRY
|
||
{
|
||
/* Close files, if we opened them */
|
||
pGraphicsFile->CloseFile();
|
||
|
||
pJPEGFile->CloseFile();
|
||
}
|
||
CATCH(CFileException, e)
|
||
{
|
||
pGraphicsFile->AbortFile();
|
||
pJPEGFile->AbortFile();
|
||
|
||
e->GetErrorMessage(ErrorBuffer, SIZE_ERROR_BUF);
|
||
THROW(new COXJPEGException(e->m_cause, (LPCTSTR)ErrorBuffer));
|
||
}
|
||
END_CATCH
|
||
|
||
CString sWarnings = GetWarningMessages();
|
||
if (!sWarnings.IsEmpty())
|
||
return 2;
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
// Protected
|
||
void COXJPEGCompressor::ProcessSwitches(j_compress_ptr cinfo, BOOL bForReal)
|
||
{
|
||
cinfo->err->trace_level = 0;
|
||
|
||
// Select DCT algoritm
|
||
switch(m_eDisCosTransf)
|
||
{
|
||
case DC_Int:
|
||
cinfo->dct_method = JDCT_ISLOW;
|
||
break;
|
||
case DC_FastInt:
|
||
cinfo->dct_method = JDCT_IFAST;
|
||
break;
|
||
case DC_Float:
|
||
cinfo->dct_method = JDCT_FLOAT;
|
||
break;
|
||
default:
|
||
// do nothing
|
||
break;
|
||
}
|
||
|
||
if (m_bGrayScale)
|
||
// Force a monochrome jpeg to be generated
|
||
jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
|
||
|
||
if (m_nMaxMem != 0)
|
||
// Maximum memory in Kb
|
||
cinfo->mem->max_memory_to_use = m_nMaxMem * 1000L;
|
||
|
||
if (m_bOptimize)
|
||
/* Enable entropy parm optimization. */
|
||
{
|
||
#ifdef ENTROPY_OPT_SUPPORTED
|
||
cinfo->optimize_coding = TRUE;
|
||
#else
|
||
TRACE(_T("Entropy optimization was not compiled\n"));
|
||
#endif
|
||
}
|
||
|
||
if (m_nQuality != QUALITY_DEFAULT)
|
||
jpeg_quality_scaling(m_nQuality);
|
||
|
||
|
||
if (m_nSmooth != 0)
|
||
cinfo->smoothing_factor = m_nSmooth;
|
||
|
||
if (bForReal)
|
||
{
|
||
if (m_nQuality != QUALITY_DEFAULT)
|
||
jpeg_set_quality(cinfo, m_nQuality, m_bBaseLine);
|
||
|
||
if (m_bProgressive)
|
||
{
|
||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||
jpeg_simple_progression(cinfo);
|
||
#else
|
||
TRACE(_T("progressive output was not compiled\n"));
|
||
#endif
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|