00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "mximg.h"
00023 #include<cassert>
00024 #include<cstring>
00025 #include<cstdio>
00026
00027
00028 namespace mx
00029 {
00030
00031 mximg_Item::mximg_Item() {
00032 compressed_length = 0;
00033 data_length = 0;
00034 name_length = 0;
00035 offset = 0;
00036 }
00037
00038 mximg_Writer::mximg_Writer() {
00039
00040
00041 }
00042
00043 bool mximg_Writer::addItem(const char *item) {
00044
00045 std::fstream f;
00046 f.open(item, std::ios::in | std::ios::binary);
00047 if(!f.is_open())
00048 return false;
00049 f.seekg(0, std::ios::end);
00050 size_t len = f.tellg();
00051 f.close();
00052
00053 if(len == 0) {
00054 std::cout << item << " is zero bytes, skipping..\n";
00055 return true;
00056 }
00057
00058
00059 mximg_Item it;
00060 it.data_length = len;
00061
00062 it.fullname = item;
00063
00064 std::string ex = item;
00065 if(ex.rfind("/")) {
00066 ex = ex.substr(ex.rfind("/")+1, ex.length());
00067 std::cout << ex << "\n";
00068 }
00069
00070 it.name_length = ex.length()+1;
00071 snprintf(it.name, it.name_length, "%s", ex.c_str());
00072
00073 return addItem(it);
00074 }
00075
00076 bool mximg_Writer::addItem(const mximg_Item &item) {
00077
00078 assert(item.data_length != 0);
00079 assert(item.name_length != 0);
00080
00081 items_.push_back(item);
00082 return true;
00083 }
00084
00085 bool mximg_Writer::writeData(std::fstream &file) {
00086
00087 std::vector<mximg_Item>::iterator i, last;
00088
00089 for(i = items_.begin(), last = items_.end(); i != last; i++) {
00090
00091 if(i->name_length <= 0) continue;
00092 if(i->data_length <= 0) continue;
00093
00094
00095 file.write((char*)&i->name_length, sizeof(unsigned int));
00096 file.write((char*)i->name, i->name_length);
00097
00098 unsigned char *temp_bytes = new unsigned char [ i->data_length + 1 ];
00099 std::fstream temp_file;
00100 temp_file.open(i->fullname.c_str(), std::ios::in | std::ios::binary);
00101 if(!temp_file.is_open()) {
00102 std::cerr << " could not open input file: " << i->name << "\n";
00103 file.close();
00104 return false;
00105 }
00106 temp_file.read((char*)temp_bytes, i->data_length);
00107 temp_file.close();
00108 i->compressed_length = i->data_length;
00109
00110 int err;
00111
00112 i->compressed_length = compressBound(i->data_length);
00113 unsigned char *comp_bytes = new unsigned char [ i->compressed_length + 1 ];
00114
00115 if((err = compress((Bytef*)comp_bytes, (uLongf*)&i->compressed_length, (const Bytef*)temp_bytes, (uLong) i->data_length)) != Z_OK) {
00116 file.close();
00117 delete [] temp_bytes;
00118 delete [] comp_bytes;
00119 std::cerr << "error on compression of " << i->name << " " << zError(err) << " ...\n";
00120 return false;
00121 }
00122
00123 file.write((char*)&i->data_length, sizeof(unsigned int));
00124 file.write((char*)&i->compressed_length, sizeof(unsigned int));
00125 file.write((char*)comp_bytes, i->compressed_length);
00126
00127 delete [] temp_bytes;
00128 delete [] comp_bytes;
00129 }
00130
00131 file.close();
00132
00133 return true;
00134 }
00135
00136
00137 bool mximg_Writer::concatItems(const char *filen) {
00138
00139 std::fstream file;
00140
00141 file.open(filen, std::ios::binary | std::ios::app | std::ios::out);
00142 if(!file.is_open()) return false;
00143
00144 return writeData(file);
00145 }
00146
00147 bool mximg_Writer::writeItems(const char *filen)
00148 {
00149 std::fstream file;
00150 file.open(filen, std::ios::out | std::ios::binary);
00151 if(!file.is_open())
00152 return false;
00153
00154 return writeData(file);
00155 }
00156
00157 mximg_Reader::mximg_Reader() {}
00158
00159
00160 bool mximg_Reader::openArchive(const char *filen) {
00161
00162 std::fstream f;
00163
00164 f.open(filen, std::ios::in | std::ios::binary);
00165
00166 if(!f.is_open()) return false;
00167
00168 while(!f.eof() ) {
00169
00170 mximg_Item item;
00171 f.read((char*)&item.name_length, sizeof(unsigned int));
00172 f.read((char*)&item.name, item.name_length);
00173 f.read((char*)&item.data_length, sizeof(unsigned int));
00174 f.read((char*)&item.compressed_length, sizeof(unsigned int));
00175 item.offset = f.tellg();
00176 f.seekg(item.compressed_length, std::ios::cur);
00177
00178 if(item.compressed_length != 0)
00179 items_.push_back(item);
00180 }
00181 f.close();
00182 file_name = filen;
00183 return true;
00184 }
00185
00186 void mximg_Reader::listItems(std::ostream &stream) {
00187
00188 std::vector<mximg_Item>::iterator i, last;
00189
00190 using namespace std;
00191
00192 stream << setw(25) << "filename" << setw(15) << "compressed" << setw(15) << "uncompressed" << "\n";
00193
00194 for(i = items_.begin(), last = items_.end(); i != last; i++) {
00195 stream << setw(25) << i->name << setw(15) << i->compressed_length << setw(15) << i->data_length << "\n";
00196 }
00197 }
00198
00199 void *mximg_Reader::accessBytes(const char *fname, size_t &length) {
00200
00201 std::vector<mximg_Item>::iterator i,last;
00202
00203 for(i = items_.begin(), last = items_.end(); i != last; i++) {
00204
00205 if(strcmp(i->name, fname) == 0) {
00206
00207
00208 std::fstream f;
00209 f.open(file_name.c_str(), std::ios::in | std::ios::binary);
00210 if(!f.is_open()) return 0;
00211
00212 length = i->data_length;
00213 unsigned char *compressed_bytes = new unsigned char [ i->compressed_length + 1 ];
00214 unsigned char *uncompressed = new unsigned char [ i->data_length + 1 ];
00215
00216 f.seekg(i->offset, std::ios::beg);
00217 f.read((char*)compressed_bytes, i->compressed_length);
00218 f.close();
00219 if( uncompress((Bytef*)uncompressed, (uLongf*)&i->data_length,(const Bytef*)compressed_bytes, (uLongf)i->compressed_length) != Z_OK ) {
00220
00221 std::cerr << "error on decompression\n";
00222 delete [] uncompressed;
00223 delete [] compressed_bytes;
00224 return 0;
00225 }
00226
00227 delete [] compressed_bytes;
00228 return uncompressed;
00229 }
00230
00231 }
00232 return 0;
00233 }
00234
00235 void mximg_Reader::extractItem(const char *path, const char *fname) {
00236
00237 std::string p = path;
00238 if(p[p.length()-1] == '/') p += fname; else p = p + '/' + fname;
00239
00240 std::fstream file;
00241 file.open(p.c_str(), std::ios::out | std::ios::binary);
00242 if(!file.is_open()) {
00243 std::cerr << "error path is incorrect, supply correct path for extraction.";
00244 return;
00245 }
00246
00247 size_t length = 0;
00248 char *bytes = (char*) accessBytes(fname, length);
00249 if(bytes == 0) std::cerr << "invalid identifier for extraction.";
00250
00251 file.write((char*)bytes, length);
00252 file.close();
00253 delete [] bytes;
00254
00255 }
00256
00257 void mximg_Reader::extractAll(const char *path) {
00258
00259 std::vector<mximg_Item>::iterator i, last;
00260 for(i = items_.begin(), last = items_.end(); i != last; i++)
00261 extractItem(path, i->name);
00262
00263 }
00264
00265 void mximg_Reader::closeArchive() {
00266 if(!items_.empty())
00267 items_.clear();
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291