<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pt-BR">
    <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/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/tags/codec/atom.xml</id>
    <entry xml:lang="pt-BR">
        <title>Minhas apostas antes de comprimir as cartas</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/blog/apostas-antes-de-comprimir-as-cartas/"/>
        <id>https://brennercruvinel.blog/blog/apostas-antes-de-comprimir-as-cartas/</id>
        
        <content type="html" xml:base="https://brennercruvinel.blog/blog/apostas-antes-de-comprimir-as-cartas/">&lt;p&gt;A compressão não pode ter perda, mesmo que a gente tenha que inventar. Eu escrevi essa frase no plano, com essa firmeza, depois do &lt;a href=&quot;https://brennercruvinel.blog/blog/nest-archiver-de-cartas-de-magic/&quot;&gt;primeiro build&lt;/a&gt;. Duas linhas depois eu dizia que vídeo lossless com as cartas ordenadas por similaridade era um caminho, e mais acima tinha descartado o &lt;code&gt;jpegtran&lt;/code&gt; porque &quot;sem perda não conta&quot;. Só fui perceber quando sentei pra escrever as apostas e tive que definir o que eu ia medir, e medir exige dizer contra o quê. Sem perda em relação a quê? Eu não tinha resposta. Eu tinha usado a mesma palavra pra três coisas e não tinha notado.&lt;/p&gt;
