Notícias

Boas-vindas ao novo mantenedor do Ansel

Jiyoné (Guillaume Stutin) assumiu a manutenção do Ansel desde outubro de 2025. O objetivo atual é transformar o Ansel em uma cooperativa  na qual os usuários possam se tornar membros e controlar democraticamente as orientações e prioridades do projeto, mas também garantir uma retribuição justa e um ambiente de trabalho seguro para aqueles que dedicam sua força de trabalho ao projeto. Apresentei a descrição do problema e a solução proposta na página democracia.

Mudanças na distribuição de pacotes do Ansel

Desenvolvimento

Target clones

Compilar o software nativamente no computador costumava melhorar o desempenho na CPU em cerca de 30 %, em comparação com pacotes pré-compilados. O motivo é que o compilador faz otimizações específicas para o hardware alvo no qual é compilado, enquanto os pacotes pré-compilados precisam permanecer genéricos e acionar otimizações mais conservadoras em prol de um suporte amplo. Note que os kernels OpenCL são, de qualquer forma, compilados para a sua GPU específica usando o seu driver OpenCL, então a história é diferente nesse caso.

Controles de cor finalmente corretos

Development Design

Introdução

Ferramentas vs. Máquinas, Ofícios vs. Indústria

Em seu livro, A Sociedade Tecnológica (1954), Jacques Ellul apresenta a diferença entre o período pré e pós-revolução industrial da seguinte forma:

A era pré-industrial é o reinado da ferramenta e do artesanato. A propriedade principal das ferramentas é serem genéricas, versáteis e adaptáveis. Cabe ao artesão desenvolver suas habilidades para fazer as ferramentas seguirem sua intenção, de modo que a mão compense as limitações do instrumento. Esse conceito ainda é bem conhecido pelos músicos hoje: você tem que praticar, aprender, tentar, falhar, tentar de novo… não há atalhos. Ellul enfatiza a ideia de parcimônia que acompanha as ferramentas: os recursos são limitados, então seu conjunto de ferramentas é praticamente definido pelo que você pode pagar, carregar, dominar e construir localmente. As tendências mudam lentamente e são locais, porque usam recursos locais e se adaptam a necessidades locais, e as ferramentas seguem o mesmo padrão. As ferramentas são heranças passadas de mestre para aprendiz, de pai para filho. Elas não se tornam incompatíveis nem obsoletas.

Reformulando a mesa de luz e o cache de mipmap

Desenvolvimento Redesenho Desempenho

Entre janeiro de 2022 e março de 2026, o Ansel integrou 297 commits (sem contar merges) referentes à grade da mesa de luz, suas miniaturas e seu pipeline de renderização e caching. Tentei me virar com o desleixado código da mesa de luz do Darktable, apenas desengordurado, pelo maior tempo que consegui, mas infelizmente era pura dívida técnica e era dolorosamente lento.

De fato, o Darktable “gerencia” a porcaria de sua mesa de luz reduzindo o tamanho dela: os painéis laterais esquerdo e direito ocupam bastante superfície de exibição, o que deixa uma área ainda menor para a mesa de luz repintar. Como o Ansel removeu o painel lateral direito, fundindo seu conteúdo com o esquerdo e com o menu global, havia mais superfície para pintar, mais trabalho de CPU a fazer, e o péssimo design da mesa de luz tornou-se ainda mais prejudicial.

Revisão completa do pipeline

Development

Desde que comecei a usar o Darktable, por volta de 2012, sempre me surpreendi com a pouca quantidade de RAM que ele usava. As pessoas acham que é uma coisa boa um aplicativo usar a memória com parcimônia, e isso certamente é verdade quando falamos do seu ambiente de trabalho. Mas, tratando-se de um software de produção que faz renderização pesada de pixels em imagens de 12 a 54 Mpixels, isso significa que os mesmos cálculos pesados são feitos repetidamente em vez de serem salvos para reutilização posterior. É para isso que serve um cache: evitar cálculos custosos. E ele deveria usar toda a RAM disponível para isso, porque computar é desperdiçar energia, e isso tem um impacto concreto se você está trabalhando na bateria. Além disso, você pagou por essa RAM e usá-la não esvazia sua bateria. A CPU/GPU, por outro lado…

Mesclagem de histórico tornada robusta e previsível

Development

Memórias de um cara que passou tempo demais limpando a merda dos outros e pagando pelas más decisões deles, episódio #tantos que perdi a conta.

