Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F123508
PNGLoader.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
PNGLoader.cpp
View Options
#include
<echo/Resource/PNGLoader.h>
#include
<echo/FileSystem/File.h>
#include
<iostream>
namespace
Echo
{
png_voidp
PngAlloc
(
png_structp
p
,
png_size_t
s
)
{
png_voidp
d
=
(
png_voidp
)
(
new
u8
[
s
]);
return
d
;
}
void
PngFree
(
png_structp
p
,
png_voidp
s
)
{
u8
*
u8p
=
reinterpret_cast
<
u8
*>
(
s
);
delete
[]
u8p
;
}
void
PngRead
(
png_structp
png_ptr
,
png_bytep
data
,
png_size_t
length
)
{
voidp
read_io_ptr
=
png_get_io_ptr
(
png_ptr
);
if
(
read_io_ptr
)
{
File
&
file
=
*
reinterpret_cast
<
File
*>
(
read_io_ptr
);
file
.
Read
(
data
,
1
,
(
u32
)
length
);
}
}
PNGLoader
::
PNGLoader
()
:
mWidth
(
0
),
mHeight
(
0
),
mFormat
(
Texture
::
Formats
::
UNKNOWN
),
mFile
(
0
)
{}
PNGLoader
::~
PNGLoader
()
{}
bool
PNGLoader
::
ProcessFile
(
File
&
textureFile
)
{
mFile
=
0
;
mCurrentRow
=
0
;
if
(
!
textureFile
.
IsOpen
())
{
std
::
cout
<<
"PNGLoader: Error input file is not open: "
<<
textureFile
.
GetFileName
()
<<
std
::
endl
;
return
false
;
}
std
::
cout
<<
"LoadPNG: "
<<
textureFile
.
GetFileName
()
<<
std
::
endl
;
u8
header
[
8
];
//Read first 8 bytes - if we couldn't then that really sucks
if
(
textureFile
.
Read
((
void
*
)
(
&
header
),
1
,
8
)
<
8
)
{
std
::
cout
<<
"PNGLoader: Failed to read in first 8 bytes: "
<<
textureFile
.
GetFileName
()
<<
std
::
endl
;
return
0
;
}
//Check the file is a PNG
bool
is_png
=
!
png_sig_cmp
(
header
,
0
,
8
);
if
(
!
is_png
)
{
std
::
cout
<<
"PNGLoader: File is not a PNG file: "
<<
textureFile
.
GetFileName
()
<<
std
::
endl
;
return
0
;
}
//Allocate memory for the png stuct and the info struct
mPNGPtr
=
png_create_read_struct_2
(
PNG_LIBPNG_VER_STRING
,
0
,
0
,
0
,
0
,
PngAlloc
,
PngFree
);
if
(
!
mPNGPtr
)
{
std
::
cout
<<
"PNGLoader: png_create_read_struct: "
<<
textureFile
.
GetFileName
()
<<
std
::
endl
;
return
0
;
}
mInfoPtr
=
png_create_info_struct
(
mPNGPtr
);
if
(
!
mInfoPtr
)
{
png_destroy_read_struct
(
&
mPNGPtr
,
(
png_infopp
)
0
,
(
png_infopp
)
0
);
std
::
cout
<<
"PNGLoader: png_create_info_struct:1: "
<<
textureFile
.
GetFileName
()
<<
std
::
endl
;
return
0
;
}
mEndInfo
=
png_create_info_struct
(
mPNGPtr
);
if
(
!
mEndInfo
)
{
png_destroy_read_struct
(
&
mPNGPtr
,
&
mInfoPtr
,
(
png_infopp
)
0
);
std
::
cout
<<
"PNGLoader: png_create_info_struct:2: "
<<
textureFile
.
GetFileName
()
<<
std
::
endl
;
return
0
;
}
mFile
=
&
textureFile
;
png_set_read_fn
(
mPNGPtr
,
mFile
,
PngRead
);
png_set_sig_bytes
(
mPNGPtr
,
8
);
png_read_png
(
mPNGPtr
,
mInfoPtr
,
PNG_TRANSFORM_IDENTITY
,
NULL
);
if
(
mInfoPtr
->
color_type
==
PNG_COLOR_TYPE_RGB_ALPHA
)
{
png_set_swap_alpha
(
mPNGPtr
);
}
//We only support 8 bit channels at the moment
if
(
mInfoPtr
->
bit_depth
==
16
)
{
png_set_strip_16
(
mPNGPtr
);
}
mRowPointers
=
png_get_rows
(
mPNGPtr
,
mInfoPtr
);
mWidth
=
png_get_image_width
(
mPNGPtr
,
mInfoPtr
);
mHeight
=
png_get_image_height
(
mPNGPtr
,
mInfoPtr
);
mBytesPerPixel
=
png_get_channels
(
mPNGPtr
,
mInfoPtr
);
switch
(
mBytesPerPixel
)
{
case
4
:
if
(
mInfoPtr
->
color_type
==
PNG_COLOR_TYPE_RGB_ALPHA
)
{
mFormat
=
Texture
::
Formats
::
R8G8B8A8
;
}
else
if
(
mInfoPtr
->
color_type
==
PNG_COLOR_TYPE_RGB
)
{
mFormat
=
Texture
::
Formats
::
R8G8B8X8
;
}
break
;
case
3
:
mFormat
=
Texture
::
Formats
::
R8G8B8
;
break
;
case
2
:
//PNG_COLOR_TYPE_GRAY_ALPHA
return
false
;
break
;
case
1
:
//PNG_COLOR_TYPE_GRAY
//PNG_COLOR_TYPE_PALETTE
return
false
;
break
;
}
return
true
;
}
std
::
string
PNGLoader
::
GetFileExtension
()
const
{
return
"png"
;
}
u32
PNGLoader
::
GetWidth
()
const
{
return
mWidth
;
}
u32
PNGLoader
::
GetHeight
()
const
{
return
mHeight
;
}
Texture
::
Format
PNGLoader
::
GetFormat
()
const
{
return
mFormat
;
}
bool
PNGLoader
::
GetLoadInverted
()
const
{
return
false
;
}
void
PNGLoader
::
ReadLine
(
u8
*
lineStart
,
u32
maxLength
)
{
if
(
!
mFile
)
{
return
;
}
u32
widthBytes
=
std
::
min
(
mWidth
*
mBytesPerPixel
,
maxLength
);
//copy the data
for
(
u32
c
=
0
;
c
<
widthBytes
;
++
c
)
{
lineStart
[
c
]
=
mRowPointers
[
mCurrentRow
][
c
];
}
mCurrentRow
++
;
}
void
PNGLoader
::
CleanUp
()
{
png_destroy_read_struct
(
&
mPNGPtr
,
&
mInfoPtr
,
(
png_infopp
)
0
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Thu, Jan 16, 2:00 AM (14 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71842
Default Alt Text
PNGLoader.cpp (4 KB)
Attached To
Mode
rEE Echo 3
Attached
Detach File
Event Timeline
Log In to Comment