#include "stdafx.h"
#include "Imagr.h"
#include "ImagrDoc.h"
#include "ImagrView.h"
//-----------------------------------------------------------------------
// This function handles rotations of the active bitmap.
//-----------------------------------------------------------------------
void CImagrView::Rotate(int opt)
{
CImagrDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc) return;
CMyImage *image = &pDoc->m_image;
if (!pDoc->ChkDIB()) return;
int *p, *q, *q0, *buf; /* Image ptrs */
unsigned long i, j, nx, ny;
nx = image->GetWidth();
ny = image->GetHeight();
unsigned long n = nx * ny;
p = (int *) image->GetBits(); // Ptr to bitmap
CString hint;
if (nx != ny) {
//sprintf_s(hint, sizeof(hint), "Rotate(%d) %d x %d", opt,
// image->GetWidth(), image->GetHeight());
hint.Format("Rotate(%d) %d x %d", opt,
image->GetWidth(), image->GetHeight());
}
else {
hint.Format("Rotate(%d)", opt);
}
switch (opt) {
case -90:
case +90:
// Allocate n sized array for temp storage
if (!(buf = (int *)malloc(n * sizeof(int)))) {
fMessageBox("Error - " __FUNCTION__, MB_ICONERROR,
"malloc() error for size: %d", n);
return;
}
memcpy_s(buf, n * sizeof(int), p, n * sizeof(int)); // Copy bitmap to buf
pDoc->OnDo(hint); // Pass hint for UnDo
if (nx != ny) {
i = nx; // Swap nx, ny
nx = ny;
ny = i;
// Start a new CImage with new dimensions
image->Destroy();
if (!image->Create(nx, -(int)ny, 32, 0)) {
fMessageBox("Error - " __FUNCTION__, MB_ICONERROR,
"Failed bitmap .Create()");
return;
}
// Set view for new dimensions
SetScrollSizes(MM_TEXT, CSize(nx, ny)); // Set to image size
GetParentFrame()->RecalcLayout(); // Ensure view window set for ResizeParentToFit()
ResizeParentToFit(false); // Size window to image size
//UpdateStatusbar();
}
BeginWaitCursor();
switch (opt) {
case -90:
for (j = 0, q0 = buf + ny-1; j < ny; j++, q0--) {
for (i = 0, q = q0; i < nx; i++, p++, q += ny) {
*p = *q;
}
}
break;
case +90:
for (j = 0, q0 = buf + ny*(nx-1); j < ny; j++, q0++) {
for (i = 0, q = q0; i < nx; i++, p++, q -= ny) {
*p = *q;
}
}
break;
}
EndWaitCursor();
free(buf);
break;
case -1: // Mirror rotation (in place)
pDoc->OnDo(hint); // Pass hint for UnDo
BeginWaitCursor();
int t, *p0;
for (j = 0, p0 = p, q0 = p + nx-1; j < ny; j++, p0 += nx, q0 += nx) {
for (i = 0, p = p0, q = q0; i < nx/2; i++, p++, --q) {
t = *p;
*p = *q;
*q = t;
}
}
EndWaitCursor();
break;
}
pDoc->SetModifiedFlag(true);
Invalidate();
}