somewhatnifty
@somewhatnifty

this is because they are wimps. just do it. just do what an mp3 does but like with whatever. i want to shrink my gigabytes of random crap down to arbitrary size and send them fast to my pals. it's all just numbers anyway, right? so long as most of the digits are sorta close i don't see the issue. lossy zip a text file? you can probably make out most of the words. lossy zip a .wav? there'll probably be some sounds in there. you can listen to those. lossy zip an .exe? it might not even crash right away. maybe it'll do something cool. you don't know.


lexi
@lexi

i am not joking you can now compress your files as lossy JPEGs

echo hello world |
  node index --quality 100 --compress - |
  node index --decompress -
hel�mv�qld�
curl https://www.gnu.org/licenses/gpl-3.0.txt |
  node index --quality 100 --compress - |
  node index --decompress - |
  head -c1000
 !□   □   □   □   □GNU□HFO□R@L□OTA□IC□JBE□RD  □   □   □   □!!□!!!□ U□rsi□n1□ 19□Juo□1/□5
□Cnq□rhg□s (□) 1□/6"□rde□Sod□xar□ En□nb`□hnn□Im□.<□ttp□9/.□sf.□sf.□
 D□fr|□ne □s p□rlh□tdc□sn □ooy□amc□dis□rib□te □dqa□tim□dpr□er
□pg □hhr□jic□nre□bnb□mdm□,a□ra□bmj□mg□sg□mn□_l□mve□.

□   □   □   □   □!!□   □   □sd_□bkd□
 □ge□OU#□dmd□bj □ual□d M□cep□ei□ `□qee□ bn□xld□t l□cen□f!f□q        t□fsw□qe□nc □shc□ ji□cs□fw□rjs□
         □She□jic□nre□ en□mn□t r□fsw□qe□mc □shc□op□bth□al□nql□ aq□ de□hfm□b
t□r`□d a□`y!□nus□eqe□cnl□sn □gaq□am□ ch□nfe□shc□xps□s-□Ax□omt□_su□
th□ GN□Fd□dq_□ Pt□kha□Lic□osf□is □nre□fde□ro □u`q□nre□xn□qe□eec□m t□ sg□rf □nc□hbn□d _□ku□rsi□mr!□fa□oro□s_l□,sm□mak□rt□d i□rd□ahn□fq□c
r□fsw□qe□or!□kk□ss□ser□- □c+ □ge□qee□Sof□xar□ Ep□mc`□hpo□ tr□sh□
GN□ Ge□dq_□ Ou□mh`□Lic□nre□eor□nps□ne□nus□snf□xar□;h□an□mgc□ ak□m t`m□or□er□nqj□sdk□ate□ th□r v□xa□ hs□ au□gnr□-"□ou!□am□ppl□ hs□tn
□nus□psp□r`l□-s□n-     □ U□dm □es□d`j□of□qee□snf□xar□, v□ aq□rb□drq□mg□

and this is how the GPL looks:

random noise and a black rectangle

source code

this is licensed under the Whatever The Fuck You Do, Do Not Use This Software Under Any Circumstances License

you need node.js installed, and need to npm install jimp command-line-usage command-line-args. then download the script from here or copy the source code:

const commandLineArgs = require('command-line-args')
const commandLineUsage = require('command-line-usage')
const jimp = require('jimp')
const fs = require('fs')

const optionDefinitions = [
    {
        name: 'help',
        alias: 'h',
        type: Boolean,
        description: 'Display this usage guide.'
    },
    {
        name: 'decompress',
        alias: 'd',
        type: String,
        description: 'File to decompress',
        typeLabel: '<files>'
    },
    {
        name: "compress",
        alias: "c",
        type: String,
        description: "File to compress into",
        typeLabel: "<files>"
    },
    {
        name: "quality",
        alias: "q",
        type: Number,
        description: "Lossy quality",

    },
    {
        name: "output",
        alias: "o",
        type: String,
        description: "Output file",
    }
]

