- Removed DCanvas::Blit(), as it's no longer used.

- Added a function to create a texture from a stand-alone PNG file. The save/
  load menus now use this to get their thumbnails.


SVN r652 (trunk)
This commit is contained in:
Randy Heit 2007-12-28 01:54:14 +00:00
parent c911e995a9
commit 522e7fe07f
10 changed files with 88 additions and 161 deletions

View file

@ -1,3 +1,8 @@
December 27, 2007
- Removed DCanvas::Blit(), as it's no longer used.
- Added a function to create a texture from a stand-alone PNG file. The save/
load menus now use this to get their thumbnails.
December 27, 2007 (Changes by Graf Zahl)
- Fixed: DFrameBuffer::CopyPixelData copied data as RGBA instead of BGRA.
- Temporarily changed FPNGTexture and FDDSTexture to always create True Color

View file

@ -254,7 +254,7 @@ static FState *PlayerState;
static int PlayerTics;
static int PlayerRotation;
static DCanvas *SavePic;
static FTexture *SavePic;
static FBrokenLines *SaveComment;
static List SaveGames;
static FSaveGameNode *TopSaveGame;
@ -1039,7 +1039,7 @@ static void M_ExtractSaveData (const FSaveGameNode *node)
}
// Extract pic
SavePic = M_CreateCanvasFromPNG (png);
SavePic = FPNGTexture::CreateFromFile(png, node->Filename);
delete png;
}
@ -1099,8 +1099,11 @@ static void M_DrawSaveLoadCommon ()
M_DrawFrame (savepicLeft, savepicTop, savepicWidth, savepicHeight);
if (SavePic != NULL)
{
screen->Blit(savepicLeft, savepicTop, savepicWidth, savepicHeight,
SavePic, 0, 0, SavePic->GetWidth(), SavePic->GetHeight());
screen->DrawTexture(SavePic, savepicLeft, savepicTop,
DTA_DestWidth, savepicWidth,
DTA_DestHeight, savepicHeight,
DTA_Masked, false,
TAG_DONE);
}
else
{

View file

@ -30,9 +30,6 @@
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
** Currently, only 256-color paletted images are supported, as these are all
** that ZDoom needs to support. Expect this to become more complete in the
** future if I decide to add support for graphic patches stored as PNGs.
*/
// HEADER FILES ------------------------------------------------------------
@ -454,66 +451,6 @@ void M_FreePNG (PNGHandle *png)
delete png;
}
//==========================================================================
//
// M_CreateCanvasFromPNG
//
// Creates a simple canvas containing the contents of the PNG file's IDAT
// chunk(s). Only 8-bit images are supported.
//
//==========================================================================
DCanvas *M_CreateCanvasFromPNG (PNGHandle *png)
{
IHDR imageHeader;
DSimpleCanvas *canvas;
int width, height;
unsigned int chunklen;
if (M_FindPNGChunk (png, MAKE_ID('I','H','D','R')) == 0)
{
return NULL;
}
if (png->File->Read (&imageHeader, sizeof(IHDR)) != sizeof(IHDR))
{
return NULL;
}
if (imageHeader.Width == 0 ||
imageHeader.Height == 0 ||
// Only images that M_CreatePNG can write are supported
imageHeader.BitDepth != 8 ||
imageHeader.ColorType != 3 ||
imageHeader.Compression != 0 ||
imageHeader.Filter != 0 ||
imageHeader.Interlace != 0
)
{
return NULL;
}
chunklen = M_FindPNGChunk (png, MAKE_ID('I','D','A','T'));
if (chunklen == 0)
{
return NULL;
}
width = BigLong((int)imageHeader.Width);
height = BigLong((int)imageHeader.Height);
canvas = new DSimpleCanvas (width, height);
if (canvas == NULL)
{
return NULL;
}
canvas->Lock ();
bool success = M_ReadIDAT (png->File, canvas->GetBuffer(), width, height, canvas->GetPitch(), 8, 3, 0, chunklen);
canvas->Unlock ();
if (!success)
{
delete canvas;
canvas = NULL;
}
return canvas;
}
//==========================================================================
//
// ReadIDAT

View file

@ -100,10 +100,6 @@ unsigned int M_NextPNGChunk (PNGHandle *png, DWORD chunkID);
char *M_GetPNGText (PNGHandle *png, const char *keyword);
bool M_GetPNGText (PNGHandle *png, const char *keyword, char *buffer, size_t buffsize);
// Creates a simple canvas containing the contents of the PNG file's IDAT
// chunk(s). Only 8-bit images are supported.
DCanvas *M_CreateCanvasFromPNG (PNGHandle *png);
// The file must be positioned at the start of the first IDAT. It reads
// image data into the provided buffer. Returns true on success.
bool M_ReadIDAT (FileReader *file, BYTE *buffer, int width, int height, int pitch,

View file

@ -243,13 +243,15 @@ public:
int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y);
bool UseBasePalette();
protected:
static FTexture *CreateFromFile (PNGHandle *png, const FString &filename);
protected:
static bool Check (FileReader &file);
static FTexture *Create (FileReader &file, int lumpnum);
FPNGTexture (FileReader &lump, int lumpnum, int width, int height, BYTE bitdepth, BYTE colortype, BYTE interlace);
FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height, BYTE bitdepth, BYTE colortype, BYTE interlace);
int SourceLump;
FString SourceFile;
BYTE *Pixels;
Span **Spans;

