Skip to content

Commit

Permalink
- Fixed YCC/RGB clipping statistics
Browse files Browse the repository at this point in the history
- Disabled MCU marker array if image too large (eg. 40+ megapixel images).
  • Loading branch information
calvinhass committed Feb 21, 2011
1 parent 0b9138b commit 2addbd5
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 39 deletions.
70 changes: 41 additions & 29 deletions ImgDecode.cpp
Expand Up @@ -198,11 +198,17 @@ CimgDecode::CimgDecode(CDocLog* pLog, CwindowBuf* pWBuf)

HuffMaskLookupGen();

m_bMarkedMcuMapEn = false;

// Allocate Marker MCU map
m_abMarkedMcuMap = new bool[MARKMCUMAP_SIZE];
if (!m_abMarkedMcuMap) {
AfxMessageBox("ERROR: Not enough memory for Image Decoder MCU Marker Map");
m_bMarkedMcuMapEn = false;
// Don't make this a fatal error, just skip feature
//exit(1);
} else {
m_bMarkedMcuMapEn = true;
}


Expand Down Expand Up @@ -264,6 +270,7 @@ CimgDecode::~CimgDecode()
if (m_abMarkedMcuMap) {
delete m_abMarkedMcuMap;
m_abMarkedMcuMap = NULL;
m_bMarkedMcuMapEn = false;
}

}
Expand All @@ -289,7 +296,7 @@ void CimgDecode::ResetNewFile()
{

// Reset the markers
if (m_abMarkedMcuMap) {
if (m_bMarkedMcuMapEn && m_abMarkedMcuMap) {
memset(m_abMarkedMcuMap, 0, (MARKMCUMAP_SIZE*sizeof(bool)) );
}
m_nMarkedMcuLastXY = 0;
Expand Down Expand Up @@ -2504,21 +2511,18 @@ void CimgDecode::DecodeScanImg(unsigned nStart,bool bDisplay,bool bQuiet,CSnoopC
// Assume that Marked MCU map is already allocated (in Constructor)
// Double-check that it is large enough for our use
if (!m_abMarkedMcuMap) {
AfxMessageBox("ERROR: Not enough memory for Image Decoder MCU Marker Map");
exit(1);
}
if (m_nMcuYMax*m_nMcuXMax > MARKMCUMAP_SIZE) {
AfxMessageBox("ERROR: Not enough Marker MCU Map memory for current image size.");
exit(1);
//AfxMessageBox("ERROR: Not enough memory for Image Decoder MCU Marker Map");
// We would have already reported that we didn't have sufficient memory
// Don't make this a fatal error, just skip feature
//exit(1);
}
/*
m_abMarkedMcuMap = new bool[m_nMcuYMax*m_nMcuXMax];
if (!m_abMarkedMcuMap) {
AfxMessageBox("ERROR: Not enough memory for Image Decoder MCU Marker Map");
exit(1);
if (m_bMarkedMcuMapEn & (m_nMcuYMax*m_nMcuXMax > MARKMCUMAP_SIZE)) {
AfxMessageBox("NOTE: Not enough Marker MCU Map memory for current image size. Disabling feature.");
m_bMarkedMcuMapEn = false;
// Don't make this a fatal error, just skip feature
//exit(1);
}
memset(m_abMarkedMcuMap, 0, (m_nMcuYMax*m_nMcuXMax*sizeof(bool)) );
*/


// Allocate the 8x8 Block DC Map
m_pBlkValY = new short[m_nBlkYMax*m_nBlkXMax];
Expand Down Expand Up @@ -2691,14 +2695,12 @@ void CimgDecode::DecodeScanImg(unsigned nStart,bool bDisplay,bool bQuiet,CSnoopC
//CAL! Should add a check to make sure that we only process
// files that have m_nImgSofCompNum == 1 or 3

// Temporary pixel value for color conversion
PixelCcClip my_pix_clip;

m_nNumPixels = 0;

if (bDisplay) {
// Clear CC clipping stats
memset(&my_pix_clip,0,sizeof(my_pix_clip));
memset(&m_sStatClip,0,sizeof(m_sStatClip));
memset(&m_sHisto,0,sizeof(m_sHisto));


Expand Down Expand Up @@ -3037,11 +3039,11 @@ void CimgDecode::DecodeScanImg(unsigned nStart,bool bDisplay,bool bQuiet,CSnoopC
if (CC_CLIP_YCC_EN) {
tmpStr.Format(_T(" YCC clipping in DC:"));
m_pLog->AddLine(tmpStr);
tmpStr.Format(_T(" Y component: [<0=%5u] [>255=%5u]"),my_pix_clip.y_under,my_pix_clip.y_over);
tmpStr.Format(_T(" Y component: [<0=%5u] [>255=%5u]"),m_sStatClip.y_under,m_sStatClip.y_over);
m_pLog->AddLine(tmpStr);
tmpStr.Format(_T(" Cb component: [<0=%5u] [>255=%5u]"),my_pix_clip.cb_under,my_pix_clip.cb_over);
tmpStr.Format(_T(" Cb component: [<0=%5u] [>255=%5u]"),m_sStatClip.cb_under,m_sStatClip.cb_over);
m_pLog->AddLine(tmpStr);
tmpStr.Format(_T(" Cr component: [<0=%5u] [>255=%5u]"),my_pix_clip.cr_under,my_pix_clip.cr_over);
tmpStr.Format(_T(" Cr component: [<0=%5u] [>255=%5u]"),m_sStatClip.cr_under,m_sStatClip.cr_over);
m_pLog->AddLine(tmpStr);
m_pLog->AddLine("");
}
Expand Down Expand Up @@ -3091,14 +3093,14 @@ void CimgDecode::DecodeScanImg(unsigned nStart,bool bDisplay,bool bQuiet,CSnoopC

tmpStr.Format(_T(" RGB clipping in DC:"));
m_pLog->AddLine(tmpStr);
tmpStr.Format(_T(" R component: [<0=%5u] [>255=%5u]"),my_pix_clip.r_under,my_pix_clip.r_over);
tmpStr.Format(_T(" R component: [<0=%5u] [>255=%5u]"),m_sStatClip.r_under,m_sStatClip.r_over);
m_pLog->AddLine(tmpStr);
tmpStr.Format(_T(" G component: [<0=%5u] [>255=%5u]"),my_pix_clip.g_under,my_pix_clip.g_over);
tmpStr.Format(_T(" G component: [<0=%5u] [>255=%5u]"),m_sStatClip.g_under,m_sStatClip.g_over);
m_pLog->AddLine(tmpStr);
tmpStr.Format(_T(" B component: [<0=%5u] [>255=%5u]"),my_pix_clip.b_under,my_pix_clip.b_over);
tmpStr.Format(_T(" B component: [<0=%5u] [>255=%5u]"),m_sStatClip.b_under,m_sStatClip.b_over);
m_pLog->AddLine(tmpStr);
/*
tmpStr.Format(_T(" White Highlight: [>255=%5u]"),my_pix_clip.white_over);
tmpStr.Format(_T(" White Highlight: [>255=%5u]"),m_sStatClip.white_over);
m_pLog->AddLine(tmpStr);
*/
m_pLog->AddLine("");
Expand Down Expand Up @@ -3844,6 +3846,7 @@ void CimgDecode::CapYccRange(unsigned nMcuX,unsigned nMcuY,PixelCc &rPix)
nMcuX,nMcuY,cur_y,cur_cb,cur_cr,GetScanBufPos());
m_pLog->AddLineWarn(tmpStr);
m_nWarnYccClipNum++;
m_sStatClip.y_over++;
if (m_nWarnYccClipNum == YCC_CLIP_REPORT_MAX) {
tmpStr.Format(_T(" Only reported first %u instances of this message..."),YCC_CLIP_REPORT_MAX);
m_pLog->AddLineWarn(tmpStr);
Expand All @@ -3859,6 +3862,7 @@ void CimgDecode::CapYccRange(unsigned nMcuX,unsigned nMcuY,PixelCc &rPix)
nMcuX,nMcuY,cur_y,cur_cb,cur_cr,GetScanBufPos());
m_pLog->AddLineWarn(tmpStr);
m_nWarnYccClipNum++;
m_sStatClip.y_under++;
if (m_nWarnYccClipNum == YCC_CLIP_REPORT_MAX) {
tmpStr.Format(_T(" Only reported first %u instances of this message..."),YCC_CLIP_REPORT_MAX);
m_pLog->AddLineWarn(tmpStr);
Expand All @@ -3874,6 +3878,7 @@ void CimgDecode::CapYccRange(unsigned nMcuX,unsigned nMcuY,PixelCc &rPix)
nMcuX,nMcuY,cur_y,cur_cb,cur_cr,GetScanBufPos());
m_pLog->AddLineWarn(tmpStr);
m_nWarnYccClipNum++;
m_sStatClip.cb_over++;
if (m_nWarnYccClipNum == YCC_CLIP_REPORT_MAX) {
tmpStr.Format(_T(" Only reported first %u instances of this message..."),YCC_CLIP_REPORT_MAX);
m_pLog->AddLineWarn(tmpStr);
Expand All @@ -3889,6 +3894,7 @@ void CimgDecode::CapYccRange(unsigned nMcuX,unsigned nMcuY,PixelCc &rPix)
nMcuX,nMcuY,cur_y,cur_cb,cur_cr,GetScanBufPos());
m_pLog->AddLineWarn(tmpStr);
m_nWarnYccClipNum++;
m_sStatClip.cb_under++;
if (m_nWarnYccClipNum == YCC_CLIP_REPORT_MAX) {
tmpStr.Format(_T(" Only reported first %u instances of this message..."),YCC_CLIP_REPORT_MAX);
m_pLog->AddLineWarn(tmpStr);
Expand All @@ -3904,6 +3910,7 @@ void CimgDecode::CapYccRange(unsigned nMcuX,unsigned nMcuY,PixelCc &rPix)
nMcuX,nMcuY,cur_y,cur_cb,cur_cr,GetScanBufPos());
m_pLog->AddLineWarn(tmpStr);
m_nWarnYccClipNum++;
m_sStatClip.cr_over++;
if (m_nWarnYccClipNum == YCC_CLIP_REPORT_MAX) {
tmpStr.Format(_T(" Only reported first %u instances of this message..."),YCC_CLIP_REPORT_MAX);
m_pLog->AddLineWarn(tmpStr);
Expand All @@ -3919,6 +3926,7 @@ void CimgDecode::CapYccRange(unsigned nMcuX,unsigned nMcuY,PixelCc &rPix)
nMcuX,nMcuY,cur_y,cur_cb,cur_cr,GetScanBufPos());
m_pLog->AddLineWarn(tmpStr);
m_nWarnYccClipNum++;
m_sStatClip.cr_under++;
if (m_nWarnYccClipNum == YCC_CLIP_REPORT_MAX) {
tmpStr.Format(_T(" Only reported first %u instances of this message..."),YCC_CLIP_REPORT_MAX);
m_pLog->AddLineWarn(tmpStr);
Expand Down Expand Up @@ -3973,6 +3981,7 @@ void CimgDecode::CapRgbRange(unsigned nMcuX,unsigned nMcuY,PixelCc &rPix)
m_pLog->AddLineWarn(tmpStr);
}
rPix.clip |= CC_CLIP_R_UNDER;
m_sStatClip.r_under++;
r_lim = 0;
}
if (g_lim < 0) {
Expand All @@ -3983,6 +3992,7 @@ void CimgDecode::CapRgbRange(unsigned nMcuX,unsigned nMcuY,PixelCc &rPix)
m_pLog->AddLineWarn(tmpStr);
}
rPix.clip |= CC_CLIP_G_UNDER;
m_sStatClip.g_under++;
g_lim = 0;
}
if (b_lim < 0) {
Expand All @@ -3993,6 +4003,7 @@ void CimgDecode::CapRgbRange(unsigned nMcuX,unsigned nMcuY,PixelCc &rPix)
m_pLog->AddLineWarn(tmpStr);
}
rPix.clip |= CC_CLIP_B_UNDER;
m_sStatClip.b_under++;
b_lim = 0;
}
if (r_lim > 255) {
Expand All @@ -4003,6 +4014,7 @@ void CimgDecode::CapRgbRange(unsigned nMcuX,unsigned nMcuY,PixelCc &rPix)
m_pLog->AddLineWarn(tmpStr);
}
rPix.clip |= CC_CLIP_R_OVER;
m_sStatClip.r_over++;
r_lim = 255;
}
if (g_lim > 255) {
Expand All @@ -4013,6 +4025,7 @@ void CimgDecode::CapRgbRange(unsigned nMcuX,unsigned nMcuY,PixelCc &rPix)
m_pLog->AddLineWarn(tmpStr);
}
rPix.clip |= CC_CLIP_G_OVER;
m_sStatClip.g_over++;
g_lim = 255;
}
if (b_lim > 255) {
Expand All @@ -4023,6 +4036,7 @@ void CimgDecode::CapRgbRange(unsigned nMcuX,unsigned nMcuY,PixelCc &rPix)
m_pLog->AddLineWarn(tmpStr);
}
rPix.clip |= CC_CLIP_B_OVER;
m_sStatClip.b_over++;
b_lim = 255;
}