&lt;h2 id=&quot;por-que-zstd-nao-morde-jpeg&quot;&gt;Por que zstd não morde JPEG&lt;/h2&gt;
&lt;p&gt;Um JPEG já passou por três etapas que esgotam a redundância que um compressor genérico sabe achar. A imagem vira coeficientes de frequência, os coeficientes de alta frequência são arredondados (é aí que a perda acontece), e o resultado passa por um codificador de entropia. O que sai é um fluxo de bits onde os padrões repetidos já foram comidos. O zstd procura exatamente padrão repetido. É como tentar dobrar um papel que já foi dobrado até o limite: não fica menor, só amassa.&lt;/p&gt;
&lt;p&gt;Então &quot;sem perda&quot; em cima de JPEG tem três sentidos, e só um merece o nome. O primeiro é reempacotar o JPEG de um jeito que a operação inversa devolve o arquivo original byte a byte. O JPEG XL faz isso: pega os coeficientes já arredondados e reescreve com um codificador de entropia melhor, guardando o suficiente pra desfazer. A perda do JPEG continua lá, mas a embalagem fica mais apertada.&lt;/p&gt;
&lt;p&gt;O segundo é re-salvar o mesmo JPEG com &lt;code&gt;jpegtran&lt;/code&gt; ou &lt;code&gt;jpegoptim&lt;/code&gt;. Os pixels ficam idênticos e os bytes mudam. Sem perda pra quem olha, não pra quem confere o hash. E se a fonte já veio otimizada, como os arquivos do Scryfall, o ganho tende a zero.&lt;/p&gt;
&lt;p&gt;O terceiro é o que eu estava propondo sem saber: decodificar os pixels e recomprimir com outro codec sem perda, PNG, WebP, ou vídeo em FFV1. Parece o sentido mais puro e é o pior. O novo codec recebe pixels que carregam o ruído do arredondamento do JPEG como se fosse sinal, e gasta bit pra representar esse ruído com fidelidade. O resultado tem tudo pra ficar maior que o JPEG de origem, não menor. Eu escrevi isso e ainda não acreditava, por isso a aposta.&lt;/p&gt;
&lt;p&gt;Tem uma quarta coisa, que não é um sentido e sim um buraco. Em 2016, um grupo da Tianjin University e da Microsoft Research Asia publicou &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;: eles organizam uma coleção de fotos JPEG como um pseudo-vídeo, compensam a diferença entre fotos vizinhas e tiram o que sobra de redundância no domínio da frequência, e ainda assim devolvem cada JPEG original sem perder um bit. Economia média acima de 31%. É exatamente o que a minha ideia inventada queria ser, feito do jeito certo. Só que não achei implementação aberta, e eu não ia escrever um codec naquela semana. Então o que eu podia medir era o teto com as ferramentas que existem. O teto de verdade, se aquele paper reproduz em carta de Magic, está mais alto, e eu quero deixar isso dito antes de dar meu número.&lt;/p&gt;
&lt;h2 id=&quot;o-que-eu-apostei-e-por-que&quot;&gt;O que eu apostei e por quê&lt;/h2&gt;
&lt;p&gt;Anotei antes de rodar porque da última vez que publiquei um número sem aposta escrita tive que corrigir dois dias depois, e corrigir número publicado é pior do que errar aposta em público.&lt;/p&gt;
&lt;p&gt;Vídeo AV1 com perda comprime bem mais que JPEG solto? Sim, foi o que o primeiro build mostrou e o que eu tinha visto na dermatoscopia. Quanto mais parecidas as cartas vizinhas, mais o vídeo ganha? Sim, e com força: o banco tem 100 mil impressões pra 52 mil ilustrações, quase metade das cartas repete uma arte que já existe em outra, e todas dividem a mesma moldura. Se existe ganho de vídeo, ele mora aí.&lt;/p&gt;
&lt;p&gt;Acelerar o vídeo corta bytes? Eu tinha jogado um dos MP4 no CapCut, acelerado sessenta vezes, e o arquivo saiu com metade do tamanho. Aposto que sim, e se for verdade é a coisa mais barata da lista. Tar mais zstd ganha alguma coisa? Acho que não, pelo motivo da seção de cima. E a ordenação por similaridade vale também pra cartas únicas? Acho que não, já vi ordenação não fazer nada em outro dataset, mas a moldura compartilhada me deixa em dúvida.&lt;/p&gt;
&lt;p&gt;E a que eu mais queria: existe sem perda melhor que JPEG, &quot;mesmo inventando&quot;. Depois de escrever os três sentidos mudei de ideia no meio da aposta. O candidato passou a ser o JPEG XL, e o vídeo sem perda ordenado por similaridade, a ideia inventada, vai perder. As duas que eu mais queria que fossem verdade, o CapCut e o sem perda, eram as que eu menos conseguia defender. Isso costuma ser um sinal.&lt;/p&gt;
&lt;p&gt;A bateria sem perda rodou na mesma noite, dez gerações em cima das mesmas 2.048 cartas. Tar mais zstd deu um pra um, cravado. Re-salvar com &lt;code&gt;jpegtran&lt;/code&gt; rendeu menos de um por cento, os JPEG do Scryfall já vêm otimizados. O teto foi o reempacotamento em JPEG XL, uns 11% menor, com os 2.048 arquivos originais reconstruídos e validados por hash. Subir o esforço do encoder pro máximo rende menos de um por cento a mais por seis vezes o tempo, então o padrão ficou no esforço médio.&lt;/p&gt;
&lt;p&gt;E a ideia inventada perdeu feio. FFV1 e x264 sem quantização, com as cartas ordenadas por similaridade, ficaram três a quatro vezes maiores que o JPEG de origem. A ordenação, nesse regime, moveu o tamanho em quase nada, uma fração de mega num arquivo de centenas. Pixel decodificado de JPEG carrega ruído e nenhum codec prevê ruído, do jeito que eu tinha escrito de manhã sem acreditar.&lt;/p&gt;
&lt;p&gt;Isso virou o perfil de arquivo do Nest: quem não aceita perder nada recebe o JPEG XL reempacotado, 3,6 GB pro corpus inteiro, e cada JPEG volta bit a bit quando pedir. Não é o número que eu queria. É o número que dá pra defender com hash, e eu prefiro esse. As outras apostas, as com perda, estavam rodando enquanto eu escrevia isso. A do CapCut eu já tava com medo de olhar.&lt;/p&gt;
</content>
        
    </entry>
</feed>
