Skip to content

pdvzip update #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 73 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
fb3820c
Update README.md
CleasbyCode Oct 17, 2024
40dbdfa
Delete demo_image/pdvimg_21365.png
CleasbyCode Oct 17, 2024
3fc0fc5
Delete demo_image/pdvimg_30657.png
CleasbyCode Oct 17, 2024
095e0ce
Add files via upload
CleasbyCode Oct 17, 2024
2563136
Update README.md
CleasbyCode Oct 17, 2024
9cb96e3
Delete demo_image/test
CleasbyCode Oct 17, 2024
eae35f6
Delete src/pdvzip.cpp
CleasbyCode Oct 17, 2024
1982387
Add files via upload
CleasbyCode Oct 17, 2024
4386346
Delete src/script_info.txt
CleasbyCode Oct 17, 2024
1bb5712
Update README.md
CleasbyCode Oct 29, 2024
9120623
Add files via upload
CleasbyCode Oct 29, 2024
378d0bc
Update README.md
CleasbyCode Nov 14, 2024
dc01891
Update README.md
CleasbyCode Nov 24, 2024
66f2be2
Update README.md
CleasbyCode Nov 25, 2024
3e43db4
Update pdvzip.cpp
CleasbyCode Nov 25, 2024
18c9fe1
Update extractionScripts.cpp
CleasbyCode Nov 25, 2024
5e72beb
Update README.md
CleasbyCode Dec 10, 2024
7e3b581
Add files via upload
CleasbyCode Dec 10, 2024
558846a
Add files via upload
CleasbyCode Dec 10, 2024
1b787d4
Delete src/extractionScripts.cpp
CleasbyCode Dec 10, 2024
1b90b23
Add files via upload
CleasbyCode Dec 10, 2024
cc0d09c
Create tmp.txt
CleasbyCode Dec 10, 2024
4487e8d
Add files via upload
CleasbyCode Dec 10, 2024
0b10824
Delete src/lodepng/tmp.txt
CleasbyCode Dec 10, 2024
622551b
Add files via upload
CleasbyCode Dec 10, 2024
1db5274
Delete demo_image/pzip_4172.png
CleasbyCode Dec 10, 2024
f9be4a0
Update README.md
CleasbyCode Dec 10, 2024
7df997b
Update README.md
CleasbyCode May 14, 2025
627eaf7
Update lodepng.cpp
CleasbyCode May 14, 2025
684c555
Update lodepng.h
CleasbyCode May 14, 2025
5c32a21
Update adjustZip.cpp
CleasbyCode May 14, 2025
ecd4809
Delete src/eraseChunks.cpp
CleasbyCode May 14, 2025
ddc619f
Create copyChunks.cpp
CleasbyCode May 14, 2025
da62bd2
Update crc32.cpp
CleasbyCode May 14, 2025
241c9a0
Update extractionScripts.cpp
CleasbyCode May 14, 2025
2055da8
Create fileChecks.cpp
CleasbyCode May 14, 2025
9f225d2
Update getByteValue.cpp
CleasbyCode May 14, 2025
a210ebb
Update information.cpp
CleasbyCode May 14, 2025
5407737
Update main.cpp
CleasbyCode May 14, 2025
c43be37
Update pdvzip.cpp
CleasbyCode May 14, 2025
038ee24
Update pdvzip.h
CleasbyCode May 14, 2025
14fb118
Create programArgs.cpp
CleasbyCode May 14, 2025
9099967
Update resizeImage.cpp
CleasbyCode May 14, 2025
8796c7b
Update searchFunc.cpp
CleasbyCode May 14, 2025
9c61687
Update searchFunc.cpp
CleasbyCode May 14, 2025
6317e2f
Update valueUpdater.cpp
CleasbyCode May 14, 2025
4e99432
Update writeFile.cpp
CleasbyCode May 14, 2025
8f5159b
Update copyChunks.cpp
CleasbyCode May 14, 2025
abc01be
Update pdvzip.cpp
CleasbyCode May 14, 2025
a7076e1
Update README.md
CleasbyCode May 16, 2025
794b60c
Add files via upload
CleasbyCode May 16, 2025
974af81
Delete src/adjustZip.cpp
CleasbyCode May 16, 2025
03ea89e
Delete src/copyChunks.cpp
CleasbyCode May 16, 2025
60e689d
Delete src/crc32.cpp
CleasbyCode May 16, 2025
2994a10
Delete src/extractionScripts.cpp
CleasbyCode May 16, 2025
6fbd211
Delete src/fileChecks.cpp
CleasbyCode May 16, 2025
1f3b633
Delete src/getByteValue.cpp
CleasbyCode May 16, 2025
bb088e9
Delete src/information.cpp
CleasbyCode May 16, 2025
94bee64
Delete src/main.cpp
CleasbyCode May 16, 2025
6e2dfe0
Delete src/pdvzip.cpp
CleasbyCode May 16, 2025
96d33cf
Delete src/pdvzip.h
CleasbyCode May 16, 2025
996fceb
Delete src/programArgs.cpp
CleasbyCode May 16, 2025
0e5ffdc
Delete src/resizeImage.cpp
CleasbyCode May 16, 2025
e7d5467
Delete src/searchFunc.cpp
CleasbyCode May 16, 2025
461a6c4
Delete src/valueUpdater.cpp
CleasbyCode May 16, 2025
fcbbf71
Create tmp.txt
CleasbyCode May 16, 2025
3f98c79
Delete src/writeFile.cpp
CleasbyCode May 16, 2025
9006914
Add files via upload
CleasbyCode May 16, 2025
fd07f58
Update extractionScripts.cpp
CleasbyCode May 17, 2025
ede1299
Add files via upload
CleasbyCode May 18, 2025
910dfac
Add files via upload
CleasbyCode May 18, 2025
402f5c5
Update README.md
CleasbyCode May 21, 2025
5962712
Update README.md
CleasbyCode May 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
243 changes: 150 additions & 93 deletions README.md

