Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
69 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

Contents
 Organizing Projects
 Creating Libraries
 Runtime Log Files
 Protecting
 Image Data

 Introduction
 to Scripting

 The String Table

 Printable version
 Discuss this article
 in the forums



The Series
 Beginning Windows
 Programming

 Using Resources
 in Win32 Programs

 Tracking Your
 Window/Using GDI

 Introduction
 to DirectX

 Palettes and Pixels
 in DirectDraw

 Bitmapped Graphics
 in DirectDraw

 Developing the
 Game Structure

 Basic Tile Engines
 Adding Characters
 Tips and Tricks

Protecting Image Data

Suppose you've got a great new game project going, but it needs a ton of images -- say 15MB worth. How can you make it so that the end user can't change your images to whatever they want? You could include all your images as resources... but then your .EXE would be enormous, and wasting a lot of memory space. The only other option is to include them as external files, but then people can just open them up in any image editor and change them, right? Well, there are a few things you can do with this.

The first one is obvious: make up an image file format. This can be a good bit of work, though, since you have to come up with a fully descriptive header that won't be so easy for people to figure out at a glance, then decide on some method of filtering and compression to store the image data. There are plenty of compression libraries out there that you can use, like zlib, but there's one other way to go.

The other thing you can do is to either expand an existing file format, or assign meaning to some bytes in an image header that are either reserved or not currently used. As a couple examples, the .BMP file header has two reserved fields that must be set to zero for a standard bitmap, and the .PNG file structure is based on "chunks" and is expandable, so you can add your own fields. Now, what good is this? The idea is to use these extra storage locations to hold some sort of image "key" which is calculated in a manner known only to you, based on the image data. Ideally, you should have it set up so that if the image data changes, the key will also change. That way, when you load an image from your game, you can look at the image data and calculate the key value. If the calculated key is different from the one stored in the image file, you know the user's been tampering with your image, and you can spit out an angry error message.

The only question is, how do you decide on a method for generating a key? Let's try a few things. How about using the width plus the height of the image? That's no good, because if people were to change the image, chances are that they would not alter the dimensions, only the contents. So, how about the image file size in bytes? That's OK for some things, but for uncompressed file formats like .BMP, the file size won't change unless the color depth or image dimensions change, neither of which is likely. A better idea would be to do something like this. While you're displaying the image, you have to go through every pixel anyway... so while you're doing that, you might as well add up the total values for red, green, and blue as you go. Or just one of the three would be OK. Let's say you do it for green. At the end, you'll have a very large number which is the combined intensity for green from every pixel in the image. Now just because you can, raise that value to the 10/9 power, multiply by 3, and add 1331. Why? Because nobody would guess to do that particular operation.

Key choices like that are much better because they will almost certainly be affected no matter what the user does to the image. There are a few things to watch out for, though. For instance, in my last example, a very large image might give you an overflow when you calculated the key. You can combat that by making sure the original key never gets too high. For example, as you're adding up the green values, you can do the addition modulo 216 so that when you're done, you have a lot of room to work with. If you're working with an integer key, then you need to make sure you don't narrow the range too much. For example, if your key involves something like taking a fifth root of your initial calculation, then a very high key value can change quite a bit, and still have the fifth root evaluate the same when you're working with integers. Floating-point keys don't have that fault.

Other possible choices for keys would be things like how much each pixel differs from the one immediately to the right of it, in terms of any one of the color channels. Calculate all those values and add them up. For compressed image file formats like .PNG, you have even more choices. You can look at how each row compresses, and form a key based on the ratio of the compression of each row to the row beneath it. In any case, you can simply store the key within the image header, or make up a new section of the image file in which to store data. You can even generate multiple keys to make it that much harder to figure out. Users will probably be able to see your image files if you take this approach, since you're still using a standard image file format, but it's not easy to change them without the game program realizing it.

If you're interested in working with other image file formats, check out wotsit.org for as much information as you could ever want on more file formats than you ever knew existed. :) I'd highly recommend looking into using .PNG for games. It supports high-color modes, unlike .GIF, and uses a lossless compression algorithm, unlike .JPG. In fact, .PNG's compression is so good that for artistic-type images (as opposed to photorealistic ones), .PNG will often compress as good as, if not a good deal better than .JPG will. The .JPG format wins hands-down for photorealistic images, but that's generally not what you'll be using for games, at least not at this point, so it's better to have something using lossless compression.





Next : Introduction to Scripting