You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/CryEngine/RenderDll/Common/Textures/Image/CImage.h

233 lines
6.6 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_IMAGE_CIMAGE_H
#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_IMAGE_CIMAGE_H
#pragma once
#include "IImage.h"
#define SH_LITTLE_ENDIAN
// The mask for extracting just R/G/B from an ulong or SRGBPixel
#ifdef SH_BIG_ENDIAN
# define RGB_MASK 0xffffff00
#else
# define RGB_MASK 0x00ffffff
#endif
/**
* An RGB pixel.
*/
struct SRGBPixel
{
uint8 blue, green, red, alpha;
SRGBPixel() /* : red(0), green(0), blue(0), alpha(255) {} */
{
*(unsigned int*)this = (unsigned int)~RGB_MASK;
}
SRGBPixel(int r, int g, int b)
: red(r)
, green(g)
, blue(b)
, alpha(255) {}
//bool eq (const SRGBPixel& p) const { return ((*(unsigned int *)this) & RGB_MASK) == ((*(unsigned int *)&p) & RGB_MASK); }
};
class CImageFile;
namespace DDSSplitted {
struct DDSDesc;
}
struct IImageFileStreamCallback
{
virtual void OnImageFileStreamComplete(CImageFile* pImFile) = 0;
protected:
virtual ~IImageFileStreamCallback() {}
};
struct SImageFileStreamState
{
enum
{
MaxStreams = 64
};
struct Request
{
void* pOut;
size_t nOffs;
size_t nSize;
};
void RaiseComplete(CImageFile* pFile)
{
if (m_pCallback)
{
m_pCallback->OnImageFileStreamComplete(pFile);
m_pCallback = NULL;
}
}
volatile int m_nPending;
uint32 m_nFlags;
IImageFileStreamCallback* m_pCallback;
IReadStreamPtr m_pStreams[MaxStreams];
Request m_requests[MaxStreams];
};
class CImageFile
: public IImageFile
, public IStreamCallback
{
private:
CImageFile(const CImageFile&);
CImageFile& operator = (const CImageFile&);
private:
volatile int m_nRefCount;
bool m_bIsImageMissing = false;
protected:
int m_Width; // Width of image.
int m_Height; // Height of image.
int m_Depth; // Depth of image.
int m_Sides; // Depth of image.
int m_ImgSize;
int m_NumMips;
int m_NumPersistentMips;
int m_Flags; // e.g. FIM_GREYSCALE|FIM_ALPHA
int m_nStartSeek;
float m_fAvgBrightness;
ColorF m_cMinColor;
ColorF m_cMaxColor;
union // The image data.
{
byte* m_pByteImage[6];
SRGBPixel* m_pPixImage[6];
};
EImFileError m_eError; // Last error code.
string m_FileName; // file name
ETEX_Format m_eFormat;
ETEX_TileMode m_eTileMode;
SImageFileStreamState* m_pStreamState;
protected:
CImageFile(const string& filename);
void mfSet_error(const EImFileError error, const char* detail = NULL);
void mfSet_dimensions(const int w, const int h);
public:
virtual ~CImageFile();
virtual int AddRef()
{
return CryInterlockedIncrement(&m_nRefCount);
}
virtual int Release()
{
int nRef = CryInterlockedDecrement(&m_nRefCount);
if (nRef == 0)
{
delete this;
}
else if (nRef < 0)
{
assert(0);
CryFatalError("Deleting Reference Counted Object Twice");
}
return nRef;
}
const string& mfGet_filename() const { return m_FileName; }
void mfChange_Filename(const string& newName)
{
// used when one texture (such as the 'missing texture') is masquerading as another one until reloaded.
m_FileName = newName;
}
int mfGet_width() const { return m_Width; }
int mfGet_height() const { return m_Height; }
int mfGet_depth() const { return m_Depth; }
int mfGet_NumSides() const { return m_Sides; }
bool mfGet_IsImageMissing() const
{
return m_bIsImageMissing;
}
EImFileError mfGet_error() const { return m_eError; }
byte* mfGet_image(const int nSide);
void mfFree_image(const int nSide);
bool mfIs_image(const int nSide) const { return m_pByteImage[nSide] != NULL; }
int mfGet_StartSeek() const { return m_nStartSeek; }
void mfSet_ImageSize(int Size) { m_ImgSize = Size; }
int mfGet_ImageSize() const { return m_ImgSize; }
ETEX_Format mfGetFormat() const { return m_eFormat; }
ETEX_TileMode mfGetTileMode() const { return m_eTileMode; }
void mfSet_numMips(const int num) { m_NumMips = num; }
int mfGet_numMips() const { return m_NumMips; }
void mfSet_numPersistentMips(const int num) { m_NumPersistentMips = num; }
int mfGet_numPersistentMips() const { return m_NumPersistentMips; }
void mfSet_avgBrightness(const float avgBrightness) { m_fAvgBrightness = avgBrightness; }
float mfGet_avgBrightness() const { return m_fAvgBrightness; }
void mfSet_minColor(const ColorF& minColor) { m_cMinColor = minColor; }
const ColorF& mfGet_minColor() const { return m_cMinColor; }
void mfSet_maxColor(const ColorF& maxColor) { m_cMaxColor = maxColor; }
const ColorF& mfGet_maxColor() const { return m_cMaxColor; }
void mfSet_Flags(const int Flags) { m_Flags |= Flags; }
int mfGet_Flags() const { return m_Flags; }
void mfAbortStreaming();
virtual DDSSplitted::DDSDesc mfGet_DDSDesc() const;
public:
/**
* Load a image from memory by assigning the image byte data directly without copying.
*
* @param filename The image filename
* @param data byte image data, caller owns this data and is responsible for cleanup.
* @param width image width
* @param height image height
* @param format image format (eTF_R8G8B8A8, eTF_PVRTC4 etc.)
* @param numMips number of mip maps
* @param nFlags image flags (e.g. FIM_GREYSCALE|FIM_ALPHA)
*/
static _smart_ptr<CImageFile> mfLoad_mem(const string& filename, void* data, int width, int height, ETEX_Format format, int numMips, const uint32 nFlags);
static _smart_ptr<CImageFile> mfLoad_file(const string& filename, const uint32 nFlags);
static _smart_ptr<CImageFile> mfStream_File(const string& filename, const uint32 nFlags, IImageFileStreamCallback* pCallback);
};
#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_IMAGE_CIMAGE_H