Large diffs are not rendered by default.

Binary file removed demo_image/pdvimg_21365.png
Binary file not shown.
Binary file removed demo_image/pdvimg_30657.png
Binary file not shown.
Binary file added demo_image/pzip_83973.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion demo_image/test

This file was deleted.

67 changes: 67 additions & 0 deletions src/adjustZip.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// ZIP file has been moved to another location. We need to find and adjust the ZIP file record offsets to their new location.

#include "adjustZip.h"
#include "searchFunc.h"
#include "getByteValue.h"
#include <iterator>

void adjustZipOffsets(std::vector<uint8_t>& vec, const uint32_t VEC_SIZE, const uint32_t LAST_IDAT_INDEX) {
auto valueUpdater = [](std::vector<uint8_t>& vec, uint32_t value_insert_index, const uint32_t NEW_VALUE, uint8_t bits) {
while (bits) { vec[value_insert_index--] = (NEW_VALUE >> (bits -= 8)) & 0xff; }
};

constexpr uint8_t
SIG_LENGTH = 4,
CENTRAL_LOCAL_INDEX_DIFF = 45,
END_CENTRAL_START_INDEX_DIFF = 19,
ZIP_COMMENT_LENGTH_INDEX_DIFF = 21,
ZIP_RECORDS_INDEX_DIFF = 11,
ZIP_LOCAL_INDEX_DIFF = 4,
INCREMENT_SEARCH_INDEX = 1,
PNG_IEND_LENGTH = 16,
BYTE_LENGTH = 2;

constexpr std::array<uint8_t, SIG_LENGTH>
ZIP_LOCAL_SIG { 0x50, 0x4B, 0x03, 0x04 },
END_CENTRAL_DIR_SIG { 0x50, 0x4B, 0x05, 0x06 },
START_CENTRAL_DIR_SIG { 0x50, 0x4B, 0x01, 0x02 };

// Starting from the end of the vector storing the archive, a single reverse search of the contents finds the "end_central directory" index.
const uint32_t END_CENTRAL_DIR_INDEX = VEC_SIZE - static_cast<uint32_t>(std::distance(vec.rbegin(), std::search(vec.rbegin(), vec.rend(),
END_CENTRAL_DIR_SIG.rbegin(), END_CENTRAL_DIR_SIG.rend()))) - SIG_LENGTH;
uint32_t
total_zip_records_index = END_CENTRAL_DIR_INDEX + ZIP_RECORDS_INDEX_DIFF,
end_central_start_index = END_CENTRAL_DIR_INDEX + END_CENTRAL_START_INDEX_DIFF,
zip_comment_length_index = END_CENTRAL_DIR_INDEX + ZIP_COMMENT_LENGTH_INDEX_DIFF,
zip_record_local_index = LAST_IDAT_INDEX + ZIP_LOCAL_INDEX_DIFF,
start_central_dir_index = VEC_SIZE;

bool isBigEndian = false;

uint16_t
total_zip_records = getByteValue(vec, total_zip_records_index, BYTE_LENGTH, isBigEndian),
zip_comment_length = getByteValue(vec, zip_comment_length_index, BYTE_LENGTH, isBigEndian) + PNG_IEND_LENGTH, // Extend comment length to include end bytes of PNG. Important for JAR files.
record_count = 0;

uint8_t value_bit_length = 16;
valueUpdater(vec, zip_comment_length_index, zip_comment_length, value_bit_length);

// Find the 1st / main "start_central directory" index location by iterating over the vector, working backwards from the vector's content.
// By starting the search from the end of the vector, we know we are already within the record section data of the archive and this
// avoids the possibility of a "false-positive" signature match, if we were to search the vector from the beginning and read through the image and file data first.
while (record_count++ != total_zip_records) {
start_central_dir_index = VEC_SIZE - static_cast<uint32_t>(std::distance(vec.rbegin(), std::search(vec.rbegin() + (VEC_SIZE - start_central_dir_index + SIG_LENGTH),
vec.rend(), START_CENTRAL_DIR_SIG.rbegin(), START_CENTRAL_DIR_SIG.rend()))) - SIG_LENGTH;
}

uint32_t central_dir_local_index = start_central_dir_index + CENTRAL_LOCAL_INDEX_DIFF;

value_bit_length = 32;
valueUpdater(vec, end_central_start_index, start_central_dir_index, value_bit_length); // Update end_central index location with start_central directory offset.

while (total_zip_records--) {
valueUpdater(vec, central_dir_local_index, zip_record_local_index, value_bit_length); // Write the new zip_record index/offset to the central_dir_local index location.
zip_record_local_index = searchFunc(vec, zip_record_local_index, INCREMENT_SEARCH_INDEX, ZIP_LOCAL_SIG); // Get the next zip_record index/offset.
central_dir_local_index = searchFunc(vec, central_dir_local_index, INCREMENT_SEARCH_INDEX, START_CENTRAL_DIR_SIG) + CENTRAL_LOCAL_INDEX_DIFF; // Get the next central_dir index location.
}
}
6 changes: 6 additions & 0 deletions src/adjustZip.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

#include <vector>
#include <cstdint>

void adjustZipOffsets(std::vector<uint8_t>&, const uint32_t, const uint32_t);
15 changes: 15 additions & 0 deletions src/compile_pdvzip.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

# compile_pdvzip.sh

g++ main.cpp lodepng/lodepng.cpp programArgs.cpp fileChecks.cpp copyChunks.cpp \
information.cpp adjustZip.cpp writeFile.cpp getByteValue.cpp valueUpdater.cpp \
crc32.cpp resizeImage.cpp extractionScripts.cpp pdvZip.cpp \
-Wall -O2 -s -o pdvzip

if [ $? -eq 0 ]; then
echo "Compilation successful. Executable 'pdvzip' created."
else
echo "Compilation failed."
exit 1
fi
84 changes: 84 additions & 0 deletions src/copyChunks.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@

#include "copyChunks.h"
#include "searchFunc.h"
#include "getByteValue.h"
#include <iterator>
#include <stdexcept>
#include <utility>

void copyEssentialChunks(std::vector<uint8_t>& image_vec) {
constexpr uint8_t SIG_LENGTH = 4;

constexpr std::array<uint8_t, SIG_LENGTH>
PLTE_SIG {0x50, 0x4C, 0x54, 0x45},
TRNS_SIG {0x74, 0x52, 0x4E, 0x53},
IDAT_SIG {0x49, 0x44, 0x41, 0x54};

constexpr uint8_t
PNG_FIRST_BYTES = 33,
PNG_IEND_BYTES = 12,
PNG_COLOR_TYPE_INDEX = 0x19,
PNG_TRUECOLOR_VAL = 2,
PNG_INDEXED_COLOR_VAL = 3;

const size_t IMAGE_VEC_SIZE = image_vec.size();

const uint32_t FIRST_IDAT_INDEX = searchFunc(image_vec, 0, 0, IDAT_SIG);

if (FIRST_IDAT_INDEX == IMAGE_VEC_SIZE) {
throw std::runtime_error("Image Error: Invalid or corrupt image file. IDAT chunk not found.");
}

std::vector<uint8_t> copied_image_vec;
copied_image_vec.reserve(IMAGE_VEC_SIZE);

std::copy_n(image_vec.begin(), PNG_FIRST_BYTES, std::back_inserter(copied_image_vec));

auto copy_chunk_type = [&](const auto& chunk_signature) {
constexpr uint8_t
PNG_CHUNK_FIELDS_COMBINED_LENGTH = 12, // Size_field + Name_field + CRC_field.
PNG_CHUNK_LENGTH_FIELD_SIZE = 4,
SEARCH_INCREMENT = 5;

uint32_t
chunk_search_pos = 0,
chunk_length_pos = 0,
chunk_count = 0,
chunk_length = 0;

bool isBigEndian = true;

while (true) {
chunk_search_pos = searchFunc(image_vec, chunk_search_pos, SEARCH_INCREMENT, chunk_signature);

if (chunk_signature != IDAT_SIG && chunk_search_pos > FIRST_IDAT_INDEX) {
if (chunk_signature == PLTE_SIG && !chunk_count) {
throw std::runtime_error("Image Error: Invalid or corrupt image file. PLTE chunk not found.");
} else {
break;
}
} else if (chunk_search_pos == IMAGE_VEC_SIZE) {
break;
}

++chunk_count;
chunk_length_pos = chunk_search_pos - PNG_CHUNK_LENGTH_FIELD_SIZE;
chunk_length = getByteValue(image_vec, chunk_length_pos, PNG_CHUNK_LENGTH_FIELD_SIZE, isBigEndian) + PNG_CHUNK_FIELDS_COMBINED_LENGTH;
std::copy_n(image_vec.begin() + chunk_length_pos, chunk_length, std::back_inserter(copied_image_vec));
}
};

if (image_vec[PNG_COLOR_TYPE_INDEX] == PNG_INDEXED_COLOR_VAL) {
copy_chunk_type(PLTE_SIG);
copy_chunk_type(TRNS_SIG);
}

if (image_vec[PNG_COLOR_TYPE_INDEX] == PNG_TRUECOLOR_VAL) {
copy_chunk_type(TRNS_SIG);
}

copy_chunk_type(IDAT_SIG);

std::copy_n(image_vec.end() - PNG_IEND_BYTES, PNG_IEND_BYTES, std::back_inserter(copied_image_vec));
image_vec = std::move(copied_image_vec);
}
6 changes: 6 additions & 0 deletions src/copyChunks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

