📄 jpegenc.cpp
字号:
/*
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright (c) 2001-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "precomp.h"
#include <stdio.h>
#include <string.h>
#ifndef __IPPJ_H__
#include "ippj.h"
#endif
#ifndef __JPEGBASE_H__
#include "jpegbase.h"
#endif
#ifndef __JPEGENC_H__
#include "jpegenc.h"
#endif
CJPEGEncoder::CJPEGEncoder(void)
{
m_src.p.Data8u[0] = 0;
m_src.p.Data8u[1] = 0;
m_src.p.Data8u[2] = 0;
m_src.width = 0;
m_src.height = 0;
m_src.lineStep[0] = 0;
m_src.lineStep[1] = 0;
m_src.lineStep[2] = 0;
m_src.precision = 0;
m_src.nChannels = 0;
m_src.color = JC_UNKNOWN;
m_src.sampling = JS_OTHER;
m_jpeg_ncomp = 0;
m_jpeg_precision = 8;
m_jpeg_sampling = JS_444;
m_jpeg_color = JC_UNKNOWN;
m_jpeg_quality = 100;
m_jpeg_restart_interval = 0;
m_jpeg_mode = JPEG_BASELINE;
m_numxMCU = 0;
m_numyMCU = 0;
m_mcuWidth = 0;
m_mcuHeight = 0;
m_ccWidth = 0;
m_ccHeight = 0;
m_xPadding = 0;
m_yPadding = 0;
m_rst_go = 0;
m_restarts_to_go = 0;
m_next_restart_num = 0;
m_scan_count = 0;
m_scan_script = 0;
m_block_buffer = 0;
m_ss = 0;
m_se = 63;
m_ah = 0;
m_al = 0;
m_predictor = 1;
m_pt = 0;
// 1 - to set generated table, 0 for default or external tables
m_optimal_htbl = 0;
#ifdef __TIMING__
m_clk_dct = 0;
m_clk_ss = 0;
m_clk_cc = 0;
m_clk_diff = 0;
m_clk_huff = 0;
#endif
return;
} // ctor
CJPEGEncoder::~CJPEGEncoder(void)
{
Clean();
return;
} // dtor
JERRCODE CJPEGEncoder::Clean(void)
{
int i;
for(i = 0; i < MAX_HUFF_TABLES; i++)
{
m_dctbl[i].Destroy();
m_actbl[i].Destroy();
}
if(0 != m_scan_script)
{
delete[] m_scan_script;
m_scan_script = 0;
}
if(0 != m_block_buffer)
{
ippFree(m_block_buffer);
m_block_buffer = 0;
}
m_src.p.Data8u[0] = 0;
m_src.p.Data8u[1] = 0;
m_src.p.Data8u[2] = 0;
m_src.width = 0;
m_src.height = 0;
m_src.lineStep[0] = 0;
m_src.lineStep[1] = 0;
m_src.lineStep[2] = 0;
m_src.precision = 0;
m_src.nChannels = 0;
m_src.color = JC_UNKNOWN;
m_src.sampling = JS_OTHER;
m_jpeg_ncomp = 0;
m_jpeg_sampling = JS_444;
m_jpeg_color = JC_UNKNOWN;
m_jpeg_quality = 100;
m_jpeg_restart_interval = 0;
m_jpeg_mode = JPEG_BASELINE;
m_numxMCU = 0;
m_numyMCU = 0;
m_mcuWidth = 0;
m_mcuHeight = 0;
m_ccWidth = 0;
m_ccHeight = 0;
m_xPadding = 0;
m_yPadding = 0;
m_restarts_to_go = 0;
m_next_restart_num = 0;
m_scan_count = 0;
m_optimal_htbl = 0;
m_state.Destroy();
return JPEG_OK;
} // CJPEGEncoder::Clean()
JERRCODE CJPEGEncoder::SetSource(
Ipp8u* pSrc,
int srcStep,
IppiSize srcSize,
int srcChannels,
JCOLOR srcColor,
JSS srcSampling,
int srcPrecision)
{
m_src.p.Data8u[0] = pSrc;
m_src.lineStep[0] = srcStep;
m_src.width = srcSize.width;
m_src.height = srcSize.height;
m_src.nChannels = srcChannels;
m_src.color = srcColor;
m_src.sampling = srcSampling;
m_src.precision = srcPrecision;
m_src.order = JD_PIXEL;
return JPEG_OK;
} // CJPEGEncoder::SetSource()
JERRCODE CJPEGEncoder::SetSource(
Ipp16s* pSrc,
int srcStep,
IppiSize srcSize,
int srcChannels,
JCOLOR srcColor,
JSS srcSampling,
int srcPrecision)
{
m_src.p.Data16s[0] = pSrc;
m_src.lineStep[0] = srcStep;
m_src.width = srcSize.width;
m_src.height = srcSize.height;
m_src.nChannels = srcChannels;
m_src.color = srcColor;
m_src.sampling = srcSampling;
m_src.precision = srcPrecision;
m_src.order = JD_PIXEL;
if(m_src.precision > 10)
m_optimal_htbl = 1;
return JPEG_OK;
} // CJPEGEncoder::SetSource()
JERRCODE CJPEGEncoder::SetSource(
Ipp8u* pSrc[],
int srcStep[],
IppiSize srcSize,
int srcChannels,
JCOLOR srcColor,
JSS srcSampling ,
int srcPrecision)
{
if(JC_YCBCR != srcColor && JS_411 != srcSampling)
return JPEG_NOT_IMPLEMENTED;
m_src.p.Data8u[0] = pSrc[0];
m_src.p.Data8u[1] = pSrc[1];
m_src.p.Data8u[2] = pSrc[2];
m_src.p.Data8u[3] = pSrc[3];
m_src.lineStep[0] = srcStep[0];
m_src.lineStep[1] = srcStep[1];
m_src.lineStep[2] = srcStep[2];
m_src.lineStep[3] = srcStep[3];
m_src.order = JD_PLANE;
m_src.width = srcSize.width;
m_src.height = srcSize.height;
m_src.nChannels = srcChannels;
m_src.color = srcColor;
m_src.sampling = srcSampling;
m_src.precision = srcPrecision;
return JPEG_OK;
}
JERRCODE CJPEGEncoder::SetSource(
Ipp16s* pSrc[],
int srcStep[],
IppiSize srcSize,
int srcChannels,
JCOLOR srcColor,
JSS srcSampling ,
int srcPrecision)
{
if(JC_YCBCR != srcColor && JS_411 != srcSampling)
return JPEG_NOT_IMPLEMENTED;
m_src.p.Data16s[0] = pSrc[0];
m_src.p.Data16s[1] = pSrc[1];
m_src.p.Data16s[2] = pSrc[2];
m_src.p.Data16s[3] = pSrc[3];
m_src.lineStep[0] = srcStep[0];
m_src.lineStep[1] = srcStep[1];
m_src.lineStep[2] = srcStep[2];
m_src.lineStep[3] = srcStep[3];
m_src.order = JD_PLANE;
m_src.width = srcSize.width;
m_src.height = srcSize.height;
m_src.nChannels = srcChannels;
m_src.color = srcColor;
m_src.sampling = srcSampling;
m_src.precision = srcPrecision;
if(m_src.precision > 10)
m_optimal_htbl = 1;
return JPEG_OK;
}
#define BS_BUFLEN 16384
JERRCODE CJPEGEncoder::SetDestination(
CBaseStreamOutput* pStreamOut)
{
JERRCODE jerr;
jerr = m_BitStreamOut.Attach(pStreamOut);
if(JPEG_OK != jerr)
return jerr;
jerr = m_BitStreamOut.Init(BS_BUFLEN);
if(JPEG_OK != jerr)
return jerr;
return JPEG_OK;
} // CJPEGEncoder::SetDestination()
JERRCODE CJPEGEncoder::SetParams(
JMODE mode,
JCOLOR color,
JSS sampling,
int restart,
int huff_opt,
int quality)
{
int i;
JERRCODE jerr;
if(JPEG_BASELINE != mode && JPEG_EXTENDED != mode && JPEG_PROGRESSIVE != mode)
return JPEG_ERR_PARAMS;
m_jpeg_mode = mode;
m_jpeg_color = color;
m_jpeg_sampling = sampling;
m_jpeg_restart_interval = restart;
// baseline/progressive specific params
m_jpeg_quality = quality;
m_optimal_htbl = huff_opt;
m_restarts_to_go = m_jpeg_restart_interval;
m_jpeg_precision = m_src.precision;
m_mcuWidth = (m_jpeg_sampling == JS_444) ? 8 : 16;
m_mcuHeight = (m_jpeg_sampling == JS_411) ? 16 : 8;
m_numxMCU = (m_src.width + (m_mcuWidth - 1)) / m_mcuWidth;
m_numyMCU = (m_src.height + (m_mcuHeight - 1)) / m_mcuHeight;
switch(m_jpeg_color)
{
case JC_GRAY: m_jpeg_ncomp = 1; break;
case JC_RGB: m_jpeg_ncomp = 3; break;
case JC_YCBCR: m_jpeg_ncomp = 3; break;
case JC_CMYK: m_jpeg_ncomp = 4; break;
case JC_YCCK: m_jpeg_ncomp = 4; break;
default: m_jpeg_ncomp = IPP_MIN(MAX_COMPS_PER_SCAN,m_src.nChannels); break;
// default:
// return JPEG_NOT_IMPLEMENTED;
}
if(JPEG_BASELINE == mode || JPEG_PROGRESSIVE == mode)
{
jerr = InitQuantTable((Ipp8u*)DefaultLuminanceQuant, 0, m_jpeg_quality);
if(JPEG_OK != jerr)
{
LOG0("Error: can't attach quant table");
return jerr;
}
if(m_jpeg_ncomp > 1)
{
jerr = InitQuantTable((Ipp8u*)DefaultChrominanceQuant, 1, m_jpeg_quality);
if(JPEG_OK != jerr)
{
LOG0("Error: can't attach quant table");
return jerr;
}
}
}
else
{
Ipp16u buf[64];
for(i = 0; i < DCTSIZE2; i++)
buf[i] = (Ipp16u)DefaultLuminanceQuant[i];
jerr = InitQuantTable(buf, 0, quality);
if(JPEG_OK != jerr)
{
LOG0("Error: can't attach quant table");
return jerr;
}
if(m_jpeg_ncomp > 1)
{
for(i = 0; i < DCTSIZE2; i++)
buf[i] = (Ipp16u)DefaultChrominanceQuant[i];
jerr = InitQuantTable(buf, 1, quality);
if(JPEG_OK != jerr)
{
LOG0("Error: can't attach quant table");
return jerr;
}
}
}
if(JPEG_EXTENDED != mode)
{
jerr = m_dctbl[0].Create();
if(JPEG_OK != jerr)
return jerr;
jerr = m_actbl[0].Create();
if(JPEG_OK != jerr)
return jerr;
if(m_jpeg_ncomp > 1)
{
jerr = m_dctbl[1].Create();
if(JPEG_OK != jerr)
return jerr;
jerr = m_actbl[1].Create();
if(JPEG_OK != jerr)
return jerr;
}
}
else
{
for(i = 0; i < m_jpeg_ncomp; i++)
{
jerr = m_dctbl[i].Create();
if(JPEG_OK != jerr)
return jerr;
jerr = m_actbl[i].Create();
if(JPEG_OK != jerr)
return jerr;
}
}
if(JPEG_BASELINE == mode)
{
jerr = InitHuffmanTable((Ipp8u*)DefaultLuminanceDCBits, (Ipp8u*)DefaultLuminanceDCValues, 0, DC);
if(JPEG_OK != jerr)
return jerr;
jerr = InitHuffmanTable((Ipp8u*)DefaultLuminanceACBits, (Ipp8u*)DefaultLuminanceACValues, 0, AC);
if(JPEG_OK != jerr)
return jerr;
if(m_jpeg_ncomp > 1)
{
jerr = InitHuffmanTable((Ipp8u*)DefaultChrominanceDCBits, (Ipp8u*)DefaultChrominanceDCValues, 1, DC);
if(JPEG_OK != jerr)
return jerr;
jerr = InitHuffmanTable((Ipp8u*)DefaultChrominanceACBits, (Ipp8u*)DefaultChrominanceACValues, 1, AC);
if(JPEG_OK != jerr)
return jerr;
}
}
int id[4] = { 0, 1, 1, 0 };
for(i = 0; i < m_jpeg_ncomp; i++)
{
jerr = AttachQuantTable(id[i], i);
if(JPEG_OK != jerr)
return jerr;
jerr = AttachHuffmanTable(id[i], DC, i);
if(JPEG_OK != jerr)
return jerr;
jerr = AttachHuffmanTable(id[i], AC, i);
if(JPEG_OK != jerr)
return jerr;
}
return JPEG_OK;
} // CJPEGEncoder::SetParams()
JERRCODE CJPEGEncoder::SetParams(
JMODE mode,
JCOLOR color,
JSS sampling,
int restart,
int huff_opt,
int point_transform,
int predictor)
{
int c, i;
JERRCODE jerr;
if(JPEG_LOSSLESS != mode)
return JPEG_ERR_PARAMS;
if(JS_444 != sampling)
return JPEG_NOT_IMPLEMENTED;
m_jpeg_mode = mode;
m_jpeg_color = color;
m_jpeg_sampling = sampling;
m_jpeg_restart_interval = restart;
// lossless specific params
m_pt = point_transform;
m_predictor = predictor;
m_optimal_htbl = m_src.precision > 11 ? 1 : huff_opt;
m_jpeg_precision = m_src.precision;
m_restarts_to_go = m_jpeg_restart_interval;
m_mcuWidth = 1;
m_mcuHeight = 1;
m_numxMCU = (m_src.width + (m_mcuWidth - 1)) / m_mcuWidth;
m_numyMCU = (m_src.height + (m_mcuHeight - 1)) / m_mcuHeight;
switch(m_jpeg_color)
{
case JC_GRAY: m_jpeg_ncomp = 1; break;
case JC_RGB: m_jpeg_ncomp = 3; break;
case JC_YCBCR: m_jpeg_ncomp = 3; break;
case JC_CMYK: m_jpeg_ncomp = 4; break;
case JC_YCCK: m_jpeg_ncomp = 4; break;
default: m_jpeg_ncomp = IPP_MIN(MAX_COMPS_PER_SCAN,m_src.nChannels); break;
}
if(!m_optimal_htbl)
{
jerr = m_dctbl[0].Create();
if(JPEG_OK != jerr)
return jerr;
jerr = InitHuffmanTable((Ipp8u*)DefaultLuminanceDCBits, (Ipp8u*)DefaultLuminanceDCValues, 0, DC);
if(JPEG_OK != jerr)
return jerr;
// lossless mode defaults is one huffman table for all JPEG color components
for(i = 0; i < m_jpeg_ncomp; i++)
{
jerr = AttachHuffmanTable(0, DC, i);
if(JPEG_OK != jerr)
return jerr;
}
}
else
{
for(c = 0; c < m_jpeg_ncomp; c++)
{
jerr = m_dctbl[c].Create();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -