void TLJPak::insert(int pos, const std::vector<char>& buffer) { if (chunks.size() == 0) read_chunks(); assert(chunks.size() > 0); int chunk_id = files[pos].chunk_id; if (chunk_id != -1) { if (chunk_id >= 0 && chunk_id < int(chunks.size())) { chunks[chunk_id] = buffer; } else { std::cout << "Error: TLJPak::insert(): Couldn't insert file at " << chunk_id << " only have " << chunks.size() << " entries" << std::endl; } } else { std::cout << "Error: TLJPak::insert(): " << chunk_id << " not a valid file entry" << std::endl; } }
PNGLoader::PNGLoader(IODevice iodevice, bool force_srgb) : file(iodevice), force_srgb(force_srgb), scanline(nullptr), prev_scanline(nullptr), scanline_4ub(nullptr), scanline_4us(nullptr), palette(nullptr) { read_magic(); read_chunks(); decode_header(); decode_palette(); decode_colorkey(); decode_image(); }
int main(int argc, char **argv) { time_t time_st = 0; /* Default timestamp */ long long offset = 0, offset_orig; /* offset in kB */ size_t chunksize = ONE_MB; /* IO chunk size */ char *chunk_buf = NULL; unsigned int force = 0; /* run test run without confirmation*/ unsigned long long dev_size = 0; char yesno[4]; int mode = O_RDWR; /* mode which device should be opened */ int fd; int error = 0, c; progname = strrchr(argv[0], '/') == NULL ? argv[0] : strrchr(argv[0], '/') + 1; while ((c = getopt_long(argc, argv, "c:fhlo:pqrt:vw", longopts, NULL)) != -1) { switch (c) { case 'c': chunksize = (strtoul(optarg, NULL, 0) * ONE_MB); if (!chunksize) { fprintf(stderr, "%s: chunk size value should be" "nonzero and multiple of 1MB\n", progname); return -1; } break; case 'f': force = 1; break; case 'l': full = 1; break; case 'o': offset = strtoull(optarg, NULL, 0) * ONE_KB; break; case 'p': full = 0; break; case 'q': verbose = 0; break; case 'r': readoption = 1; mode = O_RDONLY; break; case 't': time_st = (time_t)strtoul(optarg, NULL, 0); break; case 'v': verbose++; break; case 'w': writeoption = 1; mode = O_WRONLY; break; case 'h': default: usage (1); return 0; } } offset_orig = offset; devname = argv[optind]; if (!devname) { fprintf(stderr, "%s: device name not given\n", progname); usage (1); return -1; } if (readoption && writeoption) mode = O_RDWR; if (!readoption && !writeoption) { readoption = 1; writeoption = 1; } if (!force && writeoption) { printf("%s: permanently overwrite all data on %s (yes/no)? ", progname, devname); if (scanf("%3s", yesno) == EOF && ferror(stdin)) { perror("reading from stdin"); return -1; } if (!(strcasecmp("yes", yesno) || strcasecmp("y", yesno))) { printf("Not continuing due to '%s' response", yesno); return 0; } } if (!writeoption && time_st == 0) { fprintf(stderr, "%s: must give timestamp for read-only test\n", progname); usage(1); } fd = open_dev(devname, mode); dev_size = sizeof_dev(fd); if (!dev_size) { fprintf(stderr, "%s: cannot test on device size < 1MB\n", progname); error = 7; goto close_dev; } if (dev_size < (offset * 2)) { fprintf(stderr, "%s: device size %llu < offset %llu\n", progname, dev_size, offset); error = 6; goto close_dev; } if (!time_st) (void)time(&time_st); isatty_flag = isatty(STDOUT_FILENO); if (verbose) printf("Timestamp: %lu\n", time_st); chunk_buf = (char *)calloc(chunksize, 1); if (chunk_buf == NULL) { fprintf(stderr, "%s: memory allocation failed for chunk_buf\n", progname); error = 4; goto close_dev; } if (writeoption) { c = write_chunks(fd, offset, dev_size, chunk_buf, chunksize, time_st, 0, devname); if (c < 0 && c != -ENOSPC) { error = 3; goto chunk_buf; } if (!full) { /* end of device aligned to a block */ offset = ((dev_size - chunksize + BLOCKSIZE - 1) & ~(BLOCKSIZE - 1)); c = write_chunks(fd, offset, dev_size, chunk_buf, chunksize, time_st, 0, devname); if (c < 0 && c != -ENOSPC) { error = 3; goto chunk_buf; } } offset = offset_orig; } if (readoption) { if (read_chunks(fd, offset, dev_size, chunk_buf, chunksize, time_st, 0, devname)) { error = 2; goto chunk_buf; } if (!full) { /* end of device aligned to a block */ offset = ((dev_size - chunksize + BLOCKSIZE - 1) & ~(BLOCKSIZE - 1)); if (read_chunks(fd, offset, dev_size, chunk_buf, chunksize, time_st, 0, devname)) { error = 2; goto chunk_buf; } } if (verbose) printf("\n%s: data verified successfully\n", progname); } error = error_count; chunk_buf: free(chunk_buf); close_dev: close(fd); return error; }
void TLJPak::write(const std::string& outfile) { if (chunks.size() == 0) read_chunks(); assert(chunks.size() > 0); generate_filetable(); std::ofstream out(outfile.c_str(), std::ios::binary); if (!out) throw std::runtime_error("TLJPak::write(): Couldn't open " + outfile); out.write(magic, 12); out.write(reinterpret_cast<char*>(&file_count), sizeof(int)); out.write(reinterpret_cast<char*>(&number_count), sizeof(int)); out.write(reinterpret_cast<char*>(&byte_count), sizeof(int)); // write file index table for(int i = 0; i < file_count; ++i) { out.write(reinterpret_cast<char*>(&files[i].offset), sizeof(int)); out.write(reinterpret_cast<char*>(&files[i].filesize), sizeof(int)); out.write(reinterpret_cast<char*>(&files[i].nametable_offset), sizeof(int)); out.write(reinterpret_cast<char*>(&files[i].path_length), sizeof(int)); out.write(reinterpret_cast<char*>(&files[i].nametable_index), sizeof(int)); } // write byte block for(int i = 0; i < int(nametable.size()); ++i) { // FIXME: Encode this //out.write(reinterpret_cast<char*>(&nametable[i]), sizeof(char)); out.put(ascii2nametable(nametable[i])); } // write number block for(int i = 0; i < int(indextable.size()); ++i) { out.write(reinterpret_cast<char*>(&indextable[i]), sizeof(int)); } for(int i = 0; i < header_padding; ++i) out.put(0); for(int i = 0; i < int(chunks.size()); ++i) { out.write(reinterpret_cast<char*>(&*chunks[i].begin()), chunks[i].size()); } { // fill in padding bytes at the end of file to reach a total // filesize of a multiple of 131072, not sure if these are // needed, but we do so to have exactly the same file structure // like in the original paks out.seekp(0, std::ios::end); int end = out.tellp(); if ((end % 131072) != 0) { for(int i = 0; i < 131072 - (end % 131072); ++i) out.put(0xae); } } out.close(); }