#include <vector>
#include <cstdint>

void copyEssentialChunks(std::vector<uint8_t>&);
36 changes: 36 additions & 0 deletions src/crc32.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// The following function (slightly modified) to compute CRC32 for PNG chunks is taken from: https://www.w3.org/TR/2003/REC-PNG-20031110/#D-CRCAppendix

#include "crc32.h"
#include <array>

uint32_t crcUpdate(uint8_t* buf, uint32_t buf_length) {
constexpr uint16_t TABLE_LENGTH = 256;

constexpr std::array<uint32_t, TABLE_LENGTH> CRC_TABLE {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x76DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0xEDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x9B64C2B, 0x7EB17CBD,
0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x1DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x6B6B51F,
0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0xF00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x86D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE,
0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x3B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x4DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0xD6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0xA00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0,
0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x26D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x5005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0xCB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0xBDBDF21, 0x86D3D2D4, 0xF1D4E242,
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };

uint32_t
buf_index{},
crc_value = 0xffffffffL;

while (buf_length--) { crc_value = CRC_TABLE[(crc_value ^ buf[buf_index++]) & 0xff] ^ (crc_value >> 8); }
return (crc_value) ^ 0xffffffffL;
}
5 changes: 5 additions & 0 deletions src/crc32.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include <cstdint>

uint32_t crcUpdate(uint8_t*, uint32_t);
Loading