 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
Ferrero
Joined: 19 Dec 2005 Posts: 15
|
Posted: Fri Jan 06, 2006 2:03 am Post subject: [Code]Loading a PCX file |
|
|
Hi everybody, I've developped a little class to load and blit a PCX file.
The interest of this :
- You can have an image larger than 512x512 pixels.
Another thing :
- As a PCX file is an indexed color image file (compressed), finally you have an array of byte which you can fill with a picture editor. So in this file you can store a map to have a 2D tiled game, and this file is compressed.
Here's the class :
| Code: |
-------------------------------------------------------------------------------
--
-- Author : Lepecq Michael (Ferrero)
-- Version : 1.0
-- Copyright : 2005 - 2006
--
-------------------------------------------------------------------------------
--
-- This object is designed to manage PCX Files
--
-- Methods :
--
-- Public :
--
-- load : load a PCX file
--
-- Private :
--
-- decodeHeader : Decode the header of a pcx file
-- loadPalette256 : Load the 256 colors palette of the file
-- readPixel : Read the Pixel of the file
--
-- Properties :
--
--
-- Public :
--
-- BitsPerPixel : The number of bits per pixel per plane in the image data.
-- MaxNumberOfColors : The maximum number of colors allowed in the file
-- Palette : Hold the different colors of the image
-- ImageWidth : Width of the image in pixel
-- ImageHeight : Hieght of the image in scanlines
-- BlitTo : Blit the PCX to an image
--
-- Private :
--
-- XStart : Left of the image
-- YStart : Top of the image
-- XEnd : Right of the image
-- YEnd : Bottom of the image
-- NumBitPlanes : Number of bit planes
-- BytesPerLine : Length of an unencoded line in a plane
-- ScanLineLength : Length of an unencoded line
-- Pixel : Array of pixels [y][x]
-- LinePaddingSize : Padding of a scanline (end of a scan line)
--
-------------------------------------------------------------------------------
clsPCX =
{
BitsPerPixel = 0,
XStart = 0,
YStart = 0,
XEnd = 0,
YEnd = 0,
NumBitPlanes = 0,
MaxNumberOfColors = 0,
BytesPerLine = 0,
Palette = {},
ImageWidth = 0,
ImageHeight = 0,
Pixel = {},
LinePaddingSize = 0
}
function clsPCX:new()
mtbPCX = {};
setmetatable(mtbPCX, self);
self.__index = self;
return mtbPCX;
end
function clsPCX:load(filename)
local file = assert(io.open(filename, "rb"));
local header = file:read(128);
-- Decoding the header
assert(self:decodeHeader(header));
-- Reading the Pixel
assert(self:readPixel(file));
-- Loading the palette
if (self.MaxNumberOfColors == 256) then
assert(self:loadPalette256(file));
else
return nil, "This palette mode is not supported yet";
end
-- Closing the file
assert(file:close());
return true
end
function clsPCX:decodeHeader(header)
if (string.byte(header, 1) == 10) then
self.BitsPerPixel = string.byte(header, 4);
self.XStart = string.byte(header, 6) * 256 + string.byte(header, 5);
self.YStart = string.byte(header, 8) * 256 + string.byte(header, 7);
self.XEnd = string.byte(header, 10) * 256 + string.byte(header, 9);
self.YEnd = string.byte(header, 12) * 256 + string.byte(header, 11);
self.NumBitPlanes = string.byte(header, 66);
self.BytesPerLine = string.byte(header, 68) * 256 + string.byte(header, 67);
self.MaxNumberOfColors = (2^self.BitsPerPixel * self.NumBitPlanes);
self.ScanLineLength = self.NumBitPlanes * self.BytesPerLine;
self.ImageWidth = self.XEnd - self.XStart + 1;
self.ImageHeight = self.YEnd - self.YStart + 1;
self.LinePaddingSize = ((self.BytesPerLine * self.NumBitPlanes) * (8 / self.BitsPerPixel)) - ((self.XEnd - self.XStart) + 1);
else
return nil, "This is not a valid PCX file";
end
return true;
end
function clsPCX:loadPalette256(file)
file:seek("end", -769);
local CheckByte = file:read(1);
local Palette = file:read(768);
local j=0;
local i=0;
if (string.byte(CheckByte) == 12) then
for i=1,768,3 do
self.Palette[j] = Color.new(string.byte(Palette, i), string.byte(Palette, i+1), string.byte(Palette, i + 2));
j = j + 1;
end
else
return nil, "256 colors palette not found:"..CheckByte;
end
return true;
end
function clsPCX:readPixel(file)
local y;
local runcount;
local byte;
local x;
local i;
for y=0,self.ImageHeight-1 do
self.Pixel[y] = {};
x = 0;
while (x<self.ScanLineLength) do
byte = string.byte(file:read(1));
if (byte >= 192) then
runcount = byte - 192;
byte = string.byte(file:read(1));
for i=0, runcount do
self.Pixel[y][x+i] = byte;
end
x = x + runcount;
else
self.Pixel[y][x] = byte;
x = x + 1;
end
end
end
return true;
end
function clsPCX:blitTo(image_x, image_y, image, rect_left, rect_top, rect_right, rect_bottom)
local line;
local y;
local x;
local color;
local ymin;
local ymax;
local xmin;
local xmax;
-- Computing the clipping
if image_y < 0 then
rect_top = rect_top - image_y;
ymin = 0;
else
ymin = image_y;
end
if image_x < 0 then
rect_left = rect_left - image_x;
xmin = 0;
else
xmin = image_x;
end
if ymin + (rect_bottom - rect_top) >= image:height() then
ymax = image:height() - 1;
else
ymax = ymin + (rect_bottom - rect_top);
end
if xmin + (rect_right - rect_left) >= image:width() then
xmax = image:width() - 1;
else
xmax = xmin + (rect_right - rect_left);
end
if (xmax + rect_left >= self.ImageWidth) then
xmax = self.ImageWidth - rect_left - 1;
end
if (ymax + rect_top >= self.ImageHeight) then
ymax = self.ImageHeight - rect_top - 1;
end
-- Drawing the image
for y=ymin,ymax do
line = rect_top + y - image_y;
for x=xmin, xmax do
color = self.Palette[self.Pixel[line][rect_left + x - image_x]];
image:pixel(x, y, color);
end
end
return true;
end |
And how to use it :
| Code: |
map=clsPCX:new();
assert(map:load("..\\maps\\map1560.pcx"));
screen:clear();
map:blitTo(0,0,screen,0,0,480,272);
screen.flip();
control = Controls.read();
while control:start() == false do
control = Controls.read();
screen.waitVblankStart();
end
|
|
|
| Back to top |
|
 |
LuMo
Joined: 21 Aug 2005 Posts: 410 Location: Austria
|
Posted: Fri Jan 06, 2006 3:43 am Post subject: |
|
|
how fast is it?
did you test it running compared to normal blit?
greets
lumo
PS: interesting! _________________ "Good artists copy, great artists steal."
Pablo Picasso
go2lumo.com |
|
| Back to top |
|
 |
Ferrero
Joined: 19 Dec 2005 Posts: 15
|
Posted: Fri Jan 06, 2006 6:17 pm Post subject: |
|
|
The blit is quite slow,
I use it like this :
First, I blit it to an 512*512 image and I use this image to blit onto the screen.
And when the image does not contain the needed datas I blit a portion of the image on itself to keep the datas I need, and then blit the portion of the PCX I need. |
|
| Back to top |
|
 |
LuMo
Joined: 21 Aug 2005 Posts: 410 Location: Austria
|
Posted: Fri Jan 06, 2006 8:16 pm Post subject: |
|
|
only blit the really needed data, otherwise it really slows down...
480x272px more is never needed
greets
lumo _________________ "Good artists copy, great artists steal."
Pablo Picasso
go2lumo.com |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|