Files
core/ASCImageStudio3/ASCImageCompose3/SmartImage.h

183 lines
3.3 KiB
C++

#pragma once
#include "../Common/ImageColors.h"
#include "../Common/ImageCore.h"
class SmartImage
{
ImageStudio::Core::MediaData m_oMediaData;
public:
int Width;
int Height;
BYTE* Pixels;
BYTE* Backup;
public:
SmartImage()
{
Width = 0;
Height = 0;
Pixels = 0;
Backup = 0;
}
~SmartImage()
{
Destroy();
}
void Destroy()
{
m_oMediaData.Destroy();
if (Backup)
{
delete[] Backup;
Backup = 0;
}
Width = 0;
Height = 0;
Pixels = 0;
}
BOOL IsValid()
{
if (Width < 1 || Height < 1 || !Pixels)
return FALSE;
return TRUE;
}
BOOL BackupImage()
{
// check for valid image
if (!IsValid())
return FALSE;
// delete existing backup (if any)
if (Backup)
{
delete[] Backup;
Backup = 0;
}
// allocate memory for backup
Backup = new BYTE[4*Width*Height];
// check for valid image
if (!Backup)
return FALSE;
// save memory
memcpy(Backup, Pixels, 4*Width*Height);
// all ok
return TRUE;
}
BOOL CopyFrom(SmartImage& image)
{
// check for valid image
if (!image.IsValid())
return FALSE;
// check for the same sizes
if (Width != image.Width || Height != image.Height)
return FALSE;
// copy memory context
memcpy(Pixels, image.Pixels, 4*Width*Height);
// backup image (if necessary)
if (image.Backup)
{
return BackupImage();
}
// all ok
return TRUE;
}
ImageStudio::Core::MediaData& GetMediaData()
{
return m_oMediaData;
}
BOOL Extract(SAFEARRAY** Array, BOOL BackupIt = FALSE)
{
// destroy existing image
Destroy();
int Channels = 0;
Pixels = ImageStudioUtils::ExtractImage(Array, Width, Height, Channels);
if (!Pixels)
return FALSE;
// backup image (if necessary)
if (BackupIt)
return BackupImage();
// all ok
return IsValid();
}
BOOL Extract(IUnknown** pMediaData, BOOL BackupIt = FALSE)
{
if (NULL == pMediaData)
return FALSE;
Destroy();
if (!m_oMediaData.Create(*pMediaData, FALSE) || !m_oMediaData.IsValidBGRA())
return FALSE;
Pixels = m_oMediaData.GetBuffer();
Width = m_oMediaData.GetWidth();
Height = m_oMediaData.GetHeight();
// backup image (if necessary)
if (BackupIt)
return BackupImage();
return IsValid();
}
BYTE GetBilinear(double x, double y, int c, BYTE def)
{
double e = 1; // 0.0001
if (x < -e || y < -e || x > Width - 1 + e || y > Height - 1 + e)
return def;
if (x < 0) x = 0;
if (y < 0) y = 0;
if (x > Width - 1) x = Width - 1;
if (y > Height - 1) y = Height - 1;
int nX = (int)floor(x);
int nY = (int)floor(y);
// no interpolation: return Pixels[c + 4*(nX + nY*Width)];
if (nX == Width - 1)
nX = Width - 2;
if (nY == Height - 1)
nY = Height - 2;
double dX = x - nX;
double dY = y - nY;
int nIndex = c + 4*(nX + nY*Width);
BYTE byLT = Pixels[nIndex];
BYTE byRT = Pixels[nIndex + 4];
BYTE byRB = Pixels[nIndex + 4 + 4*Width];
BYTE byLB = Pixels[nIndex + 4*Width];
return (BYTE)
(
(1 - dX)*(1 - dY)*byLT + // Left - Top corner
( dX)*(1 - dY)*byRT + // Right - Top corner
( dX)*( dY)*byRB + // Right - Bottom corner
(1 - dX)*( dY)*byLB // Left - Bottom corner
);
}
};