DEMO.DESIGN
Frequently Asked Questions
 
оглавление | demo party в ex-СССР | infused bytes e-mag | новости от ib/news | другие проекты | письмо | win koi lat

следующий фpагмент (2)
Format of a .pcx file ===================== I've had enough of this. Time to put money where mouth is (and if anyone says "I don't want his money after it's been up his bottom" then I'm leaving). Here is the file format for yer bog standad Z-SOFT compat .PCX file complete with some C++ code. Credit for this must go to Let us continue. THE HEADER PCX files begin with a 128 byte header. --------------------------------------------------------------------------- BYTE SIZE DESCRIPTION 0 1 Flag, 10=ZSoft .PCX (Just a Manufacturer ID) 1 1 Version info. 2 1 Encoding. (1 = run length encoding) 3 1 Bits per pixel/per plane. 4 8 Picture dimensions. (Xmin, Ymin) - (Xmax - Ymax) in pixels. 12 2 Horizontal res of creation device. 14 2 Vertical res of creation device. 16 48 16 Colour EGA/VGA palette setting (see below). 64 1 <reserved> 65 1 Number of planes. 66 2 Bytes per scan line. 68 2 1 = colour/BW, 2 = greyscale 70 58 Filler to pad out 128 byte header. [RUN LENGTH ENCODED IMAGE DATA] For 256 colour images the palette is stored after the image data. --------------------------------------------------------------------------- DECODING Run Length Encoded files 1. Find dimensions of image by calculating size. XSize = Xmax - Xmin + 1 and YSize = Ymax - Ymin + 1. 2. Calculate how many bytes required for one scanline. TotalBytes = NumberOfPlanes * BytesPerLine. The encoding method is... READ byte IF byte in range of 0 to 191, copy to bitmap buffer unchanged IF byte in range 192 to 255, subtract 192 from byte. The result is the run-length count for the next byte. Read in this byte and copy it <that> number of times to the bitmap buffer. Repeat until all of bitmap = decompressed. Failing that, go and buy a book. Here is a sample C++ structure for the header. struct PCX_Header { char Blob; // Manufact' ID char Version; // 5 for 256-color files char Encoding; // 1 = Run length char BitsPerPixel; // 8 for 256-color files int Xmin,Ymin; // Coordinates for top left corner int Xmax,Ymax; // Width and height of image int Hres; // Horizontal res of image int Vres; // Vertical res of image char Palette[48]; // EGA palette; not used for 256-color files char Reserved; // Reserved char Colour_Planes; // Color planes int BytesPerLine; // Number of bytes per scan line int PaletteType; // Should be 2 for color palette char Filler[58]; // Funky filler, how about some diary appointments here? }; THE PALETTE The 256 palette is stored in the format Red value Green value Blue value, 3 bytes per entry, that's 3 * 256. The same format for the 16 colour EGA/VGA palette. struct PCX_Palette { unsigned char Palette[3*256]; }
следующий фpагмент (3)|пpедыдущий фpагмент (1)
{$M$1000,0,$A0000,L-,D-,S-,I-,E-} Program PCXViewer; Uses VESA,Crt,Dos; Type PByte = ^Byte; Var dt,ln : PByte; filename : Array[0..79] Of Char; fl : File; header : Record Manufacturer : Byte; { Always $0A, or 10 } Version : Byte; { Version number: 0 - Mono; 2 - 16 Colour; 3 - Def Pal. 5 - 256 Colour } Encoding : Byte; { Always 1 } BitsPerPixel : Byte; { Colour bits } XMin, YMin : Integer; { Image Origin } XMax, YMax : Integer; { Image Dimensions } HRes, VRes : Integer; { Resolution Values } Palette : Array [0..47] Of Byte; { Colour Palette } Reserved : Byte; ColourPlanes : Byte; { Colour Planes } BytesPerLine : Integer; { Line Buffer Size } PaletteType : Integer; { Grey or Colour Palette } Filler : Array [0..57] Of Byte; End; palette : Array[0..767] Of Byte; Function StrPCopy(Dest:PChar; Source:String):PChar; Assembler; Asm Push ds Cld Lds si,Source Les di,Dest Mov bx,di Mov dx,es Lodsb Xor ah,ah Xchg ax,cx Rep Movsb Xor al,al Stosb Xchg ax,bx Pop ds End; Procedure BlankPalette; Var r : Registers; p : Array[0..767] Of Byte; Begin FillChar(p,768,0); r.ax:=$1012; r.bx:=0; r.cx:=256; r.dx:=Ofs(p); r.es:=Seg(p); Intr($10,r); End; Procedure SetPalette; Const Pal16:Array[0..15]Of Byte=(0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63); Var i : Word; r : Registers; Begin If header.BitsPerPixel=8 Then For i:=0 To 767 Do palette[i]:=palette[i] Shr 2 Else For i:=0 To 15 Do Begin palette[Pal16[i]*3]:=header.Palette[i*3] Shr 2; palette[Pal16[i]*3+1]:=header.Palette[i*3+1] Shr 2; palette[Pal16[i]*3+2]:=header.Palette[i*3+2] Shr 2; End; r.ax:=$1012; r.bx:=0; r.cx:=256; r.dx:=Ofs(palette); r.es:=Seg(palette); Intr($10,r); End; Procedure Image256(dat,line:PByte); Assembler; Var xmax,bytes : Word; i,ym,bank : Word; handle : Word; dseg,btg : Word; cp : Word; Asm Mov dseg,ds Mov bank,0 Mov ax,header.YMax Inc ax Cmp ax,VesaMode.Height Jnz @0A Mov ax,VesaMode.Height @0A: Mov ym,ax Mov ax,header.Xmax Inc ax Mov xmax,ax Mov ax,VesaMode.bytes Mov bytes,ax Sub ax,xmax Mov btg,ax Mov es,VesaMode.SegA Xor di,di Mov dx,Offset filename Mov ax,$3D00 Int $21 Jc @Ex Mov handle,ax Lds si,dat Mov dx,si { Read a byte } Mov cx,$80 Mov bx,handle Mov ah,$3F Int $21 Mov i,0 { Initialize loop variables } Call @@FR Jmp @01 @@FR: Lds si,dat { DS:SI -> disk buffer } Mov dx,si { Read a byte } Mov cx,$FFF0 Mov bx,handle Mov ah,$3F Int $21 Mov bx,ax { Number of bytes to decode } RetN @01: Xor dx,dx Xor ch,ch @02: Lodsb { AL - data byte } Dec bx Jnz @03 Push ax Push cx Push dx Call @@FR Pop dx Pop cx Pop ax @03: Mov ah,al { see if it is a string or data } And ah,$C0 Cmp ah,$C0 Jne @05 And al,$3F { Set repeat counter } Mov cl,al Lodsb { AL - data to repeat } Dec bx Jnz @04 Push ax Push cx Push dx Call @@FR Pop dx Pop cx Pop ax @04: Add dx,cx Push dx Mov dx,di Add dx,cx Pop dx Jc @0B Rep Stosb Jmp @06 @0B: Stosb { Loop to fill area with data } Or di,di Jnz @0C Inc bank Call @B1 @0C: Loop @0B Jmp @06 @05: Stosb Inc dx Or di,di Jnz @06 Inc bank Call @B1 @06: Cmp dx,xmax Jne @02 { End of draw line } Add di,btg Jnc @07 Inc bank Call @B1 @07: Inc i Mov ax,ym Cmp ax,i Jne @01 Jmp @Ex @B1: Push ax Push ds Mov ds,dseg Mov al,vesaon Or al,al Jz @B3 Push bx Push dx Mov dx,bank Xor bx,bx Mov ax,64 Mul dx Div VesaMode.Gran Mov dx,ax Push dx Call VesaMode.WinFunc Pop dx Inc bx Call VesaMode.WinFunc Pop dx Pop bx @B3: Pop ds Pop ax RetN @Ex: Mov bx,handle { Close the file } Mov ah,$3E Int $21 Mov ds,dseg End; { Doesn't work properly in 1280x1024 for one line (a two bank line) } Procedure Image16(dat,line:PByte); Assembler; Var bytes,vbytes,bank : Word; i,ym ,dseg : Word; handle,vseg : Word; cp,mask : Byte; Asm Mov dseg,ds Mov cx,header.XMax Mov ah,$FF Not cl And cl,7 Shl ah,cl Mov mask,ah Mov bank,0 Mov ax,VesaMode.SegA Mov vseg,ax Mov ax,VesaMode.Bytes Mov vbytes,ax Mov ax,header.BytesPerLine Mov bytes,ax Mov al,header.ColourPlanes Mov cp,al Mov ax,header.YMax Inc ax Mov ym,ax Mov dx,Offset filename Mov ax,$3D00 Int $21 Jc @Ex Mov handle,ax Lds si,dat Mov dx,si { Read a byte } Mov cx,$80 Mov bx,handle Mov ah,$3F Int $21 Mov i,0 { Initialize loop variables } Call @@FR Jmp @01 @@FR: Lds si,dat { DS:SI -> disk buffer } Mov dx,si { Read a byte } Mov cx,$FFF0 Mov bx,handle Mov ah,$3F Int $21 Mov bx,ax { Number of bytes to decode } RetN @01: Les di,line { ES:DI -> decoded line } Xor dx,dx Xor ch,ch @02: Lodsb { AL - data byte } Dec bx Jnz @03 Push ax Push cx Push dx Call @@FR Pop dx Pop cx Pop ax @03: Mov ah,al { see if it is a string or data } And ah,$C0 Cmp ah,$C0 Jne @05 And al,$3F { Set repeat counter } Mov cl,al Lodsb { AL - data to repeat } Dec bx Jnz @04 Push ax Push cx Push dx Call @@FR Pop dx Pop cx Pop ax @04: Add dx,cx Rep Stosb { Loop to fill area with data } Jmp @06 @05: Stosb Inc dx @06: Mov ax,bytes Shl ax,2 { x4 for all planes } Cmp ax,dx Jne @02 Mov es,vseg Push ds Push si { Draw line } @10: Lds si,line { DS:SI -> image line } Mov ax,vbytes Mul i Mov di,ax Cmp dx,bank Je @09 Mov bank,dx Call @B1 @09: Mov ah,1 { Set colour plane to draw on } @11: Push di Mov al,2 Mov dx,$3C4 Out dx,ax Mov cx,bytes Dec cx Dec cx Mov al,es:[di] { Perform read to initialize video buffer } Rep Movsb { Transfer data line to video buffer } Lodsb And al,mask Stosb Movsb { End of draw line } Pop di Shl ah,1 Cmp ah,16 Jne @11 Inc i Pop si Pop ds Mov ax,ym Cmp ax,i Jne @01 Jmp @Ex @B1: Push ax Push ds Mov ds,dseg Mov al,vesaon Or al,al Jz @B3 Push bx Push dx Mov dx,bank Xor bx,bx Mov ax,64 Mul dx Div VesaMode.Gran Mov dx,ax Push dx Call VesaMode.WinFunc Pop dx Inc bx Call VesaMode.WinFunc Pop dx Pop bx @B3: Pop ds Pop ax RetN @Ex: Mov bx,handle { Close the file } Mov ah,$3E Int $21 Mov ds,dseg End; Procedure ShowImage; Begin GetMem(dt,$FFF0); GetMem(ln,2048); Case header.BitsPerPixel Of 1: Begin Case header.XMax Of 0..639 : SetMode($12); 640..799 : SetMode($102); 800..1023 : SetMode($104); 1024..9999 : SetMode($106); End; SetPalette; {BlankPalette;} Image16(dt,ln); End; 8: Begin Case header.XMax Of 0..319 : SetMode($13); 320..639 : SetMode($101); 640..799 : SetMode($103); 800..1023 : SetMode($105); 1024..9999 : SetMode($107); End; SetPalette; {BlankPalette;} Image256(dt,ln); End; End; {SetPalette;} Sound(660); Delay(100); Sound(880); Delay(50); Sound(440); Delay(75); NoSound; ReadKey; SetMode(3); FreeMem(ln,2048); FreeMem(dt,$FFF0); End; Begin If ParamCount>0 Then Begin If Pos('.',ParamStr(1))=0 Then StrPCopy(filename,ParamStr(1)+'.PCX') Else StrPCopy(filename,ParamStr(1)); Assign(fl,filename); {$I-} Reset(fl,1); {$I+} If IOResult=0 Then Begin BlockRead(fl,header,128); If header.BitsPerPixel=8 Then Begin Seek(fl,FileSize(fl)-769); BlockRead(fl,palette,1); If (palette[0]=12)And(IOResult=0) Then Begin {$I-} BlockRead(fl,palette,768); {$I+} End; End; Close(fl); If header.Manufacturer={PC + Roman X}10{ = PCX!!} Then Begin Writeln; Writeln('Version . . . . ',header.Version); Writeln('Width . . . . . ',header.XMax+1,' pixels'); Writeln('Height . . . . . ',header.YMax+1,' pixels'); Writeln('Bits per Pixel . ',header.BitsPerPixel); Writeln('Planes . . . . . ',header.ColourPlanes); Writeln('X Resolution . . ',header.HRes,' DPI'); Writeln('Y Resolution . . ',header.VRes,' DPI'); Write ('Palette Type . . '); If header.PaletteType=2 Then Writeln('Grey scale') Else Writeln('Colour'); Writeln; If ((header.XMax<640)And(header.YMax<480)And(header.BitsPerPixel<>1)) Or((header.YMax<320)And(header.YMax<200))Or(IsVesa) Then If header.BitsPerPixel*header.ColourPlanes>1 Then Begin Writeln('Press a key to show the image'); ReadKey; ShowImage; End Else Writeln('Cannot display the image without VESA graphics support'); End Else Writeln('It is not a PCX file'); End Else Writeln('Cannot find the file'); End Else Writeln('Usage: PCXVIEW <filename>'); End.
следующий фpагмент (4)|пpедыдущий фpагмент (2)
From : Dennis Juritchev 2:465/73 14 Aug 95 18:05:00 ============================================================== Хм ..... Мы тут потели ,страдали и вот что сделали : Hаписали вьювер PCX'ов на асме ,занимающий 140 (!) байт . Кто сможет ,пусть склепает лучше :) NOTE: Please compile it with /m2 key ! Forever with me Dennis ¦ Denn¦Z MaD C()DeR / UCL === Cut === ;****************************************************; ;* *; ;* <PCX Viewer> *; ;* *; ;* By Slava Kazakov 2:465/73.666@FidoNet <Avid.Inc> *; ;* And some optimizing *; ;* By DennIZ MaD C0DeR // UCL 2:465/73@FidoNet *; ;* *; ;****************************************************; ; NOTE : ; - This progg work _only_ in just one mode : 320x200x256 ; - This progg must run : OurPcx.Com <FileName.Pcx> ; ( If without name - some gluck :) ; - U must compile this progg only with </m2> key ( by TASM ) ; - Size of this progg just 140 bytes ! ; * This progg was maximum optimizing ,budd if U ; some optimizing it , I give U some bootles of beer ! :-) .model tiny .286 .data _paletter db 300h dup (?) _buffer db ? .code org 100h start: ; Preparing filename mov di,82h mov dx,di mov al,0Dh repne scasb mov byte ptr [di-1],bl ; Open File mov ax,3D00h int 21h ; Read Palette mov bx,ax mov ax,4202h mov cx,-1 mov dx,-768 int 21h mov ah,3Fh mov cx,768 push cx mov si,cx mov dx,offset _paletter mov bp,dx int 21h mov ah,42h xor cx,cx mov dx,80h int 21h ;Init Graphics Mode mov al,13h int 10h ; Preparing Palette loop3: shr byte ptr [si+bp],2 dec si jns loop3 ; Programming Palette mov si,bp ; BP is offset to _Paletter mov dx,3c8h mov al,0 out dx,al inc dx pop cx rep outsb mov ah,0A0h ; AL still zero ! mov es,ax xor di,di mov si,offset _buffer ; Read Block loop1: call readbyte ; Put Immage & Decompressing picture mov al,[si] mov ah,al and ah,11000000b cmp ah,11000000b jne lab2 and ax,0000000000111111b mov cx,ax push cx call readbyte pop cx mov al,[si] lab2 equ $+1 rep stosb cmp di,320*200 jne loop1 ; Close File lab1: ; Wait for key pressing ... xor ax,ax int 16h ; Close Graphics Mode mov ax,0003h int 10h ; Return to Dos ret ; Procedure for read just one byte readbyte proc mov ah,3Fh mov cx,1 mov dx,si int 21h ret endp end start === Cut ===

Всего 3 фpагмент(а/ов) |пpедыдущий фpагмент (3)

Если вы хотите дополнить FAQ - пожалуйста пишите.

design/collection/some content by Frog,
DEMO DESIGN FAQ (C) Realm Of Illusion 1994-2000,
При перепечатке материалов этой страницы пожалуйста ссылайтесь на источник: "DEMO.DESIGN FAQ, http://www.enlight.ru/demo/faq".