View file

@ -101,13 +101,44 @@ FTexture *FPNGTexture::Create(FileReader & data, int lumpnum)
}
}
return new FPNGTexture (data, lumpnum, BigLong((int)width), BigLong((int)height),
return new FPNGTexture (data, lumpnum, FString(), BigLong((int)width), BigLong((int)height),
bitdepth, colortype, interlace);
}
FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, int width, int height,
FTexture *FPNGTexture::CreateFromFile(PNGHandle *png, const FString &filename)
{
DWORD width, height;
BYTE bitdepth, colortype, compression, filter, interlace;
if (M_FindPNGChunk(png, MAKE_ID('I','H','D','R')) == 0)
{
return NULL;
}
// Check the IHDR to make sure it's a type of PNG we support.
(*png->File) >> width >> height
>> bitdepth >> colortype >> compression >> filter >> interlace;
if (compression != 0 || filter != 0 || interlace > 1)
{
return NULL;
}
if (!((1 << colortype) & 0x5D))
{
return NULL;
}
if (!((1 << bitdepth) & 0x116))
{
return NULL;
}
return new FPNGTexture (*png->File, -1, filename, BigLong((int)width), BigLong((int)height),
bitdepth, colortype, interlace);
}
FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height,
BYTE depth, BYTE colortype, BYTE interlace)
: SourceLump(lumpnum), Pixels(0), Spans(0),
: SourceLump(lumpnum), SourceFile(filename), Pixels(0), Spans(0),
BitDepth(depth), ColorType(colortype), Interlace(interlace),
PaletteMap(0), PaletteSize(0), StartOfIDAT(0)
{
@ -318,7 +349,16 @@ const BYTE *FPNGTexture::GetPixels ()
void FPNGTexture::MakeTexture ()
{
FWadLump lump = Wads.OpenLumpNum (SourceLump);
FileReader *lump;
if (SourceLump >= 0)
{
lump = new FWadLump(Wads.OpenLumpNum(SourceLump));
}
else
{
lump = new FileReader(SourceFile.GetChars());
}
Pixels = new BYTE[Width*Height];
if (StartOfIDAT == 0)
@ -328,12 +368,12 @@ void FPNGTexture::MakeTexture ()
else
{
DWORD len, id;
lump.Seek (StartOfIDAT, SEEK_SET);
lump >> len >> id;
lump->Seek (StartOfIDAT, SEEK_SET);
(*lump) >> len >> id;
if (ColorType == 0 || ColorType == 3) /* Grayscale and paletted */
{
M_ReadIDAT (&lump, Pixels, Width, Height, Width, BitDepth, ColorType, Interlace, BigLong((unsigned int)len));
M_ReadIDAT (lump, Pixels, Width, Height, Width, BitDepth, ColorType, Interlace, BigLong((unsigned int)len));
if (Width == Height)
{
@ -369,7 +409,7 @@ void FPNGTexture::MakeTexture ()
BYTE *in, *out;
int x, y, pitch, backstep;
M_ReadIDAT (&lump, tempix, Width, Height, Width*bytesPerPixel, BitDepth, ColorType, Interlace, BigLong((unsigned int)len));
M_ReadIDAT (lump, tempix, Width, Height, Width*bytesPerPixel, BitDepth, ColorType, Interlace, BigLong((unsigned int)len));
in = tempix;
out = Pixels;
@ -437,6 +477,7 @@ void FPNGTexture::MakeTexture ()
delete[] tempix;
}
}
delete lump;
if (Spans == NULL)
{
Spans = CreateSpans (Pixels);
@ -454,50 +495,60 @@ int FPNGTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height
// Parse pre-IDAT chunks. I skip the CRCs. Is that bad?
PalEntry pe[256];
DWORD len, id;
FWadLump lump = Wads.OpenLumpNum (SourceLump);
FileReader *lump;
static char bpp[]={1, 0, 3, 1, 2, 0, 4};
int pixwidth = Width * bpp[ColorType];
int transpal=false;
lump.Seek (33, SEEK_SET);
if (SourceLump >= 0)
{
lump = new FWadLump(Wads.OpenLumpNum(SourceLump));
}
else
{
lump = new FileReader(SourceFile.GetChars());
}
lump->Seek (33, SEEK_SET);
for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // default to a gray map
lump >> len >> id;
(*lump) >> len >> id;
while (id != MAKE_ID('I','D','A','T') && id != MAKE_ID('I','E','N','D'))
{
len = BigLong((unsigned int)len);
switch (id)
{
default:
lump.Seek (len, SEEK_CUR);
lump->Seek (len, SEEK_CUR);
break;
case MAKE_ID('P','L','T','E'):
for(int i=0;i<PaletteSize;i++)
{
lump >> pe[i].r >> pe[i].g >> pe[i].b;
(*lump) >> pe[i].r >> pe[i].g >> pe[i].b;
}
break;
case MAKE_ID('t','R','N','S'):
for(DWORD i=0;i<len;i++)
{
lump >> pe[i].a;
(*lump) >> pe[i].a;
pe[i].a=255-pe[i].a; // use inverse alpha so the default palette can be used unchanged
if (pe[i].a!=0 && pe[i].a!=255) transpal = true;
}
break;
}
lump >> len >> len; // Skip CRC
(*lump) >> len >> len; // Skip CRC
id = MAKE_ID('I','E','N','D');
lump >> id;
(*lump) >> id;
}
BYTE * Pixels = new BYTE[pixwidth * Height];
lump.Seek (StartOfIDAT, SEEK_SET);
lump >> len >> id;
M_ReadIDAT (&lump, Pixels, Width, Height, pixwidth, BitDepth, ColorType, Interlace, BigLong((unsigned int)len));
lump->Seek (StartOfIDAT, SEEK_SET);
(*lump) >> len >> id;
M_ReadIDAT (lump, Pixels, Width, Height, pixwidth, BitDepth, ColorType, Interlace, BigLong((unsigned int)len));
delete lump;
switch (ColorType)
{

View file

@ -562,68 +562,6 @@ static void BuildTransTable (const PalEntry *palette)
Col2RGB8_LessPrecision[64] = Col2RGB8[64];
}
void DCanvas::Blit (int destx, int desty, int destwidth, int destheight, DCanvas *src,
int srcx, int srcy, int srcwidth, int srcheight)
{
fixed_t fracxstep, fracystep;
fixed_t fracx, fracy;
int x, y;
bool lockthis, locksrc;
if ( (lockthis = (LockCount == 0)) )
{
if (Lock ())
{ // Surface was lost, so nothing to blit
Unlock ();
return;
}
}
if ( (locksrc = (src->LockCount == 0)) )
{
src->Lock ();
}
fracy = srcy << FRACBITS;
fracystep = (srcheight << FRACBITS) / destheight;
fracxstep = (srcwidth << FRACBITS) / destwidth;
BYTE *destline, *srcline;
BYTE *destbuffer = Buffer;
BYTE *srcbuffer = src->Buffer;
if (fracxstep == FRACUNIT)
{
for (y = desty; y < desty + destheight; y++, fracy += fracystep)
{
memcpy (destbuffer + y * Pitch + destx,
srcbuffer + (fracy >> FRACBITS) * src->Pitch + srcx,
destwidth);
}
}
else
{
for (y = desty; y < desty + destheight; y++, fracy += fracystep)
{
srcline = srcbuffer + (fracy >> FRACBITS) * src->Pitch + srcx;
destline = destbuffer + y * Pitch + destx;
for (x = fracx = 0; x < destwidth; x++, fracx += fracxstep)
{
destline[x] = srcline[fracx >> FRACBITS];
}
}
}
if (lockthis)
{
Unlock ();
}
if (locksrc)
{
src->Unlock ();
}
}
void DCanvas::CalcGamma (float gamma, BYTE gammalookup[256])
{
// I found this formula on the web at

View file

@ -146,9 +146,6 @@ public:
virtual void Unlock () = 0;
virtual bool IsLocked () { return Buffer != NULL; } // Returns true if the surface is locked
// Copy blocks from one canvas to another
virtual void Blit (int destx, int desty, int destwidth, int destheight, DCanvas *src, int srcx, int srcy, int srcwidth, int srcheight);
// Draw a linear block of pixels into the canvas
virtual void DrawBlock (int x, int y, int width, int height, const BYTE *src) const;

View file

@ -95,7 +95,7 @@ void BloodCrypt (void *data, int key, int len);
// A very loose reference to a lump on disk. This is really just a wrapper
// around the main wad's FILE object with a different length recorded. Since
// the two lumps from the same wad share the same FILE, you cannot read from
// two lumps from the same wad share the same FILE, you cannot read from
// both of them independantly.
class FWadLump : public FileReader
{

View file

@ -320,6 +320,7 @@ bool D3DFB::CreateResources ()
}
if (FAILED(D3DDevice->CreatePixelShader (GammaFixerDef, &GammaFixerShader)))
{
Printf ("Windowed mode gamma will not work.\n");
GammaFixerShader = NULL;
}
CurPixelShader = NULL;
@ -1371,9 +1372,6 @@ bool D3DFB::Begin2D()
Update();
In2D = 2;
// Set default state for 2D rendering.
SetAlphaBlend(TRUE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
return true;
}