flat assembler
Message board for the users of flat assembler.

Index > Windows > Simple PCX and BMP viewer

Author
Thread Post new topic Reply to topic
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek 25 Mar 2012, 20:55
PCX procedures coded from scratch. Sorry, those comments are half on russian/half on english. Code might be ugly, it's been a long time since I programmed something useful on ASM

The BMP and Window creating part is from BarMentaLisk tutorial on assembler.

Maybe someone might need this.


Description: Source code, tech ref, and executable
Download
Filename: pv.zip
Filesize: 15.83 KB
Downloaded: 358 Time(s)

Description: Example PCX files
Download
Filename: pcx_examples.zip
Filesize: 556.43 KB
Downloaded: 368 Time(s)



Last edited by bzdashek on 28 Mar 2012, 08:37; edited 4 times in total
Post 25 Mar 2012, 20:55
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 25 Mar 2012, 21:41
It crashes when there's an invalid file selected. It gives out error: 6. and then sayonara !
Post 25 Mar 2012, 21:41
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek 26 Mar 2012, 05:37
typedef wrote:
It crashes when there's an invalid file selected. It gives out error: 6. and then sayonara !

That's my error handler, you frightened it (thanks for that).

I replaced the archive in the heading post.
Post 26 Mar 2012, 05:37
View user's profile Send private message Reply with quote
gunblade



Joined: 19 Feb 2004
Posts: 209
gunblade 26 Mar 2012, 14:16
Hmm, works well.. Out of interest - what is pcx still used for? I see one of those images is from Prince of Persia? or did you just convert that from another format..

