Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
source/CTransformPane.cp
/* |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
// CTransformPane |
#include "CTransformPane.h" |
#include <LProgressBar.h> |
#if __VEC__ |
#include "vWavelet_int.h" |
#endif |
#include "sWavelet_int.h" |
#define WAVELET_32_DEPTH 3 |
#define DO_TT6_TRACE 0 |
#define SAVE_WAVELET 0 |
#define REPORT_Y_MSE 0 |
#define TIME_BURT 1 |
#define BURT_LOOPS 100 |
#define BURT_DEPTH 3 |
#define SHOW_U_TRANSORMS 0 |
#define SHOW_Y_TRANSORMS 0 |
#define REPORT_BURT_MSE 0 |
#if DO_TT6_TRACE |
#include "pitsTT6libv.h" |
#endif |
////////////////////////////////////////////////////////////////////////////////////////// |
// Quantize routine adjusts 16-bit wavelet data so that its appearance makes more |
// sense for display. It adjusts min and max based on quadrants for wavelet data of |
// a certain depth. Values are also clamped to [0, 255], with a signed value of 0 being |
// mapped to an unsigned (middle-gray) value of 128. |
////////////////////////////////////////////////////////////////////////////////////////// |
static void Quantize(short *p, unsigned long x, unsigned long y, long rowshorts, short depth) |
{ |
long leftbound; |
long rightbound; |
long topbound; |
long bottombound; |
long min,max; |
long xindex, yindex; |
short *pCurrent; |
long currentAdjusted; |
long scale; |
if (depth) { |
//////////////////////////////////////////////////////////// |
leftbound = x/2; |
rightbound = x; |
topbound = 0; |
bottombound = y/2; |
min = 0; |
max = 0; |
for (yindex = topbound; yindex < bottombound; yindex++) { |
pCurrent = p + (yindex * rowshorts) + (leftbound * 4); |
for (xindex = leftbound*4; xindex < rightbound*4; xindex++) { |
if (*pCurrent < min) min = *pCurrent; |
if (*pCurrent > max) max = *pCurrent; |
pCurrent++; |
} |
} |
scale = max; |
if (-min > scale) scale = -min; |
for (yindex = topbound; yindex < bottombound; yindex++) { |
pCurrent = p + (yindex * rowshorts) + (leftbound * 4); |
for (xindex = leftbound*4; xindex < rightbound*4; xindex++) { |
currentAdjusted = *pCurrent * 128; |
currentAdjusted /= scale; |
*pCurrent = 66 - currentAdjusted; |
pCurrent++; |
} |
} |
//////////////////////////////////////////////////////////// |
leftbound = x/2; |
rightbound = x; |
topbound = y/2; |
bottombound = y; |
min = 0; |
max = 0; |
for (yindex = topbound; yindex < bottombound; yindex++) { |
pCurrent = p + (yindex * rowshorts) + (leftbound * 4); |
for (xindex = leftbound*4; xindex < rightbound*4; xindex++) { |
if (*pCurrent < min) min = *pCurrent; |
if (*pCurrent > max) max = *pCurrent; |
pCurrent++; |
} |
} |
scale = max; |
if (-min > scale) scale = -min; |
for (yindex = topbound; yindex < bottombound; yindex++) { |
pCurrent = p + (yindex * rowshorts) + (leftbound * 4); |
for (xindex = leftbound*4; xindex < rightbound*4; xindex++) { |
currentAdjusted = *pCurrent * 128; |
currentAdjusted /= scale; |
*pCurrent = 66 - currentAdjusted; |
pCurrent++; |
} |
} |
//////////////////////////////////////////////////////////// |
leftbound = 0; |
rightbound = x/2; |
topbound = y/2; |
bottombound = y; |
min = 0; |
max = 0; |
for (yindex = topbound; yindex < bottombound; yindex++) { |
pCurrent = p + (yindex * rowshorts) + (leftbound * 4); |
for (xindex = leftbound*4; xindex < rightbound*4; xindex++) { |
if (*pCurrent < min) min = *pCurrent; |
if (*pCurrent > max) max = *pCurrent; |
pCurrent++; |
} |
} |
scale = max; |
if (-min > scale) scale = -min; |
for (yindex = topbound; yindex < bottombound; yindex++) { |
pCurrent = p + (yindex * rowshorts) + (leftbound * 4); |
for (xindex = leftbound*4; xindex < rightbound*4; xindex++) { |
currentAdjusted = *pCurrent * 128; |
currentAdjusted /= scale; |
*pCurrent = 66 - currentAdjusted; |
pCurrent++; |
} |
} |
////////////////////////////////////////////////////////////// |
Quantize(p, x/2, y/2, rowshorts, depth-1); |
} else { |
leftbound = 0; |
rightbound = x; |
topbound = 0; |
bottombound = y; |
min = 0; |
max = 0; |
for (yindex = topbound; yindex < bottombound; yindex++) { |
pCurrent = p + (yindex * rowshorts) + (leftbound * 4); |
for (xindex = leftbound*4; xindex < rightbound*4; xindex++) { |
*pCurrent = *pCurrent / 64; |
pCurrent++; |
} |
} |
} |
} |
static void Pack16To8( signed short *pSrc, |
unsigned char *pDest, |
unsigned long length) |
{ |
signed short element; |
int i; |
for (i = 0; i<length; i++) { |
element = *pSrc++; |
*pDest++ = element; |
} |
} |
#pragma mark - |
////////////////////////////////////////////// |
// NewWindowWithData |
// Creates a new window with a CCopyBitsPane |
// that uses the specified pixmap with pixel |
// data stored in data handle. |
////////////////////////////////////////////// |
LWindow *CTransformPane::NewWindowWithData(const PixMap &pmap, Handle data) |
{ |
long width = pmap.bounds.right-pmap.bounds.left; |
long height = pmap.bounds.bottom-pmap.bounds.top; |
LWindow *pWin = PP_PowerPlant::LWindow::CreateWindow(129, LCommander::GetTopCommander()); |
ThrowIfNil_(pWin); |
CCopyBitsPane* pBitsPane = dynamic_cast<CCopyBitsPane*>(pWin->FindPaneByID('BMap')); |
FailNIL_(pBitsPane); |
pBitsPane->SetPixelData(pmap, data, mPaddedX, mPaddedY); |
LCommander::SwitchTarget(pBitsPane); |
pWin->ResizeWindowTo(width, height); |
// LWindow is not initially visible in PPob resource |
pWin->Show(); |
// force a draw |
pWin->UpdatePort(); |
return pWin; |
} |
CTransformPane::CTransformPane( LStream *inStream) |
:CCopyBitsPane(inStream) |
{ |
} |
CTransformPane::~CTransformPane() |
{ |
} |
void |
CTransformPane::FindCommandStatus( |
CommandT inCommand, |
Boolean &outEnabled, |
Boolean &outUsesMark, |
Char16 &outMark, |
Str255 outName) |
{ |
switch (inCommand) { |
case cmd_WaveletTransform: |
outEnabled = true; |
break; |
default: |
LCommander::FindCommandStatus(inCommand, outEnabled, |
outUsesMark, outMark, outName); |
break; |
} |
} |
void |
CTransformPane::DoTransform() |
{ |
StHandleLocker lockBits(mBitsData); |
LWindow *pCreatedWindow; |
long width = mPaddedX; |
long height = mPaddedY; |
StHandleBlock tempBlock(width*height*4*sizeof(short)); |
StHandleBlock transformBlock(width*height*4*sizeof(short)); |
StHandleBlock recoveredBlock(width*height*4*sizeof(char)); |
StHandleLocker lockTemp(tempBlock); |
StHandleLocker lockTransform(transformBlock); |
long tickstart = TickCount(); |
#if __VEC__ |
// perform forward vector wavelet |
vFWVT_4_Quad16_2DInt((long *)*mBitsData.Get(), |
(long*)*transformBlock.Get(), |
(long*)*tempBlock.Get(), |
width, |
height, |
width, |
WAVELET_32_DEPTH); |
#else |
// perform forward scalar wavelet |
sFWVT_4_Quad16_2DInt((short *)*mBitsData.Get(), |
(short*)*transformBlock.Get(), |
(short*)*tempBlock.Get(), |
width, |
height, |
width, |
WAVELET_32_DEPTH); |
#endif |
Handle copiedHandle = transformBlock.Get(); |
FailOSErr_(HandToHand(&copiedHandle)); |
StHandleBlock adjustedWaveBlock(copiedHandle); |
{ |
StHandleLocker lock(adjustedWaveBlock); |
Quantize((short*)*adjustedWaveBlock.Get(), width, height, width*4, WAVELET_32_DEPTH); |
} |
Pack16To8((short*)*adjustedWaveBlock.Get(), (unsigned char*)*adjustedWaveBlock.Get(), ::GetHandleSize(adjustedWaveBlock)/2); |
::SetHandleSize(adjustedWaveBlock, ::GetHandleSize(adjustedWaveBlock)/2); |
pCreatedWindow = NewWindowWithData(mPixMap, adjustedWaveBlock); |
pCreatedWindow->SetDescriptor("\pWavelet Transform Data"); |
adjustedWaveBlock.Release(); |
//////////////////////////////// |
// now do inverse wavelet and |
// display result |
//////////////////////////////// |
#if __VEC__ |
// perform forward vector wavelet |
vIFWVT_4_Quad16_2DInt((long *)*transformBlock.Get(), |
(long*)*recoveredBlock.Get(), |
(long*)*tempBlock.Get(), |
width, |
height, |
width, |
WAVELET_32_DEPTH); |
#else |
// perform forward scalar wavelet |
sIFWVT_4_Quad16_2DInt((short *)*transformBlock.Get(), |
(short*)*recoveredBlock.Get(), |
(short*)*tempBlock.Get(), |
width, |
height, |
width, |
WAVELET_32_DEPTH); |
#endif |
pCreatedWindow = NewWindowWithData(mPixMap, recoveredBlock); |
pCreatedWindow->SetDescriptor("\pRecovered Image"); |
recoveredBlock.Release(); |
} |
Boolean |
CTransformPane::ObeyCommand( |
CommandT inCommand, |
void* ioParam) |
{ |
Boolean cmdHandled = false; |
switch (inCommand) { |
case cmd_WaveletTransform: |
DoTransform(); |
cmdHandled = true; |
break; |
default: |
cmdHandled = LCommander::ObeyCommand(inCommand, ioParam); |
break; |
} |
return cmdHandled; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14