flat assembler
Message board for the users of flat assembler.

Index > Heap > High-Quality Icons

Thread Post new topic Reply to topic

Joined: 17 Jan 2012
Posts: 369
Just wanted to share my HQ 128x128 icons. Created by and for ASM programmers Wink


Download: http://sungod777.zxq.net/icons.zip

My newest project is a custom file explorer/dialog. Intended for LL/systems programmers who do not have a GUI library predefined (os.file.x can be replaced with BIOS equivelants). Screenshot:


Preview of latest code and my I7 .IMAGE file format with powerful compression scheme:

;;;;;;;;;;;;;;;;; PIXELS, PALETTE ;;;;;;;;;;;;;;;;

; does color exist in pixel array or palette?
; return index or -1...

function find.color, p, c, n
locals i
.loop [i]=0 to [n]
  let eax=[p], ecx=[i], eax=[eax+ecx*4]
  .if [c]=eax
    return [i]
endf -1

macro .if.unique.color p, c, n {
find.color p, c, n
.if eax=-1

; create palette ARGB32 from image.
; search image pixels and store all unique
; colors that are not currently in palette.
; if success, return palette address and #
; of colors used in ecx...

function create.palette, image, nc
locals i, n, c, pn, pixels, palette, size
let eax=[nc], eax*4, [size]=eax
try [palette]=allocate eax
memory.zero [palette], [size]
let eax=[image], [pixels]=[?image.p+eax],\
 ecx=[?image.w+eax], edx=[?image.h+eax],\
 ecx*edx, [n]=ecx, [pn]=0
.loop [i]=0 to [n]
  let eax=[pixels], [pixels]+4, [c]=[eax],\
   ecx=[pn], ecx++
  .if.unique.color [palette], [eax], ecx
    let eax=[palette], eax+[pn],\
    [eax]=[c], [pn]+4
let ecx=[pn], ecx/4, ecx++
endf [palette]

; reverse byte order ("endianness") of
; ARGB32/BGRA32 pixels/palette...

function reverse.pixels, p, n
locals i
.loop [i]=0 to [n]
  let eax=[p], ecx=[eax]
  bswap ecx
  let [eax]=ecx, [p]+4

reverse.palette fix reverse.pixels

; convert array of pixels/colors/palette
; from.to A/RGB. p: 32=memory, 24=file

function convert.pixels.32.24, p, n
locals i
let eax=[p], edx=eax
.loop [i]=0 to [n]
  let ecx=[edx+1], ch=[edx+2],\
  [eax]=ecx, edx+4, eax+3

; 24/32 must be copied backwards because
; of overlap (like memmove in C)...

function convert.pixels.24.32, p, n
locals i
let eax=[p], edx=eax, ecx=[n],\
 eax=&[eax+ecx*4-4], ecx*3, ecx-3, edx+ecx
.loop [i]=0 to [n]
  let ecx=[edx], ecx&0FFFFFFh, ecx<<8,\
  [eax]=ecx, edx-3, eax-4

convert.palette.32.24 fix convert.pixels.32.24
convert.palette.24.32 fix convert.pixels.24.32

function convert.palette, palette, n
reverse.palette [palette], [n]
convert.palette.32.24 [palette], [n]

function restore.palette, palette, n
convert.palette.24.32 [palette], [n]
reverse.palette [palette], [n]

; create ARGB24 palette from image.
; return palette address...

function create.palette.24, image, nc
try create.palette [image], [nc]
push eax
convert.palette.32.24 eax, [nc]
pop eax

; get # of occurances in ARGB32 pixels...

function count.color, p, c, n
locals i, s, nc
let [s]=[p], [nc]=0
.loop [i]=0 to [n]
  let eax=[s], [s]+4, ecx=[eax]
  .if [c]=ecx
    let [nc]++
endf [nc]


; un/compress 7BIT pixel array...

; * 0.IIIIIII - 7BIT color index, 0-127
;               (if not &10000000b)
; * 10.AABBCC - 3 2BIT (0-3) indices
; * 110.ABCDE - 5 1BIT (0-1) indices
; * 1110.NNNN - Repeat previous color 2-15
;               # times (if N4 = 0 or 1...)
; * 1110.0000 - If N4=0000b, repeat 255
; * 1110.0001 - If N4=0001b, repeat 1023

function compress.pixels, pixels, n
locals i, p, s, c, pc, rle, size
let [size]=[n], eax=[pixels],\
 [p]=eax, [s]=eax
.loop [i]=0 to [n]
  let eax=[s], ecx==>[eax], [c]=ecx
  .if [i]
    .if [pc]=ecx         ; previous color?
      .if [eax+1] not cl ; check next pixel
        jmp .next        ; can't repeat once
      let [rle]=0
      .while [eax]=cl
        let [rle]++, eax++, [size]--,\
         edx=[rle], edx+[i]
        .if edx>=[n]
          jmp .stop
        .if [rle]>14 ; 4BIT (2-15)
          let cl=11111111b
      .endw ; set rle byte and advance...
      let [s]=eax, eax=[p], [p]++, [size]++,\
       ecx=[rle], cl|11100000b, [eax]=cl
      jmp .el
  let eax=[p], ecx==>[c], [eax]=cl,\
   [p]++, [s]++
  .el: let [pc]=[c]
endf [size]

function uncompress.pixels, pixels, n
locals i, p, q, s, c, x, pc, rle, size
let eax=[n], [size]=eax
try [p]=allocate eax
let [q]=eax, [s]=[pixels]
.loop [i]=0 to [n]
  let eax=[s], ecx==>[eax], [c]=ecx
  .if ecx&11100000b
    let ecx&1111b, [rle]=ecx, ecx--,\
     [size]+ecx, eax=[p], ecx=[c],\
     [eax]=cl, edx=[pc]
    .loop [x]=0 to [rle]
      let [eax]=dl, eax++
    let [p]=eax, [s]++
    let eax=[p], ecx=[c], [pc]=ecx,\
    [eax]=cl, [p]++, [s]++
memory.copy [pixels], [q], [size]
destroy [q]
endf [size]

;;;;;;;;;;;; MY .IMAGE I7 FILE FORMAT ;;;;;;;;;;;;


; * Fast load/save. Perfect 8BIT alignment.
;   No extra bytes
; * Designed for 7BIT color (logos, icons,
;   textures, animations, etc) and is suitable
;   for 1-2BIT (fonts, binary/monochrome
;   masks/matrix)
; * Effective RLE compression scheme. Never
;   results in greater file size. Standard RLE
;   (BMP/PCX/TGA) are not ineffecient at all
; * In one byte, it can encode 5 1BIT pixels,
;   3 2BIT pixels or repeat 2-15/255/1023 times

; HEADER: 16 bytes...

; byte id='I'
; byte type='7'
; dword w, h
; word n.colors ; # palette colors or 0=128
; dword a16

; PALETTE: offset 10h/16. colors are RGB24
; high-endian. most common colors should be
; indices 0-3 to store 3/5 pixels in 1 byte...

; byte colors[128*3] ; RGB24

; PIXELS: offset 190h/400...

; * 0.IIIIIII - 7BIT color index, 0-127
;               (if not &10000000b)
; * 10.AABBCC - 3 2BIT (0-3) indices
; * 110.ABCDE - 5 1BIT (0-1) indices
; * 1110.NNNN - Repeat previous color 2-15
;               # times (if N4 = 0 or 1...)
; * 1110.0000 - If N4=0000b, repeat 255
; * 1110.0001 - If N4=0001b, repeat 1023
; * 1111.???? - Reserved. Invalid if type=7,
;               "Corrupt pixel data"

; note: 2BIT indices may be 0=invisible,
; 1=dark/25%, 2=medium/50%, 3=pure/100% or
; 0/25/50/75 or 0/25/75/100 or 25/50/75/100

 WBYTE type
 NUMBER w, h
 BLOCK a16(6)
ENDS ?image.header

 WBYTE .type='I7'
 NUMBER .w, .h
 BLOCK .a16(6)

TEXT i.ext='.IMAGE'

;;;;;;;;;;;;;;;;;;; LOAD .IMAGE ;;;;;;;;;;;;;;;;;;

function load.i, image, file
locals i, n, p, s, f, x, y, w, h, r,\
 pixels, palette, image.p, size
let [r]=0
fault .r

; load file, read header and allocate image...

try [f]=load.file [file]
cmp word [?image.header.type+eax], 'I7'
jne .!
let ecx=[?image.header.w+eax], [w]=ecx,\
 edx=[?image.header.h+eax], [h]=edx,\
 ecx*edx, [n]=ecx,\
 edx=&[?image.header+eax+16], [palette]=edx,\
 edx+384, [pixels]=edx

try create.image [image], [w], [h]
let eax=[image], [image.p]=[?image.p+eax],\

let eax=[file.n], eax-400, [size]=eax
memory.copy [image.p], [pixels], eax

; get [n]=uncompress.pixels [image.p], [size]

.loop [i]=0 to [n]
  let eax=[p], edx=[palette], ecx=0,\
   cl=[eax], ecx*3, edx=[edx+ecx], edx<<8
  bswap edx
  let eax=[image.p], [eax]=edx,\
  [p]++, [image.p]+4

let [r]=YES
destroy [f]
endf [r]

;;;;;;;;;;;;;;;;;;; SAVE .IMAGE ;;;;;;;;;;;;;;;;;;

function save.i, image, file
locals i, p, w, h, n, r, pixels, palette
let [r]=0
fault .r

; initialize header...

let eax=[image], [p]=[?image.p+eax],\
 ecx=[?image.w+eax], [image.header.w]=ecx,\
 edx=[?image.h+eax], [image.header.h]=edx,\
 [w]=ecx, [h]=edx, ecx*edx, [n]=ecx

; allocate pixel data and create palette.
; pixels are a maximum of 1 byte each, but
; 99% of images will be much smaller...
; (you'd have to create a special image
; that intentionally trips my algorithm
; but no standard image would do this)

try [pixels]=allocate [n]
try [palette]=create.palette [image], 128
convert.palette [palette], 128

; create file, write header and palette...

try create [file]
try write image.header, 16
try write [palette], 384

restore.palette [palette], 128

; scroll through pixels and replace colors
; with 7BIT 0.IIIIIII palette indices...
; (2-DO: a function that sets pixels by
; palette: set.image.pixels.p image, p, bpp)

.loop [i]=0 to [n]
  let eax=[p], ecx=[eax], [p]+4
  find.color [palette], ecx, 128
  let edx=[pixels], edx+[i], [edx]=al

; get [n]=compress.pixels [pixels], [n]

try write [pixels], [n]
let [r]=YES
destroy [pixels], [palette]
endf [r]

; load .BMP, save as .IMAGE. .BMP must
; be saved as 8BPP with 7BIT/128 palette.
; no color quantization yet

function convert.bmp.i, image, file
locale f(256), p
let eax=&[f], [p]=eax
text.copy eax, [file]
try load.image [image], [p]
change.ext [p], i.ext
try save.i [image], [p]
endf 1    
Post 15 Mar 2013, 04:08
View user's profile Send private message Reply with quote

Joined: 30 Mar 2006
Posts: 6038
Location: Poland
These are classy and readable icons, uart777. Smile

I think that many of us will be interested to see your custom file dialog. I can imagine that your graphical programs may be useful to system programmers that may need some kind of quickly made graphical environment to boost development of the newly created OS. However, as for now, it's not a fully equivalent replacement for sophisticated window managers since it has not ability to maintain multiple windows at once and your windows haven't got drag&drop features. Anyway, the general direction is very good and it may be a good start for something far bigger - a real window manager for any open-source non-Windows OS that would be created fully in ASM. Smile

P.S. You posted me a PM over two days ago. I have answered almost immediately after receiving it but seems that you haven't received my answer yet? I still can see it in my Outbox not Sentbox, so I assume that you haven't looked inside the message. Wink
Post 16 Mar 2013, 17:28
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum

Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.