<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Brenner Cruvinel - codec</title>
    <subtitle>AI researcher and product designer building at the edge of computer science and mental health.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://brennercruvinel.blog/en/tags/codec/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://brennercruvinel.blog"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-09-01T00:00:00+00:00</updated>
    <id>https://brennercruvinel.blog/en/tags/codec/atom.xml</id>
    <entry xml:lang="en">
        <title>My bets before compressing the cards</title>
        <published>2026-09-01T00:00:00+00:00</published>
        <updated>2026-09-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            Brenner Cruvinel
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://brennercruvinel.blog/en/blog/apostas-antes-de-comprimir-as-cartas/"/>
        <id>https://brennercruvinel.blog/en/blog/apostas-antes-de-comprimir-as-cartas/</id>
        
        <content type="html" xml:base="https://brennercruvinel.blog/en/blog/apostas-antes-de-comprimir-as-cartas/">&lt;p&gt;The compression can&#39;t lose anything, even if we have to invent it. I wrote that sentence in the plan, that confidently, after the &lt;a href=&quot;https://brennercruvinel.blog/en/blog/nest-archiver-de-cartas-de-magic/&quot;&gt;first build&lt;/a&gt;. Two lines later I was saying lossless video with the cards sorted by similarity was a path, and further up I had dismissed &lt;code&gt;jpegtran&lt;/code&gt; because &quot;lossless doesn&#39;t count&quot;. I only noticed when I sat down to write the bets and had to define what I was going to measure, and measuring requires saying against what. Lossless relative to what? I had no answer. I had used the same word for three things and hadn&#39;t noticed.&lt;/p&gt;
&lt;h2 id=&quot;why-zstd-can-t-bite-into-a-jpeg&quot;&gt;Why zstd can&#39;t bite into a JPEG&lt;/h2&gt;
&lt;p&gt;A JPEG has already gone through three stages that exhaust the redundancy a general-purpose compressor knows how to find. The image becomes frequency coefficients, the high-frequency coefficients get rounded (that&#39;s where the loss happens), and the result goes through an entropy coder. What comes out is a bitstream where the repeated patterns have already been eaten. zstd looks for exactly that, repeated patterns. It&#39;s like trying to fold a sheet of paper that&#39;s already folded to the limit: it doesn&#39;t get smaller, it just crumples.&lt;/p&gt;
&lt;p&gt;So &quot;lossless&quot; on top of JPEG has three meanings, and only one deserves the name. The first is repacking the JPEG in a way where the inverse operation gives back the original file byte for byte. JPEG XL does this: it takes the already-rounded coefficients and rewrites them with a better entropy coder, keeping enough to undo it. The JPEG&#39;s loss is still there, but the packaging is tighter.&lt;/p&gt;
&lt;p&gt;The second is re-saving the same JPEG with &lt;code&gt;jpegtran&lt;/code&gt; or &lt;code&gt;jpegoptim&lt;/code&gt;. The pixels stay identical and the bytes change. Lossless for whoever looks, not for whoever checks the hash. And if the source is already optimized, like the files from Scryfall, the gain tends to zero.&lt;/p&gt;
&lt;p&gt;The third is what I was proposing without knowing it: decode the pixels and recompress them with another lossless codec, PNG, WebP, or FFV1 video. It looks like the purest meaning and it&#39;s the worst. The new codec receives pixels carrying the JPEG&#39;s rounding noise as if it were signal, and spends bits representing that noise faithfully. Everything points to the result being bigger than the source JPEG, not smaller. I wrote that and still didn&#39;t believe it, hence the bet.&lt;/p&gt;
&lt;p&gt;There&#39;s a fourth thing, which isn&#39;t a meaning but a gap. In 2016, a group from Tianjin University and Microsoft Research Asia published &lt;a rel=&quot;external&quot; href=&quot;https://doi.org/10.1109/TIP.2016.2551366&quot;&gt;&quot;Lossless Compression of JPEG Coded Photo Collections&quot;&lt;/a&gt;: they arrange a collection of JPEG photos as a pseudo-video, compensate the difference between neighboring photos, remove the remaining redundancy in the frequency domain, and still give back every original JPEG without losing a bit. Average savings above 31%. That&#39;s exactly what my invented idea wanted to be, done the right way. Except I couldn&#39;t find an open implementation, and I wasn&#39;t going to write a codec that week. So what I could measure was the ceiling with the tools that exist. The real ceiling, if that paper reproduces on Magic cards, is higher, and I want to say that before giving my number.&lt;/p&gt;
&lt;h2 id=&quot;what-i-bet-and-why&quot;&gt;What I bet and why&lt;/h2&gt;
&lt;p&gt;I wrote it down before running anything, because the last time I published a number without a written bet I had to correct it two days later, and correcting a published number is worse than losing a bet in public.&lt;/p&gt;
&lt;p&gt;Does lossy AV1 video compress much better than loose JPEGs? Yes, that&#39;s what the first build showed and what I had seen with dermoscopy. The more alike neighboring cards are, the more the video gains? Yes, and strongly: the database has 100 thousand printings for 52 thousand illustrations, almost half the cards repeat art that already exists on another, and they all share the same frame. If there&#39;s a video gain, it lives there.&lt;/p&gt;
&lt;p&gt;Does speeding up the video cut bytes? I had dropped one of the MP4s into CapCut, sped it up sixty times, and the file came out half the size. I bet yes, and if it&#39;s true it&#39;s the cheapest item on the list. Does tar plus zstd gain anything? I think not, for the reason in the section above. And does sorting by similarity help with unique cards too? I think not, I&#39;ve seen sorting do nothing on another dataset, but the shared frame leaves me unsure.&lt;/p&gt;
&lt;p&gt;And the one I wanted most: there&#39;s a lossless option better than JPEG, &quot;even if we invent it&quot;. After writing out the three meanings, I changed my mind halfway through the bet. The candidate became JPEG XL, and the lossless video sorted by similarity, the invented idea, is going to lose. The two I most wanted to be true, CapCut and lossless, were the two I could least defend. That&#39;s usually a sign.&lt;/p&gt;
&lt;p&gt;The lossless run went that same night, ten variants on the same 2,048 cards. Tar plus zstd came out one to one, exactly. Re-saving with &lt;code&gt;jpegtran&lt;/code&gt; gave less than one percent, the Scryfall JPEGs are already optimized. The ceiling was the JPEG XL repack, about 11% smaller, with all 2,048 original files rebuilt and validated by hash. Pushing the encoder effort to the maximum gives less than one percent more for six times the time, so the default stayed at medium effort.&lt;/p&gt;
&lt;p&gt;And the invented idea lost badly. FFV1 and x264 without quantization, with the cards sorted by similarity, came out three to four times bigger than the source JPEG. Sorting, in that regime, barely moved the size at all, a fraction of a megabyte on a file of hundreds. A decoded JPEG pixel carries noise and no codec predicts noise, just as I had written that morning without believing it.&lt;/p&gt;
&lt;p&gt;That became Nest&#39;s archive profile: anyone who won&#39;t accept losing anything gets the JPEG XL repack, 3.6 GB for the whole corpus, and every JPEG comes back bit for bit on request. It&#39;s not the number I wanted. It&#39;s the number I can defend with a hash, and I prefer that one. The other bets, the lossy ones, were running while I wrote this. The CapCut one, I was already afraid to look at.&lt;/p&gt;
</content>
        
    </entry>
</feed>