Also thought it would be worth mentioning.. Gimp (open source image editor) supports PCX.. however, it fails on t4, exiting with: "Unusual PCX Flavour, giving up" - You could always submit a patch to them to add the support for that format Very Happy (although you'd probably have to convert it to C.. Rolling Eyes ).
Post 26 Mar 2012, 14:16
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek 26 Mar 2012, 19:41
gunblade wrote:
Hmm, works well.. Out of interest - what is pcx still used for? I see one of those images is from Prince of Persia? or did you just convert that from another format..

Also thought it would be worth mentioning.. Gimp (open source image editor) supports PCX.. however, it fails on t4, exiting with: "Unusual PCX Flavour, giving up" - You could always submit a patch to them to add the support for that format Very Happy (although you'd probably have to convert it to C.. Rolling Eyes ).

Hello, gunblade

That file with arches, which looks like it's from Prince of Persia, is actually from the standard distribution of Windows 3.X, it was provided as a desktop wallpaper, among with other files. It's just my favorite.

It's funny that GIMP gave up reading t4. To create test files I used IrfanView32, a free picture viewer, which supports a number of formats, and t4.pcx is actually ARCHES.BMP converted by IrfanView without any additional corrections, and is a 4-bit per pixel (16-colour) PCX-standard compliant file.

I seriously doubt that someone still uses PCX format for any of the tasks I can think of, because modern file formats and modern compression techniques are much better than of PCX, so my programme is absolutely of no practical use, I believe.
Post 26 Mar 2012, 19:41
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek 28 Mar 2012, 08:38
Updated. I forgot to take debug lines out, so no OpenFileDialog opened, sorry.
Post 28 Mar 2012, 08:38
View user's profile Send private message Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
uart777 25 Apr 2012, 22:21
Here's my .TGA load/save. It uses many HL macros but you get the general idea... "let" is more advanced and open/read/write/etc operate on the "current file" so you don't have to specify a "file pointer" every time.

Code:
; $$$$$$$$$$$$$$$ Z77 ASM LIBRARY $$$$$$$$$$$$$$$$
; *************** SUNGOD SOFTWARE ****************
; ??????????????????? TGA.INC ????????????????????

tga.header db 18 dup(0)

tga.pal  equ byte [tga.header+1]
tga.type equ byte [tga.header+2]
tga.w    equ word [tga.header+12]
tga.h    equ word [tga.header+14]
tga.bpp  equ byte [tga.header+16]

tga.ext db '.tga', 0

; load 24BPP .TGA to 32BPP image/p. if success,
; return allocated image address in eax and w/h
; in ecx/edx. return 0 if error. in this case,
; "image" is the raw linear 32BPP pixel data

; void *load_tga(char *file);

command load.tga, file
locals image, p, bpp,\
x, y, w, h, n, row
open [file]         ; open and read header...
fail .error
read tga.header, 18
cmp tga.bpp, 24     ; verify bpp
jne .error
cmp tga.pal, NO     ; no palette
jne .error
cmp tga.type, 2     ; RGB only
jne .error
movsx ecx, tga.w    ; dimensions. 16BIT each
movsx edx, tga.h
let [w]=ecx,\       ; size in bytes=w*h*4
[h]=edx, ecx*edx,\
ecx<<2, [n]=ecx
allocate ecx        ; allocate image pointer
fail .error
let [image]=eax,\   ; data
ecx=18,\            ; offset=18+1st byte
cl+[tga.header]
seek ecx            ; read image pixels...
.loop [y]=0 to [h]
  let ecx=[h],\       ; row=h-y-1 (upside down)
  ecx-[y], ecx-1,\
  [row]=ecx,\
  ecx*[w], ecx<<2,\   ; ecx=row*w*4
  eax=[image],\       ; line address =
  eax+ecx, [p]=eax    ; &(image+(h-y-1)*w*4)
  .loop [x]=0 to [w]
    let eax=[p],\
    dword [eax]=0
    read [p], 3       ; read BGR24 as RGB24
    add [p], 4        ; advance pointer
  .endl
.endl
close
let eax=[image],\   ; return image
ecx=[w], edx=[h]    ; and w/h in ecx/edx
jmp .r
.error: error E.FILE
.r0: let eax=0
close
.r:
endc

; save 32BPP image as 24BPP .TGA

; int save_tga(char *file, void *image, int w, int h);

command save.tga, file, image, w, h
locals p, x, y, row
create [file]
fail .error
let ecx=[w], tga.w=cx,\
ecx=[h], tga.h=cx
write tga.header, 18
let eax=[image],\
[p]=eax             ; write image pixels...
.loop [y]=0 to [h]
  let ecx=[h],\
  ecx-[y], ecx-1,\   ; row=h-y-1 (upside down)
  [row]=ecx,\
  ecx*[w], ecx<<2,\  ; line address =
  eax=[image],\      ; &(image+(h-y-1)*w*4)
  eax+ecx, [p]=eax
  .loop [x]=0 to [w]
    write [p], 3     ; read BGR24 as RGB24
    add [p], 4       ; advance pointer
  .endl
.endl
close
let eax=1
jmp @f
.error: let eax=0
@@:
endc

; save vga/screen as .TGA. see DRAW.INC. this is
; slow due to repetitive read/write API calls
; for each pixel. just one 1024x768x32 screen
; is 786,432*4 = 3,145,728 bytes!

command screenshot, file
save.tga [file], [vga], [screen.w], [screen.h]
endc
    


bzdashek: "I seriously doubt that someone still uses PCX format"... "because modern file formats and modern compression techniques are much better than of PCX"

Many graphics developers use and/or support formats like PCX/BMP/TGA for easy portability, fast processing and high compression in .ZIP packages. But their RLE scheme wastes an extra byte per pixel.

For the best RLE compression, you can store pixels as 16BPP in files then use leftmost BIT/s for compression and remaining BITs for RGB15 or N:

Code:
* 0.RRRRRGGGGGBBBBB - Uncompressed 15BPP pixel
* 10.NNNNNN - Repeat previous color 6BIT (0-63) # times
* 11.NNNNNNNNNNNNNN - Repeat previous color 14BIT (0-16K) # times
    
Post 25 Apr 2012, 22:21
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 25 Apr 2012, 22:49
uart777 wrote:
For the best RLE compression, you can store pixels as 16BPP in files then use leftmost BIT/s for compression and remaining BITs for RGB15 or N:

Code:
* 0.RRRRRGGGGGBBBBB - Uncompressed 15BPP pixel
* 10.NNNNNN - Repeat previous color 6BIT (0-63) # times
* 11.NNNNNNNNNNNNNN - Repeat previous color 14BIT (0-16K) # times
    
The meaning of "the best" is going to be dependant on the contents of the image. I doubt that there is one single method that will gives best results always.
Post 25 Apr 2012, 22:49
View user's profile Send private message Visit poster's website Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
uart777 25 Apr 2012, 23:33
Obviously, there is no one algorithm that always gives the best results. Not all images are the same.

Simple RLE schemes like this are extremely effective for images containing several consecutive pixels and/or a low number of unique colors (1/2/4/8BBP). In addition, RLE is lossless (maintains 100% quality) which is especially important when creating art/illustration software that re/saves images.
Post 25 Apr 2012, 23:33
View user's profile Send private message Reply with quote
bzdashek



Joined: 15 Feb 2012
Posts: 147
Location: Tolstokvashino, Russia
bzdashek 27 Apr 2012, 07:47
Nice code, thank you!
Post 27 Apr 2012, 07:47
View user's profile Send private message 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 cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.