criar usplash sem precisar compilar (i386)

Iniciado por nitrofurano, 19 de Dezembro de 2007, 10:36

tópico anterior - próximo tópico

nitrofurano


A partir de algumas paginas na net (forums) e de respostas de alguns autores de
usplash, a unica resposta que obtive foi que eu precisava de compilar makefiles
para obter um .so - mas como sempre fui um bocado atrapalhado com isso de compilar codigo em C (e de certeza não sou só eu...), resolvi experimentar outras hipóteses.

Pensei na hipotese de hackear o .so para substituir as imagens - desconfiei pelo
tamanho dos .so (à volta dos 2mb) que eram grandes demais para conter imagens
comprimidas como jpeg ou png - com o sdlBasic fiz um pequeno programa para mostrar bytes como pixeis numa janela, e deu para confirmar que se tratavam de imagens descomprimidas, de profundidade de 8bit (256 cores), em vários tamanhos como 1024x768, 800x600, etc.

Tentei analisar vários .so de pacotes de usplash do repositório, como o oficial
do Ubuntu, do UbuntuStudio, Edubuntu, Xubuntu, Ichthux, etc.

Acabei por achar o do Ichthux o mais simples de todos, que tinha 3 imagens embebidas:
duas de 1024x768 (sendo a segunda pressupostamente para widescreen, mas não funcionou como tal no meu portátil... - como este hack é um mero remendo, assumi as duas imagens serem duplicadas...), e uma de 800x600.

O tamanho de cada imagem dentro dos cerca de 2mbytes (2064800 bytes) era:
(768 bytes são para a paleta: 256*3)
(1024*768)+768=787200 bytes
(800*600)+768=480768 bytes

Só me restava então localizar o endereço exacto em bytes das imagens, fazer um
script que permitisse obter os fragmentos que não fossem as imagens, e outro
para juntar esses fragmentos a outras imagens que substituissem as antigas com
rigorosamente o mesmo tamanho e localização no tal .so de 2064800 bytes

Para tanto, é necessário o imagemagick instalado, que permite converter quase
qualquer formato de imagem (pelo menos as mais comuns, como .xpm, .png, .jpg, etc.) para .bmp (de cabeça para baixo, que acaba por ser o formato mais semelhante que encontrei com a informação binaria utilizada nas imagens do .so)

Uma nota importante: só testei na arquitectura i386 - quase de certeza que os .so
utilizados em outras arquitecturas (amd64, ppc, alpha), devido aos opcodes dos
processadores serem diferentes, o tamanho dos respectivos .so e a localização das
imagens seja sensivelmente diferentes, e por se tratar de um ficheiro executável
compilado, sendo que 1 byte de erro é o suficiente para a conversão não funcionar,
ou até poder causar danos aos Linux não-i386. (como imaginam, não me responsabilizo pelos danos causados, só posso dizer que os resultados com o que testei com o codigo que disponho abaixo funcionaram comigo, senão eu nem sequer estaria a publicá-los...)

peço desculpa é dos comentários estarem em inglês, mas é pouca coisa

O codigo abaixo é para obter os fragmentos binary*.bin, utilizados pelo conversor

