473,399 Members | 4,254 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

Howto Extract PNG from binary file @ 0x80?

Hi,

As a newbie to the language, I have no idea where to start..please bare
with me..

The simcity 4 savegame file has a png image stored at the hex location
0x80. What I want to extract it and create a file with the .png
extension in that directory.

Can somebody explain with a snippet of code how I would accomplish
this? I've looked around but the information is too vague and I don't
know how to start.

-thanks in advance

Jul 18 '05 #1
7 6817
"flamesrock" <mi******@telus.net> wrote:
As a newbie to the language, I have no idea where to start..please bare
with me..

The simcity 4 savegame file has a png image stored at the hex location
0x80. What I want to extract it and create a file with the .png
extension in that directory.

Can somebody explain with a snippet of code how I would accomplish
this? I've looked around but the information is too vague and I don't
know how to start.


there are *many* ways to ignore the first 128 bytes when you read a file
(you can seek to the right location, you can read 128 bytes and throw them
a way, you can read one byte 128 times and throw each one of them away,
you can read all data and remove the first 128 bytes, etc).

here's a snippet that understands the structure of the PNG, and stops copying
when it reaches the end of the PNG:

import struct

def pngcopy(infile, outfile):

# copy header
header = infile.read(8)
if header != "\211PNG\r\n\032\n":
raise IOError("not a valid PNG file")
outfile.write(header)

# copy chunks, until IEND
while 1:
chunk = infile.read(8)
size, cid = struct.unpack("!l4s", chunk)
outfile.write(chunk)
outfile.write(infile.read(size))
outfile.write(infile.read(4)) # checksum
if cid == "IEND":
break

to use this, open the input file (the simcity file) and the output file
(the png file you want to create) in binary mode, use the "seek"
method to move to the right place in the simcity file, and call "pngcopy"
with the two file objects.

infile = open("mysimcityfile", "rb")
infile.seek(0x80)
outfile = open("myimage.png", "wb")
pngcopy(infile, outfile)
outfile.close()
infile.close()

hope this helps!

</F>

Jul 18 '05 #2
On Sat, 11 Dec 2004 10:53:19 +0100, Fredrik Lundh wrote:
"flamesrock" <mi******@telus.net> wrote:
As a newbie to the language, I have no idea where to start..please bare
with me..

The simcity 4 savegame file has a png image stored at the hex location
0x80. What I want to extract it and create a file with the .png
extension in that directory.

Can somebody explain with a snippet of code how I would accomplish
this? I've looked around but the information is too vague and I don't
know how to start.


there are *many* ways to ignore the first 128 bytes when you read a file
(you can seek to the right location, you can read 128 bytes and throw them
a way, you can read one byte 128 times and throw each one of them away,
you can read all data and remove the first 128 bytes, etc).

here's a snippet that understands the structure of the PNG, and stops copying
when it reaches the end of the PNG:

import struct

def pngcopy(infile, outfile):

# copy header
header = infile.read(8)
if header != "\211PNG\r\n\032\n":
raise IOError("not a valid PNG file")
outfile.write(header)

# copy chunks, until IEND
while 1:
chunk = infile.read(8)
size, cid = struct.unpack("!l4s", chunk)
outfile.write(chunk)
outfile.write(infile.read(size))
outfile.write(infile.read(4)) # checksum
if cid == "IEND":
break

to use this, open the input file (the simcity file) and the output file
(the png file you want to create) in binary mode, use the "seek"
method to move to the right place in the simcity file, and call "pngcopy"
with the two file objects.

infile = open("mysimcityfile", "rb")
infile.seek(0x80)
outfile = open("myimage.png", "wb")
pngcopy(infile, outfile)
outfile.close()
infile.close()

hope this helps!

</F>


Thanks! And what a pleasant surprise! I just noticed you authored the book
I've been studying - Python Standard Library. Its awesome ;)

Oh- and Sorry for the late response. Google groups wouldn't allow me to
followup. I'm using pan now.

Jul 18 '05 #3
Well, I've been working on getting this code to work, and I think I
*almost* have it...

First, according to ghex, it seems the PNG starts at the 97th byte of
the file
infile = open("mysimcityfile.sc4", "rb")
infile.seek(97)
print (infile.read(4))
output:
flamesrock@flames:~/score$ python sc4png.py
PNG
(for 5 bytes it outputs an extra line, and for 6- 
(the biology symbol for a male)) So to debug further, I took out the
exception and modified the code like this:

#import struct
#
#def pngcopy(infile, outfile):
#
# # copy header
# header = infile.read(4)
# #if header != "\211PNG\r\n\032\n":
# # raise IOError("not a valid PNG file")
# outfile.write(header)
#
# # copy chunks, until IEND
# while 1:
# chunk = infile.read(8)
# size, cid = struct.unpack("!l4s", chunk)
# outfile.write(chunk)
# outfile.write(infile.read(size))
# outfile.write(infile.read(4)) # checksum
# if cid == "IEND":
# break
#
#
#infile = open("mysimcityfile.sc4", "rb")
#infile.seek(97)
#outfile = open("myimage.png", "wb")
#pngcopy(infile, outfile)
#outfile.close()
#infile.close()

