📄 jpegdec.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 __IPPI_H__
#include "ippi.h"
#endif
#ifndef __IPPJ_H__
#include "ippj.h"
#endif
#ifndef __JPEGBASE_H__
#include "jpegbase.h"
#endif
#ifndef __JPEGDEC_H__
#include "jpegdec.h"
#endif
#define HUFF_ROW_API // enable new huffman functions, to improve performance
#define DCT_QUANT_INV8x8To1x1LS(pMCUBuf, dst, qtbl)\
{\
int val = (Ipp8u)(((pMCUBuf[0] * qtbl[0]) >> 3) + 128);\
dst[0] = (Ipp8u)(val > 255 ? 255 : (val < 0 ? 0 : val));\
}
CJPEGDecoder::CJPEGDecoder(void)
{
Reset();
return;
} // ctor
CJPEGDecoder::~CJPEGDecoder(void)
{
Clean();
return;
} // dtor
void CJPEGDecoder::Reset(void)
{
m_jpeg_width = 0;
m_jpeg_height = 0;
m_jpeg_ncomp = 0;
m_jpeg_precision = 8;
m_jpeg_sampling = JS_OTHER;
m_jpeg_color = JC_UNKNOWN;
m_jpeg_quality = 100;
m_jpeg_restart_interval = 0;
m_jpeg_mode = JPEG_UNKNOWN;
m_jpeg_dct_scale = JD_1_1;
m_dd_factor = 1;
m_jpeg_comment_detected = 0;
m_jpeg_comment = 0;
m_jpeg_comment_size = 0;
m_jfif_app0_detected = 0;
m_jfif_app0_major = 0;
m_jfif_app0_minor = 0;
m_jfif_app0_units = 0;
m_jfif_app0_xDensity = 0;
m_jfif_app0_yDensity = 0;
m_jfif_app0_thumb_width = 0;
m_jfif_app0_thumb_height = 0;
m_jfxx_app0_detected = 0;
m_jfxx_thumbnails_type = 0;
m_avi1_app0_detected = 0;
m_avi1_app0_polarity = 0;
m_avi1_app0_reserved = 0;
m_avi1_app0_field_size = 0;
m_avi1_app0_field_size2 = 0;
m_exif_app1_detected = 0;
m_exif_app1_data_size = 0;
m_exif_app1_data = 0;
m_adobe_app14_detected = 0;
m_adobe_app14_version = 0;
m_adobe_app14_flags0 = 0;
m_adobe_app14_flags1 = 0;
m_adobe_app14_transform = 0;
m_precision = 0;
m_max_hsampling = 0;
m_max_vsampling = 0;
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_sos_len = 0;
m_curr_comp_no = 0;
m_scan_ncomps = 0;
m_ss = 0;
m_se = 0;
m_al = 0;
m_ah = 0;
m_dc_scan_completed = 0;
m_ac_scans_completed = 0;
m_init_done = 0;
m_marker = JM_NONE;
m_scan_count = 0;
m_block_buffer = 0;
m_num_threads = 0;
m_nblock = 0;
m_use_qdct = 0;
#ifdef __TIMING__
m_clk_dct = 0;
m_clk_dct1x1 = 0;
m_clk_dct2x2 = 0;
m_clk_dct4x4 = 0;
m_clk_dct8x8 = 0;
m_clk_ss = 0;
m_clk_cc = 0;
m_clk_diff = 0;
m_clk_huff = 0;
#endif
return;
} // CJPEGDecoder::Reset(void)
JERRCODE CJPEGDecoder::Clean(void)
{
int i;
m_jpeg_comment_detected = 0;
if(0 != m_jpeg_comment)
{
ippFree(m_jpeg_comment);
m_jpeg_comment = 0;
m_jpeg_comment_size = 0;
}
m_avi1_app0_detected = 0;
m_avi1_app0_polarity = 0;
m_avi1_app0_reserved = 0;
m_avi1_app0_field_size = 0;
m_avi1_app0_field_size2 = 0;
m_jfif_app0_detected = 0;
m_jfxx_app0_detected = 0;
m_exif_app1_detected = 0;
if(0 != m_exif_app1_data)
{
ippFree(m_exif_app1_data);
m_exif_app1_data = 0;
}
m_adobe_app14_detected = 0;
m_scan_ncomps = 0;
m_init_done = 0;
for(i = 0; i < MAX_COMPS_PER_SCAN; i++)
{
if(0 != m_ccomp[i].m_curr_row)
{
ippFree(m_ccomp[i].m_curr_row);
m_ccomp[i].m_curr_row = 0;
}
if(0 != m_ccomp[i].m_prev_row)
{
ippFree(m_ccomp[i].m_prev_row);
m_ccomp[i].m_prev_row = 0;
}
}
for(i = 0; i < MAX_HUFF_TABLES; i++)
{
m_dctbl[i].Destroy();
m_actbl[i].Destroy();
}
if(0 != m_block_buffer)
{
ippFree(m_block_buffer);
m_block_buffer = 0;
}
m_state.Destroy();
return JPEG_OK;
} // CJPEGDecoder::Clean()
#define BS_BUFLEN 16384
JERRCODE CJPEGDecoder::SetSource(
CBaseStreamInput* pInStream)
{
JERRCODE jerr;
jerr = m_BitStreamIn.Attach(pInStream);
if(JPEG_OK != jerr)
return jerr;
return m_BitStreamIn.Init(BS_BUFLEN);
} // CJPEGDecoder::SetSource()
JERRCODE CJPEGDecoder::SetDestination(
Ipp8u* pDst,
int dstStep,
IppiSize dstSize,
int dstChannels,
JCOLOR dstColor,
JSS dstSampling,
int dstPrecision,
JDD dstDctScale)
{
m_dst.p.Data8u[0] = pDst;
m_dst.lineStep[0] = dstStep;
m_dst.width = dstSize.width;
m_dst.height = dstSize.height;
m_dst.nChannels = dstChannels;
m_dst.color = dstColor;
m_dst.sampling = dstSampling;
m_dst.precision = dstPrecision;
m_jpeg_dct_scale = dstDctScale;
m_dst.order = JD_PIXEL;
return JPEG_OK;
} // CJPEGDecoder::SetDestination()
JERRCODE CJPEGDecoder::SetDestination(
Ipp16s* pDst,
int dstStep,
IppiSize dstSize,
int dstChannels,
JCOLOR dstColor,
JSS dstSampling,
int dstPrecision)
{
m_dst.p.Data16s[0] = pDst;
m_dst.lineStep[0] = dstStep;
m_dst.width = dstSize.width;
m_dst.height = dstSize.height;
m_dst.nChannels = dstChannels;
m_dst.color = dstColor;
m_dst.sampling = dstSampling;
m_dst.precision = dstPrecision;
m_dst.order = JD_PIXEL;
return JPEG_OK;
} // CJPEGDecoder::SetDestination()
JERRCODE CJPEGDecoder::SetDestination(
Ipp8u* pDst[],
int dstStep[],
IppiSize dstSize,
int dstChannels,
JCOLOR dstColor,
JSS dstSampling,
int dstPrecision,
JDD dstDctScale)
{
m_dst.p.Data8u[0] = pDst[0];
m_dst.p.Data8u[1] = pDst[1];
m_dst.p.Data8u[2] = pDst[2];
m_dst.p.Data8u[3] = pDst[3];
m_dst.lineStep[0] = dstStep[0];
m_dst.lineStep[1] = dstStep[1];
m_dst.lineStep[2] = dstStep[2];
m_dst.lineStep[3] = dstStep[3];
m_dst.order = JD_PLANE;
m_dst.width = dstSize.width;
m_dst.height = dstSize.height;
m_dst.nChannels = dstChannels;
m_dst.color = dstColor;
m_dst.sampling = dstSampling;
m_dst.precision = dstPrecision;
m_jpeg_dct_scale = dstDctScale;
return JPEG_OK;
} // CJPEGDecoder::SetDestination()
JERRCODE CJPEGDecoder::SetDestination(
Ipp16s* pDst[],
int dstStep[],
IppiSize dstSize,
int dstChannels,
JCOLOR dstColor,
JSS dstSampling,
int dstPrecision)
{
m_dst.p.Data16s[0] = pDst[0];
m_dst.p.Data16s[1] = pDst[1];
m_dst.p.Data16s[2] = pDst[2];
m_dst.p.Data16s[3] = pDst[3];
m_dst.lineStep[0] = dstStep[0];
m_dst.lineStep[1] = dstStep[1];
m_dst.lineStep[2] = dstStep[2];
m_dst.lineStep[3] = dstStep[3];
m_dst.order = JD_PLANE;
m_dst.width = dstSize.width;
m_dst.height = dstSize.height;
m_dst.nChannels = dstChannels;
m_dst.color = dstColor;
m_dst.sampling = dstSampling;
m_dst.precision = dstPrecision;
return JPEG_OK;
} // CJPEGDecoder::SetDestination()
JERRCODE CJPEGDecoder::DetectSampling(void)
{
switch(m_jpeg_ncomp)
{
case 1:
if(m_ccomp[0].m_hsampling == 1 && m_ccomp[0].m_vsampling == 1)
{
m_jpeg_sampling = JS_444;
}
else
{
return JPEG_ERR_BAD_DATA;
}
break;
case 3:
if(m_ccomp[0].m_hsampling == 1 && m_ccomp[0].m_vsampling == 1 &&
m_ccomp[1].m_hsampling == 1 && m_ccomp[1].m_vsampling == 1 &&
m_ccomp[2].m_hsampling == 1 && m_ccomp[2].m_vsampling == 1)
{
m_jpeg_sampling = JS_444;
}
else if(m_ccomp[0].m_hsampling == 2 && m_ccomp[0].m_vsampling == 1 &&
m_ccomp[1].m_hsampling == 1 && m_ccomp[1].m_vsampling == 1 &&
m_ccomp[2].m_hsampling == 1 && m_ccomp[2].m_vsampling == 1)
{
m_jpeg_sampling = JS_422;
}
else if(m_ccomp[0].m_hsampling == 1 && m_ccomp[0].m_vsampling == 2 &&
m_ccomp[1].m_hsampling == 1 && m_ccomp[1].m_vsampling == 1 &&
m_ccomp[2].m_hsampling == 1 && m_ccomp[2].m_vsampling == 1)
{
m_jpeg_sampling = JS_244;
}
else if(m_ccomp[0].m_hsampling == 2 && m_ccomp[0].m_vsampling == 2 &&
m_ccomp[1].m_hsampling == 1 && m_ccomp[1].m_vsampling == 1 &&
m_ccomp[2].m_hsampling == 1 && m_ccomp[2].m_vsampling == 1)
{
m_jpeg_sampling = JS_411;
}
else
{
m_jpeg_sampling = JS_OTHER;
}
break;
case 4:
if(m_ccomp[0].m_hsampling == 1 && m_ccomp[0].m_vsampling == 1 &&
m_ccomp[1].m_hsampling == 1 && m_ccomp[1].m_vsampling == 1 &&
m_ccomp[2].m_hsampling == 1 && m_ccomp[2].m_vsampling == 1 &&
m_ccomp[3].m_hsampling == 1 && m_ccomp[3].m_vsampling == 1)
{
m_jpeg_sampling = JS_444;
}
else if(m_ccomp[0].m_hsampling == 2 && m_ccomp[0].m_vsampling == 1 &&
m_ccomp[1].m_hsampling == 1 && m_ccomp[1].m_vsampling == 1 &&
m_ccomp[2].m_hsampling == 1 && m_ccomp[2].m_vsampling == 1 &&
m_ccomp[3].m_hsampling == 2 && m_ccomp[3].m_vsampling == 1)
{
m_jpeg_sampling = JS_422;
}
else if(m_ccomp[0].m_hsampling == 1 && m_ccomp[0].m_vsampling == 2 &&
m_ccomp[1].m_hsampling == 1 && m_ccomp[1].m_vsampling == 1 &&
m_ccomp[2].m_hsampling == 1 && m_ccomp[2].m_vsampling == 1 &&
m_ccomp[3].m_hsampling == 1 && m_ccomp[3].m_vsampling == 2)
{
m_jpeg_sampling = JS_244;
}
else if(m_ccomp[0].m_hsampling == 2 && m_ccomp[0].m_vsampling == 2 &&
m_ccomp[1].m_hsampling == 1 && m_ccomp[1].m_vsampling == 1 &&
m_ccomp[2].m_hsampling == 1 && m_ccomp[2].m_vsampling == 1 &&
m_ccomp[3].m_hsampling == 2 && m_ccomp[3].m_vsampling == 2)
{
m_jpeg_sampling = JS_411;
}
else
{
m_jpeg_sampling = JS_OTHER;
}
break;
}
return JPEG_OK;
} // CJPEGDecoder::DetectSampling()
JERRCODE CJPEGDecoder::NextMarker(JMARKER* marker)
{
int c;
int n;
JERRCODE jerr;
n = 0;
for(;;)
{
jerr = m_BitStreamIn.ReadByte(&c);
if(JPEG_OK != jerr)
return jerr;
if(c != 0xff)
{
do
{
n++;
jerr = m_BitStreamIn.ReadByte(&c);
if(JPEG_OK != jerr)
return jerr;
} while(c != 0xff);
}
do
{
jerr = m_BitStreamIn.ReadByte(&c);
if(JPEG_OK != jerr)
return jerr;
} while(c == 0xff);
if(c != 0)
{
*marker = (JMARKER)c;
break;
}
}
if(n != 0)
{
TRC1(" skip enormous bytes - ",n);
}
return JPEG_OK;
} // CJPEGDecoder::NextMarker()
JERRCODE CJPEGDecoder::SkipMarker(void)
{
int len;
JERRCODE jerr;
jerr = m_BitStreamIn.ReadWord(&len);
if(JPEG_OK != jerr)
return jerr;
jerr = m_BitStreamIn.Seek(len - 2);
if(JPEG_OK != jerr)
return jerr;
m_marker = JM_NONE;
return JPEG_OK;
} // CJPEGDecoder::SkipMarker()
JERRCODE CJPEGDecoder::ProcessRestart(void)
{
JERRCODE jerr;
IppStatus status;
status = ippiDecodeHuffmanStateInit_JPEG_8u(m_state);
if(ippStsNoErr != status)
{
LOG0("Error: ippiDecodeHuffmanStateInit_JPEG_8u() failed");
return JPEG_ERR_INTERNAL;
}
for(int n = 0; n < m_jpeg_ncomp; n++)
{
m_ccomp[n].m_lastDC = 0;
}
jerr = ParseRST();
if(JPEG_OK != jerr)
{
LOG0("Error: ParseRST() failed");
// return jerr;
}
m_rst_go = 1;
m_restarts_to_go = m_jpeg_restart_interval;
return JPEG_OK;
} // CJPEGDecoder::ProcessRestart()
JERRCODE CJPEGDecoder::ParseSOI(void)
{
TRC0("-> SOI");
m_marker = JM_NONE;
return JPEG_OK;
} // CJPEGDecoder::ParseSOI()
JERRCODE CJPEGDecoder::ParseEOI(void)
{
TRC0("-> EOI");
m_marker = JM_NONE;
return JPEG_OK;
} // CJPEGDecoder::ParseEOI()
const int APP0_JFIF_LENGTH = 14;
const int APP0_JFXX_LENGTH = 6;
const int APP0_AVI1_LENGTH = 14;
JERRCODE CJPEGDecoder::ParseAPP0(void)
{
int b0, b1, b2, b3, b4;
int len;
JERRCODE jerr;
TRC0("-> APP0");
jerr = m_BitStreamIn.ReadWord(&len);
if(JPEG_OK != jerr)
return jerr;
len -= 2;
jerr = m_BitStreamIn.CheckByte(0,&b0);
if(JPEG_OK != jerr)
return jerr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -