How does hiding files in jpeg file works - compression

I was reading an article explaining How to Hide Files in JPEG Pictures.
I am wondering how it's possible for a file to contain both jpeg data and a rar file without any visible distortion either to the image or to the compressed file.
My guess is that it has something to do with how either the compressed file or the jpeg file is represented in binary form, but I have no idea how this works.
Can someone elaborate on that?

All that is doing is adding the archive to the end of a JPEG stream. You then hope your JPEG decoder will not read past the EOI marker, find data there, and say something is wrong.
A JPEG image is a stream of bytes starting with an SOI marker and ending with an EOI marker.
ZIP and RAR are streams of byte. A ZIP stream starts with 50 4B. A RAR stream starts with 52 61 72 21 1A 07.
The method described in the link above takes a binary copy of (multiple) a JPEG stream and appends a ZIP or RAR stream to it.
The RAR/ZIP decoders scan the stream until they find the signature for RAR or ZIP (ignoring the JPEG stream).

This answer does not address the exact case in the link you gave, but it provides another way of hiding data:
It would also be theoretically possible to hide a file within the JPEG picture itself, but you would need a complicated program to write the encoded data and then read it again.
Basically, a JPEG photograph contains a lot of information which, if it changed, would not be noticeable to the human eye. Imagine you have a photo of a person in a blue shirt. If you zoom in on that shirt you will see that it is not an even blue colour, but made up of a multitude of flecks of colour, most of which are a bluish tone (but some could be other colours as well). You could easily change some of those flecks to a slightly different tone and it would make no obvious visible difference to the picture.
A clever program could embed a code in the photo by subtly changing pixels to a pattern that represents data. A very simple example: if the "hue" (i.e. colour tone) is represented by a number between 0 and 255, pixels of an even hue could represent a "0" bit and pixels of odd hue a "1" bit. It would be hard for the human eye to detect such a difference in the picture.
It is an old idea and this article discusses how much data could be hidden in this way: High capacity data hiding in JPEG-compressed images (2004)

In general, hiding a file within another file is a practice known as Steganography. The method described in the link you provided simply concatenates the .rar to the end of the .jpg using the + operator, taking advantage of the different headers of each file type. #user3344003 does an excellent job of explaining why this works in his/her answer. This doesn't distort the image because the image data is left unaltered.
Another common method of hiding a file within an image is to use the Least Significant Bit (LSB) of each byte. The way this is performed is to replace every 8th bit in the image's bitstream with the next bit of the file you wish to hide. This works because the image's colors can be distorted slightly without being easily perceived by the human eye. In this approach, the image's size on disk will not grow as it would in the method from your link. This makes evidence of the hidden file much harder to detect. For a detailed look at this and other Steganographic methods, see this paper by Bret Dunbar.

there is a simple algorithm that I implemented it with matlab. if you division your image to 8 bit. the most significant bit has most valuable information and you can remove bit 0 and bit 1 without any change on original image. so you can put your file instead of bit 0 and 1. I saw this algorithm in anil.k.jain book.

Related

Writing image data to the disk as fast as possible

I am writing an application that generates a huge amount of images. Each frame is 1280x800 pixels large and has 1 byte per pixel for color information (greyscale). Each of the frames must be written to disk.
Currently I simply dump the raw pixel data to a binary file on the disk. The file can then be viewed with a special viewer I also created.
This is a very unsatisfactory solution, since the images can't be viewed/processed directly. They always have to run through my custom viewer/converter.
Is there an image format I could use to write my images to disk that:
Is fast to be written (no compression etc.)
Does not increase the final file's size much
Supports dumping my raw pixel buffer in there (no alignemnt changes etc.)
Can be read by common applications (Windows Explorer, Paint, Photoshop etc.)
I already tried to use .png, but the file generation takes much too long due to the compression.
Have a look at the binary Portable GrayMap (P5) format. It consists of an extremely simple header followed by raw image data (without any alignment requirements), and is widely supported by image viewers.
Both bmp and tiff can be used to save raw data. Bmp has the oddity of having image upside down, unless height is negative. And tiff has plenty of encoding options. It should be anyway feasible to reverse engineer the format to be used as a template, where the image data is copy pasted. So no need to use a library: just a header, image data and an optional footer concatenated.

Can't find logic behind png file sizes

I'm saving a large number of small png files for use in a game on a phone, so space is at a premium.
I'm trying to figure out the logic behind the file sizes so I can save things most efficiently, but even after using pngcrush the sizes are totally inconsistent.
I saved a 1x1 image and it takes 3kb. I have another 23x21 image which takes only 2kb. I have two images which are almost the same size, but one takes 6kb and the other takes 13kb. I doubled the image height and copied one image into the empty space of the other and saved that. The combined image is only 11kb!
Why is a 1x1 image larger than a 23x21 image? Why can I combine a 13kb image and a 6kb image and get an 11kb image?
Here are the images I'm talking about (there's a 1x1 pixel in between the 1st and second images. It's difficult to see, so I'll just give the URL: http://g42.org/temp/png/1x1.png):
example http://g42.org/temp/png/hat.png
example http://g42.org/temp/png/1x1.png
example http://g42.org/temp/png/helmet1.png
example http://g42.org/temp/png/helmet2.png
example http://g42.org/temp/png/helmet1_2.png
It's not a compression thing, the problem with the 1x1 image is that it has metadata (added by Photoshop, it seems), a color profile (iCCP chunk). If you look inside the binary, its' the data between the strings "iCCP" and "IDAT", it could be removed and you get a 69 bytes file.
If you reopen and save the file most image viewers (xnview), or use pngcrush, you can strip that chunk. : See it here : http://i.stack.imgur.com/fmOdA.png
And regarding the helmet images: besides other informational chunks (imageReady ads some informational text, as you can see), the difference is due to different formats: the two-helmets is a paletted image (8bits per pixel), the single helmet is a RGB with alpha (32bits per pixel)
PNG compression is based on the same algorithm as zlib and is highly sensitive to the data that is being compressed so you won't see a consistent relationship between image size and file size. In the case of the combined image, it is still bigger than the smaller image and given the similarity of the two halves of the image, the compressor was probably able to reuse a lot of the Huffman tree. I don't know enough about the algorithm to say for certain how it ended up smaller than the other half.
As long as you are not seeing oddities like the 1x1 image, which you seem to have figured out in the comments, I don't think this will make a lot of sense without extensive study of image compression.
There is a great utility called pngcrush
http://pmt.sourceforge.net/pngcrush/
Compressing to PNG is a rather difficult task - there are lost of assumptions and strategies to try - do we create a palette, or are we better off without it?
PNGcrush essentially bruteforces 100+ different compression strategies, while at the same time trimming useless tags and sections.
PNG has several sub-formats: 24-bit with or without alpha, 8-bit (includes alpha), grayscale, etc. which use different amount of bytes per pixel and have different "compressibility".
Plus PNG supports several compression tricks (filters and gzip settings) which affect how well image data is compressed.
On top of that PNG can contain metadata, which sometimes can be pretty large, like some embedded color profiles.
ImageAlpha converts images to the most space-efficient PNG8+alpha variant.
ImageOptim removes junk metadata and finds best compression parameters.
With a combination of those two your images can be reduced by 30-50%.

How did this person code "Hello World" with Microsoft Paint?

I have just seen this within the past few days and cannot figure out how it works. The video I talk about is here:
It's the top rated answer from this Stack Overflow question: Why was this program rejected by three compilers?
How is this bitmap able to show a C++ program for "Hello World"?
A BMP (DIB) image is composed by a header followed by uncompressed1 color data (for 24 bpp images it's 3 bytes per pixel, stored in reverse row order and with 4 bytes row stride).
The bytes for color data are used to represent colors (i.e. none of them are "mandated" by the file format2, they all come from the color of each pixel), and there's a perfect 1:1 correspondence between pixel colors and bytes written in the file; thus, using perfectly chosen colors you can actually write anything you want in the file (with the exception of the header).
When you open the generated file in notepad, the color data will be shown as text; you can still clearly see from the header (the part from BM to the start of the text), that is mandated by the file format.
In my opinion this video was done this way: first the author calculated the size needed for the bitmap, and created a DIB file of the correct size filled with a color that expands to a simple pattern (e.g. all bytes 65 => 'A'); then replaced such pattern with the "payload" code, as shown in the video.
Notice however that it's not impossible to hand-craft the whole thing with notepad - with the color chooser dialog, an ASCII table and a basic knowledge of the DIB format it can be done, but it would be much much slower and error-prone.
More info about the DIB format
There are RLE compressed DIBs, but in this case uncompressed bitmaps are used (and they are used really rarely anyway).
With the exception of the stride, that was avoided using rows multiple of 4 bytes.
I assume you're referring to the answer to one of the April Fools questions.
My guess is that each pixel has a binary representation for it. And that each character in source code has a binary representation for it.
The person who created the program must have worked out the color for each pixel that'd have a binary representation that'd correspond to each character.
From a theoretical computer science point of view, it would be interesting to ask, if every program can be written in such a way so that, viewed as a bitmap, you actually saw the source code that does the same thing. If you are seriously interested in such results, read e.g. about the Kleene's fixed point theorem.
Program-as-an-image can also be viewed as a form of code obfuscation. Not that it were particularly practical...

Does anyone know of a program/method to compress just certain parts of a PNG image w/o slicing it?

Please help! Thanks in advance.
Update: Sorry for the delayed response, but if it is helpful to provide more context here, since I'm not sure what alternative question I should be asking.
I have an image for a website home page that is 300px x 300px. That image has several distinct regions, including two that have graphical copy on top of the regions.
I have compressed the image down as much as I can without compromising the appearance of that text, and those critical regions of the image.
I tried slicing the less critical regions of the image and saving those at lower compressions in order to get the total kbs down, but as gregmac posted, the sections don't look right when rejoined.
I was wondering if there was a piece of software out there, or manual solution for identifying critical regions of an image to "compress less" and could compress other parts of the image more in order to get the file size down, while keeping those elements in the graphic that need to be high resolution sharper.
You cannot - you can only compress an entire PNG file.
You don't need to (I cannot think of a single case where compressing a specific portion of a PNG file would be useful)
Dividing the image in to multiple parts ("slicing") is the only way to compress different portions of a image file, although I'd even recommend again using different compression levels in one "sliced image", as differing compression artefacts joining up will probably look odd
Regarding your update,
identifying critical regions of an image to "compress less" and could compress other parts of the image more in order to get the file size down
This is inherently what image compression does - if there's a bit empty area it will be compressed to a few bytes (using RLE for example), but if there's a very detailed region it will have more bytes "spent" on it.
The problem sounds like the image is too big (in terms of file-size), have you tried other image formats, mainly GIF or JPEG (or the other PNG format, PNG-8 or PNG-24)?
I have compressed the image down as much as I can without compromising the appearance of that text
Perhaps the text could be overlaid using CSS, rather than embedded in the image? Might not be practical, but it would allow you to compress the background more (if the background image is a photo, JPEG might work best, since you no longer have to worry about the text)
Other than that, I'm out of ideas. Is the 300*300px PNG really too big?
It sounds like you are compressing parts of your image using something like JPEG and then pasting those compressed images onto a PNG combined with other images, and the entire PNG is sent to the browser where you split them up.
The problem with this is that the more you compress your JPEG parts the more decompression artifacts you will get. Then when you put these low quality images onto the PNG, which uses deflate compression, you will actually end up increasing the file size because it won't be able to compress well.
So if you are keen on keeping PNG as your file format the best solution would be to not compress the parts using JPEG which you paste onto your PNG - keep everything as sharp as possible.
PNG compresses each row separately unless you have used a "predictor" in the compression.
So it's best to keep your PNG as wide as possible with similar images next to each other horizontally rather than under each other vertically.
Perhaps upload an example of the images you're working with?

Extracting basic info from animation file

I'm writing an application that handles metadata for images and all kinds of animations, so I'm looking for a way to find basic info about an animation file, e.g:
length (in minutes/seconds/frames)
aspect ratio of pixels
resolution of individual frames
framerate
Right now, I let my program execute
mplayer -identify animfile.avi
and parse its console output, which contains all the info I need in a machine-readable format. This works fine, but I know that some potential users of the program prefer vlc as a media player so I'd rather avoid having a hard dependence on mplayer being installed.
I've tried
vlc -vv animfile.avi
which prints an ungodly amount of junk on the console, sometimes containing the stuff I'm looking for. The formatting and what data gets printed seems to vary depending on the file format of the animation though.
Is there an easier way to extract basic info from an animation of any format one has a decoder for (especially the length of the animation) using vlc or som other app/library that is usually available on a typical Linux installation?
Edit: I'd rather use another program to do the dirty work, as this is supposed to work for any animation format, e.g avi, mpg, mov, wmv, vob etc.
Edit: totem-video-indexer seems more promising, and was also included with the standard installation. Enough codecs to make it useful, however, was not. That could be fixed by installing the "non-free-codecs" package from medibuntu.
The output of totem-video-indexer is very easy to parse:
TOTEM_INFO_DURATION=5217
TOTEM_INFO_HAS_VIDEO=True
TOTEM_INFO_VIDEO_WIDTH=720
TOTEM_INFO_VIDEO_HEIGHT=480
TOTEM_INFO_VIDEO_CODEC=XVID MPEG-4
TOTEM_INFO_FPS=30
TOTEM_INFO_HAS_AUDIO=True
TOTEM_INFO_AUDIO_BITRATE=50
TOTEM_INFO_AUDIO_CODEC=MPEG 1 Audio, Layer 3 (MP3)
TOTEM_INFO_AUDIO_SAMPLE_RATE=48000
TOTEM_INFO_AUDIO_CHANNELS=Stereo
mediainfo is a pretty useful program. It's LGPL, and is just a frontend for libmediainfo, which should be exactly what you want.
http://mediainfo.sf.net/
This is a little more difficult question than you may realize. The AVI file format grew over time, and often has nearly the same information in two or three different places. In some cases those are really supposed to agree (but sometimes don't) and in other cases they're subtly different.
Just for example, you asked about the width and height. There are actually four different width/height specs for a single frame: the screen width/height, the pixel width/height (from which you derive the pixel aspect ratio), the active width/height, and the compressed width/height. The frame width and height is the (theoretical) size of the screen. The active width/height excludes the overscan area. The compressed width/height takes into account rounding -- for example, JPEG compresses in blocks of 8x8 pixels, so the compressed width and height have to be multiples of 8 for a motion JPEG file. The active width/height tells you if (for example) some pixels at the border should be ignored.
In any case, since your question is tagged C++, I'm going to guess you'd rather read the file and get the data directly than depend on spawning something else to do the dirty work. If so, you probably want to look at the OpenDML AVI file spec. You can get at least some idea of the length, resolution, and framerate just from reading the basic AVI header, which is in a fixed spot at the beginning of the file, so that much is trivial to get. It'll take a bit more work to get to the pixel aspect ratio though...