Copiar/colar histórico e estilos são recursos centrais no Ansel, e o que faz com que ele mereça (ou não) o título de “aplicativo de fluxo de trabalho”. Mas também está entre os mais difíceis de acertar internamente. Os usuários veem uma lista de edições, mas por baixo dos panos essas edições dependem da ordem do pipeline, das instâncias de módulos e das máscaras. Se duas imagens têm topologias de pipeline diferentes, copiar edições de forma ingênua pode produzir inconsistências.

Reescrevendo os atalhos de teclado (aceleradores) do zero

GUI Usabilidade

No meu texto de referência, Darktable: batendo no muro em câmera lenta, apresentei o desastre que era o novo “Grande turducken MIDI”. O propósito desse turducken1 era reescrever o sistema de atalhos de teclado para estendê-lo a dispositivos MIDI.

Até hoje, ainda estou irritado com essa empreitada de destruição em massa; aqui vai um resumo dos motivos:

  1. em 2021, substituiu um sistema de atalhos de teclado que era muito bom, completo em recursos, bem testado, estável e escrito em menos de 1500 linhas (comentários incluídos),
  2. …para adicionar suporte a dispositivos MIDI e gamepads de PlayStation (!?!)…
  3. …mas na minha pesquisa sobre o Darktable de 2022, um ano após esse novo recurso, dentre os mais de 1251 usuários que participaram:
    • 81% dos usuários não tinham um dispositivo MIDI e não planejavam adquirir um,
    • 2% nem sabiam o que era um dispositivo MIDI.
    • 8% dos usuários tinham um dispositivo MIDI mas não o usavam com o Darktable,
    • 6% estavam considerando talvez adquirir um dispositivo MIDI no futuro,
    • 2% dos usuários tinham um dispositivo MIDI que realmente usavam no Darktable,
  4. o código era absolutamente terrível, em termos de:
    • qualidade de código: instruções if/switch-case ilegíveis aninhadas em 4 níveis, no meio de funções de 1000 linhas (postei trechos de exemplo no meu artigo),
    • volume de código:
      • 3546 linhas de código para o Darktable 4.0,
      • 4397 linhas de código para o Darktable 5.0,
      • o aumento de volume é uma consequência direta de tentar corrigir bugs em uma arquitetura que não pode ser consertada porque sua complexidade promove mais complexidade. Tudo isso decorre do design, mas resolver problemas criados pela complexidade adicionando mais complexidade não é solução.
    • complexidade de código:
      • complexidade ciclomática :
        • 1088 para o Darktable 4.0,
        • 1245 para o Darktable 5.0 (detalhes ),
      • complexidade cognitiva :
        • 1885 para o Darktable 4.0,
        • 2098 para o Darktable 5.0 (detalhes ).
      • é de longe o recurso mais complexo do software, mesmo não operando sobre imagens. Para comparação, o segundo recurso mais complexo é a decodificação de metadados EXIF, que tem uma complexidade cognitiva de 1348.
  5. ele não decodifica modificadores de tecla por design, mas lida apenas com as teclas pressionadas no hardware, o que significa:
    • a entrada “1” do teclado numérico é decodificada como Keypad End,
    • a entrada “1” de um teclado francês AZERTY é decodificada como Shift+&, ou Shift+" no BÉPO,
    • portanto, você precisa duplicar todos os seus atalhos baseados em números para cada forma de inserir um número, e se preparar para que a janela de configuração de atalhos não contenha nenhum número real nas combinações de teclas.
  6. o design voltado ao usuário é absolutamente terrível, com ações e emulações demais para configurar (“efeitos”), que nem sequer estão totalmente documentadas 4 anos depois (o que é “ctrl-toggle”? “right-activate”?), e a configuração de atalhos usa uma estranha janela dividida que não faz o menor sentido,
  7. a implementação também é terrível: o recurso conhece toda a GUI do software, e a GUI do software conhece o código dos atalhos. Não há modularidade alguma aqui, e mudar qualquer coisa no código dos atalhos pode ter efeitos inesperados e indesejados em qualquer parte do software.2 Basta ver o grafo de dependências abaixo,
  8. vários “atalhos” (ou vinculações MIDI) podem estar associados à mesma ação, o que significa que cada interação do usuário precisa consultar a lista inteira de ações disponíveis, induzindo um tratamento de atalhos muito ineficiente, travamentos da GUI em alguns casos e falsos positivos de “combinação de teclas desconhecida” em casos peculiares.
image
Teclas numéricas não decodificadas e estranha divisão de janela entre "ação" e "atalho".
image

O grafo de dependências de src/gui/accelerators.c (Grande turducken MIDI) antes da reescrita. Adivinhe por que chamamos isso de “código espaguete "… Isso deixa claro que há uma dependência bidirecional entre o código dos aceleradores e o resto do código da GUI. É um pesadelo de manter.

Bem-vindo, Ansel GPT !

Anúncio

Depois de finalmente ter interligado todo o site e a documentação a um fluxo de tradução à prova d’água (usando o po4a por cima do Hugo), que por acaso usa exatamente o mesmo conjunto de ferramentas e a mesma lógica do aplicativo Ansel, tive a ideia de automatizar as traduções vazias, primeiro a partir dos arquivos de tradução do software, depois por meio da API do ChatGPT, que faz um trabalho bastante razoável ao traduzir a sintaxe Markdown.

Boas-vindas, documentação para desenvolvedores !

Desenvolvimento

Lá em dezembro de 2019, eu pedi que alguém se encarregasse de fornecer pacotes AppImage  para o Darktable. O benefício óbvio teria sido possibilitar testes precoces, antes da versão, por parte de pessoas que não conseguem compilar o código-fonte por conta própria, de modo a quem sabe fornecer feedback antecipado e ajudar a depurar antes de lançar. Isso nunca foi uma prioridade, o que significa que estava tudo bem ter uma corrida para corrigir bugs tanto antes quanto depois da versão.

Corrigindo o cache do pipeline e bugs de 10 anos de idade

Desenvolvimento

Resumo dos episódios anteriores

  1. Entre 2020 e 2022, o Darktable passou por um empreendimento de destruição em massa, conduzido por um punhado de sujeitos com mais tempo livre e benevolência do que competência de verdade,
  2. Em 2022, comecei a notar um lag incômodo  entre as interações da interface gráfica com os controles deslizantes e o feedback/atualização dos ditos controles. Por falta de um feedback indicando que a mudança de valor havia sido registrada, os usuários podiam mudá-lo de novo, iniciando assim recomputações adicionais do pipeline e efetivamente travando seus computadores, porque a estúpida interface gráfica nunca dizia “entendi, agora espere um pouco”.
  3. Descobri que as ordens de recomputação do pipeline eram emitidas duas vezes por clique (uma no evento de “botão pressionado”, outra no de “botão solto”), e mais uma vez a cada movimento do mouse, mas também que os estados da interface gráfica eram atualizados aparentemente após a recomputação do pipe.
  4. Corrigi isso reescrevendo quase por completo os controles personalizados da interface gráfica (biblioteca Bauhaus). Achei que impedir as ordens imprudentes de recomputação fosse resolver o lag: não resolveu. Então descobri que solicitar uma nova recomputação do pipeline antes de a anterior terminar esperava a anterior terminar, apesar de um mecanismo de desligamento implementado muitos anos atrás que deveria ter funcionado.
  5. Corrigi isso implementando um mecanismo de kill-switch nos pipelines, seguindo comentários no código dos anos 2010 e utilitários internos que bem podem nunca ter funcionado. Isso nem sempre funcionava porque a ordem de cancelamento vinha muitas vezes com um atraso perceptível. Mais uma vez, o lag da interface gráfica não foi corrigido.

Reescrevendo a ferramenta de importação

Desenvolvimento Redesenho

O Ansel herda do Darktable sua espinha dorsal de banco de dados: os históricos de edição não destrutiva são salvos por imagem em um banco de dados SQLite, junto com metadados e outros dados definidos pelo usuário. Fazer com que o banco de dados reconheça novas imagens é feito através da “importação” de imagens de um disco ou de um cartão de memória. É aí que entra a ferramenta de importação.

Implementando um kill-switch no pipeline

Desenvolvimento

Durante muito tempo, eu achei que houvesse algum mecanismo de kill-switch no pipeline de pixels. O caso de uso é o seguinte:

  1. você está alterando um parâmetro de módulo,
  2. as prévias (a da sala escura central e a miniatura no painel esquerdo, também usada para o histograma e os seletores de cor) recalculam seu pipeline para levar em conta essa alteração,
  3. uma das prévias termina de renderizar antes da outra, e o resultado obviamente não é o que você queria,
  4. você altera novamente o parâmetro de módulo, sem esperar que o recálculo termine.

Nesse caso, você quer encerrar todos os pipelines ativos porque sua saída não será usada, e começar a recalcular tudo imediatamente com os novos parâmetros. Só que o Darktable não faz isso, ele deixa o pipeline terminar antes de reiniciá-lo, e olhando os comentários no código-fonte, parece ser uma regressão bastante recente e não o comportamento originalmente pretendido.

Des-darktable-izando os controles da interface

Desenvolvimento