const options = commandLineArgs(optionDefinitions)

if (options.help || (!options.decompress && !options.compress)) {
    const usage = commandLineUsage([
        {
            header: 'lostar - Lossy Archiver',
            content: 'A lossy file archiver. Oh god why'
        },
        {
            header: 'Options',
            optionList: optionDefinitions
        },
        {
            content: 'Note: You can pass - for stdin/stdout. Output defaults to stdout.'
        }
    ])
    console.log(usage)
} else {
    options.quality = options.quality || 100
    let file = options.compress || options.decompress
    if (file === '-') {
        // read whole stdin into buffer
        let buffer = Buffer.alloc(0)
        process.stdin.on('data', (chunk) => {
            buffer = Buffer.concat([buffer, chunk])
        })
        process.stdin.on('end', () => {
            options.decompress ? decompress(buffer, options) : compress(buffer, options)
        })
    } else {
        let fileBuf = fs.readFileSync(file)
        options.decompress ? decompress(fileBuf, options) : compress(fileBuf, options)
    }
}

// We store files lossy by storing 3 bytes per pixel, and then we write it out as a JPEG to compress it lossy
// The image is always square, and the rest of the image that does not have any data is filled with 0s (for max compression)
// When decompressing, we just trim the trailing 0s. This is a horrible idea. Don't use this. Also, its lossy, so it will probably break

async function compress(buffer, options) {
    // We want to make a square image, so we need to find the smallest square number that is greater than or equal to the buffer size
    let size = Math.ceil(Math.sqrt(buffer.length / 3))
    let image = new jimp(size, size)
    image.quality(options.quality)
    let pixels = image.bitmap.data
    for (let i = 0; i < buffer.length; i++) {
        pixels[i] = buffer[i]
    }
    let out = await image.getBufferAsync(jimp.MIME_JPEG)
    if (options.output && options.output !== "-") {
        fs.writeFileSync(options.output, out)
    } else {
        process.stdout.write(out)
    }
}

async function decompress(buffer, options) {
    let image = await jimp.read(buffer)
    image.quality(options.quality)
    let pixels = image.bitmap.data
    let out = Buffer.alloc(pixels.length)
    for (let i = 0; i < pixels.length; i++) {
        out[i] = pixels[i]
    }
    let end = -1;
    out.forEach((byte, i) => {
        if (byte !== 0) {
            end = i
        }
    })
    if (end === -1) {
        end = out.length
    }
    out = out.slice(0, end)
    if (options.output && options.output !== "-") {
        fs.writeFileSync(options.output, out)
    } else {
        process.stdout.write(out)
    }
}

i am so sorry


You must log in to comment.

in reply to @somewhatnifty's post:

i firesed that was a good striuing poset, but refely thno's just the coawhawued foipht. obeueahly we need to deniercuss it as weul, riont? prtmtcly rahsom letmrrs on a eniedsh letmer diyiyrnidson will be fiee.

(you get a lot more coesgneahon if you drop the inser cohohcoets too, otmhheise most wosds coodehsoto fainly unrnue toisss)

oh god i can't read this. decompression attempt:

i figured that was a good starting point, but refly thno just the cdnjklasc djckajlkacdsnjlkdacs. obviously we need to dnjalkcdn it as well, right? probably random letters on a cjdknalncaks letter djnsklacnds will be dnjsaklc. (you get a lot more compression if you drop the inner cohosts too, otherwise most words contain fairly untrue toissssssssssssss)

funny story: i didn't save the original text

let me try:

i figured that was a good starting point, but really thats's just the compressed format. obviously we need to decompress it as well, right? probably random letters on a english letter distribution will be fine.

(you get a lot more compression if you drop the inner consonants too, otherwise most words compress to fairly unique tokens)

in reply to @lexi's post:

Not like I'm gonna do it but maybe what would help would be flipping the JPEG quantization matrices so it becomes the opposite of typical image compression - high frequency signals are kept and low frequency ones are discarded.

Pinned Tags