Skip to content

Commit

Permalink
Prefix image data with its length and increment TS_VERSION to 22 (aar…
Browse files Browse the repository at this point in the history
…dappel#433)

- This increments the TreeSheets file format version to 22.
- This adds a wxInt64/int64_t before the actual image data indicating its length.
- This updates the corresponding loading and saving procedures.
- This updates the file format specification.
  • Loading branch information
tobiolo authored Jun 4, 2023
1 parent 6059e7e commit 9784aa2
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 32 deletions.
4 changes: 2 additions & 2 deletions TS/docs/file_format_spec.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ struct Image
{
char ident; // marks start of image
// Character value depends on image type, i.e. 'I' for PNG and 'J' for JPEG
double display_scale; // display scale of image
int64_t imagelen; // length of image (8 bytes)
char image_data[len]; // whatever format wxImage::LoadFile uses
// to know len, you need to parse the png chunks
// sadly this means there's no way to read the Cells without doing so
}

struct Cell
Expand Down
4 changes: 3 additions & 1 deletion src/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,9 @@ struct Document {
if (image.trefc) {
fos.PutC(image.image_type);
sos.WriteDouble(image.display_scale);
fos.Write(image.image_data.data(), image.image_data.size());
wxInt64 imagelen(image.image_data.size());
sos.Write64(imagelen);
fos.Write(image.image_data.data(), imagelen);
image.savedindex = realindex++;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static const std::array<uint, 42> celltextcolors = {
};
enum { CUSTOMCOLORIDX = 0 };

enum { TS_VERSION = 21, TS_TEXT = 0, TS_GRID, TS_BOTH, TS_NEITHER };
enum { TS_VERSION = 22, TS_TEXT = 0, TS_GRID, TS_BOTH, TS_NEITHER };

static const uint TS_SELECTION_MASK = 0x80;

Expand Down
62 changes: 34 additions & 28 deletions src/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,37 +302,43 @@ struct System {
if (versionlastloaded < 9) dis.ReadString();
double sc = versionlastloaded >= 19 ? dis.ReadDouble() : 1.0;
vector<uint8_t> image_data;
off_t beforeimage = fis.TellI();

if(iti == 'I') {
uchar header[8];
fis.Read(header, 8);
uchar expected[] = {0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n'};
if (memcmp(header, expected, 8)) return _(L"Corrupt PNG header.");
dis.BigEndianOrdered(true);
for (;;) { // Skip all chunks.
wxInt32 len = dis.Read32();
char fourcc[4];
fis.Read(fourcc, 4);
fis.SeekI(len, wxFromCurrent); // skip data
dis.Read32(); // skip CRC
if (memcmp(fourcc, "IEND", 4) == 0) break;
}
} else if(iti == 'J') {
wxImage im;
im.LoadFile(fis); // fixme: write own parser logic to avoid LoadFile
if(!im.IsOk()) {
return _(L"JPEG file is corrupted!");
if(versionlastloaded >= 22) {
size_t imagelen = (size_t) dis.Read64();
image_data.resize(imagelen);
fis.Read(image_data.data(), imagelen);
} else {
off_t beforeimage = fis.TellI();

if(iti == 'I') {
uchar header[8];
fis.Read(header, 8);
uchar expected[] = {0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n'};
if (memcmp(header, expected, 8)) return _(L"Corrupt PNG header.");
dis.BigEndianOrdered(true);
for (;;) { // Skip all chunks.
wxInt32 len = dis.Read32();
char fourcc[4];
fis.Read(fourcc, 4);
fis.SeekI(len, wxFromCurrent); // skip data
dis.Read32(); // skip CRC
if (memcmp(fourcc, "IEND", 4) == 0) break;
}
} else if(iti == 'J') {
wxImage im;
im.LoadFile(fis);
if(!im.IsOk()) {
return _(L"JPEG file is corrupted!");
}
}

off_t afterimage = fis.TellI();
fis.SeekI(beforeimage);
auto sz = afterimage - beforeimage;
image_data.resize(sz);
fis.Read(image_data.data(), sz);
fis.SeekI(afterimage);
}

off_t afterimage = fis.TellI();
fis.SeekI(beforeimage);
auto sz = afterimage - beforeimage;
image_data.resize(sz);
fis.Read(image_data.data(), sz);
if (!fis.IsOk()) image_data.clear();
fis.SeekI(afterimage);

loadimageids.push() = AddImageToList(sc, std::move(image_data), iti);
break;
Expand Down

0 comments on commit 9784aa2

Please sign in to comment.