O Darktable tem sua própria biblioteca de widgets de interface, para controles deslizantes e caixas de combinação (também conhecidas como menus suspensos ou caixas de seleção), chamada Bauhaus (no código-fonte, fica em src/bauhaus/bauhaus.c). Embora usem o Gtk como backend, os Bauhaus são objetos personalizados. E, como muitas coisas no Darktable, personalizado é sinônimo de podre.

Em 2022, ‍notei redesenhos parasitas e travamentos  ao usá-los, resultando em uma experiência de usuário frustrante: o redesenho do widget parecia esperar a conclusão dos recálculos do pipeline, o que significava que os usuários não tinham certeza se a mudança de valor havia sido registrada, o que podia levá-los a tentar novamente, iniciando outro ciclo de recálculo custoso e efetivamente congelando o computador por vários minutos muito frustrantes de recálculos intermediários e inúteis do pipeline.

Mudanças no suporte de distribuição do pacote AppImage para Linux

Anúncio

O Rawspeed (a biblioteca que fornece os decodificadores para arquivos raw de câmera) descontinuou o suporte ao GCC < 12. Como resultado, não posso mais compilar o AppImage no Ubuntu 20.04 (usando os runners do Github), mas tenho que compilá-lo no 22.04.

Isso significa que qualquer distribuição Linux que tenha a libc mais antiga que a 2.35 não conseguirá iniciar os novos AppImages a partir de hoje. Isso não deve afetar a maioria dos usuários que rodam distribuições atualizadas em 2021 ou mais recentemente. O Ubuntu 20.04 e outras distribuições LTS/estáveis antigas (Debian stable) podem ser afetadas.

Explicando a reformulação dos grupos de módulos no Ansel

Design

Se você vem do Darktable, talvez esteja acostumado com isto na sala escura:

image

enquanto o Ansel oferece isto a você:

image

Isso não é por acaso, e chegou a hora de explicar por quê, e por que isso não será estendido com opções de personalização.

Novas opções de compilação para Linux

Desenvolvimento

Descobri por acaso que o script de compilação do Linux usava uma compilação “package”, o que significa que as otimizações de CPU ficam limitadas às genéricas, a fim de produzir binários portáteis que podem ser instalados em qualquer plataforma x86-64. Por “usava”, quero dizer que a compilação package não estava explicitamente desativada, então ficava ativada por padrão.

De qualquer forma, isso agora está desativado por padrão, já que os pacotes de fato (.exe e .appimage) não são compilados através desse script, que se destina principalmente a ajudar os usuários finais. Para recuperar o comportamento anterior, você precisaria executar:

Diário de desenvolvimento #2: apresentando a Chantal

Desenvolvimento

2022 foi tão ruim em termos de e-mails inúteis e ruído que comecei o Virtual Secretary , um framework em Python para escrever filtros de e-mail inteligentes cruzando informações entre várias fontes para adivinhar o que os e-mails recebidos são e se eles são importantes/urgentes ou não. Quando falo de e-mails inúteis, são também notificações do Github, pings no pixls.us (graças a Deus fechei minha conta naquele fórum idiota), YouTube e e-mails diretos de pessoas esperando conseguir alguma ajuda em particular.

Diário de desenvolvimento

Desenvolvimento

Faz aproximadamente 3 meses que renomeei o “R&Darktable” (que ninguém parecia entender direito) para “Ansel”, depois comprei o nome de domínio e criei o site do zero com o Hugo (eu nunca havia programado em Golang antes, mas é basicamente código de template).

Depois gastei um total de 70 h fazendo os builds noturnos dos pacotes para Windows e Linux funcionarem para entrega contínua, algo que o Darktable nunca acertou (“você pode compilar por conta própria, não é difícil”), só para ver o rastreador de bugs explodir depois do lançamento (nada melhor do que encadear a maratona de pré-lançamento com uma de pós-lançamento para reduzir sua expectativa de vida).

Darktable: batendo na parede em câmera lenta

O que acontece quando um bando de fotógrafos amadores, transformados em desenvolvedores amadores, acompanhados por uma turma de desenvolvedores de back-end que criam bibliotecas para desenvolvedores, decide trabalhar sem método nem estrutura em um software profissional destinado a usuários finais, cuja competência central (colorimetria e psicofísica) situa-se em algum ponto entre uma graduação em fotografia e um mestrado em ciências aplicadas, ao mesmo tempo que promete entregar 2 versões por ano sem gestão de projeto? Tudo isso, é claro, em um projeto de onde os fundadores e a primeira geração de desenvolvedores seguiram em frente e fugiram?

Search

You can also ask Chantal, the AI search engine.