jestarray
2021-4-30 17:46:03

So I’m using the software Tiled, a game map editor and it stores a tile as an array of ints: "data":[2], it has an option to compress it to base64 gzip, that is it first it compresses with gzip and then applies base64 to the result, turning into this: "data":"H4sIAAAAAAAACmNiYGAAAJcXTYsEAAAA", so how would i convert the string above back to 2 ? here is what i tried so far:

(require file/gzip) (require file/gunzip) (require net/base64) (define unb64 (base64-decode (string->bytes/utf-8 "H4sIAAAAAAAACmNiYGAAAJcXTYsEAAAA"))) (inflate (open-input-bytes unb64) (current-output-port)) //inflate: unknown inflate type and i get: inflate: unknown inflate type


soegaard2
2021-4-30 17:47:07

What’s the first, say 20, characters of (base64-decode (string->bytes/utf-8 "H4sIAAAAAAAACmNiYGAAAJcXTYsEAAAA"))) ?


jestarray
2021-4-30 17:48:05

#"\37\213\b\0\0\0\0\0\0\ncb``\0\0\227\27M\213\4\0\0\0"


jaz
2021-4-30 17:50:32

There are variations on base64 encoding, so you might be running into a problem with that


soegaard2
2021-4-30 17:51:41

According to Wikipedia a gzip header begins with 1f, 8b or 31, 139. But your strings contains 37, 213.


soegaard2
2021-4-30 17:52:33

To check that the data is as you expect: 1. Save the string in a file. 2. Use command line tools to base64 decode and unzip it.


rokitna
2021-4-30 17:52:38

37 octal is 31 decimal


soegaard2
2021-4-30 17:52:56

Oooh!


soegaard2
2021-4-30 17:53:52

And 139 is 213 octal.


rokitna
2021-4-30 17:53:54

213 octal is 139 decimal… so it looks like it’s the right header


jestarray
2021-4-30 17:57:28

{ "compressionlevel":-1, "height":1, "infinite":false, "layers":[ { "compression":"gzip", "data":"H4sIAAAAAAAACmNiYGAAAJcXTYsEAAAA", //this was [2] w/ no encoding , regular base64(uncompressed): AgAAAA== "encoding":"base64", "height":1, "id":1, "name":"a", "opacity":1, "type":"tilelayer", "visible":true, "width":1, "x":0, "y":0 }], "nextlayerid":2, "nextobjectid":1, "orientation":"orthogonal", "renderorder":"right-down", "tiledversion":"1.6.0", "tileheight":32, "tilesets":[ { "firstgid":1, "source":"tsd/breaking.json" }], "tilewidth":32, "type":"map", "version":"1.6", "width":1 } the entire file if it helps lol…


massung
2021-4-30 18:01:19

While a fun little exercise, just wanted to note for @jestarray that - unless you have to - the benefits of using the base64/gzipped “compression” for your maps will be mostly wasted unless:

• You have very few unique tiles (read: huffman encoding will benefit you a lot); and • You have fairly large maps Otherwise the 2D nature of the maps will have a difficult time benefitting a lot. Most 2D game tilemaps have good compression is when it’s done in blocks (e.g. a 4x4 tile house repeated in multiple places), but since Tiled (last I looked) is row-major in storing the data, all the benefits of those groupings is lost and can’t be compressed well.

Then you add the base64 on there and you lose compression there.

Just noting that you may want to save yourself grief and have it be straight-forward, uncompressed data. :slightly_smiling_face:


jaz
2021-4-30 18:04:05

When you say that data was "[2]", do you mean that it was a string containing 2 in square brackets, just as you wrote it, or do you mean it was just the number 2?


jestarray
2021-4-30 18:04:47

@jaz no quotes: "layers":[ { "data":[2], } ] so not a string afaik


jaz
2021-4-30 18:05:27

Okay, but interpreted literally, that’s an array, right?


jaz
2021-4-30 18:05:36

Which would need to be serialized somehow.


jestarray
2021-4-30 18:05:50

the square brackets are in there yeah


jaz
2021-4-30 18:08:01

Okay, the docs say that after you decode: Now you have an array of bytes, which should be interpreted as an array of unsigned 32-bit integers using little-endian byte ordering.


jaz
2021-4-30 18:08:06

That makes sense…. Okay:


jaz
2021-4-30 18:10:17

So, you’re using inflate in your example, but I think you need to use a gunzip function. (My limited understanding is that the deflate format is used in the data section of gzip data, but it’s not the whole thing?) At any rate, if I do the following: #lang racket/base (require net/base64 file/gunzip) (define text #"H4sIAAAAAAAACmNiYGAAAJcXTYsEAAAA") (define raw (base64-decode text)) (define raw-in (open-input-bytes raw)) (define out (open-output-bytes)) (gunzip-through-ports raw-in out) (get-output-bytes out) I get: #"\2\0\0\0" Which, according to the line I quoted above, would be interpreted as an array containing a single 32-bit, little-endian integer, 2.


jestarray
2021-4-30 18:12:57

:smile: thanks a lot, thats just what i wanted!


jestarray
2021-4-30 18:18:02

@jaz would you happen to know if there’s a zlib infliate version as well in the standard library? cant find it anywhere


jaz
2021-4-30 18:20:02

I think that’s the inflate you were using.


jaz
2021-4-30 18:21:08

IIUC, gzip is an archive format that uses the same kind of compression as zlib/pkzip .


jestarray
2021-4-30 18:22:11

i tried that but I get: inflate: error in compressed data on the same data [2] compressed with zlib instead: "data":"eJxjYmBgAAAADAAD",


jestarray
2021-4-30 18:25:58

https://groups.google.com/g/racket-users/c/3CvjHLAmwSQ reading this thread and it seems i have to add ADLER–32 check to the end of the byte string


jestarray
2021-4-30 18:28:01

seems like theres a zlib-inflate in net/gitcheckout module


jestarray
2021-4-30 18:35:35

alright got it workin now, thanks again :9


samdphillips
2021-4-30 18:41:55

Ooh just missed this, yes there is a zlib inflate in git-checkout, unfortunately it is not provided. I copied just the zlib related functions (and their deps) into a separate module and it works fine.


samdphillips
2021-4-30 18:42:16

I literally was looking at this Wednesday


jestarray
2021-4-30 18:43:29

probably should expose this or duplicate this in the gunzip module lol, excluding all of the git specific exception stuff



samdphillips
2021-4-30 18:44:28

Pretty much copied and maybe renamed a few functions


jestarray
2021-4-30 18:44:57

:kissing_heart:


samdphillips
2021-4-30 18:44:58

Also line 87 to the end are some utilities you can probably ignore (or use)


jestarray
2021-4-30 18:45:31

are you going to PR this :0 ?


samdphillips
2021-4-30 18:45:39

I didn’t really try to understand what it was doing and most of the deps were obvious


samdphillips
2021-4-30 18:47:07

Bleh I probably should.


jestarray
2021-4-30 18:47:47

:bow: please :laughing:


mflatt
2021-4-30 22:29:07

It looks like it’s really gzip format, so you want gunzip-through-ports instead of inflate. The inflate expansion will be used inside gunzip-through-ports , but there’s gzip metadata.


mflatt
2021-4-30 22:29:26

Oh, I should scroll down…