From ddbc4a2deddb78a320a88ef72695b8ee71555ea0 Mon Sep 17 00:00:00 2001 From: Vladimir Serov Date: Mon, 14 Sep 2020 17:46:58 +0300 Subject: [PATCH 1/5] save: added autorecalculation of lowres data offset Signed-off-by: Vladimir Serov --- pyphotonfile/photonfile.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyphotonfile/photonfile.py b/pyphotonfile/photonfile.py index 50d67c4..30fc6d2 100644 --- a/pyphotonfile/photonfile.py +++ b/pyphotonfile/photonfile.py @@ -304,9 +304,11 @@ def write(self, filepath): addresses['preview_lowres_header_address'] = f.tell() # remember position in file to later add the correct address f.write(struct.pack('i', self.preview_lowres_resolution_x)) f.write(struct.pack('i', self.preview_lowres_resolution_y)) - f.write(struct.pack('i', self.preview_lowres_data_address)) + offsets['preview_lowres_data_address'] = f.tell() # remember position in file to later add the correct address + f.write(struct.pack('i', 0x0 )) f.write(struct.pack('i', self.preview_lowres_data_length)) f.write(b'\x00' * 4 * 4) + addresses['preview_lowres_data_address'] = f.tell() # remember position in file to later add the correct address f.write(self.preview_lowres_data) if self.version > 1: addresses['print_properties_address'] = f.tell() # remember position in file to later add the correct address From 3949109dfdf99f5025fc8ea57d4c77e627d71903 Mon Sep 17 00:00:00 2001 From: Vladimir Serov Date: Mon, 14 Sep 2020 20:04:32 +0300 Subject: [PATCH 2/5] save: automatic calculation of preview size. can't rely on hoomans! Signed-off-by: Vladimir Serov --- pyphotonfile/photonfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyphotonfile/photonfile.py b/pyphotonfile/photonfile.py index 30fc6d2..c1553fd 100644 --- a/pyphotonfile/photonfile.py +++ b/pyphotonfile/photonfile.py @@ -298,7 +298,7 @@ def write(self, filepath): f.write(struct.pack('i', self.preview_highres_resolution_x)) f.write(struct.pack('i', self.preview_highres_resolution_y)) f.write(struct.pack('i', self.preview_highres_data_address)) - f.write(struct.pack('i', self.preview_highres_data_length)) + f.write(struct.pack('i', len(self.preview_highres_data))) f.write(b'\x00' * 4 * 4) f.write(self.preview_highres_data) addresses['preview_lowres_header_address'] = f.tell() # remember position in file to later add the correct address @@ -306,7 +306,7 @@ def write(self, filepath): f.write(struct.pack('i', self.preview_lowres_resolution_y)) offsets['preview_lowres_data_address'] = f.tell() # remember position in file to later add the correct address f.write(struct.pack('i', 0x0 )) - f.write(struct.pack('i', self.preview_lowres_data_length)) + f.write(struct.pack('i', len(self.preview_lowres_data))) f.write(b'\x00' * 4 * 4) addresses['preview_lowres_data_address'] = f.tell() # remember position in file to later add the correct address f.write(self.preview_lowres_data) From 1a6f285457bd2b80fea6a849f5d2cf8ed782c499 Mon Sep 17 00:00:00 2001 From: Vladimir Serov Date: Mon, 14 Sep 2020 20:07:16 +0300 Subject: [PATCH 3/5] added thumbnail encoder Signed-off-by: Vladimir Serov --- pyphotonfile/photonfile.py | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/pyphotonfile/photonfile.py b/pyphotonfile/photonfile.py index c1553fd..1570103 100644 --- a/pyphotonfile/photonfile.py +++ b/pyphotonfile/photonfile.py @@ -40,6 +40,33 @@ def rle_to_imgarray(data): rgb2d = x.reshape((2560,1440)) # data is stored in rows of 2560 return rgb2d +def encode_image_preview(input: Image): + output = bytes() + prev = -1 + count = 0 + c = 0 + def flush(): + nonlocal count, output, prev + if count > 1: prev |= 0x0020 + output += struct.pack("H", prev) + if count > 1: output += struct.pack("BB", (count - 1) & 0xFF, (count - 1) >> 8) + count = 0 + + for y in range(input.height): + for x in range(input.width): + r, g, b, _ = input.getpixel((x, y)) + c = (r >> 3 << 11) | (g >> 3 << 6) | (b >> 3) + if (prev == c and count < 4096) or prev == -1: + count += 1 + prev = c + else: + flush() + count = 1 + prev = c + + flush() + return output + def imgarr_to_rle(imgarr): """ @@ -252,6 +279,20 @@ def _open(self, filepath=None): self.layers.append(layer) + def set_preview_highres(self, image: Image): + self.preview_highres_data = encode_image_preview(image) + self.preview_highres_data_length = len(self.preview_highres_data) + self.preview_highres_resolution_x = image.width + self.preview_highres_resolution_y = image.height + + + def set_preview_lowres(self, image: Image): + self.preview_lowres_data = encode_image_preview(image) + self.preview_lowres_data_length = len(self.preview_lowres_data) + self.preview_lowres_resolution_x = image.width + self.preview_lowres_resolution_y = image.height + + def write(self, filepath): """ Writes the Photon-file to disk. From d45fefea50489240564ab1cdaddcd6c9d37262fc Mon Sep 17 00:00:00 2001 From: Vladimir Serov Date: Tue, 15 Sep 2020 00:04:51 +0300 Subject: [PATCH 4/5] auto calculation of highres data addresses Signed-off-by: Vladimir Serov --- pyphotonfile/photonfile.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pyphotonfile/photonfile.py b/pyphotonfile/photonfile.py index 1570103..c885c0b 100644 --- a/pyphotonfile/photonfile.py +++ b/pyphotonfile/photonfile.py @@ -314,7 +314,8 @@ def write(self, filepath): f.write(struct.pack('i', self.bottom_layers)) f.write(struct.pack('i', self.resolution_x)) f.write(struct.pack('i', self.resolution_y)) - f.write(struct.pack('i', self.preview_highres_header_address)) + offsets['preview_highres_header_address'] = f.tell() # remember position in file to later add the correct address + f.write(struct.pack('i', 0x0)) offsets['layer_def_address'] = f.tell() # remember position in file to later add the correct address f.write(struct.pack('i', 0x0 )) f.write(struct.pack('i', len(self.layers))) @@ -336,11 +337,14 @@ def write(self, filepath): f.write(b'\x00' * 3 * 4) else: f.write(b'\x00' * 6 * 4) # padding + addresses['preview_highres_header_address'] = f.tell() # remember position in file to later add the correct address f.write(struct.pack('i', self.preview_highres_resolution_x)) f.write(struct.pack('i', self.preview_highres_resolution_y)) - f.write(struct.pack('i', self.preview_highres_data_address)) + offsets['preview_highres_data_address'] = f.tell() # remember position in file to later add the correct address + f.write(struct.pack('i', 0x0)) f.write(struct.pack('i', len(self.preview_highres_data))) f.write(b'\x00' * 4 * 4) + addresses['preview_highres_data_address'] = f.tell() # remember position in file to later add the correct address f.write(self.preview_highres_data) addresses['preview_lowres_header_address'] = f.tell() # remember position in file to later add the correct address f.write(struct.pack('i', self.preview_lowres_resolution_x)) From b7ee92a0071007bb1d6a5984262651beec26543d Mon Sep 17 00:00:00 2001 From: Vladimir Serov Date: Tue, 15 Sep 2020 07:36:58 +0300 Subject: [PATCH 5/5] Added changelog Signed-off-by: Vladimir Serov --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..641428c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ + +### New since 0.2.1 ++ Thumbnail generator ++ Offsets for thumbnails are now calculated automagically