Re: Colors and palettes

new topic     » topic index » view thread      » older message » newer message

Hello David and anyone else meddling with multiple palettes,

I've rewritten my ModeX color-finder to be more generic so it can be used
for other purposes.  It was originally used to calculate a 65536-byte
table for color mixing purposes (dest=table[source+dest*256]), by
averaging every possible color combination's rgb values.  There's a more
detailed explanation of this at my Euphoria Zone,
http://www.harborside.com/home/x/xseal/euphoria/ .

The new routine can match any length sequence of rgb triplets to the
current palette.  You can use it to make a translation table for a bitmap
whose palette is different than the one you're using.  Then replace each
pixel in the bitmap with the color from the table.  You can also use the
new routine to convert 24-bit images into 8-bit using a given palette,
but it's pretty slow for large images.

------- heres the code --------
include machine.e

atom squares
squares = allocate(256*4)
for i = 0 to 255 do
    poke4(squares + i*4, power(i-and_bits(i*2,256),2))
end for

constant findcol = allocate(88)
poke(findcol,
   {#60,                    --    0: pusha
    #BA,#00,#00,#00,#00,    --    1: mov edx, source (2)
    #BF,#00,#00,#00,#00,    --    6: mov edi, dest (7)
    #B9,#00,#00,#00,#00,    --    B: mov ecx, count (12)
                            --   10: l1:
    #51,                    --   10: push ecx
    #BE,#00,#00,#00,#00,    --   11: mov esi, palette (18)
    #31,#C9,                --   16: xor ecx, ecx
    #BB,#A0,#86,#01,#00,    --   18: mov ebx, 100000
    #31,#C0,                --   1D: xor eax, eax
                            --   1F: l2:
    #AC,                    --   1F: lodsb
    #2A,#02,                --   20: sub al, [edx]
#8B,#2C,#85,#00,#00,#00,#00,--   22: mov ebp, dword ptr [eax*4 + dword
    squares] (37)
    #AC,                    --   29: lodsb
    #2A,#42,#01,            --   2A: sub al, [edx+1]
#03,#2C,#85,#00,#00,#00,#00,--   2D: add ebp, dword ptr [eax*4 + dword
    squares] (48)
    #AC,                    --   34: lodsb
    #2A,#42,#02,            --   35: sub al, [edx+2]
#03,#2C,#85,#00,#00,#00,#00,--   38: add ebp, dword ptr [eax*4 + dword
    squares] (59)
    #39,#DD,                --   3F: cmp ebp, ebx
    #7D,#04,                --   41: jge l3
    #89,#EB,                --   43: mov ebx, ebp
    #88,#0F,                --   45: mov [edi], cl
                            --   47: l3:
    #FE,#C1,                --   47: inc cl
    #80,#F9,#00,            --   49: cmp cl, byte palsize (75)
    #75,#D1,                --   4C: jne l2
    #59,                    --   4E: pop ecx
    #47,                    --   4F: inc edi
    #42,                    --   50: inc edx
    #42,                    --   51: inc edx
    #42,                    --   52: inc edx
    #49,                    --   53: dec ecx
    #75,#BA,                --   54: jnz l1
    #61,                    --   56: popa
    #C3}                    --   57: ret
    )

atom mem_palette, mem_palsize
mem_palette = 0

function find_colors(sequence colors3)
    sequence result
    atom source, dest
    source = allocate(3 * length(colors3))
    if source = 0 then return {} end if
    dest = allocate(length(colors3))
    if dest = 0 then return {} end if

    for i = 1 to length(colors3) do
        poke(source+i*3-3, colors3[i])
    end for

    poke4(findcol + 2, source)
    poke4(findcol + 7, dest)
    poke4(findcol + 12, length(colors3))
    poke4(findcol + 18, mem_palette)
    poke4(findcol + 37, squares)
    poke4(findcol + 48, squares)
    poke4(findcol + 59, squares)
    poke(findcol + 75, mem_palsize)

    call(findcol)
    free(source)
    result = peek({dest, length(colors3)})
    free(dest)
    return result
end function

procedure choose_palette(sequence pal)
    if mem_palette then
        free(mem_palette)
    end if
    mem_palette = allocate(3 * length(pal))
    mem_palsize = length(pal)
    for i = 1 to length(pal) do
        poke(mem_palette+i*3-3, pal[i])
    end for
end procedure

----------------------------------

First, choose the palette that your program uses with "choose_palette".
Then call "find_colors" with the palette of the image you want to convert,
and a sequence will be returned.  For example:

  object bmp
  sequence colortable
  bmp = read_bitmap("whatever.bmp")
  colortable = find_colors(bmp[1] * 0.25)
  bmp = bmp[2]
  for y = 1 to length(bmp) do
    for x = 1 to length(bmp[y]) do
      bmp[y][x] = colortable[bmp[y][x]+1]
    end for
  end for

I also have a modified image.e that will load 24-bit images. The image is
stored in a normal 2-d sequence with packed rgb values (r+g*256+b*65536),
in order to conserve memory.  Then the 24-to-8-bit decoder goes like this:

  bmp = read_bitmap("whtevr24.bmp")
  bmp = bmp[2]
  for y = 1 to length(bmp) do
    bmp[y] = find_colors(bmp[y] / {4,1024,262144})
  end for

And after all that, I can still use it to generate the look-up table for
the cool transparency effects. :)

Later,
 _______  ______  _______  ______
[    _  \[    _ ][ _   _ ][    _ ]
[/| [_] |[/| [_\][/ | | \][/| [_\]
  |  ___/  |  _]    | |     |  _]
[\| [/]  [\| [_/] [\| |/] [\| [_/]
[_____]  [______] [_____] [______]
       xseal at harborside.com

new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu