📄 mepnm.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) 2004-2005 Intel Corporation. All Rights Reserved.//////*/#include "mepnm.h"#include "calcvector.h"#include "mepnmwarning.h"#include "resize.h"#include "imageconvert.h"#include "pp.h"#ifdef XSCALE#include "mepnmexception.h"#endifinline void ConvertDynRangeToPNM( const Ipp64s *src, Ipp8u *dst, int size, unsigned int srcBitDepth, // NOTE: Actual bit depth is BitDepth + 1; bool srcIsSigned){ Ipp64s shift = (Ipp64s)srcBitDepth - (Ipp64s)8 + (Ipp64s)1; Ipp64s add = srcIsSigned ? (Ipp64s)1 << (Ipp64s)srcBitDepth : (Ipp64s)0; ShiftAddConvert(src, dst, size, shift, add);}void SetBestPNMInfo( const MRstrImage &rstrImage, PNMNumericFormat numFmt, PNMInfo &pnmInfo){ pnmInfo.SetSize(rstrImage.RefGridRect().Size()); unsigned int bitDepth = rstrImage.ComponentDepth()->BitDepth(); PNMColorFormat clrFmt; unsigned int nOfSrcActualComponents = (rstrImage.Palette().IsActual()) ? rstrImage.Palette().NOfChannels() : rstrImage.NOfComponents(); if(nOfSrcActualComponents > 1) clrFmt = PNM_COLOR; else if(rstrImage.ComponentDepth()->BitDepth()) clrFmt = PNM_GRAYSCALE; else { clrFmt = PNM_BLACKNWHITE; bitDepth = 0; } pnmInfo.SetMaxValue (PNMMaxDataValue(bitDepth)); pnmInfo.SetMagicNumber(MagicNumber(numFmt, clrFmt));}void SetBestPNMInfo( const MRstrImage &rstrImage, PNMNumericFormat numFmt, PNMColorFormat clrFmt, PNMInfo &pnmInfo){ pnmInfo.SetSize(rstrImage.RefGridRect().Size()); unsigned int bitDepth = (clrFmt == PNM_BLACKNWHITE) ? 0 : rstrImage.ComponentDepth()->BitDepth(); pnmInfo.SetMaxValue(PNMMaxDataValue(bitDepth)); pnmInfo.SetMagicNumber(MagicNumber(numFmt, clrFmt));}inline void ConvertDynRangeForPNM( const ImageCoreC<Ipp32s,1> &srcDst, unsigned int dstDepth, MRstrImageDepth srcDepth, const RectSize &srcDstSize){ ConvertDynRange(srcDst, srcDstSize, srcDepth.BitDepth(), srcDepth.IsSigned(), dstDepth, false);}inline void ConvertDynRangeAndAverage( const ImageCoreC<Ipp32s,1> *src, const MRstrImageDepth *srcDepth, unsigned int nOfComponents, const ImageCoreC<Ipp32s,1> &dst, const MRstrImageDepth &dstDepth, const RectSize &size){ if(nOfComponents==0) return; if(nOfComponents==1) { Copy(*src, dst, size); ConvertDynRange(dst, size, srcDepth[0].BitDepth(), srcDepth[0].IsSigned(), dstDepth.BitDepth(), dstDepth.IsSigned()); return; } double factor = 1.0 / (double)nOfComponents; Ipp32s *dstData = dst.Data(); unsigned int dstLineStep = dst.LineStep(); FixedBuffer<const Ipp32s*> srcDataPtr (nOfComponents); FixedBuffer<unsigned int> srcLineStep(nOfComponents); FixedBuffer<int> shift (nOfComponents); FixedBuffer<int> add (nOfComponents); unsigned int component; for(component = 0; component < nOfComponents; component++) { srcDataPtr [component] = src[component].Data(); srcLineStep[component] = src[component].LineStep(); shift[component] = srcDepth[component].BitDepth() - dstDepth.BitDepth(); if(dstDepth.IsSigned()) { add[component] = srcDepth[component].IsSigned() ? 0 : -(Ipp32s)1 << (Ipp32s)srcDepth[component].BitDepth(); } else { add[component] = srcDepth[component].IsSigned() ? (Ipp32s)1 << (Ipp32s)srcDepth[component].BitDepth() : 0; } } unsigned int width = size.Width(); unsigned int height = size.Height(); for(unsigned int y = 0; y < height; y++) { for(unsigned int x = 0; x < width; x++) { double sum = 0.0; for(component = 0; component < nOfComponents; component++) { Ipp32s normalized = shift[component] > 0 ? srcDataPtr[component][x] << shift[component] : srcDataPtr[component][x] >> shift[component]; normalized += add[component]; sum += (double)normalized; } sum *= factor; dstData[x] = (Ipp32s)(sum + 0.5); } addrInc(dstData, dstLineStep); for(component = 0; component < nOfComponents; component++) addrInc(srcDataPtr[component], srcLineStep[component]); }}//// Palette is not used here.//// 'isAveragingPrefferable' is actual only when it's hard to keep all channels in PNM// if it's false only first channels will be placed in PNM// if it's true the average value will be placed in PNM for all PNM channels//inline void ConverDirectImageComponentsToPNM( const ImageCoreC<Ipp32s, 1> *srcComponents, const MRstrImageDepth *srcDepth, unsigned int nOfSrcComponents, const RectSize &srcSize, const ImageCoreC<Ipp32s, 1> *dstComponents, unsigned int dstDepth, unsigned int nOfDstComponents, const RectSize &dstSize, bool isAveragingPrefferable, BDiagnOutputPtr &diagnOutputPtr){ unsigned int component; if(nOfSrcComponents == nOfDstComponents || (!isAveragingPrefferable)) { unsigned int nOfActualComponents = Min(nOfSrcComponents, nOfDstComponents); for(component = 0; component < nOfActualComponents; component++) {#ifdef XSCALE if(srcSize != dstSize) throw DiagnDescrCT<MEPNMException,compsAreResampledForPNM>(); Copy(srcComponents[component], dstComponents[component], srcSize);#else Resize( srcComponents[component], srcSize, dstComponents[component], dstSize);#endif ConvertDynRangeForPNM( dstComponents[component], dstDepth, srcDepth [component], srcSize); Saturate(dstComponents[component], srcSize, 0, PNMMaxDataValue(dstDepth)); } for( ; component < nOfDstComponents; component++) Copy(dstComponents[0], dstComponents[component], dstSize); } else { // multiple input channels, single output ... // sometimes it's hard to do something better in this case diagnOutputPtr->Warning(DiagnDescrCT<MEPNMWarning, MEPNMAveragingOfComponents>()); MRstrImageDepth dstImgDepth(dstDepth, false); ImageC<Ipp32s,1> dst(srcSize); ConvertDynRangeAndAverage(srcComponents, srcDepth, nOfSrcComponents, dst, dstImgDepth, srcSize);#ifdef XSCALE if(srcSize != dstSize) throw DiagnDescrCT<MEPNMException,compsAreResampledForPNM>(); Copy(dst, dstComponents[0], srcSize);#else Resize(dst, srcSize, dstComponents[0], dstSize);#endif Saturate(dst, srcSize, 0, PNMMaxDataValue(dstDepth)); for(component = 1; component < nOfDstComponents; component++) Copy(dstComponents[0], dstComponents[component], dstSize); }}// return false if impossibleinline void DepalettizeForPNM( const MRstrImagePalette &palette, const ImageCoreC<Ipp32s, 1> *srcComponent, unsigned int nOfComponents, const ImageCoreC<Ipp32s, 1> &dst, const RectSize &size, Ipp16u channel){ unsigned int compIndex = palette.ComponentIndex(channel); if(compIndex >= nOfComponents) Zero(dst, size); const ImageCoreC<Ipp32s, 1> &src = srcComponent[compIndex]; unsigned int nOfEntries = palette.NOfEntries(); FixedBuffer<Ipp64s> paletteVector(nOfEntries); for(unsigned int i = 0; i < nOfEntries; i++) { paletteVector[i] = palette.ChannelValue(channel, i); } FixedBuffer<Ipp8u> paletteVector8u(nOfEntries); ConvertDynRangeToPNM( paletteVector, paletteVector8u, nOfEntries, palette.ChannelDepth(channel).BitDepth(), palette.ChannelDepth(channel).IsSigned()); const Ipp32s *srcData = src.Data(); unsigned int srcLineStep = src.LineStep(); Ipp32s *dstData = dst.Data(); unsigned int dstLineStep = dst.LineStep(); unsigned int width = size.Width(); unsigned int height = size.Height(); for(unsigned int y = 0; y < height; y++) { for(unsigned int x = 0; x < width; x++) { Ipp32s index = srcData[x]; if (index > (Ipp32s)nOfEntries) index = nOfEntries - 1; else if(index < 0) index = 0; dstData[x] = paletteVector8u[(unsigned int)index]; } addrInc(srcData, srcLineStep); addrInc(dstData, dstLineStep); }}inline void DepalettizeForPNM( const MRstrImagePalette &palette, const ImageCoreC<Ipp32s, 1> *srcComponent, unsigned int nOfComponents, ImagePn<Ipp32s> &dst, const RectSize &size){ dst.ReAlloc(size, palette.NOfChannels()); for(Ipp16u channel = 0; channel < palette.NOfChannels(); channel++) { DepalettizeForPNM( palette, srcComponent, nOfComponents, dst.Channel(channel), size, channel); }}// isAveragingPrefferable is actual only when it's hard to keep all channels in PNM// if it's false only first channels will be placed in PNM// if it's true the average value will be placed in PNM for all PNM channelsvoid ConvertImageChannelsToPNM( const MRstrImage &rstrImage, const PNMInfo &pnmInfo, const ImageCoreC<Ipp32s, 1> *pnmImageChannels, bool isAveragingPrefferable, BDiagnOutputPtr &diagnOutputPtr){ unsigned int nOfRstrComponents = rstrImage.NOfComponents(); unsigned int nOfPNMChannels = NOfChannels(pnmInfo.MagicNumber()); unsigned int rstrComponent; Rect rstrRect = rstrImage.RefGridRect(); // resample all of components for single sampling factor ImagePn<Ipp32s> rstrResizedComponents(rstrRect.Size(), rstrImage.NOfComponents()); for(rstrComponent = 0; rstrComponent < nOfRstrComponents; rstrComponent++) {#ifdef XSCALE if( rstrImage.ComponentImage() [rstrComponent].Size() != rstrRect.Size() || rstrImage.ComponentSampleSize() [rstrComponent] != RectSize(1,1) ) throw DiagnDescrCT<MEPNMException,compsAreResampledForPNM>(); Copy( rstrImage.ComponentImage() [rstrComponent], rstrResizedComponents.Channels()[rstrComponent], rstrImage.ComponentImage() [rstrComponent].Size());#else ResizeUp( rstrImage.ComponentImage() [rstrComponent], rstrImage.ComponentImage() [rstrComponent].Size(), rstrImage.ComponentSampleSize() [rstrComponent], rstrResizedComponents.Channels()[rstrComponent], rstrRect);#endif } if(rstrImage.Palette().IsActual()) { ImagePn<Ipp32s> depalletizedComponents; DepalettizeForPNM( rstrImage.Palette(), rstrResizedComponents.Channels(), nOfRstrComponents, depalletizedComponents, rstrResizedComponents.Size()); FixedBuffer<MRstrImageDepth> pnmDepth(depalletizedComponents.NOfChannels()); for(unsigned int i = 0; i < depalletizedComponents.NOfChannels(); i++) pnmDepth[i] = MRstrImageDepth(7, false); ConverDirectImageComponentsToPNM( depalletizedComponents.Channels(), pnmDepth, depalletizedComponents.NOfChannels(), depalletizedComponents.Size(), pnmImageChannels, BitDepth(pnmInfo.MaxValue()), nOfPNMChannels, pnmInfo.Size(), isAveragingPrefferable, diagnOutputPtr); } else { ConverDirectImageComponentsToPNM( rstrResizedComponents.Channels(), rstrImage.ComponentDepth(), rstrResizedComponents.NOfChannels(), rstrResizedComponents.Size(), pnmImageChannels, BitDepth(pnmInfo.MaxValue()), nOfPNMChannels, pnmInfo.Size(), isAveragingPrefferable, diagnOutputPtr); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -