views:

89

answers:

3

Greetings all,

I load set of images and generate volume data.I save this volume data in a

unsigned char *volume

array.

Now I want to save this array in a file and retrieve.But before saving I want to compress the byte array since the volume data is huge.

Any tips on this?

Thanks in advance.

+1  A: 

You will need to use a 3rd party api (as already suggested). If this is C++/CLI you can use zlib.net, but if not then you will need some other library like gzip or lzma.

Here is a link for 7-zip sdk: http://www.7-zip.org/sdk.html

pstrjds
+5  A: 

volume in your example is not an array. As for compression, there are books written on the topic. For something quick and easy to use with C++, check out the boost.iostream library, which comes with zlib, gzip, and bzip2 compressors.

To offset my nitpicking, here's an example (changing to char because it's a lot more verbose with unsigned chars)

#include <fstream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/copy.hpp>
namespace io = boost::iostreams;
int main()
{
    const size_t N = 1000000;
    char* volume = new char[N];
    std::fill_n(volume, N, 'a'); // 100,000 letters 'a'

    io::stream< io::array_source > source (volume, N);

    {  
      std::ofstream file("volume.bz2", std::ios::out | std::ios::binary); 
      io::filtering_streambuf<io::output> outStream; 
      outStream.push(io::bzip2_compressor()); 
      outStream.push(file); 
      io::copy(source, outStream); 
     }
    // at this point, volume.bz2 is written and closed. It is 48 bytes long
}
Cubbi
Good call on the boost library, they have lots of well maintained code. Second point though, unsigned char* is an array in C++, you don't have to declare with [] brackets, if you are using C-style allocation you can dynamically allocate an array using malloc and return it to an unsigned char*
pstrjds
@pstr, no, `volume` is definitely a pointer, not an array, in both C and C++.
Matthew Flaschen
sure, its a pointer, but I pass arrays around as pointers all the time, I almost never declare my arrays with the [] syntax since most of the time I am passing them around and using malloc to allocate them, I think the pointer syntax is cleaner (but I confess I learned C first as a physics major and so it was not in a "CS" environment, a lot was focused on just get it to work so I grew to love pointers.) I will give you the fact that since it is a pointer it doesn't have to be an array, it could be a single unsigned char, but given the question I am assuming it is a chunk of data.
pstrjds
actually 'volume' is a pointer of size (image-width*image-height*num-of-images)
umanga
it is a pointer with a definite size and according to the Complete C Reference by Herbert Schildt it is a pointer (grant it he also calls them dynamically allocated arrays) :), but having said that, to be exact on syntax it is a pointer to an array, not an array. Matthew Flaschen and Cubbi win, I will now sneak away embarrassed.
pstrjds
They're just nit-picking. We all know that you meant volume is a pointer to the start of an array of unsigned chars, like you get from new unsigned char[w*h*n]
Michael Anderson
Come on guys - the question seeks insight re compression, not pointer/array usage or terminology.
Tony
+3  A: 

It depends on the type of data. If the images are already compressed (jpeg, png, etc), then it won't compress anymore.

You could use zlib http://www.zlib.net/ for uncompressed images, but I'd suggest to compress each of them with something specialized on images.

Edit:

1) Lossy compression will give much higher compression rates.

2) You mentioned that they are the same size. Are they also similar? A video codec would be the best choise in that case.

ruslik
Voted up for comment about already compressed images.
pstrjds
The question talks of compressing volume data generated from images (whatever that is), not compressing the images themselves.
Tony
@Tony I gave just enough information for umanga to make a decision.
ruslik
i load image into QImage (QT framework) and get each pixels color in grayscale.Then store the pixel value in my 'volume' pointer.
umanga
@umanga if you're using Qt, you could compress the data using `qCompress` (this directly uses zlib). Or you could use `QImage::save(QIODevice *, ...)` to save the image to an in-memory `QBuffer` as a PNG.
Doug