returning the following output:
flamesrock@flames:~/score$ python sc4png.py
Traceback (most recent call last):
File "sc4png.py", line 26, in ?
pngcopy(infile, outfile)
File "sc4png.py", line 14, in pngcopy
size, cid = struct.unpack("!l4s", chunk)
struct.error: unpack str size does not match format

Any ideas on how to fix it? If I understand this page correctly,
http://www.python.org/doc/current/li...le-struct.html
a png is basically a 'big endian string of 14 chars'? Changing it to
!14b" gives a"ValueError: unpack tuple of wrong size"
-thanks in advance for any help

Jul 18 '05 #4
flamesrock wrote:

[snip]
flamesrock@flames:~/score$ python sc4png.py
Traceback (most recent call last):
File "sc4png.py", line 26, in ?
pngcopy(infile, outfile)
File "sc4png.py", line 14, in pngcopy
size, cid = struct.unpack("!l4s", chunk)
struct.error: unpack str size does not match format

Any ideas on how to fix it? If I understand this page correctly,
http://www.python.org/doc/current/li...le-struct.html
a png is basically a 'big endian string of 14 chars'? Changing it to
!14b" gives a"ValueError: unpack tuple of wrong size"
-thanks in advance for any help


No, the chunk header is specified as "!l4s" where that second character
is a lower-case "L", not one "1". The struct is "a 4-byte long integer
in big-endian format followed by a 4-character string".

I think the error you are running into is that the chunk you are passing
in does not have 8 characters. Is your input truncated somehow?

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
Jul 18 '05 #5
Hmm...I'm not sure exactly. One of the things I've read is that
sometimes stuff is compressed in a savegame file, but I don't know why
they'd do that with a png..

I have some code that does the exact same thing in php only I don't
understand php syntax and how they did it. Does it give any clues as to
whether its truncated or not? (assuming you understand php)
http://simcitysphere.com/sc4Extractor.php.txt (original, only extracts
png)
http://simcitysphere.com/regionFileDecode_inc.php.txt (extracts png and
some fancy stuff like image map position)

-thanks

Jul 18 '05 #6
Don't seek to position 97. Seek to 96. You're off by one. That's why
there's the test for the header (which you removed).

Files (and Python strings for that matter) are 0-indexed. The first
character is 0, the second 1, and so on. If you want the 97th character,
you have to seek to position 96.

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
Jul 18 '05 #7
omg, it works!! thankyou!!!!!
and thankyou again, Frederick for the original code!

I've discovered a weird thing when changing header = infile.read(8) to
header = infile.read(4):
For some reason, the extracted png image is the exact same size as the
savegame archive (10.1 megs.) When reading 8bytes, its closer to
~200kb. Any clue as to why that is?

-thanks

#import struct
#
#def pngcopy(infile, outfile):
#
# # copy header
# header = infile.read(8)
# if header != "\211PNG\r\n\032\n":
# raise IOError("not a valid PNG file")
# outfile.write(header)
#
# # copy chunks, until IEND
# while 1:
# chunk = infile.read(8)
# size, cid = struct.unpack("!l4s", chunk)
# outfile.write(chunk)
# outfile.write(infile.read(size))
# outfile.write(infile.read(4)) # checksum
# if cid == "IEND":
# break
#
#
#infile = open("mysimcityfile.sc4", "rb")
#infile.seek(96)
###print (infile.read(4))
#outfile = open("myimage.png", "wb")
#pngcopy(infile, outfile)
#outfile.close()
#infile.close()

(http://simcitysphere.com/peachville.sc4)

Jul 18 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: Kevin Knorpp | last post by:
Hello. I need to be able to extract the data from the attached file (or any file in the same format) so that I can work with the data in PHP. I'm fairly comfortable with using PHP with...
5
by: Senger | last post by:
Hi. How I can Include or Extract bites in a binary file?? I'm tring to use a fopen method, but without success. Do you have any idea??? Thanks!!!
18
by: David Buchan | last post by:
Hi guys, This may be a dumb question; I'm just getting into C language here. I wrote a program to unpack a binary file and write out the contents to a new file as a list of unsigned integers....
0
by: ATS | last post by:
HOWTO Extract resources from .NEt User Control and save them to file. Please help, I have a .NET C# User Control (derrived from System.Windows.Forms.UserControl), and I want to embed into it...
2
by: Jack | last post by:
Hi I am having a little trouble trying to read a binary file, I would like to write an ascii to Metastock converter in python but am not having a lot of success. The file formats are ...
8
by: Shalaka Joshi | last post by:
Hi, I have binary file say, "test.bin". I write "FF" in the file and expect my code to read 255 for me. char * lbuf; int lreadBytes ; long lData; FILE *pFile = fopen ("c:\\testbin","rb");
9
by: lokeshrajoria | last post by:
hello everybody, i need some help in binary file handling in perl. can anybody give me some information about binary file. actully i am reading data from some text file and extracting some usefull...
8
by: Bryan.Fodness | last post by:
Hello, I am having trouble writing the code to read a binary string. I would like to extract the values for use in a calculation. Any help would be great. Here is my function that takes in...
6
by: BlackLibrary | last post by:
The title probably tells it all. I'm a VB6 going to C# and trying to take a task I can do easily in VB6 and do it in C#.NET. I can really use some help and any pointers you can share. Below is...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.