Expand Down Expand Up @@ -4418,7 +4432,7 @@ void CimgDecode::SetMarker(unsigned blk_x,unsigned blk_y)

void CimgDecode::SetMarkerMcu(unsigned nMcuX,unsigned nMcuY,unsigned nState)
{
if (m_abMarkedMcuMap) {
if (m_bMarkedMcuMapEn && m_abMarkedMcuMap) {
unsigned nXYCur = nMcuY*m_nMcuXMax + nMcuX;
bool bCur = m_abMarkedMcuMap[nXYCur];
if (nState == 0) {
Expand All @@ -4438,7 +4452,7 @@ void CimgDecode::SetMarkerMcu(unsigned nMcuX,unsigned nMcuY,unsigned nState)
// Shift key was held down so set a run
void CimgDecode::SetMarkerMcuTo(unsigned nMcuX,unsigned nMcuY,unsigned nState)
{
if (m_abMarkedMcuMap) {
if (m_bMarkedMcuMapEn && m_abMarkedMcuMap) {
unsigned nXYCur = nMcuY*m_nMcuXMax + nMcuX;
bool bCur = m_abMarkedMcuMap[nXYCur];
if (nState == 0) {
Expand Down Expand Up @@ -4932,7 +4946,7 @@ void CimgDecode::ViewMcuMarkedOverlay(CDC* pDC)
for (unsigned nMcuY=0;nMcuY<m_nMcuYMax;nMcuY++) {
for (unsigned nMcuX=0;nMcuX<m_nMcuXMax;nMcuX++) {
unsigned nXY = nMcuY*m_nMcuXMax + nMcuX;
if (m_abMarkedMcuMap && m_abMarkedMcuMap[nXY]) {
if (m_bMarkedMcuMapEn && m_abMarkedMcuMap && m_abMarkedMcuMap[nXY]) {
unsigned nXZoomed = (unsigned)(nMcuX*m_nMcuWidth*m_nZoom);
unsigned nYZoomed = (unsigned)(nMcuY*m_nMcuHeight*m_nZoom);

Expand Down Expand Up @@ -5028,8 +5042,6 @@ CString CimgDecode::GetStatusFilePosText()



const BYTE CimgDecode::m_anMaskByte[] = { 0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF };


// FIXME would like to share this with CjfifDecode!
const unsigned CimgDecode::m_sZigZag[64] =
Expand Down
15 changes: 11 additions & 4 deletions ImgDecode.h
Expand Up @@ -92,7 +92,11 @@
// Allocate enough space for 40 megapixel image
// Note that we pre-allocate space because we don't want to
// lose the markers between re-process events!
#define MARKMCUMAP_SIZE (40000000/64)
// TODO: This is a VERY wasteful way of capturing the list of MCUs that
// we want to mark. Instead, an array of selected coordinates would
// be far more appropriate, but slightly slower in processing later
// (due to the linear search).
#define MARKMCUMAP_SIZE (40000000/(8*8))


typedef struct {
Expand Down Expand Up @@ -365,6 +369,9 @@ class CimgDecode


// Array that indicates whether or not an MCU has been marked
// NOTE: This feature is disabled if the image is too large (and
// is marked by a NULL pointer).
bool m_bMarkedMcuMapEn; // Is Marked MCU map enabled?
bool * m_abMarkedMcuMap;
unsigned m_nMarkedMcuLastXY;

Expand Down Expand Up @@ -547,7 +554,9 @@ class CimgDecode
bool m_bHistEn; // Histograms enabled? (by AppConfig)
bool m_bStatClipEn; // UNUSED *** Enable scan clipping stats?
unsigned m_nNumPixels;
PixelCcHisto m_sHisto;
PixelCcHisto m_sHisto; // YCC/RGB histogram (min/max/avg)
PixelCcClip m_sStatClip; // YCC/RGB clipping stats

unsigned m_pCC_histo_r[HISTO_BINS];
unsigned m_pCC_histo_g[HISTO_BINS];
unsigned m_pCC_histo_b[HISTO_BINS];
Expand All @@ -556,8 +565,6 @@ class CimgDecode
unsigned m_histo_y_full[FULL_HISTO_BINS];
unsigned m_histo_y_subset[FULL_HISTO_BINS];

public: // FIXME for ImgMod
static const BYTE m_anMaskByte[];
private:

// For View management
Expand Down
10 changes: 5 additions & 5 deletions JPEGsnoop.rc
Expand Up @@ -631,8 +631,8 @@ END
//

VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,5,1,0
PRODUCTVERSION 1,5,1,0
FILEVERSION 1,5,2,0
PRODUCTVERSION 1,5,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
Expand All @@ -649,12 +649,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "ImpulseAdventure"
VALUE "FileDescription", "JPEGsnoop"
VALUE "FileVersion", "1.5.1.0"
VALUE "FileVersion", "1.5.2.0"
VALUE "InternalName", "JPEGsnoop.exe"
VALUE "LegalCopyright", "(c) 2010 Calvin Hass. All rights reserved."
VALUE "LegalCopyright", "(c) 2011 Calvin Hass. All rights reserved."
VALUE "OriginalFilename", "JPEGsnoop.exe"
VALUE "ProductName", "JPEGsnoop"
VALUE "ProductVersion", "1.5.1.0"
VALUE "ProductVersion", "1.5.2.0"
END
END
BLOCK "VarFileInfo"
Expand Down
6 changes: 6 additions & 0 deletions VERSION.txt
Expand Up @@ -3,6 +3,12 @@
// by Calvin Hass
// ==================================

1.5.2 (02/20/11)
- Fixed YCC/RGB clipping statistics
- Disabled MCU marker array if image too large (eg. 40+ megapixel images).
[Added m_bMarkedMcuMapEn. The proper solution would be to update
m_abMarkedMcuMap to use a list of selected coordinates.]

1.5.1 (11/14/10)
- Improved robustness of batch mode operation
- Added average luminance report
Expand Down
2 changes: 1 addition & 1 deletion snoop.h
Expand Up @@ -25,7 +25,7 @@
// - Note that when the version number is incremented, I need
// to also update the corresponding version numbers in the
// JPEGsnoop.rc resource under "Version.VS_VERSION_INFO".
#define VERSION_STR "1.5.1"
#define VERSION_STR "1.5.2"

// Version number for the database signatures
// - This version number has been provided in case I decide
Expand Down

0 comments on commit 2addbd5

Please sign in to comment.