O ficheiro de origem é usplash-theme-ichthux.so, retirado de
ichthux-artwork-usplash_6.10-2_i386.deb (da versão Feisty Fawn do Ubuntu
http://packages.ubuntu.com - funcionou perfeitamente comigo no Gutsy Gibbon)

No terminal, no directório onde está usplash-theme-ichthux.so, façam
'md5sum usplash-theme-ichthux.so' e verifiquem se é 4f2bda51bc2173cfcbacedbe89df3562 , e se o tamanho é exactamente de 2064800 bytes

o ficheiro abaixo na mesma pasta (directorio) em que está usplash-theme-ichthux.so

sofragmentextract.py

#! /usr/bin/python
# -*- coding: latin-1 -*-
import os,sys
# attention: i386 version only (this extractor)
# md5sum: 4f2bda51bc2173cfcbacedbe89df3562  usplash-theme-ichthux.so  2064800 bytes
# from ichthux-artwork-usplash_6.10-2_i386.deb  (http://packages.ubuntu.com - feisty)
# other platforms (amd64, ppc, alpha, etc.) please compare both, and be sure on
#   what you're doing, since adresses almost surelly would be different - the pictures
#   embedded in the .so are 8 bitdepth uncompressed, and their palettes always takes
#   768 bytes - not that hard to find
finp_fl=open("usplash-theme-ichthux.so","r")
fout_fl=open("binary0.bin","w")
for i in range (0,8128,1):
  byte_st=finp_fl.read(1);fout_fl.write(byte_st)
fout_fl.close()
for i in range (8128,795328,1):
  byte_st=finp_fl.read(1)
fout_fl=open("binary1.bin","w")
for i in range (795328,795360,1):
  byte_st=finp_fl.read(1);fout_fl.write(byte_st)
fout_fl.close()
for i in range (795360,1582560,1):
  byte_st=finp_fl.read(1)
fout_fl=open("binary2.bin","w")
for i in range (1582560,1582592,1):
  byte_st=finp_fl.read(1);fout_fl.write(byte_st)
fout_fl.close()
for i in range (1582592,2063360,1):
  byte_st=finp_fl.read(1)
fout_fl=open("binary3.bin","w")
for i in range (2063360,2064800,1):
  byte_st=finp_fl.read(1);fout_fl.write(byte_st)
fout_fl.close()
finp_fl.close()
#os.system("gksudo chmod 555 bin*.bin")
os.system("mkdir data")
os.system("mv bin*.bin data")


E entrem 'python sofragmentextract.py'

Devem ser criados 4 ficheiros binary*.bin dentro da pasta './data/'

E com o converor abaixo, dentro da mesma pasta onde está './sofragmentextract.py'

pic2iso.py

#! /usr/bin/python
# -*- coding: latin-1 -*-
import os,sys

# usage: python pic2so.py splashfilename.jpg
# a neighbour file named splashfilename.jpg.so will appear
# needs imagemagick installed

finp_st=sys.argv[1]
os.system("convert "+finp_st+" -flip -colors 255 -compress None -resize 800x600! _tmpr_800600.bmp")
os.system("convert "+finp_st+" -flip -colors 255 -compress None -resize 1024x768! _tmpr_1024768.bmp")

finp_fl=open("_tmpr_1024768.bmp","r")
for i in range (0,0x0A,1):byte_st=finp_fl.read(1)
byte_st=finp_fl.read(1);ppos=ord(byte_st);byte_st=finp_fl.read(1);ppos+=(ord(byte_st))*256
finp_fl.close()
finp_fl=open("_tmpr_1024768.bmp","r")
for i in range (0,0x32,1):byte_st=finp_fl.read(1)
byte_st=finp_fl.read(1);cpos=ord(byte_st);byte_st=finp_fl.read(1);cpos+=(ord(byte_st))*256
finp_fl.close()
finp_fl=open("_tmpr_1024768.bmp","r")
for i in range (0,ppos-(cpos*4),1):byte_st=finp_fl.read(1)
fout_fl=open("_tmpr_palette01.bin","w")
for i in range (0,256,1):
  bc_st=finp_fl.read(1);gc_st=finp_fl.read(1);rc_st=finp_fl.read(1);xc_st=finp_fl.read(1)
  fout_fl.write(rc_st);fout_fl.write(gc_st);fout_fl.write(bc_st)
finp_fl.close();fout_fl.close()
finp_fl=open("_tmpr_1024768.bmp","r")
for i in range (0,ppos,1):byte_st=finp_fl.read(1)
fout_fl=open("_tmpr_pic01.bin","w")
for i in range (0,1024*768,1):byte_st=finp_fl.read(1);fout_fl.write(byte_st)
finp_fl.close();fout_fl.close()

finp_fl=open("_tmpr_800600.bmp","r")
for i in range (0,0x0A,1):byte_st=finp_fl.read(1)
byte_st=finp_fl.read(1);ppos=ord(byte_st);byte_st=finp_fl.read(1);ppos+=(ord(byte_st))*256
finp_fl.close()
finp_fl=open("_tmpr_800600.bmp","r")
for i in range (0,0x32,1):byte_st=finp_fl.read(1)
byte_st=finp_fl.read(1);cpos=ord(byte_st);byte_st=finp_fl.read(1);cpos+=(ord(byte_st))*256
finp_fl.close()
finp_fl=open("_tmpr_800600.bmp","r")
for i in range (0,ppos-(cpos*4),1):byte_st=finp_fl.read(1)
fout_fl=open("_tmpr_palette02.bin","w")
for i in range (0,256,1):
  bc_st=finp_fl.read(1);gc_st=finp_fl.read(1);rc_st=finp_fl.read(1);xc_st=finp_fl.read(1)
  fout_fl.write(rc_st);fout_fl.write(gc_st);fout_fl.write(bc_st)
finp_fl.close();fout_fl.close()
finp_fl=open("_tmpr_800600.bmp","r")
for i in range (0,ppos,1):byte_st=finp_fl.read(1)
fout_fl=open("_tmpr_pic02.bin","w")
for i in range (0,800*600,1):byte_st=finp_fl.read(1);fout_fl.write(byte_st)
finp_fl.close();fout_fl.close()

os.system("cat data/binary0.bin > _final_.bin")
os.system("cat _tmpr_palette01.bin >> _final_.bin")
os.system("cat _tmpr_pic01.bin >> _final_.bin")
os.system("cat data/binary1.bin >> _final_.bin")
os.system("cat _tmpr_palette01.bin >> _final_.bin")
os.system("cat _tmpr_pic01.bin >> _final_.bin")
os.system("cat data/binary2.bin >> _final_.bin")
os.system("cat _tmpr_palette02.bin >> _final_.bin")
os.system("cat _tmpr_pic02.bin >> _final_.bin")
os.system("cat data/binary3.bin >> _final_.bin")
os.system("mv _final_.bin "+finp_st+".so")
os.system("rm _tmpr_*.*")


Metam uma imagem qualquer na mesma pasta e entrem
'python pic2iso.py imagemescolhida.jpg'

E o .so resultante deverá aparecer, também com 2064800 bytes

Só resta verem como instalar este .so resultante. '/usr/lib/usplash' é um dos
directórios onde normalmente ficam esses .so - creio que existam utilitários
ou tutoriais em forums ou paginas que expliquem melhor como instalá-los.

Uma nota importante: verifiquem a proporção das imagens originais antes de
as converterem - 1024x768, 1600x1200 e 640x480 são 4x3, 800x500 e 1280x800 são 8x5, e 1280x1024 é 5x4 - importante, para que o resultado não apareça distorcido (como é tão comum acontecer a tanta gente...)

comentem...


Cleitonsb

Muito bom msm... Quando sai pra algum .so com base no 7.10? ou no 8.04?