1266 lines
55 KiB
C
1266 lines
55 KiB
C
/****************************************************************************
|
||
ORIENT.C
|
||
|
||
$Log: S:\products\wangview\oiwh\display\orient.c_v $
|
||
*
|
||
* Rev 1.20 22 Apr 1996 08:08:10 BEG06016
|
||
* Cleaned up error checking.
|
||
*
|
||
* Rev 1.19 02 Jan 1996 09:56:50 BLJ
|
||
* Changed alot of UINTs to ints.
|
||
* Changed IMG structure to include the image data.
|
||
* Changed lp prefix to p.
|
||
*
|
||
* Rev 1.18 02 Nov 1995 10:12:44 BLJ
|
||
* Adding Undo functionality.
|
||
*
|
||
* Rev 1.17 07 Sep 1995 13:21:44 BLJ
|
||
* Modified scaling to allow for proper rotation of fax images.
|
||
*
|
||
* Rev 1.16 28 Aug 1995 12:03:28 BLJ
|
||
* Moved RotateAll code to CacheFile.
|
||
*
|
||
* Rev 1.15 17 Aug 1995 12:36:44 RC
|
||
* Fixed rgb24 flip bug with middle line of image being corrupted
|
||
*
|
||
* Rev 1.14 09 Aug 1995 08:45:34 BLJ
|
||
* Got Busy/NotBusy back in sync.
|
||
*
|
||
* Rev 1.13 08 Aug 1995 14:29:30 BLJ
|
||
* Turned on background caching.
|
||
* Added last viewed support.
|
||
*
|
||
* Rev 1.12 07 Aug 1995 08:14:56 BLJ
|
||
* Changed bArchive to have different bits indicating how the image was changed.
|
||
*
|
||
****************************************************************************/
|
||
|
||
#include "privdisp.h"
|
||
|
||
|
||
//
|
||
/*****************************************************************************
|
||
|
||
FUNCTION: IMGOrientDisplay
|
||
|
||
PURPOSE: This function sets the image parameters so that the next
|
||
repaint or display will nse a different orientation.
|
||
This routine may be called prior to receiving any data
|
||
(after IMGOpenDisplay and before IMGWriteDisplay). The
|
||
reorientation may be specified as immediate or delayed.
|
||
|
||
INPUT: hWnd - Identifies the image window containing the
|
||
image to reorient.
|
||
nOrientation - Specifies the orientation. It consists
|
||
of one of the following valu
|
||
OD_ROTRIGHT Rotate the image clockwise 90 degrees.
|
||
OD_ROTLEFT Rotate the image counterclockwise 90 degrees.
|
||
OD_FLIP Rotate the image 180 degrees.
|
||
bMode - Specifies whether the reorientation should be
|
||
immediate or at the next repaint/display. If the
|
||
value is nonzero the reorientation will occur
|
||
immediately, otherwise this command will only
|
||
npdate internal structures to be nsed for the
|
||
next repaint/display.
|
||
|
||
*****************************************************************************/
|
||
|
||
int WINAPI IMGOrientDisplay(HWND hWnd, int nOrientation, BOOL bMode){
|
||
|
||
int nStatus;
|
||
PWINDOW pWindow;
|
||
PANO_IMAGE pAnoImage;
|
||
PIMAGE pImage;
|
||
PIMAGE pFormImage;
|
||
|
||
PMARK pMark;
|
||
PIMG pImg = 0;
|
||
LRECT lrOldSelectBox;
|
||
PARM_SCROLL_STRUCT Scroll;
|
||
RECT ClientRect;
|
||
int nTemp;
|
||
long templeft;
|
||
long temptop;
|
||
long tempright;
|
||
LRECT lrFSClientRect;
|
||
|
||
|
||
CheckError2( Init(hWnd, &pWindow, &pAnoImage, TRUE, TRUE));
|
||
pImage = pAnoImage->pBaseImage;
|
||
pFormImage = pAnoImage->pDisplayFormImage;
|
||
|
||
CheckError2( ValidateCache(hWnd, pAnoImage));
|
||
|
||
// Check for operation in progress.
|
||
if (pAnoImage->Annotations.ppMarks){
|
||
pMark = pAnoImage->Annotations.ppMarks[pAnoImage->Annotations.nMarks];
|
||
if (pMark){
|
||
OiOpEndOperation(hWnd);
|
||
pMark = pAnoImage->Annotations.ppMarks[pAnoImage->Annotations.nMarks];
|
||
if (pMark){
|
||
OiOpEndOperation(hWnd);
|
||
}
|
||
}
|
||
}
|
||
|
||
CheckError2( UndoSavelpWindow(pAnoImage, pWindow));
|
||
CheckError2( UndoSaveSelectionState(pAnoImage));
|
||
CheckError2( UndoSavelpAnnotations(pAnoImage));
|
||
CheckError2( UndoSavelpAnoImage(pAnoImage));
|
||
CheckError2( UndoSavelpBaseImage(pAnoImage));
|
||
|
||
GetSelectBox(pAnoImage, &lrOldSelectBox);
|
||
GetClientRect(hWnd, &ClientRect);
|
||
CopyRect (lrFSClientRect, ClientRect);
|
||
ConvertRect(pWindow, &lrFSClientRect, CONV_WINDOW_TO_FULLSIZE);
|
||
|
||
switch (nOrientation){
|
||
case OD_FLIP:
|
||
CheckError2( Flip(pImage->pImg, (int) pImage->nWidth, (int) pImage->nHeight));
|
||
if (pFormImage){
|
||
templeft = pAnoImage->pFormMark->Attributes.lrBounds.left;
|
||
temptop = pAnoImage->pFormMark->Attributes.lrBounds.top;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.left
|
||
= pImage->nWidth - pAnoImage->pFormMark->Attributes.lrBounds.right;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.top
|
||
= pImage->nHeight - pAnoImage->pFormMark->Attributes.lrBounds.bottom;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.right = pImage->nWidth - templeft;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.bottom = pImage->nHeight - temptop;
|
||
}
|
||
|
||
pAnoImage->lrSelectBox.top = pImage->nHeight - lrOldSelectBox.bottom;
|
||
pAnoImage->lrSelectBox.bottom = pImage->nHeight - lrOldSelectBox.top;
|
||
pAnoImage->lrSelectBox.left = pImage->nWidth - lrOldSelectBox.right;
|
||
pAnoImage->lrSelectBox.right = pImage->nWidth - lrOldSelectBox.left;
|
||
Scroll.lHorz = max(0l, pImage->nWidth - lrFSClientRect.right);
|
||
Scroll.lVert = max(0l, pImage->nHeight - lrFSClientRect.bottom);
|
||
|
||
if ((pImage->nFileRotation += 180) >= 360){
|
||
pImage->nFileRotation -= 360;
|
||
}
|
||
break;
|
||
|
||
case OD_HMIRROR:
|
||
CheckError2( HorizontalMirror(pImage->pImg, (int) pImage->nWidth, (int) pImage->nHeight));
|
||
|
||
if (pFormImage){
|
||
temptop = pAnoImage->pFormMark->Attributes.lrBounds.top;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.top
|
||
= pImage->nHeight - pAnoImage->pFormMark->Attributes.lrBounds.bottom;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.bottom = pImage->nHeight - temptop;
|
||
}
|
||
|
||
pAnoImage->lrSelectBox.top = pImage->nHeight - lrOldSelectBox.bottom;
|
||
pAnoImage->lrSelectBox.bottom = pImage->nHeight - lrOldSelectBox.top;
|
||
|
||
Scroll.lHorz = lrFSClientRect.left;
|
||
Scroll.lVert = max(0l, pImage->nHeight - lrFSClientRect.bottom);
|
||
break;
|
||
|
||
case OD_VMIRROR:
|
||
CheckError2( VerticalMirror(pImage->pImg, (int) pImage->nWidth, (int) pImage->nHeight));
|
||
if (pFormImage){
|
||
templeft = pAnoImage->pFormMark->Attributes.lrBounds.left;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.left
|
||
= pImage->nWidth - pAnoImage->pFormMark->Attributes.lrBounds.right;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.right = pImage->nWidth - templeft;
|
||
}
|
||
|
||
pAnoImage->lrSelectBox.left = pImage->nWidth - lrOldSelectBox.right;
|
||
pAnoImage->lrSelectBox.right = pImage->nWidth - lrOldSelectBox.left;
|
||
|
||
Scroll.lHorz = max(0l, pImage->nWidth - lrFSClientRect.right);
|
||
Scroll.lVert = lrFSClientRect.top;
|
||
break;
|
||
|
||
case OD_ROTRIGHT:
|
||
case OD_ROTLEFT:
|
||
CheckError2( CreateAnyImgBuf(&pImg, pImage->nHeight,
|
||
pImage->nWidth, pImage->pImg->nType));
|
||
|
||
if (nOrientation == OD_ROTRIGHT){
|
||
CheckError2( RotateRight90(pImage->pImg, pImg,(int) pImage->nWidth, (int) pImage->nHeight));
|
||
if (pFormImage){
|
||
tempright = pAnoImage->pFormMark->Attributes.lrBounds.right;
|
||
temptop = pAnoImage->pFormMark->Attributes.lrBounds.top;
|
||
templeft = pAnoImage->pFormMark->Attributes.lrBounds.left;
|
||
|
||
pAnoImage->pFormMark->Attributes.lrBounds.left
|
||
= pImage->nHeight - pAnoImage->pFormMark->Attributes.lrBounds.bottom;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.top = templeft;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.right
|
||
= pImage->nHeight - temptop;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.bottom = tempright;
|
||
}
|
||
pAnoImage->lrSelectBox.top = lrOldSelectBox.left;
|
||
pAnoImage->lrSelectBox.bottom = lrOldSelectBox.right;
|
||
pAnoImage->lrSelectBox.left = pImage->nHeight - lrOldSelectBox.bottom;
|
||
pAnoImage->lrSelectBox.right = pImage->nHeight - lrOldSelectBox.top;
|
||
|
||
Scroll.lHorz = max(0l, pImage->nHeight - lrFSClientRect.bottom);
|
||
Scroll.lVert = lrFSClientRect.left;
|
||
|
||
if ((pImage->nFileRotation += 90) >= 360){
|
||
pImage->nFileRotation -= 360;
|
||
}
|
||
|
||
}else{ // OD_ROTLEFT
|
||
CheckError2( RotateRight270(pImage->pImg, pImg, (int) pImage->nWidth, (int) pImage->nHeight));
|
||
if (pFormImage){
|
||
templeft = pAnoImage->pFormMark->Attributes.lrBounds.left;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.left
|
||
= pAnoImage->pFormMark->Attributes.lrBounds.top;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.top
|
||
= pImage->nWidth - pAnoImage->pFormMark->Attributes.lrBounds.right;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.right
|
||
= pAnoImage->pFormMark->Attributes.lrBounds.bottom;
|
||
pAnoImage->pFormMark->Attributes.lrBounds.bottom
|
||
= pImage->nWidth - templeft;
|
||
}
|
||
|
||
pAnoImage->lrSelectBox.top = pImage->nWidth - lrOldSelectBox.right;
|
||
pAnoImage->lrSelectBox.bottom = pImage->nWidth - lrOldSelectBox.left;
|
||
pAnoImage->lrSelectBox.left = lrOldSelectBox.top;
|
||
pAnoImage->lrSelectBox.right = lrOldSelectBox.bottom;
|
||
|
||
Scroll.lHorz = lrFSClientRect.top;
|
||
// this is to ensure that a rotate right followed by a
|
||
// rotate left displays the original portion of the image
|
||
Scroll.lVert = max(0l, pImage->nWidth - (lrFSClientRect.left
|
||
+ (lrFSClientRect.bottom - lrFSClientRect.top)));
|
||
|
||
if ((pImage->nFileRotation += 270) >= 360){
|
||
pImage->nFileRotation -= 360;
|
||
}
|
||
}
|
||
FreeImgBuf(&pImage->pImg);
|
||
MoveImage(&pImg, &pImage->pImg);
|
||
nTemp = pImage->nHRes;
|
||
pImage->nHRes = pImage->nVRes;
|
||
pImage->nVRes = nTemp;
|
||
break;
|
||
|
||
default:
|
||
nStatus = Error(DISPLAY_INVALIDORIENTATION);
|
||
goto Exit;
|
||
}
|
||
|
||
pImage->bArchive |= ARCHIVE_ROTATED_IMAGE;
|
||
// if there is a form, then have it regenerated
|
||
if (pFormImage){
|
||
if (pAnoImage->pDisplayFormImage){
|
||
CheckError2( FreeImgBuf(&pAnoImage->pDisplayFormImage->pImg));
|
||
CheckError2( FreeMemory((PPSTR) &pAnoImage->pDisplayFormImage));
|
||
}
|
||
if (pAnoImage->pBasePlusFormImg != pImage->pImg){
|
||
CheckError2( FreeImgBuf(&pAnoImage->pBasePlusFormImg));
|
||
}
|
||
pAnoImage->nBPFValidLines = 0;
|
||
}
|
||
|
||
CheckError2( OrientAnnotations(hWnd, pWindow, pImage, nOrientation));
|
||
|
||
pImage->nWidth = pImage->pImg->nWidth;
|
||
pImage->nHeight = pImage->pImg->nHeight;
|
||
pImage->nLinesRead = pImage->nHeight;
|
||
switch (pImage->pImg->nType){
|
||
case ITYPE_BI_LEVEL:
|
||
pImage->nlMaxRWOffset = pImage->nHeight * (( pImage->nWidth + 7) / 8);
|
||
break;
|
||
|
||
case ITYPE_GRAY4:
|
||
case ITYPE_PAL4:
|
||
pImage->nlMaxRWOffset = pImage->nHeight * (( pImage->nWidth + 1) / 2);
|
||
break;
|
||
|
||
case ITYPE_GRAY7:
|
||
case ITYPE_GRAY8:
|
||
case ITYPE_COMPAL8:
|
||
case ITYPE_CUSPAL8:
|
||
pImage->nlMaxRWOffset = pImage->nHeight * pImage->nWidth;
|
||
break;
|
||
|
||
case ITYPE_RGB24:
|
||
case ITYPE_BGR24:
|
||
pImage->nlMaxRWOffset = pImage->nHeight * pImage->nWidth * 3;
|
||
break;
|
||
|
||
default:
|
||
Error(nStatus = DISPLAY_INTERNALDATAERROR);
|
||
goto Exit;
|
||
}
|
||
|
||
pWindow->bRepaintClientRect = TRUE;
|
||
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SCROLL, &Scroll,
|
||
PARM_ABSOLUTE | PARM_PIXEL | PARM_FULLSIZE));
|
||
CheckError2( InvalidateAllDisplayRects(pWindow, pImage, NULL, TRUE));
|
||
|
||
if (bMode){
|
||
CheckError2( IMGRepaintDisplay(hWnd, (PRECT) -1));
|
||
}
|
||
|
||
Exit:
|
||
FreeImgBuf(&pImg);
|
||
DeInit(TRUE, TRUE);
|
||
return(nStatus);
|
||
}
|
||
//
|
||
/*****************************************************************************
|
||
|
||
FUNCTION: VerticalMirror
|
||
|
||
PURPOSE: This function performs a vertical mirror of the data.
|
||
This function assumes inplace mirroring.
|
||
|
||
*****************************************************************************/
|
||
|
||
int WINAPI VerticalMirror(PIMG pImg, int nWidth, int nHeight){
|
||
|
||
int nStatus = 0;
|
||
|
||
BYTE cMirrorTable[256];
|
||
PBYTE pLine1;
|
||
PBYTE pLine2;
|
||
int nLine;
|
||
int nHalfWidth;
|
||
int nWidthBytes;
|
||
BYTE cLeftShiftAmount;
|
||
BYTE cRightShiftAmount;
|
||
int nLoop;
|
||
|
||
uchar c1 = 0;
|
||
uchar c2 = 0;
|
||
uchar c3 = 0;
|
||
|
||
|
||
switch (pImg->nType){
|
||
case ITYPE_BI_LEVEL:
|
||
// Build mirror table.
|
||
for (nLoop = 0; nLoop < 256; nLoop++){
|
||
cMirrorTable[nLoop] = ((nLoop & 0x01) << 7) | ((nLoop & 0x02) << 5)
|
||
| ((nLoop & 0x04) << 3) | ((nLoop & 0x08) << 1)
|
||
| ((nLoop & 0x10) >> 1) | ((nLoop & 0x20) >> 3)
|
||
| ((nLoop & 0x40) >> 5) | ((nLoop & 0x80) >> 7);
|
||
}
|
||
nWidthBytes = (nWidth + 7) / 8;
|
||
nHalfWidth = (nWidthBytes + 1) / 2;
|
||
if (!(nWidth & 7)){
|
||
for (nLine = 0; nLine < nHeight; nLine++){
|
||
pLine1 = &pImg->bImageData[0] + (nLine * pImg->nBytesPerLine);
|
||
pLine2 = pLine1 + (nWidthBytes - 1);
|
||
for (nLoop = nHalfWidth; nLoop; nLoop--){
|
||
c1 = cMirrorTable[*pLine1];
|
||
*pLine1 = cMirrorTable[*pLine2];
|
||
*pLine2 = c1;
|
||
pLine1++;
|
||
pLine2--;
|
||
}
|
||
}
|
||
}else{ // if ((nWidth & 7)){
|
||
cRightShiftAmount = nWidth & 7;
|
||
cLeftShiftAmount = 8 - cRightShiftAmount;
|
||
for (nLine = 0; nLine < nHeight; nLine++){
|
||
pLine1 = &pImg->bImageData[0] + (nLine * pImg->nBytesPerLine);
|
||
pLine2 = pLine1 + (nWidthBytes - 1);
|
||
nLoop = nHalfWidth;
|
||
c3 = 0;
|
||
for (; nLoop; nLoop--){
|
||
c2 = c3;
|
||
c1 = cMirrorTable[*pLine2] << cLeftShiftAmount;
|
||
c1 |= cMirrorTable[*(pLine2 - 1)] >> cRightShiftAmount;
|
||
c2 |= cMirrorTable[*pLine1] << cLeftShiftAmount;
|
||
c3 = cMirrorTable[*pLine1] >> cRightShiftAmount;
|
||
*(pLine1++) = c1;
|
||
*(pLine2--) = c2;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ITYPE_GRAY4:
|
||
case ITYPE_PAL4:
|
||
nWidthBytes = (nWidth + 1) / 2;
|
||
nHalfWidth = (nWidthBytes + 1) / 2;
|
||
if (!(nWidth & 1)){
|
||
for (nLine = 0; nLine < nHeight; nLine++){
|
||
pLine1 = &pImg->bImageData[0] + (nLine * pImg->nBytesPerLine);
|
||
pLine2 = pLine1 + (nWidthBytes - 1);
|
||
for (nLoop = nHalfWidth; nLoop; nLoop--){
|
||
c1 = (*pLine1 >> 4) | (*pLine1 << 4);
|
||
*pLine1 = (*pLine2 >> 4) | (*pLine2 << 4);
|
||
*pLine2 = c1;
|
||
pLine1++;
|
||
pLine2--;
|
||
}
|
||
}
|
||
}else{ // if ((nWidth & 1)){
|
||
for (nLine = 0; nLine < nHeight; nLine++){
|
||
pLine1 = &pImg->bImageData[0] + (nLine * pImg->nBytesPerLine);
|
||
pLine2 = pLine1 + (nWidthBytes - 1);
|
||
c3 = 0;
|
||
for (nLoop = nHalfWidth; nLoop; nLoop--){
|
||
c2 = c3;
|
||
c1 = *pLine2 & 0xf0;
|
||
c1 |= *(pLine2 - 1) & 0x0f;
|
||
c2 |= *pLine1 & 0xf0;
|
||
c3 = *pLine1 & 0x0f;
|
||
*(pLine1++) = c1;
|
||
*(pLine2--) = c2;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ITYPE_GRAY7:
|
||
case ITYPE_GRAY8:
|
||
case ITYPE_COMPAL8:
|
||
case ITYPE_CUSPAL8:
|
||
nHalfWidth = (nWidth + 1) / 2;
|
||
for (nLine = 0; nLine < nHeight; nLine++){
|
||
pLine1 = &pImg->bImageData[0] + (nLine * pImg->nBytesPerLine);
|
||
pLine2 = pLine1 + (nWidth - 1);
|
||
for (nLoop = nHalfWidth; nLoop; nLoop--){
|
||
c1 = *pLine1;
|
||
*pLine1 = *pLine2;
|
||
*pLine2 = c1;
|
||
pLine1++;
|
||
pLine2--;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ITYPE_RGB24:
|
||
case ITYPE_BGR24:
|
||
nHalfWidth = (nWidth + 1) / 2;
|
||
for (nLine = 0; nLine < nHeight; nLine++){
|
||
pLine1 = &pImg->bImageData[0] + (nLine * pImg->nBytesPerLine);
|
||
pLine2 = pLine1 + ((nWidth - 1) * 3);
|
||
for (nLoop = nHalfWidth; nLoop; nLoop--){
|
||
c1 = *pLine1;
|
||
*(pLine1++) = *pLine2;
|
||
*(pLine2++) = c1;
|
||
c1 = *pLine1;
|
||
*(pLine1++) = *pLine2;
|
||
*(pLine2++) = c1;
|
||
c1 = *pLine1;
|
||
*(pLine1++) = *pLine2;
|
||
*pLine2 = c1;
|
||
pLine2 -= 5;
|
||
}
|
||
}
|
||
break;
|
||
|
||
default:
|
||
Error(nStatus = DISPLAY_INTERNALDATAERROR);
|
||
goto Exit;
|
||
}
|
||
|
||
|
||
Exit:
|
||
return(nStatus);
|
||
}
|
||
//
|
||
/*****************************************************************************
|
||
|
||
FUNCTION: HorizontalMirror
|
||
|
||
PURPOSE: This function performs a horizontal mirror of the data.
|
||
This function assumes inplace mirroring.
|
||
|
||
*****************************************************************************/
|
||
|
||
int WINAPI HorizontalMirror(PIMG pImg, int nWidth, int nHeight){
|
||
|
||
int nStatus = 0;
|
||
|
||
PBYTE pLine1;
|
||
PBYTE pLine2;
|
||
int nLine1;
|
||
int nLine2;
|
||
int nHalfHeight;
|
||
int nLoop;
|
||
|
||
uchar c1 = 0;
|
||
|
||
|
||
nHalfHeight = (nHeight + 1) >> 1;
|
||
for (nLine1 = 0, nLine2 = nHeight - 1; nLine1 < nHalfHeight; nLine1++, nLine2--){
|
||
pLine1 = &pImg->bImageData[0] + (nLine1 * pImg->nBytesPerLine);
|
||
pLine2 = &pImg->bImageData[0] + (nLine2 * pImg->nBytesPerLine);
|
||
for (nLoop = pImg->nBytesPerLine; nLoop; nLoop--){
|
||
c1 = *pLine1;
|
||
*pLine1 = *pLine2;
|
||
*pLine2 = c1;
|
||
pLine1++;
|
||
pLine2++;
|
||
}
|
||
}
|
||
|
||
return(nStatus);
|
||
}
|
||
//
|
||
/*****************************************************************************
|
||
|
||
FUNCTION: Flip
|
||
|
||
PURPOSE: This function performs a 180 degree rotation of the data.
|
||
This function assumes inplace flipping.
|
||
|
||
*****************************************************************************/
|
||
|
||
int WINAPI Flip(PIMG pImg, int nWidth, int nHeight){
|
||
|
||
int nStatus = 0;
|
||
|
||
BYTE cMirrorTable[256];
|
||
PBYTE pLine1;
|
||
PBYTE pLine2;
|
||
int nLine1;
|
||
int nLine2;
|
||
int nWidthBytes;
|
||
int nHalfHeight;
|
||
BYTE cLeftShiftAmount;
|
||
BYTE cRightShiftAmount;
|
||
int nLoop;
|
||
uchar c1 = 0;
|
||
uchar c2 = 0;
|
||
uchar c3 = 0;
|
||
|
||
|
||
switch (pImg->nType){
|
||
case ITYPE_BI_LEVEL:
|
||
// Build mirror table.
|
||
for (nLoop = 0; nLoop < 256; nLoop++){
|
||
cMirrorTable[nLoop] = ((nLoop & 0x01) << 7) | ((nLoop & 0x02) << 5)
|
||
| ((nLoop & 0x04) << 3) | ((nLoop & 0x08) << 1)
|
||
| ((nLoop & 0x10) >> 1) | ((nLoop & 0x20) >> 3)
|
||
| ((nLoop & 0x40) >> 5) | ((nLoop & 0x80) >> 7);
|
||
}
|
||
nWidthBytes = (nWidth + 7) / 8;
|
||
nHalfHeight = (nHeight + 1) / 2;
|
||
if (!(nWidth & 7)){
|
||
for (nLine1 = 0, nLine2 = nHeight - 1; nLine1 < nHalfHeight; nLine1++, nLine2--){
|
||
pLine1 = &pImg->bImageData[0] + (nLine1 * pImg->nBytesPerLine);
|
||
pLine2 = &pImg->bImageData[0] + (nLine2 * pImg->nBytesPerLine);
|
||
pLine2 += nWidthBytes - 1;
|
||
if (nLine1 == nLine2){
|
||
for (nLoop = nWidthBytes / 2; nLoop; nLoop--){
|
||
c1 = cMirrorTable[*pLine1];
|
||
*pLine1 = cMirrorTable[*pLine2];
|
||
*pLine2 = c1;
|
||
pLine1++;
|
||
pLine2--;
|
||
}
|
||
if (nWidthBytes & 1){
|
||
*pLine1 = cMirrorTable[*pLine1];
|
||
}
|
||
}else{
|
||
for (nLoop = nWidthBytes; nLoop; nLoop--){
|
||
c1 = cMirrorTable[*pLine1];
|
||
*pLine1 = cMirrorTable[*pLine2];
|
||
*pLine2 = c1;
|
||
pLine1++;
|
||
pLine2--;
|
||
}
|
||
}
|
||
}
|
||
}else{ // if ((nWidth & 7))
|
||
cRightShiftAmount = nWidth & 7;
|
||
cLeftShiftAmount = 8 - cRightShiftAmount;
|
||
for (nLine1 = 0, nLine2 = nHeight - 1; nLine1 < nHalfHeight; nLine1++, nLine2--){
|
||
pLine1 = &pImg->bImageData[0] + (nLine1 * pImg->nBytesPerLine);
|
||
pLine2 = &pImg->bImageData[0] + (nLine2 * pImg->nBytesPerLine);
|
||
pLine2 += nWidthBytes - 1;
|
||
if (nLine1 == nLine2){
|
||
c3 = 0;
|
||
for (nLoop = (nWidthBytes - 1) / 2; nLoop; nLoop--){
|
||
c2 = c3;
|
||
c1 = cMirrorTable[*pLine2] << cLeftShiftAmount;
|
||
c1 |= cMirrorTable[*(pLine2 - 1)] >> cRightShiftAmount;
|
||
c2 |= cMirrorTable[*pLine1] << cLeftShiftAmount;
|
||
c3 = cMirrorTable[*pLine1] >> cRightShiftAmount;
|
||
*(pLine1++) = c1;
|
||
*(pLine2--) = c2;
|
||
}
|
||
if (nWidthBytes & 1){
|
||
c2 = c3;
|
||
c2 |= cMirrorTable[*pLine1] << cLeftShiftAmount;
|
||
*pLine2 = c2;
|
||
}else{
|
||
c2 = c3;
|
||
c1 = cMirrorTable[*pLine2] << cLeftShiftAmount;
|
||
c1 |= cMirrorTable[*(pLine2 - 1)] >> cRightShiftAmount;
|
||
c2 |= cMirrorTable[*pLine1] << cLeftShiftAmount;
|
||
*pLine1 = c1;
|
||
*pLine2 = c2;
|
||
}
|
||
}else{
|
||
c3 = 0;
|
||
for (nLoop = nWidthBytes - 1; nLoop; nLoop--){
|
||
c2 = c3;
|
||
c1 = cMirrorTable[*pLine2] << cLeftShiftAmount;
|
||
c1 |= cMirrorTable[*(pLine2 - 1)] >> cRightShiftAmount;
|
||
c2 |= cMirrorTable[*pLine1] << cLeftShiftAmount;
|
||
c3 = cMirrorTable[*pLine1] >> cRightShiftAmount;
|
||
*(pLine1++) = c1;
|
||
*(pLine2--) = c2;
|
||
}
|
||
c2 = c3;
|
||
c1 = cMirrorTable[*pLine2] << cLeftShiftAmount;
|
||
c2 |= cMirrorTable[*pLine1] << cLeftShiftAmount;
|
||
*pLine1 = c1;
|
||
*pLine2 = c2;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ITYPE_GRAY4:
|
||
case ITYPE_PAL4:
|
||
nWidthBytes = (nWidth + 1) / 2;
|
||
nHalfHeight = (nHeight + 1) / 2;
|
||
if (!(nWidth & 1)){
|
||
for (nLine1 = 0, nLine2 = nHeight - 1; nLine1 < nHalfHeight; nLine1++, nLine2--){
|
||
pLine1 = &pImg->bImageData[0] + (nLine1 * pImg->nBytesPerLine);
|
||
pLine2 = &pImg->bImageData[0] + (nLine2 * pImg->nBytesPerLine);
|
||
pLine2 += nWidthBytes - 1;
|
||
if (nLine1 == nLine2){
|
||
for (nLoop = nWidthBytes / 2; nLoop; nLoop--){
|
||
c1 = (*pLine1 >> 4) | (*pLine1 << 4);
|
||
*pLine1 = (*pLine2 >> 4) | (*pLine2 << 4);
|
||
*pLine2 = c1;
|
||
pLine1++;
|
||
pLine2--;
|
||
}
|
||
if (nWidthBytes & 1){
|
||
c1 = (*pLine1 >> 4) | (*pLine1 << 4);
|
||
*pLine2 = c1;
|
||
}
|
||
}else{
|
||
for (nLoop = nWidthBytes; nLoop; nLoop--){
|
||
c1 = (*pLine1 >> 4) | (*pLine1 << 4);
|
||
*pLine1 = (*pLine2 >> 4) | (*pLine2 << 4);
|
||
*pLine2 = c1;
|
||
pLine1++;
|
||
pLine2--;
|
||
}
|
||
}
|
||
}
|
||
}else{ // if ((nWidth & 1))
|
||
for (nLine1 = 0, nLine2 = nHeight - 1; nLine1 < nHalfHeight; nLine1++, nLine2--){
|
||
pLine1 = &pImg->bImageData[0] + (nLine1 * pImg->nBytesPerLine);
|
||
pLine2 = &pImg->bImageData[0] + (nLine2 * pImg->nBytesPerLine);
|
||
pLine2 += nWidthBytes - 1;
|
||
if (nLine1 == nLine2){
|
||
c3 = 0;
|
||
for (nLoop = nWidthBytes / 2; nLoop; nLoop--){
|
||
c2 = c3;
|
||
c1 = *pLine2 & 0xf0;
|
||
c1 |= *(pLine2 - 1) & 0x0f;
|
||
c2 |= *pLine1 & 0xf0;
|
||
c3 = *pLine1 & 0x0f;
|
||
*(pLine1++) = c1;
|
||
*(pLine2--) = c2;
|
||
}
|
||
if (nWidthBytes & 1){
|
||
c2 = c3;
|
||
c2 |= *pLine1 & 0xf0;
|
||
*(pLine2--) = c2;
|
||
}
|
||
}else{
|
||
c3 = 0;
|
||
for (nLoop = nWidthBytes & -2; nLoop; nLoop--){
|
||
c2 = c3;
|
||
c1 = *pLine2 & 0xf0;
|
||
c1 |= *(pLine2 - 1) & 0x0f;
|
||
c2 |= *pLine1 & 0xf0;
|
||
c3 = *pLine1 & 0x0f;
|
||
*(pLine1++) = c1;
|
||
*(pLine2--) = c2;
|
||
}
|
||
if (nWidthBytes & 1){
|
||
c2 = c3;
|
||
c1 = *pLine2 & 0xf0;
|
||
c2 |= *pLine1 & 0xf0;
|
||
*(pLine1) = c1;
|
||
*(pLine2) = c2;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ITYPE_GRAY7:
|
||
case ITYPE_GRAY8:
|
||
case ITYPE_COMPAL8:
|
||
case ITYPE_CUSPAL8:
|
||
nHalfHeight = (nHeight + 1) / 2;
|
||
nWidthBytes = nWidth;
|
||
for (nLine1 = 0, nLine2 = nHeight - 1; nLine1 < nHalfHeight; nLine1++, nLine2--){
|
||
pLine1 = &pImg->bImageData[0] + (nLine1 * pImg->nBytesPerLine);
|
||
pLine2 = &pImg->bImageData[0] + (nLine2 * pImg->nBytesPerLine);
|
||
pLine2 += nWidthBytes - 1;
|
||
if (nLine1 == nLine2){
|
||
nLoop = nWidth / 2;
|
||
}else{
|
||
nLoop = nWidth;
|
||
}
|
||
for (; nLoop; nLoop--){
|
||
c1 = *pLine1;
|
||
*pLine1 = *pLine2;
|
||
*pLine2 = c1;
|
||
pLine1++;
|
||
pLine2--;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ITYPE_RGB24:
|
||
case ITYPE_BGR24:
|
||
nHalfHeight = (nHeight + 1) / 2;
|
||
nWidthBytes = nWidth * 3;
|
||
for (nLine1 = 0, nLine2 = nHeight - 1; nLine1 < nHalfHeight; nLine1++, nLine2--){
|
||
pLine1 = &pImg->bImageData[0] + (nLine1 * pImg->nBytesPerLine);
|
||
pLine2 = &pImg->bImageData[0] + (nLine2 * pImg->nBytesPerLine);
|
||
pLine2 += nWidthBytes - 3;
|
||
if (nLine1 == nLine2){
|
||
nLoop = nWidth / 2;
|
||
}else{
|
||
nLoop = nWidth;
|
||
}
|
||
for (; nLoop; nLoop--){
|
||
c1 = *pLine1;
|
||
*(pLine1++) = *pLine2;
|
||
*(pLine2++) = c1;
|
||
c1 = *pLine1;
|
||
*(pLine1++) = *pLine2;
|
||
*(pLine2++) = c1;
|
||
c1 = *pLine1;
|
||
*(pLine1++) = *pLine2;
|
||
*(pLine2) = c1;
|
||
pLine2 -= 5;
|
||
}
|
||
}
|
||
break;
|
||
|
||
default:
|
||
Error(nStatus = DISPLAY_INTERNALDATAERROR);
|
||
goto Exit;
|
||
}
|
||
|
||
|
||
Exit:
|
||
return(nStatus);
|
||
}
|
||
//
|
||
/*****************************************************************************
|
||
|
||
FUNCTION: RotateRight90
|
||
|
||
PURPOSE: This function performs a 90 degree rotation of the data to the right.
|
||
This function assumes different source and dest image buffers.
|
||
|
||
INPUT: nWidth is the source width.
|
||
nHeight is the source height.
|
||
|
||
*****************************************************************************/
|
||
|
||
int WINAPI RotateRight90(PIMG pSourceImg, PIMG pDestImg,
|
||
int nWidth, int nHeight){
|
||
|
||
int nStatus = 0;
|
||
|
||
PBYTE pSourceLine;
|
||
PBYTE pDestLine1;
|
||
PBYTE pDestLine2;
|
||
int nDestLine;
|
||
int nSourceLine;
|
||
int nDestHeight;
|
||
int nDestPixel;
|
||
int nDestByte;
|
||
int nDestLineStart;
|
||
int nDestLineEnd;
|
||
int nSourceByteStart;
|
||
BYTE cBytes[8];
|
||
|
||
int nSourceLines;
|
||
int nDestLines;
|
||
int nLoop;
|
||
int nDestLine2;
|
||
BYTE cTemp;
|
||
|
||
int nSourceByte;
|
||
int nSourceByteAdd;
|
||
PBYTE pSourceByte;
|
||
PBYTE pDestByte;
|
||
int nLoopEnd;
|
||
|
||
|
||
switch (pSourceImg->nType){
|
||
case ITYPE_BI_LEVEL:
|
||
for (nSourceLine = pSourceImg->nHeight - 1; nSourceLine >= 0; nSourceLine -= 8){
|
||
nSourceLines = min(8, nSourceLine + 1);
|
||
nSourceByteAdd = (nSourceLines * pSourceImg->nBytesPerLine) + 1;
|
||
for (nSourceByte = 0; nSourceByte < pSourceImg->nBytesPerLine; nSourceByte++){
|
||
pSourceByte = &pSourceImg->bImageData[0] + (nSourceLine * pSourceImg->nBytesPerLine) + nSourceByte;
|
||
pDestByte = &pDestImg->bImageData[0]
|
||
+ ((nSourceByte << 3) * pDestImg->nBytesPerLine)
|
||
+ ((pSourceImg->nHeight - nSourceLine - 1) >> 3);
|
||
nDestLines = min(8, pSourceImg->nWidth - (nSourceByte << 3));
|
||
nLoopEnd = 8 - nSourceLines;
|
||
|
||
// Move Source bytes to cBytes.
|
||
for (nLoop = 7; nLoop >= nLoopEnd; nLoop--){
|
||
cBytes[nLoop] = *pSourceByte;
|
||
pSourceByte -= pSourceImg->nBytesPerLine;
|
||
}
|
||
pSourceByte += nSourceByteAdd;
|
||
|
||
// Rotates cBytes. // Data equals: A B x x x x x x
|
||
if ((cBytes[0] != 0xff && cBytes[0] != 0) // C D x x x x x x
|
||
|| (cBytes[0] != cBytes[1]) || (cBytes[0] != cBytes[2]) // x x x x x x x x
|
||
|| (cBytes[0] != cBytes[3]) || (cBytes[0] != cBytes[4]) // x x x x x x x x
|
||
|| (cBytes[0] != cBytes[5]) || (cBytes[0] != cBytes[6]) // x x x x x x x x
|
||
|| (cBytes[0] != cBytes[7])){ // x x x x x x x x
|
||
// x x x x x x x x
|
||
// x x x x x x x x
|
||
// Rotate the data 90 degrees.
|
||
// swap blocks of 1x1 bits:
|
||
cTemp = ((cBytes[0] >> 1) ^ cBytes[1]) & 0x55; // Data equals: D B x x x x x x
|
||
cBytes[1] ^= cTemp; // C A x x x x x x
|
||
cBytes[0] ^= cTemp << 1; // x x x x x x x x
|
||
// x x x x x x x x
|
||
cTemp = ((cBytes[2] >> 1) ^ cBytes[3]) & 0x55; // x x x x x x x x
|
||
cBytes[3] ^= cTemp; // x x x x x x x x
|
||
cBytes[2] ^= cTemp << 1; // x x x x x x x x
|
||
// x x x x x x x x
|
||
cTemp = ((cBytes[4] >> 1) ^ cBytes[5]) & 0x55;
|
||
cBytes[5] ^= cTemp;
|
||
cBytes[4] ^= cTemp << 1;
|
||
|
||
cTemp = ((cBytes[6] >> 1) ^ cBytes[7]) & 0x55;
|
||
cBytes[7] ^= cTemp;
|
||
cBytes[6] ^= cTemp << 1;
|
||
|
||
// swap blocks of 2x2 bits:
|
||
cTemp = ((cBytes[0] >> 2) ^ cBytes[2]) & 0x33; // Data equals: x x x x x x x x
|
||
cBytes[2] ^= cTemp; // x x x x x x x x
|
||
cBytes[0] ^= cTemp << 2; // x x D B x x x x
|
||
// x x C A x x x x
|
||
cTemp = ((cBytes[1] >> 2) ^ cBytes[3]) & 0x33; // x x x x x x x x
|
||
cBytes[3] ^= cTemp; // x x x x x x x x
|
||
cBytes[1] ^= cTemp << 2; // x x x x x x x x
|
||
// x x x x x x x x
|
||
cTemp = ((cBytes[4] >> 2) ^ cBytes[6]) & 0x33;
|
||
cBytes[6] ^= cTemp;
|
||
cBytes[4] ^= cTemp << 2;
|
||
|
||
cTemp = ((cBytes[5] >> 2) ^ cBytes[7]) & 0x33;
|
||
cBytes[7] ^= cTemp;
|
||
cBytes[5] ^= cTemp << 2;
|
||
|
||
// swap blocks of 4x4 bits:
|
||
cTemp = ((cBytes[0] >> 4) ^ cBytes[4]) & 0x0f; // Data equals: x x x x x x x x
|
||
cBytes[4] ^= cTemp; // x x x x x x x x
|
||
cBytes[0] ^= cTemp << 4; // x x x x x x x x
|
||
// x x x x x x x x
|
||
cTemp = ((cBytes[1] >> 4) ^ cBytes[5]) & 0x0f; // x x x x x x x x
|
||
cBytes[5] ^= cTemp; // x x x x x x x x
|
||
cBytes[1] ^= cTemp << 4; // x x x x x x D B
|
||
// x x x x x x C A
|
||
cTemp = ((cBytes[2] >> 4) ^ cBytes[6]) & 0x0f;
|
||
cBytes[6] ^= cTemp;
|
||
cBytes[2] ^= cTemp << 4;
|
||
|
||
cTemp = ((cBytes[3] >> 4) ^ cBytes[7]) & 0x0f;
|
||
cBytes[7] ^= cTemp;
|
||
cBytes[3] ^= cTemp << 4;
|
||
}
|
||
|
||
// Move cBytes to Dest.
|
||
nLoopEnd = 8 - nDestLines;
|
||
for (nLoop = 7; nLoop >= nLoopEnd; nLoop--){
|
||
*pDestByte = cBytes[nLoop];
|
||
pDestByte += pDestImg->nBytesPerLine;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ITYPE_GRAY4:
|
||
case ITYPE_PAL4:
|
||
nDestHeight = nWidth;
|
||
for (nDestLine = 0; nDestLine < nDestHeight; nDestLine += nDestLines){
|
||
nDestPixel = nHeight - 1;
|
||
nDestLineStart = nDestLine;
|
||
pDestLine1 = &pDestImg->bImageData[0] + (nDestLine * pDestImg->nBytesPerLine);
|
||
nDestLines = (int) nDestHeight - nDestLineStart;
|
||
if ((nDestLineStart & 1) || (nDestLines == 1)){
|
||
nDestLines = 1;
|
||
}else{
|
||
nDestLines &= -2;
|
||
}
|
||
nDestLineEnd = nDestLineStart + nDestLines;
|
||
nSourceByteStart = nDestLineStart >> 1;
|
||
for (nSourceLine = 0; nSourceLine < nHeight; nSourceLine++){
|
||
pSourceLine = &pSourceImg->bImageData[0] + (nSourceLine * pSourceImg->nBytesPerLine);
|
||
pSourceLine += nSourceByteStart;
|
||
nDestByte = nDestPixel >> 1;
|
||
pDestLine2 = pDestLine1 + nDestByte;
|
||
|
||
if (nDestLines == 1){
|
||
// Do only one pixel.
|
||
if (nDestLineStart & 1){
|
||
if (nDestPixel & 1){
|
||
*pDestLine2 = (*pDestLine2 & 0xf0) | (*pSourceLine & 0x0f);
|
||
}else{
|
||
*pDestLine2 = (*pDestLine2 & 0x0f) | ((*pSourceLine & 0x0f) << 4);
|
||
}
|
||
}else{
|
||
if (nDestPixel & 1){
|
||
*pDestLine2 = (*pDestLine2 & 0xf0) | ((*pSourceLine & 0xf0) >> 4);
|
||
}else{
|
||
*pDestLine2 = (*pDestLine2 & 0x0f) | ((*pSourceLine & 0xf0));
|
||
}
|
||
}
|
||
}else{
|
||
// Do a loop of pixels.
|
||
if (nDestPixel & 1){
|
||
for (nDestLine2 = nDestLineEnd - nDestLineStart; nDestLine2; nDestLine2 -= 2){
|
||
*pDestLine2 = (*pDestLine2 & 0xf0) | ((*pSourceLine & 0xf0) >> 4);
|
||
pDestLine2 += pDestImg->nBytesPerLine;
|
||
*pDestLine2 = (*pDestLine2 & 0xf0) | ((*(pSourceLine++) & 0x0f));
|
||
pDestLine2 += pDestImg->nBytesPerLine;
|
||
}
|
||
}else{
|
||
for (nDestLine2 = nDestLineEnd - nDestLineStart; nDestLine2; nDestLine2 -= 2){
|
||
*pDestLine2 = (*pDestLine2 & 0x0f) | ((*pSourceLine & 0xf0));
|
||
pDestLine2 += pDestImg->nBytesPerLine;
|
||
*pDestLine2 = (*pDestLine2 & 0x0f) | ((*(pSourceLine++) & 0x0f) << 4);
|
||
pDestLine2 += pDestImg->nBytesPerLine;
|
||
}
|
||
}
|
||
}
|
||
nDestPixel--;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ITYPE_GRAY7:
|
||
case ITYPE_GRAY8:
|
||
case ITYPE_COMPAL8:
|
||
case ITYPE_CUSPAL8:
|
||
pDestImg->nBytesPerLine = nHeight;
|
||
nDestHeight = nWidth;
|
||
for (nDestLine = 0; nDestLine < nDestHeight; nDestLine += nDestLines){
|
||
nDestPixel = nHeight - 1;
|
||
nDestLineStart = nDestLine;
|
||
pDestLine1 = &pDestImg->bImageData[0] + (nDestLine * pDestImg->nBytesPerLine);
|
||
nDestLines = (int) (nDestHeight - nDestLineStart);
|
||
nDestLineEnd = nDestLineStart + nDestLines;
|
||
nSourceByteStart = nDestLineStart;
|
||
for (nSourceLine = 0; nSourceLine < nHeight; nSourceLine++){
|
||
pSourceLine = &pSourceImg->bImageData[0] + (nSourceLine * pSourceImg->nBytesPerLine);
|
||
pSourceLine += nSourceByteStart;
|
||
nDestByte = nDestPixel;
|
||
pDestLine2 = pDestLine1 + nDestByte;
|
||
for (nDestLine2 = nDestLineEnd - nDestLineStart; nDestLine2; nDestLine2--){
|
||
*pDestLine2 = *(pSourceLine++);
|
||
pDestLine2 += pDestImg->nBytesPerLine;
|
||
}
|
||
nDestPixel--;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ITYPE_RGB24:
|
||
case ITYPE_BGR24:
|
||
pDestImg->nBytesPerLine = nHeight * 3;
|
||
nDestHeight = nWidth;
|
||
for (nDestLine = 0; nDestLine < nDestHeight; nDestLine += nDestLines){
|
||
nDestPixel = nHeight - 1;
|
||
nDestLineStart = nDestLine;
|
||
pDestLine1 = &pDestImg->bImageData[0] + (nDestLine * pDestImg->nBytesPerLine);
|
||
nDestLines = (int) (nDestHeight - nDestLineStart);
|
||
nDestLineEnd = nDestLineStart + nDestLines;
|
||
nSourceByteStart = nDestLineStart * 3;
|
||
for (nSourceLine = 0; nSourceLine < nHeight; nSourceLine++){
|
||
pSourceLine = &pSourceImg->bImageData[0] + (nSourceLine * pSourceImg->nBytesPerLine);
|
||
pSourceLine += nSourceByteStart;
|
||
nDestByte = nDestPixel * 3;
|
||
pDestLine2 = pDestLine1 + nDestByte;
|
||
for (nDestLine2 = nDestLineEnd - nDestLineStart; nDestLine2; nDestLine2--){
|
||
*(pDestLine2++) = *(pSourceLine++);
|
||
*(pDestLine2++) = *(pSourceLine++);
|
||
*pDestLine2 = *(pSourceLine++);
|
||
pDestLine2 += pDestImg->nBytesPerLine - 2;
|
||
}
|
||
nDestPixel--;
|
||
}
|
||
}
|
||
break;
|
||
|
||
default:
|
||
Error(nStatus = DISPLAY_INTERNALDATAERROR);
|
||
goto Exit;
|
||
}
|
||
|
||
|
||
Exit:
|
||
return(nStatus);
|
||
}
|
||
//
|
||
/*****************************************************************************
|
||
|
||
FUNCTION: RotateRight270
|
||
|
||
PURPOSE: This function performs a 270 degree rotation of the data to the right.
|
||
This function assumes different source and dest image buffers.
|
||
|
||
INPUT: nWidth is the source width.
|
||
nHeight is the source height.
|
||
|
||
*****************************************************************************/
|
||
|
||
int WINAPI RotateRight270(PIMG pSourceImg, PIMG pDestImg,
|
||
int nWidth, int nHeight){
|
||
|
||
int nStatus = 0;
|
||
|
||
PBYTE pSourceLine;
|
||
PBYTE pDestLine1;
|
||
PBYTE pDestLine2;
|
||
int nSourceLine;
|
||
int nDestHeight;
|
||
int nDestPixel;
|
||
int nDestByte;
|
||
int nDestLineStart;
|
||
int nDestLineEnd;
|
||
int nSourceByteStart;
|
||
BYTE cBytes[8];
|
||
|
||
int nSourceLines;
|
||
int nDestLine;
|
||
int nDestLines;
|
||
int nLoop;
|
||
|
||
int nDestLine2;
|
||
BYTE cTemp;
|
||
|
||
int nSourceByte;
|
||
int nSourceByteSub;
|
||
PBYTE pSourceByte;
|
||
PBYTE pDestByte;
|
||
|
||
|
||
switch (pSourceImg->nType){
|
||
case ITYPE_BI_LEVEL:
|
||
for (nSourceLine = 0; nSourceLine < pSourceImg->nHeight; nSourceLine += 8){
|
||
nSourceLines = min(8, pSourceImg->nHeight - nSourceLine);
|
||
nSourceByteSub = (nSourceLines * pSourceImg->nBytesPerLine) - 1;
|
||
for (nSourceByte = 0; nSourceByte < pSourceImg->nBytesPerLine; nSourceByte++){
|
||
pSourceByte = &pSourceImg->bImageData[0] + (nSourceLine * pSourceImg->nBytesPerLine) + nSourceByte;
|
||
nDestLines = min(8, pSourceImg->nWidth - (nSourceByte << 3));
|
||
pDestByte = &pDestImg->bImageData[0]
|
||
+ (((pDestImg->nHeight - (nSourceByte << 3)) - 1) * pDestImg->nBytesPerLine)
|
||
+ (nSourceLine >> 3);
|
||
|
||
// Move Source bytes to cBytes.
|
||
for (nLoop = 0; nLoop < nSourceLines; nLoop++){
|
||
cBytes[nLoop] = *pSourceByte;
|
||
pSourceByte += pSourceImg->nBytesPerLine;
|
||
}
|
||
pSourceByte -= nSourceByteSub;
|
||
|
||
// Rotates cBytes. // Data equals: A B x x x x x x
|
||
if ((cBytes[0] != 0xff && cBytes[0] != 0) // Data equals: x x x x x x B A
|
||
|| (cBytes[0] != cBytes[1]) || (cBytes[0] != cBytes[2]) // x x x x x x D C
|
||
|| (cBytes[0] != cBytes[3]) || (cBytes[0] != cBytes[4]) // x x x x x x x x
|
||
|| (cBytes[0] != cBytes[5]) || (cBytes[0] != cBytes[6]) // x x x x x x x x
|
||
|| (cBytes[0] != cBytes[7])){ // x x x x x x x x
|
||
// x x x x x x x x
|
||
// Rotate the data 270 degrees (left 90). // x x x x x x x x
|
||
// x x x x x x x x
|
||
|
||
// swap blocks of 1x1 bits:
|
||
cTemp = ((cBytes[0] << 1) ^ cBytes[1]) & 0xaa; // Data equals: x x x x x x B D
|
||
cBytes[1] ^= cTemp; // x x x x x x A C
|
||
cBytes[0] ^= cTemp >> 1; // x x x x x x x x
|
||
// x x x x x x x x
|
||
cTemp = ((cBytes[2] << 1) ^ cBytes[3]) & 0xaa; // x x x x x x x x
|
||
cBytes[3] ^= cTemp; // x x x x x x x x
|
||
cBytes[2] ^= cTemp >> 1; // x x x x x x x x
|
||
// x x x x x x x x
|
||
cTemp = ((cBytes[4] << 1) ^ cBytes[5]) & 0xaa;
|
||
cBytes[5] ^= cTemp;
|
||
cBytes[4] ^= cTemp >> 1;
|
||
|
||
cTemp = ((cBytes[6] << 1) ^ cBytes[7]) & 0xaa;
|
||
cBytes[7] ^= cTemp;
|
||
cBytes[6] ^= cTemp >> 1;
|
||
|
||
// swap blocks of 2x2 bits:
|
||
cTemp = ((cBytes[0] << 2) ^ cBytes[2]) & 0xcc; // Data equals: x x x x x x x x
|
||
cBytes[2] ^= cTemp; // x x x x x x x x
|
||
cBytes[0] ^= cTemp >> 2; // x x x x B D x x
|
||
// x x x x A C x x
|
||
cTemp = ((cBytes[1] << 2) ^ cBytes[3]) & 0xcc; // x x x x x x x x
|
||
cBytes[3] ^= cTemp; // x x x x x x x x
|
||
cBytes[1] ^= cTemp >> 2; // x x x x x x x x
|
||
// x x x x x x x x
|
||
cTemp = ((cBytes[4] << 2) ^ cBytes[6]) & 0xcc;
|
||
cBytes[6] ^= cTemp;
|
||
cBytes[4] ^= cTemp >> 2;
|
||
|
||
cTemp = ((cBytes[5] << 2) ^ cBytes[7]) & 0xcc;
|
||
cBytes[7] ^= cTemp;
|
||
cBytes[5] ^= cTemp >> 2;
|
||
|
||
// swap blocks of 4x4 bits:
|
||
cTemp = ((cBytes[0] << 4) ^ cBytes[4]) & 0xf0; // Data equals: x x x x x x x x
|
||
cBytes[4] ^= cTemp; // x x x x x x x x
|
||
cBytes[0] ^= cTemp >> 4; // x x x x x x x x
|
||
// x x x x x x x x
|
||
cTemp = ((cBytes[1] << 4) ^ cBytes[5]) & 0xf0; // x x x x x x x x
|
||
cBytes[5] ^= cTemp; // x x x x x x x x
|
||
cBytes[1] ^= cTemp >> 4; // B D x x x x x x
|
||
// A C x x x x x x
|
||
cTemp = ((cBytes[2] << 4) ^ cBytes[6]) & 0xf0;
|
||
cBytes[6] ^= cTemp;
|
||
cBytes[2] ^= cTemp >> 4;
|
||
|
||
cTemp = ((cBytes[3] << 4) ^ cBytes[7]) & 0xf0;
|
||
cBytes[7] ^= cTemp;
|
||
cBytes[3] ^= cTemp >> 4;
|
||
}
|
||
|
||
// Move cBytes to Dest.
|
||
for (nLoop = 0; nLoop < nDestLines; nLoop++){
|
||
*pDestByte = cBytes[nLoop];
|
||
pDestByte -= pDestImg->nBytesPerLine;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ITYPE_GRAY4:
|
||
case ITYPE_PAL4:
|
||
nDestHeight = nWidth;
|
||
for (nDestLine = (int) nDestHeight - 1; nDestLine >= 0; nDestLine -= nDestLines){
|
||
nDestPixel = 0;
|
||
nDestLineStart = nDestLine;
|
||
pDestLine1 = &pDestImg->bImageData[0] + (nDestLine * pDestImg->nBytesPerLine);
|
||
nDestLines = nDestLine + 1;
|
||
if (((nDestLineStart & 1) != ((nDestHeight - 1) & 1)) || (nDestLines == 1)){
|
||
nDestLines = 1;
|
||
}else{
|
||
nDestLines &= -2;
|
||
}
|
||
nDestLineEnd = nDestLineStart - nDestLines;
|
||
nSourceByteStart = (nDestHeight - 1) - nDestLineStart >> 1;
|
||
for (nSourceLine = 0; nSourceLine < nHeight; nSourceLine++){
|
||
pSourceLine = &pSourceImg->bImageData[0] + (nSourceLine * pSourceImg->nBytesPerLine);
|
||
pSourceLine += nSourceByteStart;
|
||
nDestByte = nDestPixel >> 1;
|
||
pDestLine2 = pDestLine1 + nDestByte;
|
||
|
||
if (nDestLines == 1){
|
||
// Do only one pixel.
|
||
if (nDestLineStart & 1){
|
||
if (nDestPixel & 1){
|
||
*pDestLine2 = (*pDestLine2 & 0xf0) | (*pSourceLine & 0x0f);
|
||
}else{
|
||
*pDestLine2 = (*pDestLine2 & 0x0f) | ((*pSourceLine & 0x0f) << 4);
|
||
}
|
||
}else{
|
||
if (nDestPixel & 1){
|
||
*pDestLine2 = (*pDestLine2 & 0xf0) | ((*pSourceLine & 0xf0) >> 4);
|
||
}else{
|
||
*pDestLine2 = (*pDestLine2 & 0x0f) | ((*pSourceLine & 0xf0));
|
||
}
|
||
}
|
||
}else{
|
||
// Do a loop of pixels.
|
||
if (nDestPixel & 1){
|
||
for (nDestLine2 = nDestLineStart - nDestLineEnd; nDestLine2; nDestLine2 -= 2){
|
||
*pDestLine2 = (*pDestLine2 & 0xf0) | ((*pSourceLine & 0xf0) >> 4);
|
||
pDestLine2 -= pDestImg->nBytesPerLine;
|
||
*pDestLine2 = (*pDestLine2 & 0xf0) | ((*(pSourceLine++) & 0x0f));
|
||
pDestLine2 -= pDestImg->nBytesPerLine;
|
||
}
|
||
}else{
|
||
for (nDestLine2 = nDestLineStart - nDestLineEnd; nDestLine2; nDestLine2 -= 2){
|
||
*pDestLine2 = (*pDestLine2 & 0x0f) | ((*pSourceLine & 0xf0));
|
||
pDestLine2 -= pDestImg->nBytesPerLine;
|
||
*pDestLine2 = (*pDestLine2 & 0x0f) | ((*(pSourceLine++) & 0x0f) << 4);
|
||
pDestLine2 -= pDestImg->nBytesPerLine;
|
||
}
|
||
}
|
||
}
|
||
nDestPixel++;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ITYPE_GRAY7:
|
||
case ITYPE_GRAY8:
|
||
case ITYPE_COMPAL8:
|
||
case ITYPE_CUSPAL8:
|
||
nDestHeight = nWidth;
|
||
for (nDestLine = (int) nDestHeight - 1; nDestLine >= 0; nDestLine -= nDestLines){
|
||
nDestPixel = 0;
|
||
nDestLineStart = nDestLine;
|
||
pDestLine1 = &pDestImg->bImageData[0] + (nDestLine * pDestImg->nBytesPerLine);
|
||
nDestLines = nDestLine + 1;
|
||
nDestLineEnd = nDestLineStart - nDestLines;
|
||
nSourceByteStart = (nDestHeight - 1) - nDestLineStart;
|
||
for (nSourceLine = 0; nSourceLine < nHeight; nSourceLine++){
|
||
pSourceLine = &pSourceImg->bImageData[0] + (nSourceLine * pSourceImg->nBytesPerLine);
|
||
pSourceLine += nSourceByteStart;
|
||
nDestByte = nDestPixel;
|
||
pDestLine2 = pDestLine1 + nDestByte;
|
||
for (nDestLine2 = nDestLineStart - nDestLineEnd; nDestLine2; nDestLine2--){
|
||
*pDestLine2 = *(pSourceLine++);
|
||
pDestLine2 -= pDestImg->nBytesPerLine;
|
||
}
|
||
nDestPixel++;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ITYPE_RGB24:
|
||
case ITYPE_BGR24:
|
||
nDestHeight = nWidth;
|
||
for (nDestLine = (int) nDestHeight - 1; nDestLine >= 0; nDestLine -= nDestLines){
|
||
nDestPixel = 0;
|
||
nDestLineStart = nDestLine;
|
||
pDestLine1 = &pDestImg->bImageData[0] + (nDestLine * pDestImg->nBytesPerLine);
|
||
nDestLines = nDestLine + 1;
|
||
nDestLineEnd = nDestLineStart - nDestLines;
|
||
nSourceByteStart = ((nDestHeight - 1) - nDestLineStart) * 3;
|
||
for (nSourceLine = 0; nSourceLine < nHeight; nSourceLine++){
|
||
pSourceLine = &pSourceImg->bImageData[0] + (nSourceLine * pSourceImg->nBytesPerLine);
|
||
pSourceLine += nSourceByteStart;
|
||
nDestByte = nDestPixel * 3;
|
||
pDestLine2 = pDestLine1 + nDestByte;
|
||
for (nDestLine2 = nDestLineStart - nDestLineEnd; nDestLine2; nDestLine2--){
|
||
*(pDestLine2++) = *(pSourceLine++);
|
||
*(pDestLine2++) = *(pSourceLine++);
|
||
*pDestLine2 = *(pSourceLine++);
|
||
pDestLine2 -= pDestImg->nBytesPerLine + 2;
|
||
}
|
||
nDestPixel++;
|
||
}
|
||
}
|
||
break;
|
||
|
||
default:
|
||
Error(nStatus = DISPLAY_INTERNALDATAERROR);
|
||
goto Exit;
|
||
}
|
||
|
||
|
||
Exit:
|
||
return(nStatus);
|
||
}
|