syslinux-legacy-3.63+dfsg/0000775000175000017500000000000011730614544014177 5ustar evanevansyslinux-legacy-3.63+dfsg/rawcon.inc0000664000175000017500000000256710777447273016212 0ustar evanevan; ; writechr: Write a single character in AL to the console without ; mangling any registers. This does raw console writes, ; since some PXE BIOSes seem to interfere regular console I/O. ; %if IS_ISOLINUX writechr_full: %else writechr: %endif push ds push cs pop ds test byte [UsingVGA], 08h jz .videook call vgaclearmode .videook: call write_serial ; write to serial port if needed pushfd test byte [DisplayCon],01h ; Write to screen? jz .nothing pushad mov bh,[BIOS_page] push ax mov ah,03h ; Read cursor position int 10h pop ax cmp al,8 je .bs cmp al,13 je .cr cmp al,10 je .lf push dx mov bh,[BIOS_page] mov bl,07h ; White on black mov cx,1 ; One only mov ah,09h ; Write char and attribute int 10h pop dx inc dl cmp dl,[VidCols] jna .curxyok xor dl,dl .lf: inc dh cmp dh,[VidRows] ja .scroll .curxyok: mov bh,[BIOS_page] mov ah,02h ; Set cursor position int 10h .ret: popad .nothing: popfd pop ds ret .scroll: dec dh mov bh,[BIOS_page] mov ah,02h int 10h mov ax,0601h ; Scroll up one line mov bh,[ScrollAttribute] xor cx,cx mov dx,[ScreenSize] ; The whole screen int 10h jmp short .ret .cr: xor dl,dl jmp short .curxyok .bs: sub dl,1 jnc .curxyok mov dl,[VidCols] sub dh,1 jnc .curxyok xor dh,dh jmp short .curxyok syslinux-legacy-3.63+dfsg/writehex.inc0000664000175000017500000000217610777447273016554 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; writehex.inc ;; ;; Write hexadecimal numbers to the console ;; section .text ; ; writehex[248]: Write a hex number in (AL, AX, EAX) to the console ; writehex2: pushfd pushad rol eax,24 mov cx,2 jmp short writehex_common writehex4: pushfd pushad rol eax,16 mov cx,4 jmp short writehex_common writehex8: pushfd pushad mov cx,8 writehex_common: .loop: rol eax,4 push eax and al,0Fh cmp al,10 jae .high .low: add al,'0' jmp short .ischar .high: add al,'A'-10 .ischar: call writechr pop eax loop .loop popad popfd ret syslinux-legacy-3.63+dfsg/ui.inc0000664000175000017500000003567610777447273015345 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ; ; This file should be entered with the config file open (for getc) ; load_config_file: call parse_config ; Parse configuration file no_config_file: call adv_init ; ; Check for an ADV boot-once entry ; mov dl,ADV_BOOTONCE call adv_get jcxz .no_bootonce .have_bootone: ; We apparently have a boot-once set; clear it and ; then execute the boot-once... ; Save the boot-once data; SI = data, CX = length mov di,command_line rep movsb xor ax,ax stosb ; Clear the boot-once data from the ADV xor cx,cx ; Set to zero = delete call adv_set jc .err call adv_write .err: jmp load_kernel .no_bootonce: ; ; Check whether or not we are supposed to display the boot prompt. ; check_for_key: cmp word [ForcePrompt],0 ; Force prompt? jnz enter_command test byte [KbdFlags],5Bh ; Shift Alt Caps Scroll jz auto_boot ; If neither, default boot enter_command: cmp word [NoEscape],0 ; If NOESCAPE, no prompt, jne auto_boot ; always run default cmd mov si,boot_prompt call cwritestr mov byte [FuncFlag],0 ; not pressed mov di,command_line ; ; get the very first character -- we can either time ; out, or receive a character press at this time. Some dorky BIOSes stuff ; a return in the buffer on bootup, so wipe the keyboard buffer first. ; clear_buffer: mov ah,11h ; Check for pending char int 16h jz get_char_time mov ah,10h ; Get char int 16h jmp short clear_buffer ; For the first character, both KbdTimeout and ; TotalTimeout apply; after that, only TotalTimeout. get_char_time: mov eax,[TotalTimeout] mov [ThisTotalTo],eax mov eax,[KbdTimeout] mov [ThisKbdTo],eax get_char: call getchar_timeout and dword [ThisKbdTo],0 ; For the next time... and al,al jz func_key got_ascii: cmp al,7Fh ; == je backspace cmp al,' ' ; ASCII? jb not_ascii ja enter_char cmp di,command_line ; Space must not be first je short get_char enter_char: test byte [FuncFlag],1 jnz ctrl_f ; Keystroke after cmp di,max_cmd_len+command_line ; Check there's space jnb short get_char stosb ; Save it call writechr ; Echo to screen jmp short get_char not_ascii: cmp al,0Dh ; Enter je command_done cmp al,'F' & 1Fh ; je set_func_flag %if IS_PXELINUX cmp al,'N' & 1Fh ; je show_network_info %endif cmp al,'U' & 1Fh ; je kill_command ; Kill input line cmp al,'V' & 1Fh ; je print_version cmp al,'X' & 1Fh ; je force_text_mode cmp al,08h ; Backspace jne get_char backspace: cmp di,command_line ; Make sure there is anything je get_char ; to erase dec di ; Unstore one character mov si,wipe_char ; and erase it from the screen call cwritestr get_char_2: jmp short get_char kill_command: call crlf jmp enter_command force_text_mode: call vgaclearmode jmp enter_command set_func_flag: mov byte [FuncFlag],1 jmp short get_char_2 ctrl_f: xor ah,ah mov [FuncFlag],ah cmp al,'0' jb get_char_2 je .zero ; 0 = F10 or al,20h ; Lower case cmp al,'9' jna .digit cmp al,'a' ; F10-F12 = A, B, C jb get_char_2 cmp al,'c' ja get_char_2 sub al,'a'-10 jmp show_help .zero: mov al,10 jmp show_help .digit: sub al,'1' jmp show_help func_key: ; AL = 0 if we get here xchg al,ah cmp al,44h ; F10 ja .f11_f12 sub al,3Bh ; F1 jb get_char_2 jmp show_help .f11_f12: cmp al,85h ; F11 jb get_char_2 cmp al,86h ; F12 ja get_char_2 sub al,85h-10 show_help: ; AX = func key # (0 = F1, 9 = F10, 11 = F12) push di ; Save end-of-cmdline pointer shl ax,FILENAME_MAX_LG2 ; Convert to pointer add ax,FKeyName xchg di,ax cmp byte [di+NULLOFFSET],NULLFILE je short fk_nofile ; Undefined F-key call open jz short fk_nofile ; File not found call crlf call get_msg_file jmp short fk_wrcmd print_version: push di ; Command line write pointer mov si,syslinux_banner call cwritestr %ifdef HAVE_BIOSNAME mov si,[BIOSName] call cwritestr %endif mov si,copyright_str call cwritestr ; ... fall through ... ; Write the boot prompt and command line again and ; wait for input. Note that this expects the cursor ; to already have been CRLF'd, and that the old value ; of DI (the command line write pointer) is on the stack. fk_wrcmd: mov si,boot_prompt call cwritestr pop di ; Command line write pointer push di mov byte [di],0 ; Null-terminate command line mov si,command_line call cwritestr ; Write command line so far fk_nofile: pop di jmp get_char ; ; Show network info (in the form of the ipappend strings) ; %if IS_PXELINUX show_network_info: push di ; Command line write pointer call crlf mov si,IPAppends ; See comboot.doc mov cx,numIPAppends .loop: lodsw push si mov si,ax call cwritestr call crlf pop si loop .loop jmp fk_wrcmd %endif ; ; Jump here to run the default command line ; auto_boot: mov si,default_cmd mov di,command_line mov cx,(max_cmd_len+4) >> 2 rep movsd jmp short load_kernel ; ; Jump here when the command line is completed ; command_done: call crlf cmp di,command_line ; Did we just hit return? je auto_boot xor al,al ; Store a final null stosb load_kernel: ; Load the kernel now ; ; First we need to mangle the kernel name the way DOS would... ; mov si,command_line mov di,KernelName push si call mangle_name pop si ; ; Fast-forward to first option (we start over from the beginning, since ; mangle_name doesn't necessarily return a consistent ending state.) ; clin_non_wsp: lodsb cmp al,' ' ja clin_non_wsp clin_is_wsp: and al,al jz clin_opt_ptr lodsb cmp al,' ' jbe clin_is_wsp clin_opt_ptr: dec si ; Point to first nonblank mov [CmdOptPtr],si ; Save ptr to first option ; ; If "allowoptions 0", put a null character here in order to ignore any ; user-specified options. ; mov ax,[AllowOptions] and ax,ax jnz clin_opt_ok mov [si],al clin_opt_ok: ; ; Now check if it is a "virtual kernel" ; vk_check: mov esi,[HighMemSize] ; Start from top of memory .scan: cmp esi,[VKernelEnd] jbe .not_vk mov di,VKernelBuf call rllunpack ; ESI updated on return sub di,cx ; Return to beginning of buf push si mov si,KernelName mov cx,FILENAME_MAX es repe cmpsb pop si je .found jmp .scan ; ; We *are* using a "virtual kernel" ; .found: push es push word real_mode_seg pop es mov di,cmd_line_here mov si,VKernelBuf+vk_append mov cx,[VKernelBuf+vk_appendlen] rep movsb mov [CmdLinePtr],di ; Where to add rest of cmd pop es mov di,KernelName push di mov si,VKernelBuf+vk_rname mov cx,FILENAME_MAX ; We need ECX == CX later rep movsb pop di %if IS_PXELINUX mov al,[VKernelBuf+vk_ipappend] mov [IPAppend],al %endif xor bx,bx ; Try only one version mov al, [VKernelBuf+vk_type] mov [KernelType], al %if IS_PXELINUX || IS_ISOLINUX ; Is this a "localboot" pseudo-kernel? %if IS_PXELINUX cmp byte [VKernelBuf+vk_rname+4], 0 %else cmp byte [VKernelBuf+vk_rname], 0 %endif jne get_kernel ; No, it's real, go get it mov ax, [VKernelBuf+vk_rname+1] jmp local_boot %else jmp get_kernel %endif .not_vk: ; ; Not a "virtual kernel" - check that's OK and construct the command line ; cmp word [AllowImplicit],byte 0 je bad_implicit push es push si push di mov di,real_mode_seg mov es,di mov si,AppendBuf mov di,cmd_line_here mov cx,[AppendLen] rep movsb mov [CmdLinePtr],di pop di pop si pop es mov [KernelType], cl ; CL == 0 here ; ; Find the kernel on disk ; get_kernel: mov byte [KernelName+FILENAME_MAX],0 ; Zero-terminate filename/extension mov di,KernelName+4*IS_PXELINUX xor al,al mov cx,FILENAME_MAX-5 ; Need 4 chars + null repne scasb ; Scan for final null jne .no_skip dec di ; Point to final null .no_skip: mov [KernelExtPtr],di mov bx,exten_table .search_loop: push bx mov di,KernelName ; Search on disk call searchdir pop bx jnz kernel_good mov eax,[bx] ; Try a different extension mov si,[KernelExtPtr] mov [si],eax mov byte [si+4],0 add bx,byte 4 cmp bx,exten_table_end jna .search_loop ; allow == case (final case) ; Fall into bad_kernel ; ; bad_kernel: Kernel image not found ; bad_implicit: The user entered a nonvirtual kernel name, with "implicit 0" ; bad_implicit: bad_kernel: mov cx,[OnerrorLen] and cx,cx jnz on_error .really: mov si,KernelName mov di,KernelCName push di call unmangle_name ; Get human form mov si,err_notfound ; Complain about missing kernel call cwritestr pop si ; KernelCName call cwritestr mov si,crlf_msg jmp abort_load ; Ask user for clue ; ; on_error: bad kernel, but we have onerror set; CX = OnerrorLen ; on_error: mov si,Onerror mov di,command_line push si ; push di ; push cx ; push cx ; push di ; repe cmpsb pop di ; di == command_line pop bx ; bx == [OnerrorLen] je bad_kernel.really ; Onerror matches command_line already neg bx ; bx == -[OnerrorLen] lea cx,[max_cmd_len+bx] ; CX == max_cmd_len-[OnerrorLen] mov di,command_line+max_cmd_len-1 mov byte [di+1],0 ; Enforce null-termination lea si,[di+bx] std rep movsb ; Make space in command_line cld pop cx ; cx == [OnerrorLen] pop di ; di == command_line pop si ; si == Onerror rep movsb jmp load_kernel ; ; kernel_corrupt: Called if the kernel file does not seem healthy ; kernel_corrupt: mov si,err_notkernel jmp abort_load ; ; Get a key, observing ThisKbdTO and ThisTotalTO -- those are timeouts ; which can be adjusted by the caller based on the corresponding ; master variables; on return they're updated. ; ; This cheats. If we say "no timeout" we actually get a timeout of ; 7.5 years. ; getchar_timeout: call vgashowcursor RESET_IDLE .loop: push word [BIOS_timer] call pollchar jnz .got_char pop ax cmp ax,[BIOS_timer] ; Has the timer advanced? je .loop DO_IDLE dec dword [ThisKbdTo] jz .timeout dec dword [ThisTotalTo] jnz .loop .timeout: ; Timeout!!!! pop cx ; Discard return address call vgahidecursor mov si,Ontimeout ; Copy ontimeout command mov di,command_line mov cx,[OntimeoutLen] ; if we have one... rep movsb jmp command_done .got_char: pop cx ; Discard call getchar call vgahidecursor ret ; ; This is it! We have a name (and location on the disk)... let's load ; that sucker!! First we have to decide what kind of file this is; base ; that decision on the file extension. The following extensions are ; recognized; case insensitive: ; ; .com - COMBOOT image ; .cbt - COMBOOT image ; .c32 - COM32 image ; .bs - Boot sector ; .0 - PXE bootstrap program (PXELINUX only) ; .bin - Boot sector ; .bss - Boot sector, but transfer over DOS superblock (SYSLINUX only) ; .img - Floppy image (ISOLINUX only) ; ; Anything else is assumed to be a Linux kernel. ; section .bss alignb 4 Kernel_EAX resd 1 Kernel_SI resw 1 section .text kernel_good_saved: ; Alternate entry point for which the return from ; searchdir is stored in memory. This is used for ; COMBOOT function INT 22h, AX=0016h. mov si,[Kernel_SI] mov eax,[Kernel_EAX] mov dx,[Kernel_EAX+2] kernel_good: pusha mov si,KernelName mov di,KernelCName call unmangle_name sub di,KernelCName mov [KernelCNameLen],di popa push di push ax mov di,KernelName+4*IS_PXELINUX xor al,al mov cx,FILENAME_MAX repne scasb jne .one_step dec di .one_step: mov ecx,[di-4] ; 4 bytes before end pop ax pop di ; ; At this point, DX:AX contains the size of the kernel, SI contains ; the file handle/cluster pointer, and ECX contains the extension (if any.) ; movzx di,byte [KernelType] add di,di jmp [kerneltype_table+di] is_unknown_filetype: or ecx,20202000h ; Force lower case (except dot) cmp ecx,'.com' je is_comboot_image cmp ecx,'.cbt' je is_comboot_image cmp ecx,'.c32' je is_com32_image %if IS_ISOLINUX cmp ecx,'.img' je is_disk_image %endif cmp ecx,'.bss' je is_bss_sector cmp ecx,'.bin' je is_bootsector shr ecx,8 cmp ecx,'.bs' je is_bootsector shr ecx,8 cmp cx,'.0' je is_bootsector ; Otherwise Linux kernel jmp is_linux_kernel is_config_file: pusha mov si,KernelCName ; Save the config file name, for posterity mov di,ConfigName call strcpy popa call openfd call reset_config jmp load_config_file ; This is an image type we can't deal with is_bad_image: mov si,err_badimage call cwritestr jmp enter_command %if IS_SYSLINUX || IS_MDSLINUX ; ok %else is_bss_sector equ is_bad_image %endif %if IS_ISOLINUX ; ok %else is_disk_image equ is_bad_image %endif section .data boot_prompt db 'boot: ', 0 wipe_char db BS, ' ', BS, 0 err_badimage db 'Invalid image type for this media type!', CR, LF, 0 err_notfound db 'Could not find kernel image: ',0 err_notkernel db CR, LF, 'Invalid or corrupt kernel image.', CR, LF, 0 align 2, db 0 kerneltype_table: dw is_unknown_filetype ; VK_KERNEL dw is_linux_kernel ; VK_LINUX dw is_bootsector ; VK_BOOT dw is_bss_sector ; VK_BSS dw is_bootsector ; VK_PXE dw is_disk_image ; VK_FDIMAGE dw is_comboot_image ; VK_COMBOOT dw is_com32_image ; VK_COM32 dw is_config_file ; VK_CONFIG section .bss alignb 4 ThisKbdTo resd 1 ; Temporary holder for KbdTimeout ThisTotalTo resd 1 ; Temporary holder for TotalTimeout KernelExtPtr resw 1 ; During search, final null pointer CmdOptPtr resw 1 ; Pointer to first option on cmd line KbdFlags resb 1 ; Check for keyboard escapes FuncFlag resb 1 ; Escape sequences received from keyboard KernelType resb 1 ; Kernel type, from vkernel, if known section .text ; ; Linux kernel loading code is common. ; %include "runkernel.inc" ; ; COMBOOT-loading code ; %include "comboot.inc" %include "com32.inc" %include "cmdline.inc" ; ; Boot sector loading code ; %include "bootsect.inc" ; ; Abort loading code ; %include "abort.inc" ; ; Hardware cleanup common code ; %include "cleanup.inc" syslinux-legacy-3.63+dfsg/graphics.inc0000664000175000017500000001472410777447273016517 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ; ---------------------------------------------------------------------------- ; VGA splash screen code ; ---------------------------------------------------------------------------- ; ; vgadisplayfile: ; Display a graphical splash screen. ; The file is already opened on the top of the getc stack. ; ; Assumes CS == DS == ES. ; section .text vgadisplayfile: ; This is a cheap and easy way to make sure the screen is ; cleared in case we were in graphics mode already call vgaclearmode call vgasetmode jnz .error_nz .graphalready: ; Load the header. mov cx,4+2*2+16*3 mov di,LSSHeader .gethdr: call getc stosb loop .gethdr jc .error ; The header WILL be in the first chunk. cmp dword [LSSMagic],0x1413f33d ; Magic number .error_nz: jne .error mov dx,GraphColorMap ; Color map offset mov ax,1012h ; Set RGB registers xor bx,bx ; First register number mov cx,16 ; 16 registers int 10h .movecursor: mov ax,[GraphYSize] ; Number of pixel rows mov dx,[VGAFontSize] add ax,dx dec ax div dl xor dx,dx ; Set column to 0 cmp al,[VidRows] jb .rowsok mov al,[VidRows] dec al .rowsok: mov dh,al mov ah,2 xor bx,bx int 10h ; Set cursor below image mov cx,[GraphYSize] ; Number of graphics rows mov word [VGAPos],0 .drawpixelrow: push cx mov di,VGARowBuffer ; Pre-clear the row buffer push di mov cx,640/4 xor eax,eax rep stosd pop di push di mov cx,[GraphXSize] call rledecode ; Decode one row pop si push es mov di,0A000h ; VGA segment mov es,di mov di,[VGAPos] mov bp,640 call packedpixel2vga add word [VGAPos],80 pop es pop cx loop .drawpixelrow .error: jmp close ; Tailcall! ; ; rledecode: ; Decode a pixel row in RLE16 format. ; ; getc stack -> input ; CX -> pixel count ; ES:DI -> output (packed pixel) ; rledecode: xor dx,dx ; DL = last pixel, DH = nybble buffer .loop: call .getnybble cmp al,dl je .run ; Start of run sequence stosb mov dl,al dec cx jnz .loop .done: ret .run: xor bx,bx call .getnybble or bl,al jz .longrun .dorun: push cx mov cx,bx mov al,dl rep stosb pop cx sub cx,bx ja .loop jmp short .done .longrun: call .getnybble mov bl,al call .getnybble shl al,4 or bl,al add bx,16 jmp short .dorun .getnybble: test dh,10h jz .low and dh,0Fh mov al,dh ret .low: call getc mov dh,al shr dh,4 or dh,10h ; Nybble already read and al,0Fh ret ; ; packedpixel2vga: ; Convert packed-pixel to VGA bitplanes ; ; DS:SI -> packed pixel string ; BP -> pixel count (multiple of 8) ; ES:DI -> output ; packedpixel2vga: mov dx,3C4h ; VGA Sequencer Register select port mov al,2 ; Sequencer mask out dx,al ; Select the sequencer mask inc dx ; VGA Sequencer Register data port mov al,1 mov bl,al .planeloop: pusha out dx,al .loop1: mov cx,8 .loop2: xchg cx,bx lodsb shr al,cl rcl ch,1 ; VGA is bigendian. Sigh. xchg cx,bx loop .loop2 mov al,bh stosb sub bp,byte 8 ja .loop1 popa inc bl shl al,1 cmp bl,4 jbe .planeloop ret ; ; vgasetmode: ; Enable VGA graphics, if possible; return ZF=1 on success ; DS must be set to the base segment; ES is set to DS. ; vgasetmode: push ds pop es mov al,[UsingVGA] cmp al,01h je .success ; Nothing to do... test al,04h jz .notvesa ; We're in a VESA mode, which means VGA; use VESA call ; to revert the mode, and then call the conventional ; mode-setting for good measure... mov ax,4F02h mov bx,0012h int 10h jmp .setmode .notvesa: mov ax,1A00h ; Get video card and monitor xor bx,bx int 10h sub bl, 7 ; BL=07h and BL=08h OK cmp bl, 1 ja .error ; ZF=0 ; mov bx,TextColorReg ; mov dx,1009h ; Read color registers ; int 10h .setmode: mov ax,0012h ; Set mode = 640x480 VGA 16 colors int 10h mov dx,linear_color mov ax,1002h ; Write color registers int 10h mov [UsingVGA], byte 1 ; Set GXPixCols and GXPixRows mov dword [GXPixCols],640+(480 << 16) call use_font ; Set graphics font/data mov byte [ScrollAttribute], 00h .success: xor ax,ax ; Set ZF .error: ret ; ; vgaclearmode: ; Disable VGA graphics. It is not safe to assume any value ; for DS or ES. ; vgaclearmode: push ds push es pushad mov ax,cs mov ds,ax mov es,ax mov al,[UsingVGA] and al,al ; Already in text mode? jz .done test al,04h jz .notvesa mov ax,4F02h ; VESA return to normal video mode mov bx,0003h int 10h .notvesa: mov ax,0003h ; Return to normal video mode int 10h ; mov dx,TextColorReg ; Restore color registers ; mov ax,1002h ; int 10h mov [UsingVGA], byte 0 mov byte [ScrollAttribute], 07h call use_font ; Restore text font/data .done: popad pop es pop ds ret ; ; vgashowcursor/vgahidecursor: ; If VGA graphics is enabled, draw a cursor/clear a cursor ; vgashowcursor: pushad mov al,'_' jmp short vgacursorcommon vgahidecursor: pushad mov al,' ' vgacursorcommon: cmp [UsingVGA], byte 1 jne .done mov ah,09h mov bx,0007h mov cx,1 int 10h .done: popad ret section .data ; Map colors to consecutive DAC registers linear_color db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0 ; See comboot.doc, INT 22h AX=0017h for the semantics ; of this byte. UsingVGA db 0 section .bss1 alignb 4 LSSHeader equ $ LSSMagic resd 1 ; Magic number GraphXSize resw 1 ; Width of splash screen file GraphYSize resw 1 ; Height of splash screen file GraphColorMap resb 3*16 VGAPos resw 1 ; Pointer into VGA memory VGAFilePtr resw 1 ; Pointer into VGAFileBuf ; TextColorReg resb 17 ; VGA color registers for text mode %if IS_SYSLINUX VGAFileBuf resb FILENAME_MAX+2 ; Unmangled VGA image name %else VGAFileBuf resb FILENAME_MAX ; Unmangled VGA image name %endif VGAFileBufEnd equ $ VGAFileMBuf resb FILENAME_MAX ; Mangled VGA image name ; We need a buffer of 640+80 bytes. At this point, command_line should ; not be in use, so use that buffer. VGARowBuffer equ command_line syslinux-legacy-3.63+dfsg/keywords.inc0000664000175000017500000000543710777447273016567 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; keywords.inc ;; ;; Common header file for the handling of keyword hash and macros ;; %ifndef DEPEND ; Generated file %include "kwdhash.gen" %endif %macro keyword 2 dd hash_%1 ; Hash value dw 0 ; No argument dw %2 ; Entrypoint %endmacro %macro keyword 3 dd hash_%1 ; Hash value dw %3 ; 16-bit argument dw %2 ; Entrypoint %endmacro %macro keyword 4 dd hash_%1 ; Hash value db %3, %4 ; 2 8-bit arguments dw %2 ; Entrypoint %endmacro keywd_size equ 8 ; Bytes per keyword align 4, db 0 %define FKeyN(n) (FKeyName+(((n)-1) << FILENAME_MAX_LG2)) keywd_table: keyword menu, pc_comment keyword text, pc_text keyword include, pc_opencmd, pc_include keyword append, pc_append keyword default, pc_default keyword display, pc_opencmd, get_msg_file keyword font, pc_filecmd, loadfont keyword implicit, pc_setint16, AllowImplicit keyword kbdmap, pc_filecmd, loadkeys keyword kernel, pc_kernel, VK_KERNEL keyword linux, pc_kernel, VK_LINUX keyword boot, pc_kernel, VK_BOOT keyword bss, pc_kernel, VK_BSS keyword pxe, pc_kernel, VK_PXE keyword fdimage, pc_kernel, VK_FDIMAGE keyword comboot, pc_kernel, VK_COMBOOT keyword com32, pc_kernel, VK_COM32 keyword config, pc_kernel, VK_CONFIG keyword label, pc_label keyword prompt, pc_setint16, ForcePrompt keyword say, pc_say keyword serial, pc_serial keyword console, pc_setint16, DisplayCon keyword timeout, pc_timeout, KbdTimeout keyword totaltimeout, pc_timeout, TotalTimeout keyword ontimeout, pc_ontimeout keyword onerror, pc_onerror keyword allowoptions, pc_setint16, AllowOptions keyword noescape, pc_setint16, NoEscape keyword f1, pc_fkey, FKeyN(1) keyword f2, pc_fkey, FKeyN(2) keyword f3, pc_fkey, FKeyN(3) keyword f4, pc_fkey, FKeyN(4) keyword f5, pc_fkey, FKeyN(5) keyword f6, pc_fkey, FKeyN(6) keyword f7, pc_fkey, FKeyN(7) keyword f8, pc_fkey, FKeyN(8) keyword f9, pc_fkey, FKeyN(9) keyword f10, pc_fkey, FKeyN(10) keyword f0, pc_fkey, FKeyN(10) keyword f11, pc_fkey, FKeyN(11) keyword f12, pc_fkey, FKeyN(12) %if IS_PXELINUX keyword ipappend, pc_ipappend %endif %if IS_PXELINUX || IS_ISOLINUX keyword localboot, pc_localboot %endif keywd_count equ ($-keywd_table)/keywd_size syslinux-legacy-3.63+dfsg/dos/0000775000175000017500000000000010777447344015000 5ustar evanevansyslinux-legacy-3.63+dfsg/dos/memcpy.S0000664000175000017500000000043110777447273016415 0ustar evanevan# # memcpy.S # # Simple 16-bit memcpy() implementation # .text .code16gcc .globl memcpy .type memcpy, @function memcpy: cld pushw %di pushw %si movw %ax,%di movw %dx,%si # The third argument is already in cx rep ; movsb popw %si popw %di ret .size memcpy,.-memcpy syslinux-legacy-3.63+dfsg/dos/malloc.h0000664000175000017500000000243710777447273016427 0ustar evanevan/* * malloc.h * * Internals for the memory allocator */ #include #include /* * This is the minimum chunk size we will ask the kernel for; this should * be a multiple of the page size on all architectures. */ #define MALLOC_CHUNK_SIZE 65536 #define MALLOC_CHUNK_MASK (MALLOC_CHUNK_SIZE-1) /* * This structure should be a power of two. This becomes the * alignment unit. */ struct free_arena_header; struct arena_header { size_t type; size_t size; /* Also gives the location of the next entry */ struct free_arena_header *next, *prev; }; #ifdef DEBUG_MALLOC #define ARENA_TYPE_USED 0x64e69c70 #define ARENA_TYPE_FREE 0x012d610a #define ARENA_TYPE_HEAD 0x971676b5 #define ARENA_TYPE_DEAD 0xeeeeeeee #else #define ARENA_TYPE_USED 0 #define ARENA_TYPE_FREE 1 #define ARENA_TYPE_HEAD 2 #endif #define ARENA_SIZE_MASK (sizeof(struct arena_header)-1) #define ARENA_ALIGN_UP(p) ((char *)(((uintptr_t)(p) + ARENA_SIZE_MASK) & ~ARENA_SIZE_MASK)) #define ARENA_ALIGN_DOWN(p) ((char *)((uintptr_t)(p) & ~ARENA_SIZE_MASK)) /* * This structure should be no more than twice the size of the * previous structure. */ struct free_arena_header { struct arena_header a; struct free_arena_header *next_free, *prev_free; }; extern struct free_arena_header __malloc_head; syslinux-legacy-3.63+dfsg/dos/stdlib.h0000664000175000017500000000026210777447273016433 0ustar evanevan#ifndef STDLIB_H #define STDLIB_H typedef int ssize_t; typedef unsigned int size_t; void __attribute__((noreturn)) exit(int); void *malloc(size_t); void free(void *); #endif syslinux-legacy-3.63+dfsg/dos/stdio.h0000664000175000017500000000063110777447273016274 0ustar evanevan#ifndef STDIO_H #define STDIO_H #include #include typedef unsigned int off_t; int putchar(int); int puts(const char *); int sprintf(char * buf, const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args); int printf(const char *fmt, ...); #define stdin 0 #define stdout 1 #define stderr 2 #define fprintf(x, y, ...) printf(y, ## __VA_ARGS__) #endif /* STDIO_H */ syslinux-legacy-3.63+dfsg/dos/crt0.S0000664000175000017500000000171310777447273015777 0ustar evanevan .code16 #ifndef REGPARM # error "This file assumes -mregparm=3 -DREGPARM=3" #endif .section ".init","ax" .globl _start .type _start,@function _start: # Align the stack and make sure the high half is zero andl $0xfff8,%esp # Clear the .bss cld xorl %eax,%eax movw $__bss_start,%di movw $_end+3,%cx subw %di,%cx shrw $2,%cx rep ; stosl # Compute argc and argv (assumes REGPARM) xorl %edx,%edx movzbw 0x80,%bx movb %dl,0x81(%bx) # Zero-terminate string movb $0x81,%dl pushl %eax # Make space for argv movl %esp,%eax calll __parse_argv pushl %eax # argc # Initialize malloc calll __init_memory_arena # Now call main... (NOTE: gcc forces main to be regparm 0) popl %eax # argc popl %edx # argv calll main # Here %eax is the exit code, fall through into exit .size _start,.-_start .globl exit .type exit,@function exit: # Exit code already in %eax movb $0x4c,%ah # Terminate program int $0x21 1: hlt jmp 1b .size exit,.-exit syslinux-legacy-3.63+dfsg/dos/argv.c0000664000175000017500000000524410777447273016111 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * argv.c * * Parse a single C string into argc and argv (argc is return value.) * memptr points to available memory. */ #include #include #include #define ALIGN_UP(p,t) ((t *)(((uintptr_t)(p) + (sizeof(t)-1)) & ~(sizeof(t)-1))) extern char _end[]; /* Symbol created by linker */ void *__mem_end = &_end; /* Global variable for use by malloc() */ int __parse_argv(char ***argv, const char *str) { char *mem = __mem_end; const char *p = str; char *q = mem; char *r; char **arg; int wasspace = 0; int argc = 1; /* First copy the string, turning whitespace runs into nulls */ for ( p = str ; ; p++ ) { if ( *p <= ' ' ) { if ( !wasspace ) { wasspace = 1; *q++ = '\0'; } } else { if ( wasspace ) { argc++; wasspace = 0; } *q++ = *p; } /* This test is AFTER we have processed the null byte; we treat it as a whitespace character so it terminates the last argument */ if ( ! *p ) break; } /* Now create argv */ arg = ALIGN_UP(q,char *); *argv = arg; *arg++ = mem; /* argv[0] */ q--; /* Point q to final null */ for ( r = mem ; r < q ; r++ ) { if ( *r == '\0' ) { *arg++ = r+1; } } *arg++ = NULL; /* Null pointer at the end */ __mem_end = arg; /* End of memory we used */ return argc; } syslinux-legacy-3.63+dfsg/dos/code16.h0000664000175000017500000000014610777447273016234 0ustar evanevan/* Must be included first of all */ #ifdef __ASSEMBLY__ .code16 #else __asm__ (".code16gcc"); #endif syslinux-legacy-3.63+dfsg/dos/printf.c0000664000175000017500000001416310777447273016454 0ustar evanevan/* * Oh, it's a waste of space, but oh-so-yummy for debugging. It's just * initialization code anyway, so it doesn't take up space when we're * actually running. This version of printf() does not include 64-bit * support. "Live with it." * * Most of this code was shamelessly snarfed from the Linux kernel, then * modified. It's therefore GPL. * * printf() isn't actually needed to build syslinux.com, but during * debugging it's handy. */ #include #include #include "mystuff.h" static int strnlen(const char *s, int maxlen) { const char *es = s; while ( *es && maxlen ) { es++; maxlen--; } return (es-s); } #define ZEROPAD 1 /* pad with zero */ #define SIGN 2 /* unsigned/signed long */ #define PLUS 4 /* show plus */ #define SPACE 8 /* space if plus */ #define LEFT 16 /* left justified */ #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ #define do_div(n,base) ({ \ int __res; \ __res = ((unsigned long) n) % (unsigned) base; \ n = ((unsigned long) n) / (unsigned) base; \ __res; }) static char * number(char * str, long num, int base, int size, int precision ,int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; int i; if (type & LARGE) digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (type & LEFT) type &= ~ZEROPAD; if (base < 2 || base > 36) return 0; c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if (type & SIGN) { if (num < 0) { sign = '-'; num = -num; size--; } else if (type & PLUS) { sign = '+'; size--; } else if (type & SPACE) { sign = ' '; size--; } } if (type & SPECIAL) { if (base == 16) size -= 2; else if (base == 8) size--; } i = 0; if (num == 0) tmp[i++]='0'; else while (num != 0) tmp[i++] = digits[do_div(num,base)]; if (i > precision) precision = i; size -= precision; if (!(type&(ZEROPAD+LEFT))) while(size-->0) *str++ = ' '; if (sign) *str++ = sign; if (type & SPECIAL) { if (base==8) *str++ = '0'; else if (base==16) { *str++ = '0'; *str++ = digits[33]; } } if (!(type & LEFT)) while (size-- > 0) *str++ = c; while (i < precision--) *str++ = '0'; while (i-- > 0) *str++ = tmp[i]; while (size-- > 0) *str++ = ' '; return str; } /* Forward decl. needed for IP address printing stuff... */ int sprintf(char * buf, const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args) { int len; unsigned long num; int i, base; char * str; const char *s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ for (str=buf ; *fmt ; ++fmt) { if (*fmt != '%') { *str++ = *fmt; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (isdigit(*fmt)) field_width = skip_atou(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (isdigit(*fmt)) precision = skip_atou(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); } if (precision < 0) precision = 0; } /* get the conversion qualifier */ qualifier = -1; if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { qualifier = *fmt; ++fmt; } /* default base */ base = 10; switch (*fmt) { case 'c': if (!(flags & LEFT)) while (--field_width > 0) *str++ = ' '; *str++ = (unsigned char) va_arg(args, int); while (--field_width > 0) *str++ = ' '; continue; case 's': s = va_arg(args, char *); len = strnlen(s, precision); if (!(flags & LEFT)) while (len < field_width--) *str++ = ' '; for (i = 0; i < len; ++i) *str++ = *s++; while (len < field_width--) *str++ = ' '; continue; case 'p': if (field_width == -1) { field_width = 2*sizeof(void *); flags |= ZEROPAD; } str = number(str, (unsigned long) va_arg(args, void *), 16, field_width, precision, flags); continue; case 'n': if (qualifier == 'l') { long * ip = va_arg(args, long *); *ip = (str - buf); } else { int * ip = va_arg(args, int *); *ip = (str - buf); } continue; case '%': *str++ = '%'; continue; /* integer number formats - set up the flags and "break" */ case 'o': base = 8; break; case 'X': flags |= LARGE; case 'x': base = 16; break; case 'd': case 'i': flags |= SIGN; case 'u': break; default: *str++ = '%'; if (*fmt) *str++ = *fmt; else --fmt; continue; } if (qualifier == 'l') num = va_arg(args, unsigned long); else if (qualifier == 'h') { num = (unsigned short) va_arg(args, int); if (flags & SIGN) num = (short) num; } else if (flags & SIGN) num = va_arg(args, int); else num = va_arg(args, unsigned int); str = number(str, num, base, field_width, precision, flags); } *str = '\0'; return str-buf; } int sprintf(char * buf, const char *fmt, ...) { va_list args; int i; va_start(args, fmt); i=vsprintf(buf,fmt,args); va_end(args); return i; } int printf(const char *fmt, ...) { char printf_buf[1024]; va_list args; int printed; va_start(args, fmt); printed = vsprintf(printf_buf, fmt, args); va_end(args); puts(printf_buf); return printed; } syslinux-legacy-3.63+dfsg/dos/com16.ld0000664000175000017500000000722510777447273016255 0ustar evanevan/* * Linker script for COM16 binaries */ /* Script for -z combreloc: combine and sort reloc sections */ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) EXTERN(_start) ENTRY(_start) SECTIONS { /* Read-only sections, merged into text segment: */ . = 0x100; PROVIDE (__executable_start = .); .init : { KEEP (*(.init)) } =0x90909090 .text : { *(.text .stub .text.* .gnu.linkonce.t.*) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) } =0x90909090 .fini : { KEEP (*(.fini)) } =0x90909090 PROVIDE (__etext = .); PROVIDE (_etext = .); PROVIDE (etext = .); .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } /* Ensure the __preinit_array_start label is properly aligned. We could instead move the label definition inside the section, but the linker would then create the section even if it turns out to be empty, which isn't pretty. */ . = ALIGN(4); PROVIDE (__preinit_array_start = .); .preinit_array : { *(.preinit_array) } PROVIDE (__preinit_array_end = .); PROVIDE (__init_array_start = .); .init_array : { *(.init_array) } PROVIDE (__init_array_end = .); PROVIDE (__fini_array_start = .); .fini_array : { *(.fini_array) } PROVIDE (__fini_array_end = .); PROVIDE (__ctors_start = .); .ctors : { KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) } PROVIDE (__ctors_end = .); PROVIDE (__dtors_start = .); .dtors : { KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } PROVIDE (__dtors_end = .); /* Adjust the address for the data segment. Avoid mixing code and data within same 128-byte chunk. */ . = ALIGN(128); .data : { *(.data .data.* .gnu.linkonce.d.*) SORT(CONSTRUCTORS) } .data1 : { *(.data1) } _edata = .; PROVIDE (edata = .); __bss_start = .; .bss : { *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) /* Align here to ensure that the .bss section occupies space up to _end. Align after .bss to ensure correct alignment even if the .bss section disappears because there are no input sections. */ . = ALIGN(32 / 8); } . = ALIGN(32 / 8); _end = .; PROVIDE (end = .); /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions */ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2 */ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } /* DWARF 2 */ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions */ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } /DISCARD/ : { *(.note.GNU-stack) } } syslinux-legacy-3.63+dfsg/dos/mystuff.h0000664000175000017500000000035510777447273016652 0ustar evanevan#ifndef MYSTUFF_H #define MYSTUFF_H #define NULL ((void *)0) unsigned int skip_atou(const char **s); unsigned int atou(const char *s); static inline int isdigit(int ch) { return (ch >= '0') && (ch <= '9'); } #endif /* MYSTUFF_H */ syslinux-legacy-3.63+dfsg/dos/__udivmoddi4.c0000664000175000017500000000077310777447273017522 0ustar evanevan#include uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p) { uint64_t quot = 0, qbit = 1; if ( den == 0 ) { asm volatile("int $0"); return 0; /* If trap returns... */ } /* Left-justify denominator and count shift */ while ( (int64_t)den >= 0 ) { den <<= 1; qbit <<= 1; } while ( qbit ) { if ( den <= num ) { num -= den; quot += qbit; } den >>= 1; qbit >>= 1; } if ( rem_p ) *rem_p = num; return quot; } syslinux-legacy-3.63+dfsg/dos/string.h0000664000175000017500000000102510777447273016456 0ustar evanevan/* * string.h */ #ifndef _STRING_H #define _STRING_H /* Standard routines */ #define memcpy(a,b,c) __builtin_memcpy(a,b,c) #define memset(a,b,c) __builtin_memset(a,b,c) #define strcpy(a,b) __builtin_strcpy(a,b) #define strlen(a) __builtin_strlen(a) /* This only returns true or false */ static inline int memcmp(const void *__m1, const void *__m2, unsigned int __n) { _Bool rv; asm volatile("cld ; repe ; cmpsb ; setne %0" : "=abd" (rv), "+D" (__m1), "+S" (__m2), "+c" (__n)); return rv; } #endif /* _STRING_H */ syslinux-legacy-3.63+dfsg/dos/Makefile0000664000175000017500000000340710777447273016445 0ustar evanevanTMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \ then echo $(1); else echo $(2); fi; rm -f $$tmpf) M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,) \ $(call gcc_ok,-fno-stack-protector,) \ $(call gcc_ok,-fno-top-level-reorder,$(call gcc_ok,-fno-unit-at-a-time)) CC = gcc LD = ld -m elf_i386 OBJCOPY = objcopy OPTFLAGS = -g -Os -march=i386 -falign-functions=0 -falign-jumps=0 -falign-loops=0 -fomit-frame-pointer INCLUDES = -include code16.h -nostdinc -iwithprefix include \ -I. -I.. -I../libfat -I ../libinstaller CFLAGS = $(M32) -mregparm=3 -DREGPARM=3 -W -Wall -msoft-float $(OPTFLAGS) $(INCLUDES) LDFLAGS = -T com16.ld AR = ar RANLIB = ranlib LIBGCC := $(shell $(CC) --print-libgcc) SRCS = syslinux.c \ ../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c ../mbr_bin.c \ $(wildcard ../libfat/*.c) OBJS = crt0.o $(patsubst %.c,%.o,$(notdir $(SRCS))) LIBOBJS = conio.o memcpy.o memset.o skipatou.o atou.o malloc.o free.o \ argv.o printf.o __divdi3.o __udivmoddi4.o .SUFFIXES: .c .o .i .s .S .elf .com VPATH = .:..:../libfat:../libinstaller TARGETS = syslinux.com all: $(TARGETS) tidy: -rm -f *.o *.i *.s *.a .*.d *.elf clean: tidy spotless: clean -rm -f *~ $(TARGETS) installer: syslinux.elf: $(OBJS) libcom.a $(LD) $(LDFLAGS) -o $@ $^ libcom.a: $(LIBOBJS) -rm -f $@ $(AR) cq $@ $^ $(RANLIB) $@ syslinux.com: syslinux.elf $(OBJCOPY) -O binary $< $@ %.o: %.c $(CC) -Wp,-MT,$@,-MD,.$@.d $(CFLAGS) -c -o $@ $< %.i: %.c $(CC) $(CFLAGS) -E -o $@ $< %.s: %.c $(CC) $(CFLAGS) -S -o $@ $< %.o: %.S $(CC) -Wp,-MT,$@,-MD,.$@.d $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $< %.s: %.S $(CC) $(CFLAGS) -E -o $@ $< -include .*.d syslinux-legacy-3.63+dfsg/dos/atou.c0000664000175000017500000000022010777447273016107 0ustar evanevan#include "mystuff.h" unsigned int atou(const char *s) { unsigned int i = 0; while (isdigit(*s)) i = i*10 + (*s++ - '0'); return i; } syslinux-legacy-3.63+dfsg/dos/stdint.h0000664000175000017500000000760210777447273016464 0ustar evanevan/* * stdint.h */ #ifndef _STDINT_H #define _STDINT_H /* Exact types */ typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef signed long long int64_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; /* Small types */ typedef signed char int_least8_t; typedef signed short int_least16_t; typedef signed int int_least32_t; typedef signed long long int_least64_t; typedef unsigned char uint_least8_t; typedef unsigned short uint_least16_t; typedef unsigned int uint_least32_t; typedef unsigned long long uint_least64_t; /* Fast types */ typedef signed char int_fast8_t; typedef signed short int_fast16_t; typedef signed int int_fast32_t; typedef signed long long int_fast64_t; typedef unsigned char uint_fast8_t; typedef unsigned short uint_fast16_t; typedef unsigned int uint_fast32_t; typedef unsigned long long uint_fast64_t; /* Pointer types */ typedef int32_t intptr_t; typedef uint32_t uintptr_t; /* Maximal types */ typedef int64_t intmax_t; typedef uint64_t uintmax_t; /* * To be strictly correct... */ #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) # define INT8_MIN (-128) # define INT16_MIN (-32767-1) # define INT32_MIN (-2147483647-1) # define INT64_MIN (-9223372036854775807LL-1) # define INT8_MAX (127) # define INT16_MAX (32767) # define INT32_MAX (2147483647) # define INT64_MAX (9223372036854775807LL) # define UINT8_MAX (255U) # define UINT16_MAX (65535U) # define UINT32_MAX (4294967295U) # define UINT64_MAX (18446744073709551615ULL) # define INT_LEAST8_MIN (-128) # define INT_LEAST16_MIN (-32767-1) # define INT_LEAST32_MIN (-2147483647-1) # define INT_LEAST64_MIN (-9223372036854775807LL-1) # define INT_LEAST8_MAX (127) # define INT_LEAST16_MAX (32767) # define INT_LEAST32_MAX (2147483647) # define INT_LEAST64_MAX (9223372036854775807LL) # define UINT_LEAST8_MAX (255U) # define UINT_LEAST16_MAX (65535U) # define UINT_LEAST32_MAX (4294967295U) # define UINT_LEAST64_MAX (18446744073709551615ULL) # define INT_FAST8_MIN (-128) # define INT_FAST16_MIN (-32767-1) # define INT_FAST32_MIN (-2147483647-1) # define INT_FAST64_MIN (-9223372036854775807LL-1) # define INT_FAST8_MAX (127) # define INT_FAST16_MAX (32767) # define INT_FAST32_MAX (2147483647) # define INT_FAST64_MAX (9223372036854775807LL) # define UINT_FAST8_MAX (255U) # define UINT_FAST16_MAX (65535U) # define UINT_FAST32_MAX (4294967295U) # define UINT_FAST64_MAX (18446744073709551615ULL) # define INTPTR_MIN (-2147483647-1) # define INTPTR_MAX (2147483647) # define UINTPTR_MAX (4294967295U) # define INTMAX_MIN (-9223372036854775807LL-1) # define INTMAX_MAX (9223372036854775807LL) # define UINTMAX_MAX (18446744073709551615ULL) /* ptrdiff_t limit */ # define PTRDIFF_MIN (-2147483647-1) # define PTRDIFF_MAX (2147483647) /* sig_atomic_t limit */ # define SIG_ATOMIC_MIN (-2147483647-1) # define SIG_ATOMIC_MAX (2147483647) /* size_t limit */ # define SIZE_MAX (4294967295U) #endif /* STDC_LIMIT_MACROS */ #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) # define INT8_C(n) n # define INT16_C(n) n # define INT32_C(n) n # define INT64_C(n) n ## LL # define UINT8_C(n) n ## U # define UINT16_C(n) n ## U # define UINT32_C(n) n ## U # define UINT64_C(n) n ## ULL # define INTMAX_C(n) n ## LL # define UINTMAX_C(n) n ## ULL #endif /* STDC_CONSTANT_MACROS */ #endif /* _STDINT_H */ syslinux-legacy-3.63+dfsg/dos/perror.c0000664000175000017500000000016010777447273016453 0ustar evanevan#include #include void perror(const char *msg) { printf("%s: error %s\n", msg, errno); } syslinux-legacy-3.63+dfsg/dos/syslinux.c0000664000175000017500000003547410777447273017060 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 1998-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * syslinux.c - Linux installer program for SYSLINUX * * Hacked up for DOS. */ #include #include #include #include #include "mystuff.h" #include "syslinux.h" #include "libfat.h" const char *program = "syslinux"; /* Name of program */ uint16_t dos_version; #ifdef DEBUG # define dprintf printf #else # define dprintf(...) ((void)0) #endif void __attribute__((noreturn)) usage(void) { puts("Usage: syslinux [-sfmar][-d directory] : [bootsecfile]\n"); exit(1); } void unlock_device(int); void __attribute__((noreturn)) die(const char *msg) { unlock_device(0); puts("syslinux: "); puts(msg); putchar('\n'); exit(1); } void warning(const char *msg) { puts("syslinux: warning: "); puts(msg); putchar('\n'); } /* * read/write wrapper functions */ int creat(const char *filename, int mode) { uint16_t rv; uint8_t err; dprintf("creat(\"%s\", 0x%x)\n", filename, mode); rv = 0x3C00; asm volatile("int $0x21 ; setc %0" : "=bcdm" (err), "+a" (rv) : "c" (mode), "d" (filename)); if ( err ) { dprintf("rv = %d\n", rv); die("cannot open ldlinux.sys"); } return rv; } void close(int fd) { uint16_t rv = 0x3E00; dprintf("close(%d)\n", fd); asm volatile("int $0x21" : "+a" (rv) : "b" (fd)); /* The only error MS-DOS returns for close is EBADF, and we really don't care... */ } int rename(const char *oldname, const char *newname) { uint16_t rv = 0x5600; /* Also support 43FFh? */ uint8_t err; dprintf("rename(\"%s\", \"%s\")\n", oldname, newname); asm volatile("int $0x21 ; setc %0" : "=bcdm" (err), "+a" (rv) : "d" (oldname), "D" (newname)); if ( err ) { dprintf("rv = %d\n", rv); warning("cannot move ldlinux.sys"); return rv; } return 0; } ssize_t write_file(int fd, const void *buf, size_t count) { uint16_t rv; ssize_t done = 0; uint8_t err; dprintf("write_file(%d,%p,%u)\n", fd, buf, count); while ( count ) { rv = 0x4000; asm volatile("int $0x21 ; setc %0" : "=abcdm" (err), "+a" (rv) : "b" (fd), "c" (count), "d" (buf)); if ( err || rv == 0 ) die("file write error"); done += rv; count -= rv; } return done; } static inline __attribute__((const)) uint16_t data_segment(void) { uint16_t ds; asm("movw %%ds,%0" : "=rm" (ds)); return ds; } struct diskio { uint32_t startsector; uint16_t sectors; uint16_t bufoffs, bufseg; } __attribute__((packed)); void write_device(int drive, const void *buf, size_t nsecs, unsigned int sector) { uint8_t err; struct diskio dio; dprintf("write_device(%d,%p,%u,%u)\n", drive, buf, nsecs, sector); dio.startsector = sector; dio.sectors = nsecs; dio.bufoffs = (uintptr_t)buf; dio.bufseg = data_segment(); asm volatile("int $0x26 ; setc %0 ; popfw" : "=abcdm" (err) : "a" (drive-1), "b" (&dio), "c" (-1), "d" (buf), "m" (dio)); if ( err ) die("sector write error"); } void read_device(int drive, const void *buf, size_t nsecs, unsigned int sector) { uint8_t err; struct diskio dio; dprintf("read_device(%d,%p,%u,%u)\n", drive, buf, nsecs, sector); dio.startsector = sector; dio.sectors = nsecs; dio.bufoffs = (uintptr_t)buf; dio.bufseg = data_segment(); asm volatile("int $0x25 ; setc %0 ; popfw" : "=abcdm" (err) : "a" (drive-1), "b" (&dio), "c" (-1), "d" (buf), "m" (dio)); if ( err ) die("sector read error"); } /* Both traditional DOS and FAT32 DOS return this structure, but FAT32 return a lot more data, so make sure we have plenty of space */ struct deviceparams { uint8_t specfunc; uint8_t devtype; uint16_t devattr; uint16_t cylinders; uint8_t mediatype; uint16_t bytespersec; uint8_t secperclust; uint16_t ressectors; uint8_t fats; uint16_t rootdirents; uint16_t sectors; uint8_t media; uint16_t fatsecs; uint16_t secpertrack; uint16_t heads; uint32_t hiddensecs; uint32_t hugesectors; uint8_t lotsofpadding[224]; } __attribute__((packed)); uint32_t get_partition_offset(int drive) { uint8_t err; uint16_t rv; struct deviceparams dp; dp.specfunc = 1; /* Get current information */ rv = 0x440d; asm volatile("int $0x21 ; setc %0" : "=abcdm" (err), "+a" (rv), "=m" (dp) : "b" (drive), "c" (0x0860), "d" (&dp)); if ( !err ) return dp.hiddensecs; rv = 0x440d; asm volatile("int $0x21 ; setc %0" : "=abcdm" (err), "+a" (rv), "=m" (dp) : "b" (drive), "c" (0x4860), "d" (&dp)); if ( !err ) return dp.hiddensecs; die("could not find partition start offset"); } struct rwblock { uint8_t special; uint16_t head; uint16_t cylinder; uint16_t firstsector; uint16_t sectors; uint16_t bufferoffset; uint16_t bufferseg; } __attribute__((packed)); static struct rwblock mbr = { .special = 0, .head = 0, .cylinder = 0, .firstsector = 0, /* MS-DOS, unlike the BIOS, zero-base sectors */ .sectors = 1, .bufferoffset = 0, .bufferseg = 0 }; void write_mbr(int drive, const void *buf) { uint16_t rv; uint8_t err; dprintf("write_mbr(%d,%p)\n", drive, buf); mbr.bufferoffset = (uintptr_t)buf; mbr.bufferseg = data_segment(); rv = 0x440d; asm volatile("int $0x21 ; setc %0" : "=abcdm" (err), "+a" (rv) : "c" (0x0841), "d" (&mbr), "b" (drive), "m" (mbr)); if ( !err ) return; rv = 0x440d; asm volatile("int $0x21 ; setc %0" : "=abcdm" (err), "+a" (rv) : "c" (0x4841), "d" (&mbr), "b" (drive), "m" (mbr)); if ( err ) die("mbr write error"); } void read_mbr(int drive, const void *buf) { uint16_t rv; uint8_t err; dprintf("read_mbr(%d,%p)\n", drive, buf); mbr.bufferoffset = (uintptr_t)buf; mbr.bufferseg = data_segment(); rv = 0x440d; asm volatile("int $0x21 ; setc %0" : "=abcdm" (err), "+a" (rv) : "c" (0x0861), "d" (&mbr), "b" (drive), "m" (mbr)); if ( !err ) return; rv = 0x440d; asm volatile("int $0x21 ; setc %0" : "=abcdm" (err), "+a" (rv) : "c" (0x4861), "d" (&mbr), "b" (drive), "m" (mbr)); if ( err ) die("mbr read error"); } /* This call can legitimately fail, and we don't care, so ignore error return */ void set_attributes(const char *file, int attributes) { uint16_t rv = 0x4301; dprintf("set_attributes(\"%s\", 0x%02x)\n", file, attributes); asm volatile("int $0x21" : "+a" (rv) : "c" (attributes), "d" (file)); } /* * Version of the read_device function suitable for libfat */ int libfat_xpread(intptr_t pp, void *buf, size_t secsize, libfat_sector_t sector) { read_device(pp, buf, 1, sector); return secsize; } static inline void get_dos_version(void) { uint16_t ver = 0x3001; asm("int $0x21 ; xchgb %%ah,%%al" : "+a" (ver) : : "ebx", "ecx"); dos_version = ver; dprintf("DOS version %d.%d\n", (dos_version >> 8), dos_version & 0xff); } /* The locking interface relies on static variables. A massive hack :( */ static uint16_t lock_level; static inline void set_lock_device(uint8_t device) { lock_level = device; } void lock_device(int level) { uint16_t rv; uint8_t err; uint16_t lock_call; if ( dos_version < 0x0700 ) return; /* Win9x/NT only */ #if 0 /* DOS 7.10 = Win95 OSR2 = first version with FAT32 */ lock_call = (dos_version >= 0x0710) ? 0x484A : 0x084A; #else lock_call = 0x084A; /* MSDN says this is OK for all filesystems */ #endif while ( (lock_level >> 8) < level ) { uint16_t new_level = lock_level + 0x0100; dprintf("Trying lock %04x...\n", new_level); rv = 0x444d; asm volatile("int $0x21 ; setc %0" : "=abcdm" (err), "+a" (rv) : "b" (new_level), "c" (lock_call), "d"(0x0001)); if ( err ) { /* rv == 0x0001 means this call is not supported, if so we assume locking isn't needed (e.g. Win9x in DOS-only mode) */ if ( rv == 0x0001 ) return; else die("could not lock device"); } lock_level = new_level; } return; } void unlock_device(int level) { uint16_t rv; uint8_t err; uint16_t unlock_call; if ( dos_version < 0x0700 ) return; /* Win9x/NT only */ #if 0 /* DOS 7.10 = Win95 OSR2 = first version with FAT32 */ unlock_call = (dos_version >= 0x0710) ? 0x486A : 0x086A; #else unlock_call = 0x086A; /* MSDN says this is OK for all filesystems */ #endif while ( (lock_level >> 8) > level ) { uint16_t new_level = lock_level - 0x0100; rv = 0x440d; asm volatile("int $0x21 ; setc %0" : "=abcdm" (err), "+a" (rv) : "b" (new_level), "c" (unlock_call)); lock_level = new_level; } } /* * This function does any desired MBR manipulation; called with the device lock held. */ struct mbr_entry { uint8_t active; /* Active flag */ uint8_t bhead; /* Begin head */ uint8_t bsector; /* Begin sector */ uint8_t bcylinder; /* Begin cylinder */ uint8_t filesystem; /* Filesystem value */ uint8_t ehead; /* End head */ uint8_t esector; /* End sector */ uint8_t ecylinder; /* End cylinder */ uint32_t startlba; /* Start sector LBA */ uint32_t sectors; /* Length in sectors */ } __attribute__((packed)); static void adjust_mbr(int device, int writembr, int set_active) { static unsigned char sectbuf[512]; int i; if ( !writembr && !set_active ) return; /* Nothing to do */ read_mbr(device, sectbuf); if ( writembr ) { memcpy(sectbuf, syslinux_mbr, syslinux_mbr_len); *(uint16_t *)(sectbuf+510) = 0xaa55; } if ( set_active ) { uint32_t offset = get_partition_offset(device); struct mbr_entry *me = (struct mbr_entry *)(sectbuf+446); int found = 0; for ( i = 0 ; i < 4 ; i++ ) { if ( me->startlba == offset ) { me->active = 0x80; found++; } else { me->active = 0; } me++; } if ( found < 1 ) { die("partition not found"); } else if ( found > 1 ) { die("multiple aliased partitions found"); } } write_mbr(device, sectbuf); } int main(int argc, char *argv[]) { static unsigned char sectbuf[512]; int dev_fd, fd; static char ldlinux_name[] = "@:\\ldlinux.sys"; char **argp, *opt; int force = 0; /* -f (force) option */ struct libfat_filesystem *fs; libfat_sector_t s, *secp, sectors[65]; /* 65 is maximum possible */ int32_t ldlinux_cluster; int nsectors; const char *device = NULL, *bootsecfile = NULL; const char *errmsg; int i; int writembr = 0; /* -m (write MBR) option */ int set_active = 0; /* -a (set partition active) option */ const char *subdir = NULL; int stupid = 0; int raid_mode = 0; dprintf("argv = %p\n", argv); for ( i = 0 ; i <= argc ; i++ ) dprintf("argv[%d] = %p = \"%s\"\n", i, argv[i], argv[i]); (void)argc; /* Unused */ get_dos_version(); for ( argp = argv+1 ; *argp ; argp++ ) { if ( **argp == '-' ) { opt = *argp + 1; if ( !*opt ) usage(); while ( *opt ) { switch ( *opt ) { case 's': /* Use "safe, slow and stupid" code */ stupid = 1; break; case 'r': /* RAID mode */ raid_mode = 1; break; case 'f': /* Force install */ force = 1; break; case 'm': /* Write MBR */ writembr = 1; break; case 'a': /* Set partition active */ set_active = 1; break; case 'd': if ( argp[1] ) subdir = *++argp; break; default: usage(); } opt++; } } else { if ( bootsecfile ) usage(); else if ( device ) bootsecfile = *argp; else device = *argp; } } if ( !device ) usage(); /* * Figure out which drive we're talking to */ dev_fd = (device[0] & ~0x20) - 0x40; if ( dev_fd < 1 || dev_fd > 26 || device[1] != ':' || device[2] ) usage(); set_lock_device(dev_fd); lock_device(2); /* Make sure we can lock the device */ read_device(dev_fd, sectbuf, 1, 0); unlock_device(1); /* * Check to see that what we got was indeed an MS-DOS boot sector/superblock */ if( (errmsg = syslinux_check_bootsect(sectbuf)) ) { unlock_device(0); puts(errmsg); putchar('\n'); exit(1); } ldlinux_name[0] = dev_fd | 0x40; set_attributes(ldlinux_name, 0); fd = creat(ldlinux_name, 0x07); /* SYSTEM HIDDEN READONLY */ write_file(fd, syslinux_ldlinux, syslinux_ldlinux_len); close(fd); /* * Now, use libfat to create a block map. This probably * should be changed to use ioctl(...,FIBMAP,...) since * this is supposed to be a simple, privileged version * of the installer. */ lock_device(2); fs = libfat_open(libfat_xpread, dev_fd); ldlinux_cluster = libfat_searchdir(fs, 0, "LDLINUX SYS", NULL); secp = sectors; nsectors = 0; s = libfat_clustertosector(fs, ldlinux_cluster); while ( s && nsectors < 65 ) { *secp++ = s; nsectors++; s = libfat_nextsector(fs, s); } libfat_close(fs); /* * If requested, move ldlinux.sys */ if (subdir) { char new_ldlinux_name[160]; char *cp = new_ldlinux_name+3; const char *sd; int slash = 1; new_ldlinux_name[0] = dev_fd | 0x40; new_ldlinux_name[1] = ':'; new_ldlinux_name[2] = '\\'; for (sd = subdir; *sd; sd++) { char c = *sd; if (c == '/' || c == '\\') { if (slash) continue; c = '\\'; slash = 1; } else { slash = 0; } *cp++ = c; } /* Skip if subdirectory == root */ if (cp > new_ldlinux_name+3) { if (!slash) *cp++ = '\\'; memcpy(cp, "ldlinux.sys", 12); set_attributes(ldlinux_name, 0); if (rename(ldlinux_name, new_ldlinux_name)) set_attributes(ldlinux_name, 0x07); else set_attributes(new_ldlinux_name, 0x07); } } /* * Patch ldlinux.sys and the boot sector */ syslinux_patch(sectors, nsectors, stupid, raid_mode); /* * Write the now-patched first sector of ldlinux.sys */ lock_device(3); write_device(dev_fd, syslinux_ldlinux, 1, sectors[0]); /* * Muck with the MBR, if desired, while we hold the lock */ adjust_mbr(dev_fd, writembr, set_active); /* * To finish up, write the boot sector */ /* Read the superblock again since it might have changed while mounted */ read_device(dev_fd, sectbuf, 1, 0); /* Copy the syslinux code into the boot sector */ syslinux_make_bootsect(sectbuf); /* Write new boot sector */ if ( bootsecfile ) { unlock_device(0); fd = creat(bootsecfile, 0x20); /* ARCHIVE */ write_file(fd, sectbuf, 512); close(fd); } else { write_device(dev_fd, sectbuf, 1, 0); unlock_device(0); } /* Done! */ return 0; } syslinux-legacy-3.63+dfsg/dos/free.c0000664000175000017500000000326310777447273016072 0ustar evanevan/* * free.c * * Very simple linked-list based malloc()/free(). */ #include #include "malloc.h" static struct free_arena_header * __free_block(struct free_arena_header *ah) { struct free_arena_header *pah, *nah; pah = ah->a.prev; nah = ah->a.next; if ( pah->a.type == ARENA_TYPE_FREE && (char *)pah+pah->a.size == (char *)ah ) { /* Coalesce into the previous block */ pah->a.size += ah->a.size; pah->a.next = nah; nah->a.prev = pah; #ifdef DEBUG_MALLOC ah->a.type = ARENA_TYPE_DEAD; #endif ah = pah; pah = ah->a.prev; } else { /* Need to add this block to the free chain */ ah->a.type = ARENA_TYPE_FREE; ah->next_free = __malloc_head.next_free; ah->prev_free = &__malloc_head; __malloc_head.next_free = ah; ah->next_free->prev_free = ah; } /* In either of the previous cases, we might be able to merge with the subsequent block... */ if ( nah->a.type == ARENA_TYPE_FREE && (char *)ah+ah->a.size == (char *)nah ) { ah->a.size += nah->a.size; /* Remove the old block from the chains */ nah->next_free->prev_free = nah->prev_free; nah->prev_free->next_free = nah->next_free; ah->a.next = nah->a.next; nah->a.next->a.prev = ah; #ifdef DEBUG_MALLOC nah->a.type = ARENA_TYPE_DEAD; #endif } /* Return the block that contains the called block */ return ah; } void free(void *ptr) { struct free_arena_header *ah; if ( !ptr ) return; ah = (struct free_arena_header *) ((struct arena_header *)ptr - 1); #ifdef DEBUG_MALLOC assert( ah->a.type == ARENA_TYPE_USED ); #endif __free_block(ah); /* Here we could insert code to return memory to the system. */ } syslinux-legacy-3.63+dfsg/dos/syslinux.com0000775000175000017500000004607010777447312017403 0ustar evanevanff18MOQ)ff1fPff&fPffXfZf4L!f fUffffSfff1fffff}f fIfffSffffOffFf fZfYf[tfSffff<f!Ät fffff[fZf[fffSff>!f[fÍtfWfSffffVf!fDŽuf1ffPffYf[f_ffWfVfSfff13f@f!gD$g|$uu fffff)fufff[f^f_fÍtfSfgf\$ gf\$gL$gT$g\$fHgf\$f&Ýt ffeff[fÐfSfgf\$ gf\$gL$gT$g\$fHgf\$f%Ýt ffff[fÐfUfWfVfSf fgD$ f`gft$ f Dfff!Ätf`Hfff!ÄugfD$$f f[f^f_f]ffffUfWfVfSf fƉ fAff Dfff!Ät!fAHff!Ät f?fHQvR>@Q@QHtf^f*ffff9|>@Qf f[f^f_f]fÐfVfSffƁ>HQv5@Qfjf Df!gD$fƁf9gf@Qf[f[f^ffVfSffffu ff@MfcfMfKf@MfH>OUftTffTf1f1gf9Ou gƂNfAgƂNff@ufft fIt fff@MffYf[f^of@Mff^f[f^fÐgfL$fgfqfUfWfVfSfQff0!HQff1gfD$gfD$gfD$ f1gfD$gfD$g9-utgAffa<fg$gfD$9gfD$-gfD$!gfJgfBftff gfD$ gCfCtgf|$uLftgfL$ffgf f^ft(gffgfxfAfwg~:ug~tff£@Qfff fjff@Off"ffjf@Offfft*f1fIff f f ff ff@fffCf!fffoffhKfff>!ffWfffT ff fjff1f fff7gfD$fgf$gfD$fBgf$fffMftgf<$Auff ffg$(gƄ$):gƄ$*\fgf$+f!)f fjff@Offf1fff1ffYf[f^f_f]gfafÐ`gbgPfZff ffUfWfVfSf\gfD$@g@ugfsfgkgFgfCff1ff1gfL$gfgfD fBf9ugfNgfFf>f1 gf+f@f9|gff1f f[f^f_f]fÐfUfWfVfSf ffgf@, gf98tlgf@fuffuffxffftVfgfhf gfFfWffgfff=tfff1fgf;gfF,gfCgf^,ff f[f^f_f]fÍtfSfgfP,gf@,fgfXf\ffufXfZf[ffSffugfPfugf@ %f~gf;S}gfBgfKfgfC$ff[ffUfWfVfSf ffgf@ gfV$f9sgf;N qgfAf9nhff)fffHftgfAPgfNfgf{gf;~1gfFfr fffgf8ff gfVff,ffff%gf,fCff gfVfffffffgfff ftfffrgf?ff gfVffftgfgff=gfff gfVffhft.fgfffff f[f^f_f]!ff1f f[f^f_f]fÐfUfWfVfSf fff0fFffkfgf@,gf0gfxf1fff:gx 0gP f1ff8t fAf gfC gfKgFtfgfF gfC(gfNgfKgFtfgf~$gfVffgfS gfFfff gfgfC$gfS(f9f)fgfKfgfPgfSf=wgfCfff2f=wgfCgff=w@gfCgfff f9wgf{u gfF,gfCgfC fff1ff f[f^f_f]fÐfSfffffZfYf[fUfWfVfSfgfD$gfL$ f&gfD$gf|$gf|$gfT$gfD$f fgfD$ff fgft$ ÄuZgf|$0t4gfD$0ff ffgfT$gfD$0gfgfT$gfPgf}tWgfEfgfUfKg}t3gfD$f gfD$f f=hgfT$gfD$f~f f1fff[f^f_f]ffSff u f ffڴ!ff[fÍtfVfSff1 fffCg3uff[f^fÐWVlj^_fÐWLj_fÐf4Mfffgff)fgfPgf@ Mgf@Mgf@Mgf@Mf(Mf$Mf0Mf,MffUfWfVfSffgfXgfB f9gfygfir[gfgfQgff)gfXgfgfqgfH gfPgfB gfAgfxgfhgfQgfBgfQgfBgfgfogfAgfxgfAf[f^f_f]fft%gfPff,Mgf9Pr:gf@gf8uf1fÐfVfSfgfP gfpgf:u(gfZgff9ugfYgfZgfrgfV f)gff,MgfAgfAMf,MgfAgfHgf>uFgfQgff9u7gfVgfQgfVgfFgfBgfFgfPgfFgfAgfFgfH ff[f^fÐftf4fÐfUfWfVfSff64Mff1fg< fugfAffgfAf1g:tfBgfAfgfEgf0gfXfIfg:u gfBgfffBf9rgfgfCf4Mff[f^f_f]fÐfVfSfffgfD$gfT$fxf1fffffyffffffjfRfPffffft ffffYf[f^fÐfUfWfVfSf ffgfD$ gfT$$ff t ff1#gf$gfD$sfffffygf$gfD$-f9wrf9wf)fgf $gf\$ffffff ugf|$(tgfD$(gf0gfxgf$gfT$f f[f^f_f]fsyslinuxUsage: syslinux [-sfmar][-d directory] : [bootsecfile] syslinux: syslinux: warning: cannot open ldlinux.syscannot move ldlinux.sysfile write errorsector write errorsector read errorcould not find partition start offsetmbr write errormbr read errorcould not lock devicepartition not foundmultiple aliased partitions foundLDLINUX SYSH1R% FAT12 more than 4084 clusters but claims FAT12FAT16 less than 4084 clusters but claims FAT16FAT FAT32 only 512-byte sectors are supportedthis doesn't look like a valid FAT filesystemL@:\ldlinux.sysfilesystem type "????????" not supportedXSYSLINUX1м{W{ػx7V1, x?Gd|M'EufEf|r uB|?|UA1,rUu t}f}~f>$~JLLy:f|f1OUffRfPSWjf`1,Bfadr]f) !uf`11,fa}O]fRfPUSf6|f>|f1ɇfk)9vAň֊1,f`farf []fXfZf)uMuޕ.}u1ּ{fx} t ;.}v.}Boot error ᆳNG SYSLINUX 3.63 2008-04-10 >JLLy5~c>}u68.O0~*~!1ffEIt fBf9u8 ݾ~(~fMfff!t; t f`Gfa Load error - CBIOSEBIOS9f1 |+Nf0ff+!uf |f$,f+f,f+!uf$|f+ff,f,f+f ,ff,f+Ȉ2,Q 3,YHf,,@f f(,f$,f+,ff=r$Sf=r2,f,|fff,f,vP.u=s 8(fT8,f1ff}u ut fx.ft.B11r\ L>t+u P.[">v+kQ.tfh+fH.fd+fD.3f&D. <t;< rwtQ.uJsԪ< <t-<t<<t<utOrjdQ.0&Q.<0rt <9vr+WD@_1۠R.&>x+t[VW0Ǿȿl+>r+_^R.0;uO>L.SR[f6L.fD,v݋p+!uW^p? ؿVWQQW_[tۍE1Y_^ 6lu(X;ltfD.tfH.uYпn+YË6@.f<.>.`M>aWP0@uOfMX_>R.f f.comf.cbtf.c32 f.bss f.binx ff.bsi f.0] `Ia{v!u=PRVh0fff f\.ff f`. f@f;`.vf`.f)`.1^ &>UVf.1fT.>r+  6N.1l. t~< vNff=vga=t/f=mem=tVu< v.6l.1.l.< wN뼃fDf==nortKf==exttKf==asktyrωɃkr.fT.6h.fX.7&f>HdrS&n.==r&$&=r &f,fX.&1f1&f&p.&!uj.?9fT.f-f;\.xf6j.F ff)fQff詢( fY^f\.f-v1һf>d.0>l.t# 0n.p.tr df(d ?d>"rd$v df( h.9vd󤪁r&>p.u?11df>j.G@) f1ff\.ff觡&>u&.6x.>e.x.z= ÎێӼ߃ Sj19l.t p.n.P0.6l.< wN1VPN.;6l.t<,uFV ^X_.;6l.wȎ؎/ >俑d f0fQfT.fJfX.f9vffBf)ʁf;d.r\&f>t &ff)&f&fffJfX.V^fXzþ?p`þs!u=sV_01@f1f& &} & t ,&^ ؎1j0h=\f3fXfEfff`͎ݎʼn :FЉF,fah=1[1؎м{s enÊFfÊF JÎF&v&<$tHÀ>u ȈFfFSYfFSLfFINfFUXÀ>u u&Fàf`͎ݎʼnr1FF?F1N^$F~F9Î^$vÎ^$v*hyh_^$vAtFVFvÎF$^vNs1vËvF1F 1,FN"F{N$F{á~+F.F.&.`+ùFf{fx11fFffFff|ff(fvfV^&N$FFÁ~Uw/NQg If$vWdffFf(fvfV^&ÌN$FFÊF<wR.^&vw6@.<.>.^$v10؎1&E >r+N.Fw,NV@Buà t ^$F.Ffvf vufFF$^ngÁ~UwFNQg If$vWdff&vf( @dfEf)}f(+1tÁ~UwXPNQg If$vWdff&v(d؀Eꐐfdfdff((Ì^$FFVRPe0r+A)dffX^1һfٍȎ؉& "ul)(2 "껍 1а(؎а0؋%(g&.f1 1QY`Ɇ(OhfhhhhhjŁf%(1P؎Ў8 $"oȎ؎& hfRffaf.&,.&,ff`f<.&,.f$f1ۋf]aϜ`D$(`D$(g> g"6fg> ߋt$,1ɱ 󥫸G% Gffg6 g"|$0!u1ɱ g 6aÜ`L$0g> g"fg>,)σfg> ߋD$(t$,fag$06N.>r+O>r+0,0,Offf>fW1һ! ff>f|ff(f0,f |f f1f1f{fx1,{W1^1jh3x1؎{W_&fU&fu &]{{&E&][Xf71t `U<t<taþ>=Ȑ1؎м{p+!hf`11faQ8,@f?tYSu8Qe<t"eD uQVW|. e_^Yt sY[f1efDff fG2,eTfeTfff,fefDeT !Y[!tfft.=/uf,GfP< v}t   WS1?< v<\u/8t 0,,tf@&Qf׊2,ffr fffgYfZf_f, t$Sn@rn7GW1GG @[J1[SVW>n] !u0ƃmru&Fu_^[KA ] f`@]5fMg&fvfMf)M A5fa뤉Mfa0SVn7n^[WS>n] A C] [_Yr <t < t < v8ÿ0?sW6_r<-s0fPfQUf1ff1<-u<0rSt<9wM <0r% b .@:.w%.>b.ø1.þp.t..@:.w.1ɋ.6.>b+믾s.t1ɉ..>.r/.t..r.t..9!..1< t< v>~sG>~76~t`>b.a$..t+ff`~+!tP&.W tB 8uXPfaf.t tf`u~+!ttB&. 8faôu"~+!tWtB&. 8u0ôbfafP Xff` tfafaf1Ī`++)fv 󤿈0ŪfNf.ÿEÿЉ>n+ÿ؉>p+À>+wȉ>l+ÿu >-u1>À>+t DP^rf*fffP^rPbQ8uXPQQuX|+rSgs[Lv.r)fSPr7as1ۀ>.߁.f[f%_fKrfff.Pw狽>~+U$XBBB<u:JJ0Bt~9~+Pk_B1V+@󤾈ȿl+/!&#r ff%f=ENDTuff%f=EXTuÿW^ÿ1s|+uǹ)1f>. f>.þh"QfSfR1f1fOfg[fOgI8t1Cgy؀rg(ufGCf8u sCIbs ~fOg fgfOg'NfZf[Yh|覍W1fNg,s fNgs ~fNgـfNgY)tUr<#tQ ffShf[r@< v f0t*rȦ*ff9tfϥ ]< tr!tYSfPf=vffPff fW1f_fYfQfWt &gfAfVf蟌f^f_fYfXff)[uP.X 4J=6ui<wb>rY wT>.f,tt@.>0,t1ɈBH.!@H.ù1Ҹ0۸` u.̈&.aVu8Drtf>D=uiL1۹JH1:.r.Ȉƴ1J|QWf1f_WH^Nj>|罀^|PY148tIu1$tQوY)w Ãt.$úB`ˬՇwav,<t@t O1w%,f@Eb+1f`Ȏ؎, ttO,b+faf`_f` >,u faf`fNfNf1f!txf fPAMSf1ɱNsf!u[pf=PAMSuhf>NwfNf>Ntf=rf;NsfNf;NwfNrf>Ntff;NvfN~fNf;NvfNf=w8r=8O>8t9t,1t%f/-Zffgff1}ffd(fÿfVff=/-Zuf1ҹ~fffguff=d(^P18t tƁr =v1XPVW uYQ18t t#Ɓr|Wƹ)r%^^NY΁sވЪȪd)1_^Xf`}f1fffgf)Ѝ|fDffaf>0tf>4t>8t PXPXÈ&Rf`8 Ҵr uBR?RUA8;r f0 f4faf1VfRfPSjjf`8@ &Rfadr^^fRfPUf6Rf>Rf1ɇff=w'Aň֊8&Rf`far]fXfZMuIt appears your computer has less than 256K of low ("DOS") RAM. Linux needs at least this amount to boot. If you get this message in error, hold down the Ctrl key while booting, and I will take your word for it. boot:  Invalid image type for this media type! Could not find kernel image: Invalid or corrupt kernel image. !׏ޏ׏ʈT| Loading ..ready. Cannot load a ramdisk with an old kernel image. Could not find ramdisk image: Not enough memory to load specified kernel. BOOT_IMAGE=3ʼn͉Չ ډ 0L3kmيk?O~kkkkƋՋ>bxF%: attempted DOS system call COMBOOT image too large.  aborted. AAEEEIIIOOUUYAIOU@ linux autoOut of memory parsing config file Unknown keyword in configuration file. Missing parameter in configuration file. A20 gate not responding!   Copyright (C) 1994-2008 H. Peter Anvin Boot failed: please change disks and press a key to continue. /boot/syslinux/syslinux.cfginitrd=7t;eT9ۘYQ@ T2Cx+9PC̴h60eNR2GCt:t+9YwLhj1`+92d+"Qh+"^h̘Hz+9 v+9 : : : H: : : : H: :: ::H:.cbt.bss.bs.com.c32 ?(g\(f`h) fafffPfUf.)f1ff .f )f.( "b)8аذ01V ] $")ff]fXftCf9r$fgfgfgtfg|fffgfffgff1΃fgfgf`.(..Z+.P+.Z+du_.Z+$RuMouF.Z+d^`WQ1/u)Y.Z+ $Q1uY.(u-fYfaQP .(@.(e&;(XY0t uLdtC`u8!tf?fwfOft) Hufaf..(ffQfXf1f f.)f.( "6+ 1а0ذ(؎Ўf**(*:*`*,NG1؎м|WR RAU10rUu s fBZ?Q@RPf1ff!Missing operating system. f`f1һ|fRfPSjjf6{Œ6{A{fa} f`廾1SQt@ރHt[y9Y[G<t$<u"fGfVff!ufrfFfabMultiple active partitions. fDfFfD0r>}U{Z_Operating system load error. ^>b< uNGMMMMLQsyslinux-legacy-3.63+dfsg/dos/conio.c0000664000175000017500000000172310777447273016257 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * conio.c * * Output to the screen */ #include #include "mystuff.h" int putchar(int ch) { if ( ch == '\n' ) putchar('\r'); asm("movb $0x02,%%ah ; int $0x21" : : "d" (ch)); return ch; } /* Note: doesn't put '\n' like the stdc version does */ int puts(const char *s) { int count = 0; while ( *s ) { putchar(*s); count++; s++; } return count; } syslinux-legacy-3.63+dfsg/dos/skipatou.c0000664000175000017500000000022010777447273016776 0ustar evanevan#include "mystuff.h" unsigned int skip_atou(const char **s) { int i=0; while (isdigit(**s)) i = i*10 + *((*s)++) - '0'; return i; } syslinux-legacy-3.63+dfsg/dos/memset.S0000664000175000017500000000040710777447273016420 0ustar evanevan# # memset.S # # Minimal 16-bit memset() implementation # .text .code16gcc .globl memset .type memset, @function memset: cld pushw %di movw %ax,%di movb %dl,%al # The third argument is already in %cx rep ; stosb popw %di retl .size memset,.-memset syslinux-legacy-3.63+dfsg/dos/malloc.c0000664000175000017500000000523410777447273016420 0ustar evanevan/* * malloc.c * * Very simple linked-list based malloc()/free(). */ #include #include "malloc.h" struct free_arena_header __malloc_head = { { ARENA_TYPE_HEAD, 0, &__malloc_head, &__malloc_head, }, &__malloc_head, &__malloc_head }; /* This is extern so it can be overridden by the user application */ const size_t __stack_size = 4096; static inline size_t sp(void) { uint32_t sp; asm volatile("movl %%esp,%0" : "=rm" (sp)); return sp; } extern void *__mem_end; void __init_memory_arena(void) { struct free_arena_header *fp; size_t start, total_space; start = (size_t)ARENA_ALIGN_UP(__mem_end); total_space = sp() - start; fp = (struct free_arena_header *)start; fp->a.type = ARENA_TYPE_FREE; fp->a.size = total_space - __stack_size; /* Insert into chains */ fp->a.next = fp->a.prev = &__malloc_head; fp->next_free = fp->prev_free = &__malloc_head; __malloc_head.a.next = __malloc_head.a.prev = fp; __malloc_head.next_free = __malloc_head.prev_free = fp; } static void *__malloc_from_block(struct free_arena_header *fp, size_t size) { size_t fsize; struct free_arena_header *nfp, *na; fsize = fp->a.size; /* We need the 2* to account for the larger requirements of a free block */ if ( fsize >= size+2*sizeof(struct arena_header) ) { /* Bigger block than required -- split block */ nfp = (struct free_arena_header *)((char *)fp + size); na = fp->a.next; nfp->a.type = ARENA_TYPE_FREE; nfp->a.size = fsize-size; fp->a.type = ARENA_TYPE_USED; fp->a.size = size; /* Insert into all-block chain */ nfp->a.prev = fp; nfp->a.next = na; na->a.prev = nfp; fp->a.next = nfp; /* Replace current block on free chain */ nfp->next_free = fp->next_free; nfp->prev_free = fp->prev_free; fp->next_free->prev_free = nfp; fp->prev_free->next_free = nfp; } else { /* Allocate the whole block */ fp->a.type = ARENA_TYPE_USED; /* Remove from free chain */ fp->next_free->prev_free = fp->prev_free; fp->prev_free->next_free = fp->next_free; } return (void *)(&fp->a + 1); } void *malloc(size_t size) { struct free_arena_header *fp; if ( size == 0 ) return NULL; /* Add the obligatory arena header, and round up */ size = (size+2*sizeof(struct arena_header)-1) & ~ARENA_SIZE_MASK; for ( fp = __malloc_head.next_free ; fp->a.type != ARENA_TYPE_HEAD ; fp = fp->next_free ) { if ( fp->a.size >= size ) { /* Found fit -- allocate out of this block */ return __malloc_from_block(fp, size); } } /* Nothing found... need to request a block from the kernel */ return NULL; /* No kernel to get stuff from */ } syslinux-legacy-3.63+dfsg/dos/inttypes.h0000664000175000017500000000002410777447273017025 0ustar evanevan#include syslinux-legacy-3.63+dfsg/dos/__divdi3.c0000664000175000017500000000064210777447273016627 0ustar evanevan/* * arch/i386/libgcc/__divdi3.c */ #include #include extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); int64_t __divdi3(int64_t num, int64_t den) { int minus = 0; int64_t v; if ( num < 0 ) { num = -num; minus = 1; } if ( den < 0 ) { den = -den; minus ^= 1; } v = __udivmoddi4(num, den, NULL); if ( minus ) v = -v; return v; } syslinux-legacy-3.63+dfsg/dos/errno.h0000664000175000017500000000013510777447273016276 0ustar evanevan#ifndef ERRNO_H #define ERRNO_H int errno; void perror(const char *); #endif /* ERRNO_H */ syslinux-legacy-3.63+dfsg/syslinux2ansi.pl0000775000175000017500000000261510777447273017413 0ustar evanevan#!/usr/bin/perl # # Perl script to convert a Syslinux-format screen to PC-ANSI # to display in a color xterm or on the Linux console # @ansicol = (0,4,2,6,1,5,3,7); $getting_file = 0; $enable = 1; while ( read(STDIN, $ch, 1) > 0 ) { if ( $ch eq "\x1A" ) { # EOF last; } elsif ( $ch eq "\x0C" ) { # Clear screen print "\x1b[2J" if ( $enable && !$getting_file ); } elsif ( $ch eq "\x0F" ) { # Attribute change if ( !$getting_file ) { if ( read(STDIN, $attr, 2) == 2 ) { $attr = hex $attr; if ( $enable ) { print "\x1b[0;"; if ( $attr & 0x80 ) { print "5;"; $attr &= ~0x80; } if ( $attr & 0x08 ) { print "1;"; $attr &= ~0x08; } printf "%d;%dm", $ansicol[$attr >> 4] + 40, $ansicol[$attr & 7] + 30; } } } } elsif ( $ch eq "\x18" ) { # Display image # We can't display an image; pretend to be a text screen # Ignore all input until end of line $getting_file = 1; } elsif ( (ord($ch) & ~07) == 0x10 ) { # Mode controls $enable = (ord($ch) & 0x01); # Emulate the text screen } elsif ( $ch eq "\x0D" ) { # Carriage return # Ignore } elsif ( $ch eq "\x0A" ) { # Line feed if ( $getting_file ) { $getting_file = 0; } else { print $ch if ( $enable ); } } else { print $ch if ( $enable && !$getting_file ); } } syslinux-legacy-3.63+dfsg/ext2_fs.inc0000664000175000017500000001642510777447273016271 0ustar evanevan; ----------------------------------------------------------------------- ; ; Copyright 1998-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, ; USA; either version 2 of the License, or (at your option) any later ; version; incorporated herein by reference. ; ; ----------------------------------------------------------------------- ; ; ext2_fs.inc ; ; NASM include file for ext2fs data structures ; %define EXT2_SUPER_MAGIC 0xEF53 %define EXT2_GOOD_OLD_REV 0 ; The good old (original) format %define EXT2_DYNAMIC_REV 1 ; V2 format w/ dynamic inode sizes %define EXT2_GOOD_OLD_INODE_SIZE 128 ; Special inode numbers %define EXT2_BAD_INO 1 ; Bad blocks inode %define EXT2_ROOT_INO 2 ; Root inode %define EXT2_BOOT_LOADER_INO 5 ; Boot loader inode %define EXT2_UNDEL_DIR_INO 6 ; Undelete directory inode %define EXT3_RESIZE_INO 7 ; Reserved group descriptors inode %define EXT3_JOURNAL_INO 8 ; Journal inode ; We're readonly, so we only care about incompat features. %define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001 %define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 %define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 %define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 %define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 %define EXT2_FEATURE_INCOMPAT_ANY 0xffffffff %define EXT2_NDIR_BLOCKS 12 %define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS %define EXT2_DIND_BLOCK (EXT2_IND_BLOCK+1) %define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK+1) %define EXT2_N_BLOCKS (EXT2_TIND_BLOCK+1) ; ; File types and file modes ; %define S_IFDIR 0040000o ; Directory %define S_IFCHR 0020000o ; Character device %define S_IFBLK 0060000o ; Block device %define S_IFREG 0100000o ; Regular file %define S_IFIFO 0010000o ; FIFO %define S_IFLNK 0120000o ; Symbolic link %define S_IFSOCK 0140000o ; Socket %define S_IFSHIFT 12 %define T_IFDIR (S_IFDIR >> S_IFSHIFT) %define T_IFCHR (S_IFCHR >> S_IFSHIFT) %define T_IFBLK (S_IFBLK >> S_IFSHIFT) %define T_IFREG (S_IFREG >> S_IFSHIFT) %define T_IFIFO (S_IFIFO >> S_IFSHIFT) %define T_IFLNK (S_IFLNK >> S_IFSHIFT) %define T_IFSOCK (S_IFSOCK >> S_IFSHIFT) ; ; Structure definition for the ext2 superblock ; struc ext2_super_block s_inodes_count resd 1 ; Inodes count s_blocks_count resd 1 ; Blocks count s_r_blocks_count resd 1 ; Reserved blocks count s_free_blocks_count resd 1 ; Free blocks count s_free_inodes_count resd 1 ; Free inodes count s_first_data_block resd 1 ; First Data Block s_log_block_size resd 1 ; Block size s_log_frag_size resd 1 ; Fragment size s_blocks_per_group resd 1 ; # Blocks per group s_frags_per_group resd 1 ; # Fragments per group s_inodes_per_group resd 1 ; # Inodes per group s_mtime resd 1 ; Mount time s_wtime resd 1 ; Write time s_mnt_count resw 1 ; Mount count s_max_mnt_count resw 1 ; Maximal mount count s_magic resw 1 ; Magic signature s_state resw 1 ; File system state s_errors resw 1 ; Behaviour when detecting errors s_minor_rev_level resw 1 ; minor revision level s_lastcheck resd 1 ; time of last check s_checkinterval resd 1 ; max. time between checks s_creator_os resd 1 ; OS s_rev_level resd 1 ; Revision level s_def_resuid resw 1 ; Default uid for reserved blocks s_def_resgid resw 1 ; Default gid for reserved blocks s_first_ino resd 1 ; First non-reserved inode s_inode_size resw 1 ; size of inode structure s_block_group_nr resw 1 ; block group # of this superblock s_feature_compat resd 1 ; compatible feature set s_feature_incompat resd 1 ; incompatible feature set s_feature_ro_compat resd 1 ; readonly-compatible feature set s_uuid resb 16 ; 128-bit uuid for volume s_volume_name resb 16 ; volume name s_last_mounted resb 64 ; directory where last mounted s_algorithm_usage_bitmap resd 1 ; For compression s_prealloc_blocks resb 1 ; Nr of blocks to try to preallocate s_prealloc_dir_blocks resb 1 ; Nr to preallocate for dirs s_padding1 resw 1 s_reserved resd 204 ; Padding to the end of the block endstruc %ifndef DEPEND %if ext2_super_block_size != 1024 %error "ext2_super_block definition bogus" %endif %endif ; ; Structure definition for the ext2 inode ; struc ext2_inode i_mode resw 1 ; File mode i_uid resw 1 ; Owner Uid i_size resd 1 ; Size in bytes i_atime resd 1 ; Access time i_ctime resd 1 ; Creation time i_mtime resd 1 ; Modification time i_dtime resd 1 ; Deletion Time i_gid resw 1 ; Group Id i_links_count resw 1 ; Links count i_blocks resd 1 ; Blocks count i_flags resd 1 ; File flags l_i_reserved1 resd 1 i_block resd EXT2_N_BLOCKS ; Pointer to blocks i_version resd 1 ; File version (for NFS) i_file_acl resd 1 ; File ACL i_dir_acl resd 1 ; Directory ACL i_faddr resd 1 ; Fragment address l_i_frag resb 1 ; Fragment number l_i_fsize resb 1 ; Fragment size i_pad1 resw 1 l_i_reserved2 resd 2 endstruc %ifndef DEPEND %if ext2_inode_size != 128 %error "ext2_inode definition bogus" %endif %endif ; ; Structure definition for ext2 block group descriptor ; struc ext2_group_desc bg_block_bitmap resd 1 ; Block bitmap block bg_inode_bitmap resd 1 ; Inode bitmap block bg_inode_table resd 1 ; Inode table block bg_free_blocks_count resw 1 ; Free blocks count bg_free_inodes_count resw 1 ; Free inodes count bg_used_dirs_count resw 1 ; Used inodes count bg_pad resw 1 bg_reserved resd 3 endstruc %ifndef DEPEND %if ext2_group_desc_size != 32 %error "ext2_group_desc definition bogus" %endif %endif %define ext2_group_desc_lg2size 5 ; ; Structure definition for ext2 directory entry ; struc ext2_dir_entry d_inode resd 1 ; Inode number d_rec_len resw 1 ; Directory entry length d_name_len resb 1 ; Name length d_file_type resb 1 ; File type d_name equ $ endstruc syslinux-legacy-3.63+dfsg/mtools/0000775000175000017500000000000010777447344015530 5ustar evanevansyslinux-legacy-3.63+dfsg/mtools/Makefile0000664000175000017500000000172110777447273017172 0ustar evanevanTMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) ../dummy.c -o $$tmpf 2>/dev/null; \ then echo '$(1)'; else echo '$(2)'; fi; rm -f $$tmpf) comma := , LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,) CC = gcc OPTFLAGS = -g -Os INCLUDES = -I. -I.. -I../libfat -I../libinstaller CFLAGS = -W -Wall -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES) LDFLAGS = $(LDHASH) -s SRCS = syslinux.c ../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c $(wildcard ../libfat/*.c) OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS))) .SUFFIXES: .c .o .i .s .S VPATH = .:..:../libfat:../libinstaller all: installer tidy: -rm -f *.o *.i *.s *.a .*.d clean: tidy -rm -f syslinux spotless: clean -rm -f *~ installer: syslinux syslinux: $(OBJS) $(CC) $(LDFLAGS) -o $@ $^ %.o: %.c $(CC) -Wp,-MT,$@,-MMD,.$@.d $(CFLAGS) -c -o $@ $< %.i: %.c $(CC) $(CFLAGS) -E -o $@ $< %.s: %.c $(CC) $(CFLAGS) -S -o $@ $< -include .*.d syslinux-legacy-3.63+dfsg/mtools/syslinux.c0000664000175000017500000002025210777447273017574 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 1998-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * syslinux.c - Linux installer program for SYSLINUX * * This program now requires mtools. It turned out to be a lot * easier to deal with than dealing with needing mount privileges. * We need device write permission anyway. */ #define _XOPEN_SOURCE 500 /* Required on glibc 2.x */ #define _BSD_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "syslinux.h" #include "libfat.h" char *program; /* Name of program */ char *device; /* Device to install to */ pid_t mypid; off_t filesystem_offset = 0; /* Offset of filesystem */ void __attribute__((noreturn)) usage(void) { fprintf(stderr, "Usage: %s [-sfr][-d directory][-o offset] device\n", program); exit(1); } void __attribute__((noreturn)) die(const char *msg) { fprintf(stderr, "%s: %s\n", program, msg); exit(1); } /* * read/write wrapper functions */ ssize_t xpread(int fd, void *buf, size_t count, off_t offset) { char *bufp = (char *)buf; ssize_t rv; ssize_t done = 0; while ( count ) { rv = pread(fd, bufp, count, offset); if ( rv == 0 ) { die("short read"); } else if ( rv == -1 ) { if ( errno == EINTR ) { continue; } else { die(strerror(errno)); } } else { bufp += rv; offset += rv; done += rv; count -= rv; } } return done; } ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset) { const char *bufp = (const char *)buf; ssize_t rv; ssize_t done = 0; while ( count ) { rv = pwrite(fd, bufp, count, offset); if ( rv == 0 ) { die("short write"); } else if ( rv == -1 ) { if ( errno == EINTR ) { continue; } else { die(strerror(errno)); } } else { bufp += rv; offset += rv; done += rv; count -= rv; } } return done; } /* * Version of the read function suitable for libfat */ int libfat_xpread(intptr_t pp, void *buf, size_t secsize, libfat_sector_t sector) { off_t offset = (off_t)sector * secsize + filesystem_offset; return xpread(pp, buf, secsize, offset); } int main(int argc, char *argv[]) { static unsigned char sectbuf[512]; int dev_fd; struct stat st; int status; char **argp, *opt; char mtools_conf[] = "/tmp/syslinux-mtools-XXXXXX"; const char *subdir = NULL; int mtc_fd; FILE *mtc, *mtp; struct libfat_filesystem *fs; libfat_sector_t s, *secp, sectors[65]; /* 65 is maximum possible */ int32_t ldlinux_cluster; int nsectors; const char *errmsg; int force = 0; /* -f (force) option */ int stupid = 0; /* -s (stupid) option */ int raid_mode = 0; /* -r (RAID) option */ (void)argc; /* Unused */ mypid = getpid(); program = argv[0]; device = NULL; for ( argp = argv+1 ; *argp ; argp++ ) { if ( **argp == '-' ) { opt = *argp + 1; if ( !*opt ) usage(); while ( *opt ) { if ( *opt == 's' ) { stupid = 1; } else if ( *opt == 'r' ) { raid_mode = 1; } else if ( *opt == 'f' ) { force = 1; /* Force install */ } else if ( *opt == 'd' && argp[1] ) { subdir = *++argp; } else if ( *opt == 'o' && argp[1] ) { filesystem_offset = (off_t)strtoull(*++argp, NULL, 0); /* Byte offset */ } else { usage(); } opt++; } } else { if ( device ) usage(); device = *argp; } } if ( !device ) usage(); /* * First make sure we can open the device at all, and that we have * read/write permission. */ dev_fd = open(device, O_RDWR); if ( dev_fd < 0 || fstat(dev_fd, &st) < 0 ) { perror(device); exit(1); } if ( !force && !S_ISBLK(st.st_mode) && !S_ISREG(st.st_mode) ) { fprintf(stderr, "%s: not a block device or regular file (use -f to override)\n", device); exit(1); } xpread(dev_fd, sectbuf, 512, filesystem_offset); /* * Check to see that what we got was indeed an MS-DOS boot sector/superblock */ if( (errmsg = syslinux_check_bootsect(sectbuf)) ) { die(errmsg); } /* * Create an mtools configuration file */ mtc_fd = mkstemp(mtools_conf); if ( mtc_fd < 0 || !(mtc = fdopen(mtc_fd, "w")) ) { perror(program); exit(1); } fprintf(mtc, /* "MTOOLS_NO_VFAT=1\n" */ "MTOOLS_SKIP_CHECK=1\n" /* Needed for some flash memories */ "drive s:\n" " file=\"/proc/%lu/fd/%d\"\n" " offset=%llu\n", (unsigned long)mypid, dev_fd, (unsigned long long)filesystem_offset); fclose(mtc); /* * Run mtools to create the LDLINUX.SYS file */ if ( setenv("MTOOLSRC", mtools_conf, 1) ) { perror(program); exit(1); } /* This command may fail legitimately */ system("mattrib -h -r -s s:/ldlinux.sys 2>/dev/null"); mtp = popen("mcopy -D o -D O -o - s:/ldlinux.sys", "w"); if ( !mtp || (fwrite(syslinux_ldlinux, 1, syslinux_ldlinux_len, mtp) != syslinux_ldlinux_len) || (status = pclose(mtp), !WIFEXITED(status) || WEXITSTATUS(status)) ) { die("failed to create ldlinux.sys"); } /* * Now, use libfat to create a block map */ fs = libfat_open(libfat_xpread, dev_fd); ldlinux_cluster = libfat_searchdir(fs, 0, "LDLINUX SYS", NULL); secp = sectors; nsectors = 0; s = libfat_clustertosector(fs, ldlinux_cluster); while ( s && nsectors < 65 ) { *secp++ = s; nsectors++; s = libfat_nextsector(fs, s); } libfat_close(fs); /* Patch ldlinux.sys and the boot sector */ syslinux_patch(sectors, nsectors, stupid, raid_mode); /* Write the now-patched first sector of ldlinux.sys */ xpwrite(dev_fd, syslinux_ldlinux, 512, filesystem_offset + ((off_t)sectors[0] << 9)); /* Move ldlinux.sys to the desired location */ if (subdir) { char target_file[4096], command[5120]; char *cp = target_file, *ep = target_file+sizeof target_file-16; const char *sd; int slash = 1; cp += sprintf(cp, "'s:/"); for (sd = subdir; *sd; sd++) { if (*sd == '/' || *sd == '\\') { if (slash) continue; /* Remove duplicated slashes */ slash = 1; } else if (*sd == '\'' || *sd == '!') { slash = 0; if (cp < ep) *cp++ = '\''; if (cp < ep) *cp++ = '\\'; if (cp < ep) *cp++ = *sd; if (cp < ep) *cp++ = '\''; continue; } else { slash = 0; } if (cp < ep) *cp++ = *sd; } if (!slash) *cp++ = '/'; strcpy(cp, "ldlinux.sys'"); /* This command may fail legitimately */ sprintf(command, "mattrib -h -r -s %s 2>/dev/null", target_file); system(command); sprintf(command, "mmove -D o -D O s:/ldlinux.sys %s", target_file); status = system(command); if ( !WIFEXITED(status) || WEXITSTATUS(status) ) { fprintf(stderr, "%s: warning: unable to move ldlinux.sys\n", program); status = system("mattrib +r +h +s s:/ldlinux.sys"); } else { sprintf(command, "mattrib +r +h +s %s", target_file); status = system(command); } } else { status = system("mattrib +r +h +s s:/ldlinux.sys"); } if ( !WIFEXITED(status) || WEXITSTATUS(status) ) { fprintf(stderr, "%s: warning: failed to set system bit on ldlinux.sys\n", program); } /* * Cleanup */ unlink(mtools_conf); /* * To finish up, write the boot sector */ /* Read the superblock again since it might have changed while mounted */ xpread(dev_fd, sectbuf, 512, filesystem_offset); /* Copy the syslinux code into the boot sector */ syslinux_make_bootsect(sectbuf); /* Write new boot sector */ xpwrite(dev_fd, sectbuf, 512, filesystem_offset); close(dev_fd); sync(); /* Done! */ return 0; } syslinux-legacy-3.63+dfsg/mtools/syslinux0000775000175000017500000005435010777447314017360 0ustar evanevanELF4`T4 (444444 0L3 HHHDDPtd444,,Qtd/lib/ld-linux.so.2GNU GNU `s])QX"!       " K9g54KQ6x 1}`C= F'D9)"X3o_$wDt0#__gmon_start__libc.so.6_IO_stdin_usedstrcpyexitsprintfperrorunlinkpopengetpidpread64memset__errno_locationopen64memcmpmemcpyfclosemallocstderrsystemstrtoullpclosefwritemkstemp64fprintffdopensyncpwrite64strerror__libc_start_mainsetenvfree__fxstat64GLIBC_2.2GLIBC_2.1GLIBC_2.0ii ii #ii -!     $ (,048<@DHLPTX\`dhlU1C5%%h%h%h%h%h %h(% h0%h8p%h@`%hHP%hP@% hX0%$h` %(hh%,hp%0hx%4h%8h%<h%@h%Dh%Hh%Lh%Php%Th`%XhP%\h@%`h0%dh %hh%lh1^PTRhhQVhUS[8t:X[ÐUS=u? -X9v&9w[]Ít&'Utt $ÐUu5Hh5$U 5Hh5u$UWVS E }]uEES VSWuuW u hJut P$FE)MuEe[^_]UWVS E }]uEES VSWuut u hVut PG$E)MuEe[^_]ÍL$qUWVSQ%YjhNEPDž`DždDžhDžlD@H:-BpCRRPVt@~ VfplhSPp1҃  $RPhhW `PPh[pP`t\/t\uuM5't1ۀ!u.`9s3'B9s+\B9s#B9s'B`9s B1Fuu/BPPh`R)p VhmpS$f VhS$OuątP5Hh5XPVhS$ h؝uątKS5Hh 5/Q1QWhjhBjP"PV EP3Z5$5 hh@Wh@qX5$5 hh@WW#>e1Y[^_]aUWVS]EƉ5 =$WVSu ue[^_]ÐU fEfPZhh:PYUWVS,UBusfSUfFCRhjP1҃ MD B9uN1>F+@;E|1e[^_]ÐUSEP,@,X P؅u]UWVS }G, U 9th@u h:u W$1҅tBu shVw=t S=1҃PE G,C_,e[^_]ÐUE Uu BuB ~;B} JB$]UWVS uM V$F 9s;N BA9>7H)Ӊ҅tA$N{;~ Fr8PP FPVC% UQQFPVqE ƒt%=^?RR FPV#tW=2PP FPVt'%=E ue[^_]g1e[^_]US]St]]MUWVSj0E1@,EEE CPPjSTfx P 1ɸ8t A C fFKftF C(fFNfKt~$VF ʍS S(C$9spK)‰P=SwC(=w C=w1C 9w{uF,CC SEEe[^_]ÐUWVSu uSSPutz1Qj uSu8}tERj SPE0x1{t=CS.;tG =uPPVucee[^_]ÐUWV0U Eu}U܋M܉EEEE׉ƋU؉E܅UEu$9wQEƋEt&;}v;11&MЋMEԋEЋUԅt؃ڃ0^_]ÉЋU1fǃE +EME׋U NjEMMM ЋUEỦ9Ủr;Utm1dt&؃U]؃U]E&9}w 9u11EM9vO1U]Ít&'UWVS^?E)E}Ut+1ƍED$E D$E$9}u߃[^_]Ë$ÐUS E Y$D$ED$ []ÐUSt Ћu[]US[Y[%s: %s Usage: %s [-sfr][-d directory][-o offset] device short writeshort read%s: not a block device or regular file (use -f to override) wMTOOLS_SKIP_CHECK=1 drive s: file="/proc/%lu/fd/%d" offset=%llu MTOOLSRCmattrib -h -r -s s:/ldlinux.sys 2>/dev/nullmcopy -D o -D O -o - s:/ldlinux.sysfailed to create ldlinux.sys's:/ldlinux.sys'mattrib -h -r -s %s 2>/dev/nullmmove -D o -D O s:/ldlinux.sys %s%s: warning: unable to move ldlinux.sys mattrib +r +h +s s:/ldlinux.sysmattrib +r +h +s %s%s: warning: failed to set system bit on ldlinux.sys LDLINUX SYS/tmp/syslinux-mtools-XXXXXXFAT12 more than 4084 clusters but claims FAT12FAT16 less than 4084 clusters but claims FAT16FAT FAT32 only 512-byte sectors are supportedthis doesn't look like a valid FAT filesystem;(DdLzR| AB E<`AB XTiAB Cx2AB D h o` 7 p`o oo܅Ƈև&6FVfvƈֈ&6FVfvfilesystem type "????????" not supportedXSYSLINUX1м{W{ػx7V1, x?Gd|M'EufEf|r uB|?|UA1,rUu t}f}~f>$~JLLy:f|f1OUffRfPSWjf`1,Bfadr]f) !uf`11,fa}O]fRfPUSf6|f>|f1ɇfk)9vAň֊1,f`farf []fXfZf)uMuޕ.}u1ּ{fx} t ;.}v.}Boot error ᆳNG SYSLINUX 3.63 2008-04-10 >JLLy5~c>}u68.O0~*~!1ffEIt fBf9u8 ݾ~(~fMfff!t; t f`Gfa Load error - CBIOSEBIOS9f1 |+Nf0ff+!uf |f$,f+f,f+!uf$|f+ff,f,f+f ,ff,f+Ȉ2,Q 3,YHf,,@f f(,f$,f+,ff=r$Sf=r2,f,|fff,f,vP.u=s 8(fT8,f1ff}u ut fx.ft.B11r\ L>t+u P.[">v+kQ.tfh+fH.fd+fD.3f&D. <t;< rwtQ.uJsԪ< <t-<t<<t<utOrjdQ.0&Q.<0rt <9vr+WD@_1۠R.&>x+t[VW0Ǿȿl+>r+_^R.0;uO>L.SR[f6L.fD,v݋p+!uW^p? ؿVWQQW_[tۍE1Y_^ 6lu(X;ltfD.tfH.uYпn+YË6@.f<.>.`M>aWP0@uOfMX_>R.f f.comf.cbtf.c32 f.bss f.binx ff.bsi f.0] `Ia{v!u=PRVh0fff f\.ff f`. f@f;`.vf`.f)`.1^ &>UVf.1fT.>r+  6N.1l. t~< vNff=vga=t/f=mem=tVu< v.6l.1.l.< wN뼃fDf==nortKf==exttKf==asktyrωɃkr.fT.6h.fX.7&f>HdrS&n.==r&$&=r &f,fX.&1f1&f&p.&!uj.?9fT.f-f;\.xf6j.F ff)fQff詢( fY^f\.f-v1һf>d.0>l.t# 0n.p.tr df(d ?d>"rd$v df( h.9vd󤪁r&>p.u?11df>j.G@) f1ff\.ff觡&>u&.6x.>e.x.z= ÎێӼ߃ Sj19l.t p.n.P0.6l.< wN1VPN.;6l.t<,uFV ^X_.;6l.wȎ؎/ >俑d f0fQfT.fJfX.f9vffBf)ʁf;d.r\&f>t &ff)&f&fffJfX.V^fXzþ?p`þs!u=sV_01@f1f& &} & t ,&^ ؎1j0h=\f3fXfEfff`͎ݎʼn :FЉF,fah=1[1؎м{s enÊFfÊF JÎF&v&<$tHÀ>u ȈFfFSYfFSLfFINfFUXÀ>u u&Fàf`͎ݎʼnr1FF?F1N^$F~F9Î^$vÎ^$v*hyh_^$vAtFVFvÎF$^vNs1vËvF1F 1,FN"F{N$F{á~+F.F.&.`+ùFf{fx11fFffFff|ff(fvfV^&N$FFÁ~Uw/NQg If$vWdffFf(fvfV^&ÌN$FFÊF<wR.^&vw6@.<.>.^$v10؎1&E >r+N.Fw,NV@Buà t ^$F.Ffvf vufFF$^ngÁ~UwFNQg If$vWdff&vf( @dfEf)}f(+1tÁ~UwXPNQg If$vWdff&v(d؀Eꐐfdfdff((Ì^$FFVRPe0r+A)dffX^1һfٍȎ؉& "ul)(2 "껍 1а(؎а0؋%(g&.f1 1QY`Ɇ(OhfhhhhhjŁf%(1P؎Ў8 $"oȎ؎& hfRffaf.&,.&,ff`f<.&,.f$f1ۋf]aϜ`D$(`D$(g> g"6fg> ߋt$,1ɱ 󥫸G% Gffg6 g"|$0!u1ɱ g 6aÜ`L$0g> g"fg>,)σfg> ߋD$(t$,fag$06N.>r+O>r+0,0,Offf>fW1һ! ff>f|ff(f0,f |f f1f1f{fx1,{W1^1jh3x1؎{W_&fU&fu &]{{&E&][Xf71t `U<t<taþ>=Ȑ1؎м{p+!hf`11faQ8,@f?tYSu8Qe<t"eD uQVW|. e_^Yt sY[f1efDff fG2,eTfeTfff,fefDeT !Y[!tfft.=/uf,GfP< v}t   WS1?< v<\u/8t 0,,tf@&Qf׊2,ffr fffgYfZf_f, t$Sn@rn7GW1GG @[J1[SVW>n] !u0ƃmru&Fu_^[KA ] f`@]5fMg&fvfMf)M A5fa뤉Mfa0SVn7n^[WS>n] A C] [_Yr <t < t < v8ÿ0?sW6_r<-s0fPfQUf1ff1<-u<0rSt<9wM <0r% b .@:.w%.>b.ø1.þp.t..@:.w.1ɋ.6.>b+믾s.t1ɉ..>.r/.t..r.t..9!..1< t< v>~sG>~76~t`>b.a$..t+ff`~+!tP&.W tB 8uXPfaf.t tf`u~+!ttB&. 8faôu"~+!tWtB&. 8u0ôbfafP Xff` tfafaf1Ī`++)fv 󤿈0ŪfNf.ÿEÿЉ>n+ÿ؉>p+À>+wȉ>l+ÿu >-u1>À>+t DP^rf*fffP^rPbQ8uXPQQuX|+rSgs[Lv.r)fSPr7as1ۀ>.߁.f[f%_fKrfff.Pw狽>~+U$XBBB<u:JJ0Bt~9~+Pk_B1V+@󤾈ȿl+/!&#r ff%f=ENDTuff%f=EXTuÿW^ÿ1s|+uǹ)1f>. f>.þh"QfSfR1f1fOfg[fOgI8t1Cgy؀rg(ufGCf8u sCIbs ~fOg fgfOg'NfZf[Yh|覍W1fNg,s fNgs ~fNgـfNgY)tUr<#tQ ffShf[r@< v f0t*rȦ*ff9tfϥ ]< tr!tYSfPf=vffPff fW1f_fYfQfWt &gfAfVf蟌f^f_fYfXff)[uP.X 4J=6ui<wb>rY wT>.f,tt@.>0,t1ɈBH.!@H.ù1Ҹ0۸` u.̈&.aVu8Drtf>D=uiL1۹JH1:.r.Ȉƴ1J|QWf1f_WH^Nj>|罀^|PY148tIu1$tQوY)w Ãt.$úB`ˬՇwav,<t@t O1w%,f@Eb+1f`Ȏ؎, ttO,b+faf`_f` >,u faf`fNfNf1f!txf fPAMSf1ɱNsf!u[pf=PAMSuhf>NwfNf>Ntf=rf;NsfNf;NwfNrf>Ntff;NvfN~fNf;NvfNf=w8r=8O>8t9t,1t%f/-Zffgff1}ffd(fÿfVff=/-Zuf1ҹ~fffguff=d(^P18t tƁr =v1XPVW uYQ18t t#Ɓr|Wƹ)r%^^NY΁sވЪȪd)1_^Xf`}f1fffgf)Ѝ|fDffaf>0tf>4t>8t PXPXÈ&Rf`8 Ҵr uBR?RUA8;r f0 f4faf1VfRfPSjjf`8@ &Rfadr^^fRfPUf6Rf>Rf1ɇff=w'Aň֊8&Rf`far]fXfZMuIt appears your computer has less than 256K of low ("DOS") RAM. Linux needs at least this amount to boot. If you get this message in error, hold down the Ctrl key while booting, and I will take your word for it. boot:  Invalid image type for this media type! Could not find kernel image: Invalid or corrupt kernel image. !׏ޏ׏ʈT| Loading ..ready. Cannot load a ramdisk with an old kernel image. Could not find ramdisk image: Not enough memory to load specified kernel. BOOT_IMAGE=3ʼn͉Չ ډ 0L3kmيk?O~kkkkƋՋ>bxF%: attempted DOS system call COMBOOT image too large.  aborted. AAEEEIIIOOUUYAIOU@ linux autoOut of memory parsing config file Unknown keyword in configuration file. Missing parameter in configuration file. A20 gate not responding!   Copyright (C) 1994-2008 H. Peter Anvin Boot failed: please change disks and press a key to continue. /boot/syslinux/syslinux.cfginitrd=7t;eT9ۘYQ@ T2Cx+9PC̴h60eNR2GCt:t+9YwLhj1`+92d+"Qh+"^h̘Hz+9 v+9 : : : H: : : : H: :: ::H:.cbt.bss.bs.com.c32 ?(g\(f`h) fafffPfUf.)f1ff .f )f.( "b)8аذ01V ] $")ff]fXftCf9r$fgfgfgtfg|fffgfffgff1΃fgfgf`.(..Z+.P+.Z+du_.Z+$RuMouF.Z+d^`WQ1/u)Y.Z+ $Q1uY.(u-fYfaQP .(@.(e&;(XY0t uLdtC`u8!tf?fwfOft) Hufaf..(ffQfXf1f f.)f.( "6+ 1а0ذ(؎Ўf**(*:*`*,NGGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32).shstrtab.interp.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data.bss.comment 44HH !hh$84o``$>  F7No܅D[o  @j ``s pp |hhw h.44,``      !p/ PL PtSsyslinux-legacy-3.63+dfsg/kwdhash.gen0000664000175000017500000000326410777447305016341 0ustar evanevanhash_menu equ 0x003719b5 hash_text equ 0x003b9b74 hash_include equ 0x9a07d8ff hash_append equ 0xc53999a4 hash_config equ 0xc0c69547 hash_default equ 0xcc5159ed hash_display equ 0xd509bc40 hash_font equ 0x0032b1b4 hash_implicit equ 0xa6f50207 hash_ipappend equ 0xc5399af0 hash_kbdmap equ 0xd013b850 hash_kernel equ 0xd068b4cc hash_linux equ 0x06f536d8 hash_boot equ 0x0030b194 hash_bss equ 0x00018613 hash_pxe equ 0x0001cf65 hash_fdimage equ 0x4ea7089c hash_comboot equ 0x18e0b18c hash_com32 equ 0x06063252 hash_label equ 0x06f104cc hash_localboot equ 0x04f0def4 hash_prompt equ 0xe7163a74 hash_say equ 0x0001c059 hash_serial equ 0xe068a84c hash_console equ 0x18d831fd hash_timeout equ 0xd4e332c9 hash_totaltimeout equ 0xef51d0a9 hash_allowoptions equ 0x1648dd10 hash_ontimeout equ 0xd4e35eb9 hash_onerror equ 0x1a68c589 hash_noescape equ 0x0d00090e hash_f0 equ 0x00000cf0 hash_f1 equ 0x00000cf1 hash_f2 equ 0x00000cf2 hash_f3 equ 0x00000cf3 hash_f4 equ 0x00000cf4 hash_f5 equ 0x00000cf5 hash_f6 equ 0x00000cf6 hash_f7 equ 0x00000cf7 hash_f8 equ 0x00000cf8 hash_f9 equ 0x00000cf9 hash_f10 equ 0x00019e10 hash_f11 equ 0x00019e11 hash_f12 equ 0x00019e12 syslinux-legacy-3.63+dfsg/sha1pass0000775000175000017500000000112410777447273015663 0ustar evanevan#!/usr/bin/perl use bytes; use Digest::SHA1; use MIME::Base64; sub random_bytes($) { my($n) = @_; my($v, $i); if ( open(RANDOM, '<', '/dev/random') || open(RANDOM, '<', '/dev/urandom') ) { read(RANDOM, $v, $n); } else { # No real RNG available... srand($$ ^ time); $v = ''; for ( $i = 0 ; $i < $n ; $i++ ) { $v .= ord(int(rand() * 256)); } } return $v; } ($pass, $salt) = @ARGV; unless (defined($salt)) { $salt = MIME::Base64::encode(random_bytes(6), ''); } $pass = Digest::SHA1::sha1_base64($salt, $pass); print '$4$', $salt, '$', $pass, "\$\n"; syslinux-legacy-3.63+dfsg/com32.inc0000664000175000017500000002256210777447272015640 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; com32.inc ;; ;; Common code for running a COM32 image ;; ; ; Load a COM32 image. A COM32 image is the 32-bit analogue to a DOS ; .com file. A COM32 image is loaded at address 0x101000, with %esp ; set to the high end of usable memory. ; ; A COM32 image should begin with the magic bytes: ; B8 FF 4C CD 21, which is "mov eax,0x21cd4cff" in 32-bit mode and ; "mov ax,0x4cff; int 0x21" in 16-bit mode. This will abort the ; program with an error if run in 16-bit mode. ; pm_idt: equ 0x100000 pm_entry: equ 0x101000 bits 16 section .data align 2, db 0 com32_pmidt: dw 8*256 ; Limit dd pm_idt ; Address com32_rmidt: dw 0ffffh ; Limit dd 0 ; Address section .text is_com32_image: push si ; Save file handle push dx ; File length held in DX:AX push ax call make_plain_cmdline ; Copy the command line into the low cmdline buffer mov ax,real_mode_seg mov fs,ax mov si,cmd_line_here mov di,command_line mov cx,[CmdLinePtr] inc cx ; Include final null sub cx,si fs rep movsb call comboot_setup_api ; Set up the COMBOOT-style API mov edi,pm_entry ; Load address pop eax ; File length pop si ; File handle xor dx,dx ; No padding mov bx,abort_check ; Don't print dots, but allow abort call load_high com32_start: mov ebx,com32_call_start ; Where to go in PM com32_enter_pm: cli mov ax,cs mov ds,ax mov [RealModeSSSP],sp mov [RealModeSSSP+2],ss cld call a20_test jnz .a20ok call enable_a20 .a20ok: mov byte [bcopy_gdt.TSS+5],89h ; Mark TSS unbusy lgdt [bcopy_gdt] ; We can use the same GDT just fine lidt [com32_pmidt] ; Set up the IDT mov eax,cr0 or al,1 mov cr0,eax ; Enter protected mode jmp PM_CS32:.in_pm bits 32 .in_pm: xor eax,eax ; Available for future use... mov fs,eax mov gs,eax lldt ax mov al,PM_DS32 ; Set up data segments mov es,eax mov ds,eax mov ss,eax mov al,PM_TSS ; Be nice to Intel's VT by ltr ax ; giving it a valid TR mov esp,[PMESP] ; Load protmode %esp if available jmp ebx ; Go to where we need to go ; ; This is invoked right before the actually starting the COM32 ; progam, in 32-bit mode... ; com32_call_start: ; ; Point the stack to the end of (permitted) high memory ; mov esp,[word HighMemRsvd] xor sp,sp ; Align to a 64K boundary ; ; Set up the protmode IDT and the interrupt jump buffers ; We set these up in the system area at 0x100000, ; but we could also put them beyond the stack. ; mov edi,pm_idt ; Form an interrupt gate descriptor mov eax,0x00200000+((pm_idt+8*256)&0x0000ffff) mov ebx,0x0000ee00+((pm_idt+8*256)&0xffff0000) xor ecx,ecx inc ch ; ecx <- 256 push ecx .make_idt: stosd add eax,8 xchg eax,ebx stosd xchg eax,ebx loop .make_idt pop ecx ; Each entry in the interrupt jump buffer contains ; the following instructions: ; ; 00000000 60 pushad ; 00000001 B0xx mov al, ; 00000003 E9xxxxxxxx jmp com32_handle_interrupt mov eax,0e900b060h mov ebx,com32_handle_interrupt-(pm_idt+8*256+8) .make_ijb: stosd sub [edi-2],cl ; Interrupt # xchg eax,ebx stosd sub eax,8 xchg eax,ebx loop .make_ijb ; Now everything is set up for interrupts... push dword com32_cfarcall ; Cfarcall entry point push dword com32_farcall ; Farcall entry point push dword (1 << 16) ; 64K bounce buffer push dword (comboot_seg << 4) ; Bounce buffer address push dword com32_intcall ; Intcall entry point push dword command_line ; Command line pointer push dword 6 ; Argument count sti ; Interrupts OK now call pm_entry ; Run the program... ; ... on return, fall through to com32_exit ... com32_exit: mov bx,com32_done ; Return to command loop com32_enter_rm: cli cld mov [PMESP],esp ; Save exit %esp xor esp,esp ; Make sure the high bits are zero jmp PM_CS16:.in_pm16 ; Return to 16-bit mode first bits 16 .in_pm16: mov ax,PM_DS16_RM ; Real-mode-like segment mov es,ax mov ds,ax mov ss,ax mov fs,ax mov gs,ax lidt [com32_rmidt] ; Real-mode IDT (rm needs no GDT) mov eax,cr0 and al,~1 mov cr0,eax jmp 0:.in_rm .in_rm: ; Back in real mode mov ax,cs ; Set up sane segments mov ds,ax mov es,ax mov fs,ax mov gs,ax lss sp,[RealModeSSSP] ; Restore stack jmp bx ; Go to whereever we need to go... com32_done: %if DISABLE_A20 call disable_a20 %endif sti jmp enter_command ; ; 16-bit support code ; bits 16 ; ; 16-bit interrupt-handling code ; com32_int_rm: pushf ; Flags on stack push cs ; Return segment push word .cont ; Return address push dword edx ; Segment:offset of IVT entry retf ; Invoke IVT routine .cont: ; ... on resume ... mov ebx,com32_int_resume jmp com32_enter_pm ; Go back to PM ; ; 16-bit intcall/farcall handling code ; com32_sys_rm: pop gs pop fs pop es pop ds popad popfd mov [cs:Com32SysSP],sp retf ; Invoke routine .return: ; We clean up SP here because we don't know if the ; routine returned with RET, RETF or IRET mov sp,[cs:Com32SysSP] pushfd pushad push ds push es push fs push gs mov ebx,com32_syscall.resume jmp com32_enter_pm ; ; 16-bit cfarcall handing code ; com32_cfar_rm: retf .return: mov sp,[cs:Com32SysSP] mov [cs:RealModeEAX],eax mov ebx,com32_cfarcall.resume jmp com32_enter_pm ; ; 32-bit support code ; bits 32 ; ; This is invoked on getting an interrupt in protected mode. At ; this point, we need to context-switch to real mode and invoke ; the interrupt routine. ; ; When this gets invoked, the registers are saved on the stack and ; AL contains the register number. ; com32_handle_interrupt: movzx eax,al xor ebx,ebx ; Actually makes the code smaller mov edx,[ebx+eax*4] ; Get the segment:offset of the routine mov bx,com32_int_rm jmp com32_enter_rm ; Go to real mode com32_int_resume: popad iret ; ; Intcall/farcall invocation. We manifest a structure on the real-mode stack, ; containing the com32sys_t structure from as well as ; the following entries (from low to high address): ; - Target offset ; - Target segment ; - Return offset ; - Return segment (== real mode cs == 0) ; - Return flags ; com32_farcall: pushfd ; Save IF among other things... pushad ; We only need to save some, but... mov eax,[esp+10*4] ; CS:IP jmp com32_syscall com32_intcall: pushfd ; Save IF among other things... pushad ; We only need to save some, but... movzx eax,byte [esp+10*4] ; INT number mov eax,[eax*4] ; Get CS:IP from low memory com32_syscall: cld movzx edi,word [word RealModeSSSP] movzx ebx,word [word RealModeSSSP+2] sub edi,54 ; Allocate 54 bytes mov [word RealModeSSSP],di shl ebx,4 add edi,ebx ; Create linear address mov esi,[esp+11*4] ; Source regs xor ecx,ecx mov cl,11 ; 44 bytes to copy rep movsd ; EAX is already set up to be CS:IP stosd ; Save in stack frame mov eax,com32_sys_rm.return ; Return seg:offs stosd ; Save in stack frame mov eax,[edi-12] ; Return flags and eax,0x200cd7 ; Mask (potentially) unsafe flags mov [edi-12],eax ; Primary flags entry stosw ; Return flags mov bx,com32_sys_rm jmp com32_enter_rm ; Go to real mode ; On return, the 44-byte return structure is on the ; real-mode stack, plus the 10 additional bytes used ; by the target address (see above.) .resume: movzx esi,word [word RealModeSSSP] movzx eax,word [word RealModeSSSP+2] mov edi,[esp+12*4] ; Dest regs shl eax,4 add esi,eax ; Create linear address and edi,edi ; NULL pointer? jnz .do_copy .no_copy: mov edi,esi ; Do a dummy copy-to-self .do_copy: xor ecx,ecx mov cl,11 ; 44 bytes rep movsd ; Copy register block add dword [word RealModeSSSP],54 ; Remove from stack popad popfd ret ; Return to 32-bit program ; ; Cfarcall invocation. We copy the stack frame to the real-mode stack, ; followed by the return CS:IP and the CS:IP of the target function. ; com32_cfarcall: pushfd pushad cld mov ecx,[esp+12*4] ; Size of stack frame movzx edi,word [word RealModeSSSP] movzx ebx,word [word RealModeSSSP+2] mov [word Com32SysSP],di sub edi,ecx ; Allocate space for stack frame and edi,~3 ; Round sub edi,4*2 ; Return pointer, return value mov [word RealModeSSSP],di shl ebx,4 add edi,ebx ; Create linear address mov eax,[esp+10*4] ; CS:IP stosd ; Save to stack frame mov eax,com32_cfar_rm.return ; Return seg:off stosd mov esi,[esp+11*4] ; Stack frame mov eax,ecx ; Copy the stack frame shr ecx,2 rep movsd mov ecx,eax and ecx,3 rep movsb mov bx,com32_cfar_rm jmp com32_enter_rm .resume: popad mov eax,[word RealModeEAX] popfd ret bits 16 section .bss1 alignb 4 RealModeSSSP resd 1 ; Real-mode SS:SP RealModeEAX resd 1 ; Real mode EAX PMESP resd 1 ; Protected-mode ESP Com32SysSP resw 1 ; SP saved during COM32 syscall section .text syslinux-legacy-3.63+dfsg/version0000664000175000017500000000000510777447273015617 0ustar evanevan3.63 syslinux-legacy-3.63+dfsg/highmem.inc0000664000175000017500000000732610777447273016335 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; highmem.inc ;; ;; Probe for the size of high memory. This can be overridden by a ;; mem= command on the command line while booting a new kernel. ;; section .text ; ; This is set up as a subroutine; it will set up the global variable ; HighMemSize. All registers are preserved. ; highmemsize: push es pushad push cs pop es ; ; First, try INT 15:E820 (get BIOS memory map) ; ; Note: we may have to scan this multiple times, because some (daft) BIOSes ; report main memory as multiple contiguous ranges... ; get_e820: mov dword [E820Max],-(1 << 20) ; Max amount of high memory mov dword [E820Mem],(1 << 20) ; End of detected high memory .start_over: xor ebx,ebx ; Start with first record jmp short .do_e820 ; Skip "at end" check first time! .int_loop: and ebx,ebx ; If we're back at beginning... jz .e820_done ; ... we're done .do_e820: mov eax,0000E820h mov edx,534D4150h ; "SMAP" backwards xor ecx,ecx mov cl,20 ; ECX <- 20 mov di,E820Buf int 15h jnc .no_carry ; If carry, ebx == 0 means error, ebx != 0 means we're done and ebx,ebx jnz .e820_done jmp no_e820 .no_carry: cmp eax,534D4150h jne no_e820 ; ; Look for a memory block starting at <= 1 MB and continuing upward ; cmp dword [E820Buf+4], byte 0 ja .int_loop ; Start >= 4 GB? mov eax, [E820Buf] cmp dword [E820Buf+16],1 je .is_ram ; Is it memory? ; ; Non-memory range. Remember this as a limit; some BIOSes get the length ; of primary RAM incorrect! ; cmp eax, (1 << 20) jb .int_loop ; Starts in lowmem region cmp eax,[E820Max] jae .int_loop ; Already above limit mov [E820Max],eax ; Set limit jmp .int_loop .is_ram: cmp eax,[E820Mem] ja .int_loop ; Not contiguous with our starting point add eax,[E820Buf+8] jc .overflow cmp dword [E820Buf+12],0 je .nooverflow .overflow: or eax,-1 .nooverflow: cmp eax,[E820Mem] jbe .int_loop ; All is below our baseline mov [E820Mem],eax jmp .start_over ; Start over in case we find an adjacent range .e820_done: mov eax,[E820Mem] cmp eax,[E820Max] jna .not_limited mov eax,[E820Max] .not_limited: cmp eax,(1 << 20) ja got_highmem ; Did we actually find memory? ; otherwise fall through ; ; INT 15:E820 failed. Try INT 15:E801. ; no_e820: mov ax,0e801h ; Query high memory (semi-recent) int 15h jc no_e801 cmp ax,3c00h ja no_e801 ; > 3C00h something's wrong with this call jb e801_hole ; If memory hole we can only use low part mov ax,bx shl eax,16 ; 64K chunks add eax,(16 << 20) ; Add first 16M jmp short got_highmem ; ; INT 15:E801 failed. Try INT 15:88. ; no_e801: mov ah,88h ; Query high memory (oldest) int 15h cmp ax,14*1024 ; Don't trust memory >15M jna e801_hole mov ax,14*1024 e801_hole: and eax,0ffffh shl eax,10 ; Convert from kilobytes add eax,(1 << 20) ; First megabyte got_highmem: %if HIGHMEM_SLOP != 0 sub eax,HIGHMEM_SLOP %endif mov [HighMemSize],eax popad pop es ret ; Done! section .bss alignb 4 E820Buf resd 5 ; INT 15:E820 data buffer E820Mem resd 1 ; Memory detected by E820 E820Max resd 1 ; Is E820 memory capped? HighMemSize resd 1 ; End of memory pointer (bytes) syslinux-legacy-3.63+dfsg/isolinux.bin0000664000175000017500000002772110777447306016566 0ustar evanevan@|/%0~+ᆳᆳᆳᆳᆳᆳᆳᆳᆳᆳ.&p.r1м{W؎f1@|fff>hy|"f1fKyy8 f> |u'ff!tffGf(f |f|f-fflff vf |f@@1ۋ.vGflf>h&fffIt !u؎f9>|t |VfLf]}1Wa}_Gqf]}f t(fL"&fEf;]}tfLKyr`K~ar.UpM8u Ayy8t 8tJsyrӀ3B ˾PV^Xff`1fafý\É\fDU;.v.䁉lVyB^]fDfD)D!ufD{f`r È&xfat{t$P{&<w <w &䁈&X¾|Bx\Ct]7E"1؎м{rP  Xff` tfafff`fff`fff`ffP$< s07fXfaf ISOLINUX 3.63 2008-04-10 Copyright (C) 1994-2008 H. Peter Anvin isolinux: No boot info table, assuming single session disk... Spec packet missing LBA information, trying to wing it... Loading spec packet failed, trying to wing it... Found something at drive = Looks like it might be right, continuing... Extremely broken BIOS detected, last ditch attempt with drive = Failed to locate CD-ROM device; boot failed. See http://syslinux.zytor.com/sbm for more information. Disk error , AX = , drive Image checksum error, sorry... Boot failed: press a key to retry... ,pf1f+u=s 1$(fC~"f|.ff\fPff`fTff fdfXF#u KtfTfDfXf1ffPU=t>11WrE>t+u +[>v+{f+tfh+f+fd+f+7f&+ <t;< rwt+uJsԪ< <t-<t<<t<utOj"d+0&+<0rt <9vr+ W_1۠¢+>u,>x+t[VW Ǿʿl+>r+_^+ 0uO>+S [f6+fDv݋p+!u WD^@ ڿVWQQW_[tۍE1Y_^Τ 6lu(X;ltf+tf+uYcҿn+YMË6+f++` l >aWP 0uOfMX_>+f f.comf.cbtf.c32f.imgE f.bsstUVf+1f+>r+  6+1+ < vNff=vga=t/f=mem=tVu< v.6+1.+< wN뺃fDf==nortKf==exttKf==asktrωɃrf.f+6+f+7&f>HdrS&+==r&$&=r &f,f+&3f1&f&+&!u+ smf+f-f;+[f6+F ff)fQff/ fY^f+f-v1һ~f>+ >+t 5 ++tr df(d ?d>",rd$v df( +9vd󤪁r&>+u?11df>+G@) f1ff+ff&>u& ÎێӼ߃ Sj19+t++m .6+< wN1VPN.;6+t<,uFV A ^X_.;6+wȎ؎ Y > f fQf+fJf+f9vffBf)ʁf;+r\&f>t &ff)&f&fffJf+V, & ^fX~þO pþ&z!u=sV_ 1@f1f& &} & t ,&^P ؎1j ĥ\fff͋fff`͎ݎʼn  :FЉF,faĥ1[1؎м{ yeyÊFÊF^ JÎF&v&<$tÀ>ux ȈFfFSYfFSLfFINfFUXÀ>um u&Fàf`͎ݎʼn3r1ȥFF?F3N^$FFÎ^$v"Î^$vhhK^$v q9tFVFvÎF$^vNs1vËvF3F yFN"F{N$Fá~+F+F+&+`+ùF11fFffFff|ff(fvfV^&N$FFÁ~Uw/NQg If$vWdffFf(fvfV^&_ËFN$FFÊF<w⢦+^&v Jy6+++^$v18 ؎1&E >r++FwNV(*u1à t ^$F+Ffvf vufFF$^nNÁ~UwFNQg If$vWdff&vf( @dfEf)}f(+1:Á~UwXRNQg If$vWdff&v(d؀Eꐐfdfdff((Ì^$FFVRPe r+A)dffX^1һf_Ȏ؉& ju)(B "A 1а(؎а0؋%g&+f1 1QY`O(Ohhjhhhrhj?f%1֏؎ЎH $"Ȏ؎&hfRfhfaf.&.&ff`f.&.f f>1ۋf ]aϜ`D$(`D$(g>g 6fg>ߋt$,1ɱ 󥫸+G% Gffg6g |$0!u1ɱ g6aÜ`L$0g>g fg>)σfg>ߋD$(Dt$,fCag  6+>r+yO>r+Òfff>fW1һ ff>f|ff(f1f1y1jh x1؎{W_&fU&fu &]{{&E&][Xft `4<t<taþN̂1؎м{/p+!f`11faf¿fffEf;f> U 1}t ufPfR0C0ff f[f1ff!tf@f=vHf[fܰآff Ly&pKb28v܊\?8v] .&l1ҎڎŽ!t/0R1ZNZ|f.&p|!tf10zuP=/uG\fDfGfffT G t/uEzWQhPf`ދ fafZ] !u ƃmru&Fu_^[KA ] f`(]5fMg&fvfMf)M 05fa뤉Mfa0SVZ7Z^[WS>Z] A C] [_Yr <t < t < v8ÿ'sW6_r<-sfPfQUf1ff1<-u<0rSt<9wM <0r% b +@:+w%+>b+ø1+$þ+t++@:+w+1ɋ+6+>b+믾\+t1ɉ++>+r/+t++<r+t++dh!++\< t< v>fhsG>f6fhh)t`>b+a$++t+ff`~+!tP&+W tB 8uX%faf+t tf`u~+!ttB&+ 8faôu"~+!tWtB&+ 8u0ôn+ÿ%ډ>p+À>+wʉ>l+ÿƒu >-u1>,>+t1À>+t P^rf*fffP^rPb u>uXPQ duX|+rSs[}+r)fSrhs1ۀ>+߁+f[f%_fKrfff+Pw狽>~+U*X$BBB<u:JJ0 Bt~+Pk_1Vi+ʿ‹l+/&#r ff%f=ENDTuff%f=EXTuÿW.^ÿ1 s|+u¿ǹ)1f>+ f>+þjOh(QfSfR1f1fOfg[fOgI8t1Cgy؀rg(ufGCf8u sCIbs ~fOg fgfOg'NfZf[Yhv謌W1fNg,s fNgs ~fNgـfNgY)PtUr<#tQ ffSf[r@< v f0%t*r +ff9tf << tLr!tYSfPf=vffPff fW1f_fYfQfWt &gfAfVf襋f^f_fYfXff)[uP.X\ j=6ui<wb>rY wT>+ftt@+>0t1Ɉ*H+!(H+ù1Ҹ0۸` u+̈&+aVu8,"rtf>,=ui41۹2H1:+r+Ȉƴ12dQWf1f_W0^Nj>d^dPY!148tIu1$tQوY)w Ãt_$úB`ˬՇwav<t@t O1w%f(Eb+1f`Ȏ؎ ttOb+faf`_f` >u faf`fKfKf1f!txf fPAMSf1ɱKsf!u[pf=PAMSuhf>KwfKf>Ktf=rf;KsfKf;KwfKrf>Ktff;KvfK~fKf;KvfKf=w8r=bPX<tV< tN< tR>b Z:+v 0:6+w>bfafΊ>b>b+1ɋ+0ӀsΊ+s0> O> t9t,1t%f/-Zffgff1}ffd(fÿfVff=/-Zuf1ҹ~fffguff=d(^P18t tƁr =v1XPVW uYQ18t t#Ɓr|Wƹ)r%^^NY΁sވЪȪd)1_^Xf`}f1fffgf)Ѝ|fDffaf>tf>t> t PXPXÈ&Kf` Ҵr uBK?KUA Qr!f ffaf1VfRfPSjjf` @ &Kfadr^^fRfPUf6Kf>Kf1ɇff=w'Aň֊ &Kf`far]fXfZMuIt appears your computer has less than 192K of low ("DOS") RAM. Linux needs at least this amount to boot. If you get this message in error, hold down the Ctrl key while booting, and I will take your word for it. boot:  Invalid image type for this media type! Could not find kernel image: Invalid or corrupt kernel image. 5],],Rڎ Loading ..ready. Cannot load a ramdisk with an old kernel image. Could not find ramdisk image: Not enough memory to load specified kernel. BOOT_IMAGE=?MU] b u0L!39>ax󋀌njόFL[čk̎&: attempted DOS system call COMBOOT image too large.  aborted. ( linux autoOut of memory parsing config file Unknown keyword in configuration file. Missing parameter in configuration file. A20 gate not responding!  Booting from local disk... default/boot/isolinuxisolinux.cfgCannot load disk image (invalid file)? initrd=7t;z_N9YQ@ 4N2=x+3P=̴h60eNR2G=t:t+3YqLhd1`+32d+Qh+^hHz+3 v+3 4 4 4 4 4 4 4 4 44 444.cbt.img.bin.com.c32OO-O$ ?(g\(f`h) fafffPfUf.)f1ff .f )f.( "b)8аذ01V ] $")ff]fXftCf9r$fgfgfgtfg|fffgfffgff1΃fgfgf`.(..Z+.P+.Z+du_.Z+$RuMouF.Z+d^`WQ1/u)Y.Z+ $Q1uY.(uygYfaQP .(@.(e&;(XY0t uLdtC`u8!tf?fwfOft) Hufaf..(ffQfXf1f f.)f.( "6+ 1а0ذ(؎Ўf**(*:*`*syslinux-legacy-3.63+dfsg/gethostip0000775000175000017500000001061010777447307016144 0ustar evanevanELF4 4 (444444  0 HHHDDPtdp ppQtd/lib/ld-linux.so.2GNU GNUÒ]fӨOik       " K93 5mYGf9e$K=U)DD.__gmon_start__libc.so.6_IO_stdin_usedexitoptindputcharherrorstderrgethostbynamegetopt_longfprintf__libc_start_mainGLIBC_2.0ii Ț  ؚܚ U\5К%Ԛ%ؚh%ܚh%h%h%h %h(%h0%h8p%h@`1^PTRhphQVhkUS[t&X[ÐUS= u?-X9v&9w []Ít&'Utt $Ð5hL5Xt$L$qUW1VSQY$Iht0 dtfu+ ntxu # j j@r jhhnSt$ u$9u j@9uf-D$4 6u 6xux t P6ht5D$mtP3Qht-CPPBPBPBPPQhU t(CSSBPBPBPPQh j E;,$D$ZYY[^_]aÐU]Ít&'UWVS^A[E)E}Ut+1ƍED$E D$E$9}u߃[^_]Ë$ÐUSt Ћu[]US[èY[Usage: %s [-dxnf] hostname/ip... dxfnh%s: No IPv4 address associated with name %s%s %s%u.%u.%u.%u%s%02X%02X%02X%02Xhexadecimaldotted-quadfull-outputnamehelpƈxʈd҈dވfnh;4PzR| AB 8iAB C  oԁЂ ̚HotooZ"2BRbrGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32).shstrtab.interp.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data.bss.comment 44HH !hh$8H4oԁ,> FЂNoZZ[ott j s H |w  h@@0 pp  X    Ț ̚ 0    syslinux-legacy-3.63+dfsg/com32/0000775000175000017500000000000010777447273015137 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/lib/0000775000175000017500000000000010777447344015704 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/lib/strsep.c0000664000175000017500000000035510777447272017373 0ustar evanevan/* * strsep.c */ #include char *strsep(char **stringp, const char *delim) { char *s = *stringp; char *e; if ( !s ) return NULL; e = strpbrk(s, delim); if (e) *e++ = '\0'; *stringp = e; return s; } syslinux-legacy-3.63+dfsg/com32/lib/libgcc/0000775000175000017500000000000010777447344017127 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/lib/libgcc/__negdi2.S0000664000175000017500000000040510777447272020720 0ustar evanevan/* * arch/i386/libgcc/__negdi2.S * * 64-bit negation */ .text .align 4 .globl __negdi2 .type __negdi2,@function __negdi2: #ifndef REGPARM movl 4(%esp),%eax movl 8(%esp),%edx #endif negl %edx negl %eax sbbl $0,%edx ret .size __negdi2,.-__negdi2 syslinux-legacy-3.63+dfsg/com32/lib/libgcc/__moddi3.c0000664000175000017500000000064310777447272020753 0ustar evanevan/* * arch/i386/libgcc/__moddi3.c */ #include #include extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); int64_t __moddi3(int64_t num, int64_t den) { int minus = 0; int64_t v; if ( num < 0 ) { num = -num; minus = 1; } if ( den < 0 ) { den = -den; minus ^= 1; } (void) __udivmoddi4(num, den, &v); if ( minus ) v = -v; return v; } syslinux-legacy-3.63+dfsg/com32/lib/libgcc/__udivdi3.c0000664000175000017500000000036410777447272021143 0ustar evanevan/* * arch/i386/libgcc/__divdi3.c */ #include #include extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); uint64_t __udivdi3(uint64_t num, uint64_t den) { return __udivmoddi4(num, den, NULL); } syslinux-legacy-3.63+dfsg/com32/lib/libgcc/__udivmoddi4.c0000664000175000017500000000101710777447272021640 0ustar evanevan#include #include uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p) { uint64_t quot = 0, qbit = 1; if ( den == 0 ) { __divide_error(); return 0; /* If trap returns... */ } /* Left-justify denominator and count shift */ while ( (int64_t)den >= 0 ) { den <<= 1; qbit <<= 1; } while ( qbit ) { if ( den <= num ) { num -= den; quot += qbit; } den >>= 1; qbit >>= 1; } if ( rem_p ) *rem_p = num; return quot; } syslinux-legacy-3.63+dfsg/com32/lib/libgcc/__lshrdi3.S0000664000175000017500000000056110777447272021123 0ustar evanevan/* * arch/i386/libgcc/__lshrdi3.S * * 64-bit shr */ .text .align 4 .globl __lshrdi3 .type __lshrdi3,@function __lshrdi3: #ifndef REGPARM movl 4(%esp),%eax movl 8(%esp),%edx movb 12(%esp),%cl #endif cmpb $32,%cl jae 1f shrdl %cl,%edx,%eax shrl %cl,%edx ret 1: shrl %cl,%edx xorl %eax,%eax xchgl %edx,%eax ret .size __lshrdi3,.-__lshrdi3 syslinux-legacy-3.63+dfsg/com32/lib/libgcc/__umoddi3.c0000664000175000017500000000041610777447272021136 0ustar evanevan/* * arch/i386/libgcc/__umoddi3.c */ #include #include extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); uint64_t __umoddi3(uint64_t num, uint64_t den) { uint64_t v; (void) __udivmoddi4(num, den, &v); return v; } syslinux-legacy-3.63+dfsg/com32/lib/libgcc/__divdi3.c0000664000175000017500000000064210777447272020755 0ustar evanevan/* * arch/i386/libgcc/__divdi3.c */ #include #include extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); int64_t __divdi3(int64_t num, int64_t den) { int minus = 0; int64_t v; if ( num < 0 ) { num = -num; minus = 1; } if ( den < 0 ) { den = -den; minus ^= 1; } v = __udivmoddi4(num, den, NULL); if ( minus ) v = -v; return v; } syslinux-legacy-3.63+dfsg/com32/lib/libgcc/__muldi3.S0000664000175000017500000000077510777447272020757 0ustar evanevan/* * arch/i386/libgcc/__muldi3.S * * 64*64 = 64 bit unsigned multiplication */ .text .align 4 .globl __muldi3 .type __muldi3,@function __muldi3: push %esi #ifndef REGPARM movl 8(%esp),%eax movl %eax,%esi movl 16(%esp),%ecx mull %ecx imull 12(%esp),%ecx imull 20(%esp),%esi addl %ecx,%edx addl %esi,%edx #else movl %eax,%esi push %edx mull %ecx imull 8(%esp),%esi addl %esi,%edx pop %esi imull %esi,%ecx addl %ecx,%edx #endif pop %esi ret .size __muldi3,.-__muldi3 syslinux-legacy-3.63+dfsg/com32/lib/libgcc/__ashldi3.S0000664000175000017500000000056110777447272021102 0ustar evanevan/* * arch/i386/libgcc/__ashldi3.S * * 64-bit shl */ .text .align 4 .globl __ashldi3 .type __ashldi3,@function __ashldi3: #ifndef REGPARM movl 4(%esp),%eax movl 8(%esp),%edx movb 12(%esp),%cl #endif cmpb $32,%cl jae 1f shldl %cl,%eax,%edx shl %cl,%eax ret 1: xorl %edx,%edx shl %cl,%eax xchgl %edx,%eax ret .size __ashldi3,.-__ashldi3 syslinux-legacy-3.63+dfsg/com32/lib/libgcc/__ashrdi3.S0000664000175000017500000000054510777447272021112 0ustar evanevan/* * arch/i386/libgcc/__ashrdi3.S * * 64-bit sar */ .text .align 4 .globl __ashrdi3 .type __ashrdi3,@function __ashrdi3: #ifndef REGPARM movl 4(%esp),%eax movl 8(%esp),%edx movb 12(%esp),%cl #endif cmpb $32,%cl jae 1f shrdl %cl,%edx,%eax sarl %cl,%edx ret 1: sarl %cl,%edx movl %edx,%eax cdq ret .size __ashrdi3,.-__ashrdi3 syslinux-legacy-3.63+dfsg/com32/lib/realloc.c0000664000175000017500000000476610777447272017506 0ustar evanevan/* * realloc.c */ #include #include #include #include "malloc.h" void *realloc(void *ptr, size_t size) { struct free_arena_header *ah, *nah; void *newptr; size_t newsize, oldsize, xsize; if ( !ptr ) return malloc(size); if ( size == 0 ) { free(ptr); return NULL; } ah = (struct free_arena_header *) ((struct arena_header *)ptr - 1); /* Actual size of the old block */ oldsize = ah->a.size; /* Add the obligatory arena header, and round up */ newsize = (size+2*sizeof(struct arena_header)-1) & ARENA_SIZE_MASK; if ( oldsize >= newsize && newsize >= (oldsize >> 2) ) { /* This allocation is close enough already. */ return ptr; } else { xsize = oldsize; nah = ah->a.next; if ((char *)nah == (char *)ah + ah->a.size && nah->a.type == ARENA_TYPE_FREE && oldsize + nah->a.size >= newsize) { /* Merge in subsequent free block */ ah->a.next = nah->a.next; ah->a.next->a.prev = ah; nah->next_free->prev_free = nah->prev_free; nah->prev_free->next_free = nah->next_free; xsize = (ah->a.size += nah->a.size); } if (xsize >= newsize) { /* We can reallocate in place */ if (xsize >= newsize + 2*sizeof(struct arena_header)) { /* Residual free block at end */ nah = (struct free_arena_header *)((char *)ah + newsize); nah->a.type = ARENA_TYPE_FREE; nah->a.size = xsize - newsize; ah->a.size = newsize; /* Insert into block list */ nah->a.next = ah->a.next; ah->a.next = nah; nah->a.next->a.prev = nah; nah->a.prev = ah; /* Insert into free list */ if (newsize > oldsize) { /* Hack: this free block is in the path of a memory object which has already been grown at least once. As such, put it at the *end* of the freelist instead of the beginning; trying to save it for future realloc()s of the same block. */ nah->prev_free = __malloc_head.prev_free; nah->next_free = &__malloc_head; __malloc_head.prev_free = nah; nah->prev_free->next_free = nah; } else { nah->next_free = __malloc_head.next_free; nah->prev_free = &__malloc_head; __malloc_head.next_free = nah; nah->next_free->prev_free = nah; } } /* otherwise, use up the whole block */ return ptr; } else { /* Last resort: need to allocate a new block and copy */ oldsize -= sizeof(struct arena_header); newptr = malloc(size); if (newptr) { memcpy(newptr, ptr, min(size,oldsize)); free(ptr); } return newptr; } } } syslinux-legacy-3.63+dfsg/com32/lib/strncpy.c0000664000175000017500000000037510777447272017557 0ustar evanevan/* * strncpy.c * * strncpy() */ #include char *strncpy(char *dst, const char *src, size_t n) { char *q = dst; const char *p = src; char ch; while ( n-- ) { *q++ = ch = *p++; if ( !ch ) break; } return dst; } syslinux-legacy-3.63+dfsg/com32/lib/fread2.c0000664000175000017500000000034610777447272017216 0ustar evanevan/* * fread2.c * * The actual fread() function as a non-inline */ #define __NO_FREAD_FWRITE_INLINES #include size_t fread(void *ptr, size_t size, size_t nmemb, FILE *f) { return _fread(ptr, size*nmemb, f)/size; } syslinux-legacy-3.63+dfsg/com32/lib/memcpy.S0000664000175000017500000000064210777447272017324 0ustar evanevan# # memcpy.S # .text .globl memcpy .type memcpy, @function memcpy: pushl %esi pushl %edi #ifdef REGPARM movl %edx, %esi #else movl 12(%esp), %eax movl 16(%esp), %esi movl 20(%esp), %ecx #endif movl %eax, %edi movl %ecx, %edx shrl $2, %ecx cld rep ; movsl jnc 1f # The shrl had carry out if odd word count movsw 1: testb $1, %dl jz 2f movsb 2: popl %edi popl %esi ret .size memcpy, .-memcpy syslinux-legacy-3.63+dfsg/com32/lib/vasprintf.c0000664000175000017500000000056110777447272020066 0ustar evanevan/* * vasprintf.c */ #include #include #include int vasprintf(char **bufp, const char *format, va_list ap) { va_list ap1; int bytes; char *p; va_copy(ap1, ap); bytes = vsnprintf(NULL, 0, format, ap1) + 1; va_end(ap1); *bufp = p = malloc(bytes); if ( !p ) return -1; return vsnprintf(p, bytes, format, ap); } syslinux-legacy-3.63+dfsg/com32/lib/abort.c0000664000175000017500000000013710777447272017160 0ustar evanevan/* * abort.c */ #include #include void abort(void) { _exit(255); } syslinux-legacy-3.63+dfsg/com32/lib/memchr.c0000664000175000017500000000036010777447272017322 0ustar evanevan/* * memchr.c */ #include #include void *memchr(const void *s, int c, size_t n) { const unsigned char *sp = s; while ( n-- ) { if ( *sp == (unsigned char)c ) return (void *)sp; } return NULL; } syslinux-legacy-3.63+dfsg/com32/lib/strtoul.c0000664000175000017500000000010410777447272017557 0ustar evanevan#define TYPE unsigned long #define NAME strtoul #include "strtox.c" syslinux-legacy-3.63+dfsg/com32/lib/strrchr.c0000664000175000017500000000032110777447272017533 0ustar evanevan/* * strrchr.c */ #include char *strrchr(const char *s, int c) { const char *found = NULL; while ( *s ) { if ( *s == (char) c ) found = s; s++; } return (char *)found; } syslinux-legacy-3.63+dfsg/com32/lib/malloc.h0000664000175000017500000000245410777447272017331 0ustar evanevan/* * malloc.h * * Internals for the memory allocator */ #include #include /* * This is the minimum chunk size we will ask the kernel for; this should * be a multiple of the page size on all architectures. */ #define MALLOC_CHUNK_SIZE 65536 #define MALLOC_CHUNK_MASK (MALLOC_CHUNK_SIZE-1) /* * This structure should be a power of two. This becomes the * alignment unit. */ struct free_arena_header; struct arena_header { size_t type; size_t size; /* Also gives the location of the next entry */ struct free_arena_header *next, *prev; }; #ifdef DEBUG_MALLOC #define ARENA_TYPE_USED 0x64e69c70 #define ARENA_TYPE_FREE 0x012d610a #define ARENA_TYPE_HEAD 0x971676b5 #define ARENA_TYPE_DEAD 0xeeeeeeee #else #define ARENA_TYPE_USED 0 #define ARENA_TYPE_FREE 1 #define ARENA_TYPE_HEAD 2 #endif #define ARENA_SIZE_MASK (~(uintptr_t)(sizeof(struct arena_header)-1)) #define ARENA_ALIGN_UP(p) ((char *)(((uintptr_t)(p) + ~ARENA_SIZE_MASK) & ARENA_SIZE_MASK)) #define ARENA_ALIGN_DOWN(p) ((char *)((uintptr_t)(p) & ARENA_SIZE_MASK)) /* * This structure should be no more than twice the size of the * previous structure. */ struct free_arena_header { struct arena_header a; struct free_arena_header *next_free, *prev_free; }; extern struct free_arena_header __malloc_head; syslinux-legacy-3.63+dfsg/com32/lib/strlcpy.c0000664000175000017500000000047510777447272017556 0ustar evanevan/* * strlcpy.c */ #include #include size_t strlcpy(char *dst, const char *src, size_t size) { size_t bytes = 0; char *q = dst; const char *p = src; char ch; while ( (ch = *p++) ) { if ( bytes < size ) *q++ = ch; bytes++; } *q = '\0'; return bytes; } syslinux-legacy-3.63+dfsg/com32/lib/strlcat.c0000664000175000017500000000057110777447272017527 0ustar evanevan/* * strlcat.c */ #include #include size_t strlcat(char *dst, const char *src, size_t size) { size_t bytes = 0; char *q = dst; const char *p = src; char ch; while ( bytes < size && *q ) { q++; bytes++; } while ( (ch = *p++) ) { if ( bytes < size ) *q++ = ch; bytes++; } *q = '\0'; return bytes; } syslinux-legacy-3.63+dfsg/com32/lib/atexit.c0000664000175000017500000000020110777447272017337 0ustar evanevan/* * atexit.c */ #include int atexit(void (*fctn)(void)) { return on_exit((void (*)(int, void *))fctn, NULL); } syslinux-legacy-3.63+dfsg/com32/lib/init.h0000664000175000017500000000041610777447272017021 0ustar evanevan/* * init.h * * Magic to set up initializers */ #ifndef _INIT_H #define _INIT_H 1 #include #define COM32_INIT(x) static const void * const __COM32_INIT \ __attribute__((section(".init_array"),unused)) = (const void * const)&x #endif /* _INIT_H */ syslinux-legacy-3.63+dfsg/com32/lib/asprintf.c0000664000175000017500000000065010777447272017677 0ustar evanevan/* * asprintf.c */ #include #include #include int asprintf(char **bufp, const char *format, ...) { va_list ap, ap1; int rv; int bytes; char *p; va_start(ap, format); va_copy(ap1, ap); bytes = vsnprintf(NULL, 0, format, ap1) + 1; va_end(ap1); *bufp = p = malloc(bytes); if ( !p ) return -1; rv = vsnprintf(p, bytes, format, ap); va_end(ap); return rv; } syslinux-legacy-3.63+dfsg/com32/lib/getopt.c0000664000175000017500000000273010777447272017354 0ustar evanevan/* * getopt.c * * Simple POSIX getopt(), no GNU extensions... */ #include #include #include char *optarg; int optind = 1; int opterr, optopt; static const char *__optptr; int getopt(int argc, char * const *argv, const char *optstring) { const char *carg = argv[optind]; const char *osptr; int opt; /* We don't actually need argc */ (void)argc; /* First, eliminate all non-option cases */ if ( !carg || carg[0] != '-' || !carg[1] ) { return -1; } if ( carg[1] == '-' && !carg[2] ) { optind++; return -1; } if ( (uintptr_t)(__optptr-carg) > (uintptr_t)strlen(carg) ) __optptr = carg+1; /* Someone frobbed optind, change to new opt. */ opt = *__optptr++; if ( opt != ':' && (osptr = strchr(optstring, opt)) ) { if ( osptr[1] == ':' ) { if ( *__optptr ) { /* Argument-taking option with attached argument */ optarg = (char *)__optptr; optind++; } else { /* Argument-taking option with non-attached argument */ if ( argv[optind+1] ) { optarg = (char *)argv[optind+1]; optind += 2; } else { /* Missing argument */ return (optstring[0] == ':') ? ':' : '?'; } } return opt; } else { /* Non-argument-taking option */ /* __optptr will remember the exact position to resume at */ if ( ! *__optptr ) optind++; return opt; } } else { /* Unknown option */ optopt = opt; if ( ! *__optptr ) optind++; return '?'; } } syslinux-legacy-3.63+dfsg/com32/lib/srand48.c0000664000175000017500000000042210777447272017331 0ustar evanevan/* * srand48.c */ #include #include extern unsigned short __rand48_seed[3]; void srand48(long seedval) { __rand48_seed[0] = 0x330e; __rand48_seed[1] = (unsigned short)seedval; __rand48_seed[2] = (unsigned short)((uint32_t)seedval >> 16); } syslinux-legacy-3.63+dfsg/com32/lib/strncat.c0000664000175000017500000000022610777447272017526 0ustar evanevan/* * strncat.c */ #include char *strncat(char *dst, const char *src, size_t n) { strncpy(strchr(dst, '\0'), src, n); return dst; } syslinux-legacy-3.63+dfsg/com32/lib/puts.c0000664000175000017500000000022310777447272017040 0ustar evanevan/* * puts.c */ #include int puts(const char *s) { if ( fputs(s, stdout) < 0 ) return -1; return _fwrite("\n", 1, stdout); } syslinux-legacy-3.63+dfsg/com32/lib/strspn.c0000664000175000017500000000230710777447272017403 0ustar evanevan/* * strspn, strcspn */ #include #include #include #include #ifndef LONG_BIT #define LONG_BIT (CHAR_BIT*sizeof(long)) #endif static inline void set_bit(unsigned long *bitmap, unsigned int bit) { bitmap[bit/LONG_BIT] |= 1UL << (bit%LONG_BIT); } static inline int test_bit(unsigned long *bitmap, unsigned int bit) { return (int)(bitmap[bit/LONG_BIT] >> (bit%LONG_BIT)) & 1; } static size_t strxspn(const char *s, const char *map, int parity) { unsigned long matchmap[((1 << CHAR_BIT)+LONG_BIT-1)/LONG_BIT]; size_t n = 0; /* Create bitmap */ memset(matchmap, 0, sizeof matchmap); while ( *map ) set_bit(matchmap, (unsigned char) *map++); /* Make sure the null character never matches */ if ( parity ) set_bit(matchmap, 0); /* Calculate span length */ while ( test_bit(matchmap, (unsigned char) *s++)^parity ) n++; return n; } size_t strspn(const char *s, const char *accept) { return strxspn(s, accept, 0); } size_t strcspn(const char *s, const char *reject) { return strxspn(s, reject, 1); } char * strpbrk(const char *s, const char *accept) { const char *ss = s+strxspn(s, accept, 1); return *ss ? (char *)ss : NULL; } syslinux-legacy-3.63+dfsg/com32/lib/memmove.S0000664000175000017500000000361610777447272017503 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2008 rPath, Inc. - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * memmove.S * * Reasonably efficient memmove */ .globl memmove .type memmove,@function .text memmove: pushl %esi pushl %edi movl %eax,%edi movl %edx,%esi cmpl %edi,%esi jb 1f /* source >= dest, forwards move */ movl %ecx,%edx shrl $2,%ecx andl $3,%edx rep; movsl movl %edx,%ecx rep; movsb jmp 2f 1: /* source < dest, backwards move */ leal -4(%ecx,%esi),%esi leal -4(%ecx,%edi),%edi movl %ecx,%edx shrl $2,%ecx andl $3,%edx std rep; movsl movl %edx,%ecx addl $3,%esi addl $3,%edi rep; movsb cld 2: popl %edi popl %esi ret .size memmove, .-memmove syslinux-legacy-3.63+dfsg/com32/lib/memswap.c0000664000175000017500000000047010777447272017522 0ustar evanevan/* * memswap() * * Swaps the contents of two nonoverlapping memory areas. * This really could be done faster... */ #include void memswap(void *m1, void *m2, size_t n) { char *p = m1; char *q = m2; char tmp; while ( n-- ) { tmp = *p; *p = *q; *q = tmp; p++; q++; } } syslinux-legacy-3.63+dfsg/com32/lib/strndup.c0000664000175000017500000000034010777447272017544 0ustar evanevan/* * strndup.c */ #include #include char *strndup(const char *s, size_t n) { int l = n > strlen(s) ? strlen(s)+1 : n+1; char *d = malloc(l); if (d) memcpy(d, s, l); d[n] = '\0'; return d; } syslinux-legacy-3.63+dfsg/com32/lib/atox.c0000664000175000017500000000032010777447272017016 0ustar evanevan/* * atox.c * * atoi(), atol(), atoll() */ #include #include #include TYPE NAME (const char *nptr) { return (TYPE) strntoumax(nptr, (char **)NULL, 10, ~(size_t)0); } syslinux-legacy-3.63+dfsg/com32/lib/strtol.c0000664000175000017500000000010110777447272017367 0ustar evanevan#define TYPE signed long #define NAME strtol #include "strtox.c" syslinux-legacy-3.63+dfsg/com32/lib/strlen.c0000664000175000017500000000021110777447272017351 0ustar evanevan/* * strlen() */ #include size_t strlen(const char *s) { const char *ss = s; while ( *ss ) ss++; return ss-s; } syslinux-legacy-3.63+dfsg/com32/lib/exit.c0000664000175000017500000000273310777447272017026 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * exit.c * * The regular exit */ #include extern __noreturn (*__exit_handler)(int); __noreturn exit(int rv) { __exit_handler(rv); } syslinux-legacy-3.63+dfsg/com32/lib/printf.c0000664000175000017500000000036010777447272017351 0ustar evanevan/* * printf.c */ #include #include #define BUFFER_SIZE 16384 int printf(const char *format, ...) { va_list ap; int rv; va_start(ap, format); rv = vfprintf(stdout, format, ap); va_end(ap); return rv; } syslinux-legacy-3.63+dfsg/com32/lib/ctypes.c0000664000175000017500000003012210777447272017355 0ustar evanevan/* * ctypes.c * * This is the array that defines classes. * This assumes ISO 8859-1. */ #include const unsigned char __ctypes[257] = { 0, /* EOF */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl|__ctype_space, /* BS */ __ctype_cntrl|__ctype_space, /* TAB */ __ctype_cntrl|__ctype_space, /* LF */ __ctype_cntrl|__ctype_space, /* VT */ __ctype_cntrl|__ctype_space, /* FF */ __ctype_cntrl|__ctype_space, /* CR */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_print|__ctype_space, /* space */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_cntrl, /* control character */ __ctype_print|__ctype_space, /* NBSP */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_lower, /* lower accented */ }; syslinux-legacy-3.63+dfsg/com32/lib/libcom32.a0000664000175000017500000527364410777447334017504 0ustar evanevan! / 1207848668 0 0 0 11956 ` h/8AKU_tit { 4ڰD     |||||));ALUL_xd\iLuzP|(@Ì80 d) 1;E,NYDbXkx,T(Ŕ'1<I`S$zx|P\(x $38BPZ\Z\Z\a@a@ggu~,404!L0ALT^8^8h,x   ,DLLLAAkkkkkx@@@@@@@@@       L@L@L@L@PP``ll@S fdyptۘۘۘ [D kD kD kD kD kD kD kD kD kD kD kD h h h h h h h D D D D D D U U U U U U U U U | |  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp Bp                                  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\>>>>>>>>>>>>>$$$$$$$iiiiiiiiiiiiHX 6p`,T `L`"$/T/T>d>d>dT\T\T\j`j`j`<D******EpTan@~TX$$|||`*<===LXYxgxabortatexitatoiatolatollcalloccreat__ctypeserrnofgetcfgetsfopenfprintffputcputchar_setjmpsetjmplongjmpfputsfread_freadfreefwrite_fwritegetoptoptindoptargoptoptopterrjrand48mrand48__rand48_seednrand48lrand48__malloc_headmalloc__stack_sizememccpymemchrmemcmpmemcpymempcpymemmemmemmovememsetmemswapexiton_exitperrorprintfputsqsortreallocseed48snprintfsprintfsrand48sscanfstrcasecmpstrcatstrchrstrcmpstrcpystrdupstrerrorstrlenstrnlenstrncasecmpstrncatstrncmpstrncpystpncpystrndupstrntoimaxstrntoumaxstrrchrstrsepstrpbrkstrcspnstrspnstrstrstrtoimaxstrtokstrtolstrtollstrtoulstrtoullstrtoumaxvfprintfvprintfvsnprintfvsprintfasprintfvasprintfstrlcpystrlcatvsscanf__ashldi3__udivdi3__negdi2__ashrdi3__lshrdi3__muldi3__udivmoddi4__umoddi3__divdi3__moddi3__intcall__farcall__cfarcall__com32_zero_regs_start__com32__entry_esp_exit__exit_handler__parse_argv__mem_endtimes__file_infoopendevreadwriteftellcloseopen__file_read__file_closeisattyfstatopenconsole__line_inputconsole_color_tableconsole_color_table_sizegetscreensizedev_stdcon_rdev_stdcon_w__rawcon_readdev_rawcon_rdev_rawcon_wdev_error_rdev_error_wdev_null_rdev_null_w__serial_writedev_serial_w__syslinux_derivative_info__xserial_write__syslinux_derivative_info__ansi_putchar__ansi_init__ansicon_close__ansicon_write__ansicon_open__ansicon_opsdev_ansicon_wdev_ansiserial_w__vesacon_close__vesacon_write__vesacon_opendev_vesacon_wdev_vesaserial_w__vesacon_init__vesa_info__vesacon_bytes_per_pixel__vesacon_font_height__vesacon_graphics_font__vesacon_text_rows__vesacon_pixel_format__vesacon_text_display__vesacon_background__vesacon_init_cursor__vesacon_redraw_text__vesacon_doit__vesacon_erase__vesacon_set_cursor__vesacon_write_char__vesacon_scroll_up__vesacon_init_backgroundvesacon_set_backgroundvesacon_default_backgroundvesacon_load_background__vesacon_srgb_to_linear__vesacon_linear_to_srgb__vesacon_init_copy_to_screen__vesacon_copy_to_screen__vesacon_format_pixels_list__vesacon_format_pixelspci_set_config_type__pci_cfg_typefind_pci_devicepci_scanget_name_from_pci_idsget_module_name_from_pci_idspci_readbpci_readwpci_readl__pci_read_biospci_writebpci_writewpci_writel__pci_write_biosadler32compressBoundcompress2compressget_crc_tablecrc32gzungetcgzeofgzclearerrgzerrorgzflushgzclosegzwritegzputsgzputcgzprintfgzreadgzgetsgzgetcgzsetparamsgzdopengzopenuncompressdeflatePrimedeflateEnddeflateCopydeflateSetDictionarydeflatedeflateParamsdeflateBounddeflateResetdeflateInit2_deflateInit_deflate_copyright_tr_init_tr_tally_length_code_dist_code_tr_align_tr_stored_block_tr_flush_blockzlibVersionzlibCompileFlagszErrorz_errmsgzcfreezcallocinflateResetinflateInit2_inflateInit_inflateEndinflateSyncinflateSyncPointinflateCopyinflateSetDictionaryinflateinflateBackInit_inflateBackEndinflateBackinflate_tableinflate_copyrightinflate_fastpng_get_io_ptrpng_init_iopng_get_copyrightpng_get_libpng_verpng_get_header_verpng_get_header_versionpng_access_version_numberpng_init_mmx_flagspng_mmx_supportpng_reset_zstreampng_handle_as_unknownpng_sig_cmppng_check_sigpng_convert_to_rfc1123png_zfreepng_free_datapng_data_freerpng_zallocpng_info_init_3png_info_destroypng_info_initpng_destroy_info_structpng_create_info_structpng_calculate_crcpng_reset_crcpng_set_sig_bytespng_libpng_verpng_sigpng_IHDRpng_IDATpng_IENDpng_PLTEpng_bKGDpng_cHRMpng_gAMApng_hISTpng_iCCPpng_iTXtpng_oFFspng_pCALpng_sCALpng_pHYspng_sBITpng_sPLTpng_sRGBpng_tEXtpng_tIMEpng_tRNSpng_zTXtpng_pass_startpng_pass_incpng_pass_ystartpng_pass_yincpng_pass_maskpng_pass_dsp_maskpng_set_oFFspng_set_sCALpng_set_pHYspng_set_sRGBpng_set_unknown_chunk_locationpng_permit_empty_pltepng_set_read_user_chunk_fnpng_set_invalidpng_set_asm_flagspng_set_mmx_thresholdspng_set_user_limitspng_set_rowspng_set_tRNSpng_set_sBITpng_set_bKGDpng_set_keep_unknown_chunkspng_set_hISTpng_set_gAMA_fixedpng_set_gAMApng_set_cHRM_fixedpng_set_cHRMpng_set_sRGB_gAMA_and_cHRMpng_set_unknown_chunkspng_set_text_2png_set_pCALpng_set_sPLTpng_set_iCCPpng_set_textpng_set_IHDRpng_set_PLTEpng_get_validpng_get_rowbytespng_get_rowspng_get_image_widthpng_get_image_heightpng_get_bit_depthpng_get_color_typepng_get_filter_typepng_get_interlace_typepng_get_compression_typepng_get_x_pixels_per_meterpng_get_y_pixels_per_meterpng_get_pixels_per_meterpng_get_pixel_aspect_ratiopng_get_x_offset_micronspng_get_y_offset_micronspng_get_x_offset_pixelspng_get_y_offset_pixelspng_get_channelspng_get_signaturepng_get_bKGDpng_get_cHRMpng_get_cHRM_fixedpng_get_gAMApng_get_gAMA_fixedpng_get_sRGBpng_get_iCCPpng_get_sPLTpng_get_hISTpng_get_oFFspng_get_pCALpng_get_sCALpng_get_pHYspng_get_PLTEpng_get_sBITpng_get_textpng_get_tRNSpng_get_unknown_chunkspng_get_rgb_to_gray_statuspng_get_user_chunk_ptrpng_get_asm_flagspng_get_asm_flagmaskpng_get_mmx_flagmaskpng_get_mmx_bitdepth_thresholdpng_get_mmx_rowbytes_thresholdpng_get_user_width_maxpng_get_user_height_maxpng_get_IHDRpng_get_uint_32png_get_int_32png_get_uint_16png_get_uint_31png_read_start_rowpng_crc_errorpng_read_filter_rowpng_do_read_interlacepng_combine_rowpng_check_chunk_namepng_decompress_chunkpng_crc_readpng_crc_finishpng_read_finish_rowpng_handle_unknownpng_handle_zTXtpng_handle_tEXtpng_handle_sCALpng_handle_pCALpng_handle_oFFspng_handle_pHYspng_handle_iCCPpng_handle_sRGBpng_handle_cHRMpng_handle_sBITpng_handle_gAMApng_handle_IENDpng_handle_PLTEpng_handle_IHDRpng_handle_hISTpng_handle_bKGDpng_handle_tRNSpng_handle_sPLTpng_set_bgrpng_set_swappng_set_packingpng_set_packswappng_set_shiftpng_set_interlace_handlingpng_set_fillerpng_set_add_alphapng_set_swap_alphapng_set_invert_alphapng_set_invert_monopng_do_invertpng_do_swappng_do_packswappng_do_strip_fillerpng_do_bgrpng_set_user_transform_infopng_get_user_transform_ptrpng_set_read_status_fnpng_read_destroypng_destroy_read_structpng_read_endpng_start_read_imagepng_read_rowpng_read_imagepng_read_rowspng_read_update_infopng_read_infopng_read_pngpng_read_init_3png_read_init_2png_read_initpng_create_read_struct_2png_create_read_structpng_set_read_fnpng_default_read_datapng_read_datapng_set_strip_16png_set_strip_alphapng_set_gammapng_set_expandpng_set_palette_to_rgbpng_set_gray_1_2_4_to_8png_set_tRNS_to_alphapng_set_gray_to_rgbpng_set_read_user_transform_fnpng_read_transform_infopng_do_unpackpng_do_unshiftpng_do_choppng_do_read_swap_alphapng_do_read_invert_alphapng_do_read_fillerpng_do_gray_to_rgbpng_do_rgb_to_graypng_build_grayscale_palettepng_do_gammapng_do_expand_palettepng_do_expandpng_do_ditherpng_build_gamma_tablepng_init_read_transformationspng_do_backgroundpng_set_rgb_to_gray_fixedpng_set_rgb_to_graypng_set_backgroundpng_set_crc_actionpng_do_read_transformationspng_set_ditherpng_set_mem_fnpng_get_mem_ptrpng_memset_checkpng_memcpy_checkpng_free_defaultpng_freepng_destroy_struct_2png_destroy_structpng_malloc_defaultpng_mallocpng_malloc_warnpng_create_struct_2png_create_structpng_warningpng_set_error_fnpng_get_error_ptrpng_set_strip_error_numberspng_chunk_warningpng_errorpng_chunk_errorpng_push_crc_skippng_push_restore_bufferpng_push_have_infopng_push_have_endpng_push_have_rowpng_get_progressive_ptrpng_set_progressive_read_fnpng_push_fill_bufferpng_progressive_combine_rowpng_push_handle_unknownpng_push_handle_zTXtpng_push_handle_tEXtpng_push_save_bufferpng_read_push_finish_rowpng_push_process_rowpng_process_IDAT_datapng_push_read_IDATpng_push_crc_finishpng_push_read_zTXtpng_push_read_tEXtpng_push_read_chunkpng_push_read_sigpng_process_some_datapng_process_datatinyjpeg_decodetinyjpeg_get_errorstringtinyjpeg_get_sizetinyjpeg_get_componentstinyjpeg_set_componentstinyjpeg_get_bytes_per_rowtinyjpeg_set_bytes_per_rowtinyjpeg_set_flagstinyjpeg_parse_headertinyjpeg_process_Huffman_data_unittinyjpeg_freetinyjpeg_initjpeg_idct_floattinyjpeg_decode_mcu_1comp_tabletinyjpeg_decode_mcu_3comp_tableTINYJPEG_FMT_RGB24TINYJPEG_FMT_BGR24TINYJPEG_FMT_YUV420PTINYJPEG_FMT_GREYTINYJPEG_FMT_RGBA32TINYJPEG_FMT_BGRA32x86_init_fpupowstrtodsyslinux_idlesyslinux_reboot__syslinux_detect_features__syslinux_feature_flags__syslinux_get_config_file_name__syslinux_config_file__syslinux_derivative_info__syslinux_get_serial_console_info__syslinux_serial_console_info__syslinux_derivative_info__syslinux_get_ipappend_strings__syslinux_ipappend_strings__syslinux_derivative_infosyslinux_add_movelistsyslinux_free_movelistsyslinux_memory_mapsyslinux_compute_movelistsyslinux_prepare_shufflesyslinux_shuffle_boot_pmsyslinux_shuffle_boot_rmsyslinux_memmap_typesyslinux_memmap_largestsyslinux_free_memmapsyslinux_dup_memmapsyslinux_add_memmapsyslinux_init_memmapsyslinux_dump_memmapsyslinux_dump_movelistsyslinux_run_defaultsyslinux_run_commandsyslinux_final_cleanupsyslinux_local_bootsyslinux_run_kernel_imageloadfilesyslinux_boot_linuxinitramfs_add_datainitramfs_initinitramfs_mknodinitramfs_add_trailerinitramfs_add_fileinitramfs_load_fileinitramfs_load_archivepxe_get_cached_info__syslinux_get_adv__syslinux_adv_ptr__syslinux_adv_sizesyslinux_adv_writesyslinux_getadvsyslinux_setadv// 120 ` ansiserial_write.o/ vesaserial_write.o/ initramfs_file.o/ initramfs_loadfile.o/ initramfs_archive.o/ pxe_get_cached.o/ abort.o/ 1207848656 1026 1026 100664 2304 ` ELFx4( % $ > $ > .? : ; ' @o E!intx.  2 abort.c= |  Ct ts]abort long long intshort unsigned intunsigned intlong long unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned charsigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)abortshort intabort.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4  8%D+D0D?Bs> @R6N b,(^  oT ~tz    0.      abort.cabort_exit    ! & 4 ; B I P W _ fjn +atexit.o/ 1207848656 1026 1026 100664 2180 ` ELF 4(1% $ > $ > .? : ; ' I@ : ; I'  Idt</int_(,toa_2 atexit.c|  Ph3atexitGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)atexitunsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libfctnatexit.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %<+<0<bBh> hR6N Tb<$^ \ o`~sz l   t0}-.[[     atexit.catexiton_exit   ! & 9 DHP Z ,atoi.o/ 1207848656 1026 1026 100664 2472 ` ELF4(j 1% $ > $ > .? : ; ' I@: ; I I&I(int[h 3 8]4 atox.c =| CB G.Ittt tPdatoiatoi.cunsigned charshort unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlong long intnptrcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intsigned charatoiGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %L+L0LbB> RK8N x b0^  oK~z    0:.BB     atoi.catoistrntoumax    ! & - ; B I P W ^ j uy}   *atol.o/ 1207848656 1026 1026 100664 2496 ` ELF4(j 1% $ > $ > .? : ; ' I@: ; I I&I(int[h  8]4 atox.c =| CB G.Ittt tPdatolatol.cunsigned charshort unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intatollong long intnptrcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intlong intsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %L+L0LbB> RR8N b0^  oK~z  "  0B%.SS     atol.catolstrntoumax    ! & - ; B I P W ^ j uy}    *atoll.o/ 1207848656 1026 1026 100664 2480 ` ELF 4(j 1% $ > $ > .? : ; ' I@: ; I I&I'int~Zg! : 8]4 atox.c =| CB G.Ittt tPdatollunsigned charshort unsigned intatoll/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlong long intnptrcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intsigned charatoll.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %L+L0LbB> RK8N b0^  oK~z    0;.EE     atoll.catollstrntoumax    ! & - ; B I P W ^ j uy}   *calloc.o/ 1207848656 1026 1026 100664 2524 ` ELFT4(WS؉…t 1׉Z[_% : ; I$ > $ > .? : ; ' I@: ; I4: ; I &@h | 0int &v %Dq %Wptr X> ../include/bitsizecalloc.cstddef.h w=K| &AA C^ ttt #t#&t PRS$&QRP#R>calloc&unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)calloc.csizenmembsize_tcallocGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4&  %\+\0\uB>  R]\N b4^  o~z    0`.     &calloc.ccallocmalloc    ! & 1 D OSW \ f k u  Kcreat.o/ 1207848656 1026 1026 100664 2628 ` ELF4(RhBP% $ > $ > : ; I.? : ; ' I@: ; I I&I8kint%x , , P ]cO8 ../include/syscreat.ctypes.h =|  CAEA @. Itt t t t tPRhcreatcreat.cpathnameunsigned charcreatshort unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intmodelong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intsigned charmode_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 L %H+H0HoB> T RnSN  b8^   ov~rz ,    4 0.( 8     creat.ccreatopen    ! & 4 ; B I P W ^ n y}      Ectypes.o/ 1207848656 1026 1026 100664 1928 ` ELF4(% I!I/$ > 4: ; I?  &IX 56=6qh V%% ctypes.c0```````````````,,,,,,,,,,```````))))))!!!!!!!!!!!!!!!!!!!!``````******""""""""""""""""""""````0```````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!`!!!!!!!""""""""""""""""""""""""`""""""""\D__ctypesunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)/home/hpa/syslinux/release/syslinux-3.63/com32/lib__ctypesunsigned charctypes.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.debug_line.rodata.rel.debug_pubnames.debug_str.comment.note.GNU-stack4!4'4,4I>}\: (XJ)V  b!^  r0@}.4      ctypes.c__ctypes   ! 7 > E R errno.o/ 1207848656 1026 1026 100664 1468 ` ELF 4( % 4: ; I?  $ > ;a.(7int$ errno.c?%errnoGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)errno/home/hpa/syslinux/release/syslinux-3.63/com32/liberrno.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.debug_line.rel.debug_pubnames.debug_str.comment.note.GNU-stack4!4'4,40>d?: lHJ(ZV j0iuP.~~~  \   errno.cerrno   ! & 3 fgetc.o/ 1207848656 1026 1026 100664 2560 ` ELFX4(D$HtD$% $ > $ > : ; I< .? : ; ' I@: ; I4: ; I  I$7jint E$w3$f ch`{ :L4 ../includefgetc.cstdio.h[| $C t$t P Qufgetc$_IO_fileFILEfgetc.cunsigned charshort unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intfgetclong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4$  %X+X0XB> RPN b(^  o>~Bz  ^  0~c.      $fgetc.cfgetc_fread   ! & - ; F L S Z a h o {   Afgets.o/ 1207848656 1026 1026 100664 2708 ` ELF4(UWVS lj։͉ u 9u1C t Nۅt [^_]% $ > $ > : ; I< .? : ; ' I@: ; I4: ; I  IG CK5intE:~ Gs Pn 3nf ch 3p % :Y4 ../includefgets.cstdio.h OuY==Zw  XK? | $GAA AAC ttt ttGt PEWRDVDGRQFUFGQP?PCSKfgetsGunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)char_IO_filefgets.c/home/hpa/syslinux/release/syslinux-3.63/com32/libfgetsFILEGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4G %|+|0|B> R]N d b<^ l  oP~Az |  ]  0}.44      Gfgets.cfgetsfgetc   ! & - ; F Q \`d q ~    Afopen.o/ 1207848656 1026 1026 100664 3208 ` ELF4(VSƸ15rt +tau#wu BBB uŅtQhPVy1@Z[^% $ > $ > : ; I< .: ; ' I : ; I: ; I  I &I .? : ; ' I@ : ; I 4: ; I4: ; I1X Y 1)oSint"E'; 653__m5 :  % 5 o N   3  3fd 3ujk*c4 ../includefopen.cstdio.h t(w`q fK?t | 0oAA CNEAA @.HJ ttt StSXtXYtYZtZbt bltlot P nV_R _PmSdhPjkP-fopeno_IO_filefdopen__fdplusfopen.cFILEunsigned charfopenshort unsigned intfile/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intflagslong long unsigned intmodelong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4o @ %+0B{-> H RgN X bH^ `  oX~Mz p  i  x 0.  ,     ofopen.cfopenopen[   ! & - ; F L S Z a h o z             Afprintf.o/ 1207848656 1026 1026 100664 2552 ` ELFd4(L$(L$T$$D$ % : ; I I$ > $ > < .? : ; ' I@: ; I  4: ; I &IL +06Di%inta O   ap =x rv OPV 6q ../include/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includefprintf.cstdio.hstdarg.h @| C tt gfprintfunsigned int__gnuc_va_listGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)va_list/home/hpa/syslinux/release/syslinux-3.63/com32/libfprintfchar_IO_fileformatfprintf.cfileFILEGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 ( %P+P0PB> 0 RN b8(^  o` ~z    0n.      fprintf.cfprintfvfprintf   ! & 7 > I W b m x|   ~fputc.o/ 1207848656 1026 1026 100664 2452 ` ELF 4(шD$D$HtD$% $ > $ > : ; I< .? : ; ' I@: ; I4: ; I  I( W_;intE@5 3(c 3 f 3ch { :IM4 ../includefputc.cstdio.h YL| (C t(t PRQKfputc(unsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)fputcchar_IO_fileunsigned charfputc.c/home/hpa/syslinux/release/syslinux-3.63/com32/libFILEGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4( %\+\0\B> RzQN d b(^ l  oQ~Ez |  a  0.FF     (fputc.cfputc_fwrite   ! & - ; F Q \`d q ~  Aputchar.o/ 1207848656 1026 1026 100664 2312 ` ELF4(D$D$HtD$% $ > $ > .? : ; ' I@: ; I4: ; I v+PZ=intr 3+c 3 ch r{B9  putchar.c =L| +C t+t Pz:putchar+putcharunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)charunsigned charputchar.c/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4+ X%`+`0`aBz> `xR;=N bx(^  o3~z    0., <    +putchar.cputchar_fwrite   ! & - @ KOS ` s -setjmp.o/ 1207848656 1026 1026 100664 1264 ` ELF4( Y1bQjr zJÒbjr zbG setjmp.S2!//=!==== %/====f*setjmp.S/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU AS 2.17.50.0.18%*.symtab.strtab.shstrtab.text.data.bss.rel.debug_line.rel.debug_info.debug_abbrev.rel.debug_aranges4*!`'`0`K,  @j<  L^0 Z  Pm    _setjmpsetjmplongjmp, fputs.o/ 1207848656 1026 1026 100664 2540 ` ELFd4(UWVSƉՉ1҉وJ[^_]% $ > $ > : ; I< .? : ; ' I@: ; I: ; I  I &I(;CvintE{ 3(s D x  % :M4 ../includefputs.cstdio.h gI|  (AA AAttt t(tPW!V!(PR#U#(QKfputs(fputsunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)fputs.c/home/hpa/syslinux/release/syslinux-3.63/com32/libchar_IO_filefileFILEGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4( $ %\+\0\B> , RzQN b8^  o~z    0o.      (fputs.cfputs_fwrite$   ! & - ; F Q \`d q v  Afread2.o/ 1207848656 1026 1026 100664 2624 ` ELF4(SӉӋL$1ZY[% $ > : ; I$ > < .? : ; ' I@: ; I: ; I : ; I   I 5>q 7intPv ,ptr D ,W ,u f   EkT ../include/bitsize../includefread2.cstddef.hstdio.h | ACU Atttt tPRSQRVfreadunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)fread2.c/home/hpa/syslinux/release/syslinux-3.63/com32/libchar_IO_filesizefreadnmembsize_tFILEGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 ` %P+P0PB> h RoN  b 4^   o@~z (    0 0.8 H     fread2.cfread_fread   ! & - 8 F Q \ gko ~     afread.o/ 1207848656 1026 1026 100664 3312 ` ELF4(UWVS Ӊ͉1,Eىut t t )ÅuЉ [^_]% : ; I$ > $ > < .: ; ' I : ; I I .? : ; ' I@ : ; I : ; I 4: ; I 4: ; I 4: ; I? < >K[ 0QBint 0> 7+%B__f$ ,$ %K buf ,P  %n f  % rv s p .~Bx ../include../include/bitsize../include/sysfread.cstdio.hstddef.htypes.herrno.h iYN//s.J | $KAA AAC ttt ttKt P=CPRGSGKRQJUJKQIWP 'P3CP HVB_freadKsize_t_IO_filecountfread.cerrno_freadFILEunsigned charshort unsigned intptrdiff_t/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intssize_tfilenobytessigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4K %+0BVB> RN b8<^  ot~z    0.d       Kfread.c_freadreaderrno#   ! & 1 8 J Q X _ f m t              ' 5 free.o/ 1207848656 1026 1026 100664 3372 ` ELF4(VStyHQ q:uZ9uYZrV !AA AH>u+Q9u!VQVFBFPFAFH [^% : ; I$ > $ >  : ;  : ; I8  : ; I8  I .: ; ' I : ; I 4: ; I .? : ; ' @ : ; I4: ; I1X Y 1 4141 4: ; I? < V] 0int5C %#%%##4#  a2h#*3#+3#   ah pah nah ~> ptr=~,ah?U K ~6wH ../include/bitsizefree.cmalloc.hstddef.h=1MK<==g= thugkiggf| AA ttt P.9PP Q WRRVfreesize_tnextfree_arena_header__free_blockprev_freeunsigned charshort unsigned intfree.c/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intarena_header__malloc_headfreelong long intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)typeshort intsigned charsizenext_freeprevGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %+0B> R\{N b0^   o~z      09 .;;       free.cfree__malloc_head5?E   ! & 1 ? F M T [ b m u         '+/ > L UYeiw  Ufwrite2.o/ 1207848656 1026 1026 100664 2636 ` ELF4(SӉӋL$1ZY[% $ > : ; I$ > < .? : ; ' I@: ; I: ; I : ; I  I & 5TF 7intPK? ,ptr D ,W ,u f   ElU ../include/bitsize../includefwrite2.cstddef.hstdio.h | ACU Atttt tPRSQRVfwriteunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)fwrite2.cfwritechar_IO_file/home/hpa/syslinux/release/syslinux-3.63/com32/libsizenmembsize_tFILEGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 l %P+P0PB> t RpN  b4^ $  oD~z 4    < 0.@ P     fwrite2.cfwrite_fwrite   ! & - 8 F Q \ gko ~     bfwrite.o/ 1207848656 1026 1026 100664 3336 ` ELF4(UWVS Ӊ͉1,Eىut t t )ÅuЉ [^_]% : ; I$ > $ > < .: ; ' I : ; I I .? : ; ' I@ : ; I : ; I 4: ; I 4: ; I&&I4: ; I? < HKJ] 0SBint!/ 7%B__f$ ,B %K buf ,P  %n f  % rv s p 329~By ../include../include/bitsize../include/sysfwrite.cstdio.hstddef.htypes.herrno.h iYN//s.J | $KAA AAC ttt ttKt P=CPRGSGKRQJUJKQIWP 'P3CP HVL_fwriteKsize_t_IO_filecounterrnoFILEunsigned charshort unsigned int_fwritefwrite.cptrdiff_t/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intssize_tfilenobytessigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4K %+0B[L> RN bH<^  o~z    0.x       Kfwrite.c_fwritewriteerrno#   ! & 1 8 J Q X _ f m t              ' ? getopt.o/ 1207848656 1026 1026 100664 3632 ` ELF04(UWVS T$ $-D$:-ZB<-uzu E1I)9v=_<:t[$tMx:u<t4T$L$D tE9$8:u,:*u$E߉5;uE? [^_]% $ > $ > .? : ; ' I@: ; I4: ; I4: ; I4: ; I  I &I 4: ; I 4: ; I?  JAint 't:33Pcopt3        3  3  3Q getopt.c <ڟuh>!ghYg]gY? | $AA AAC ttt ttt P"R"d*Q*`"RRVVEN]getoptoptargoptind)opterr;optoptcargopterrunsigned charosptroptindshort unsigned intgetopt/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intoptarglong long unsigned intoptoptgetopt.cargclong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intargv__optptroptstringsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 h `%H+L0LBN> 8RGUN b<^  o~Iz    0;.ii ` ( =    !(/6getopt.c__optptrgetoptoptindstrchroptargoptoptopterrOfrx   ! & - ; B I P W c nrv {              %* 7< I, lrand48.o/ 1207848656 1026 1026 100664 3400 ` ELF4(UWVSP1PѺ1imލѽmމÍ4 fډfW1f_[^_]Ívf% $ > $ > : ; I.? : ; ' I@: ; I4: ; I I .? : ; ' I@ .? : ; ' I@ I !I/ 4: ; I?  1 Xint5a m Dx VbO Ppzt H"|t!z -'t O   X7 ../includelrand48.cstdint.h nF=兢u$u|  mAA AA p | ttt tmt?P?kWLiSV|PP5hjrand48mrand48nrand48lrand48"__rand48_seedjrand48uint64_t__rand48_seedunsigned charlrand48short unsigned intnrand48mrand48/home/hpa/syslinux/release/syslinux-3.63/com32/libxsubiunsigned intlong long unsigned intlong long intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intlong intsigned charlrand48.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %+0B5> (R\N bh^ @ o~Tz 0  e  8 0.$ @ d 9    mp )|1lrand48.cjrand48mrand48__rand48_seednrand48lrand48q}v   ! & 4 ; B I P W b n y}           # 0D<@LP\`malloc.o/ 1207848656 1026 1026 100664 4552 ` ELF 4(S )ʋt9v @9sB+QA AAA   [ÍvUWVStxX eq9r[C 9Ƌyir:Q)މpYH PB AxhQBQBoAxA I9u1[^_]% : ; I$ > $ >  : ;  : ; I8  : ; I8  I .: ; ' I 4: ; I .: ; ' @ 4: ; I 1X Y  41.: ; ' I : ; I: ; I4: ; I .? : ; ' I@: ; I4: ; I 1414: ; I?  4: ; I? < E|| 0intE;CW6%#[%##j#  a2h#`3#%3# sp% sp% _j# fp$ Q%%Q %%R ( /<fp;[;%=% nfp> na>e [d%dfpfQ _rzp o%QJ ../include/bitsizemalloc.cstddef.hmalloc.h"$w .0!g׻,XMNhSt=>gYg?===?==gi=iX; t| A AA AAttttt ttPS PPPR+Imalloc__malloc_headsize_tnextfree_arena_headermallocprev_free__malloc_from_blockunsigned charstartshort unsigned intinit_memory_arena/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intarena_header__malloc_headtotal_spacelong long intfsizeGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)typeshort intsigned char__mem_endsizenext_freeprev__stack_sizemalloc.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.rel.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.ctors.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 Hx)D%  /\4\zFIB VR  fb  qPm   ~ /   0. P H   &3Amalloc.cinit_memory_arena__mem_end__stack_size__malloc_headmalloc(-<HRY`gmsy  !&1?FMT[bmu &3DHOSd{     */<W 0 4stack.o/ 1207848656 1026 1026 100664 1604 ` ELF|4( % : ; I$ > $ > 4: ; I?  M(Q= 00intD%C= ../include/bitsizestack.cstddef.hQ>__stack_sizeGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)stack.cunsigned intsize_t__stack_size/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.debug_line.rel.debug_pubnames.debug_str.comment.note.GNU-stack4!4'8,8H>Q: XJGZ#V <j0;u.~     stack.c__stack_size   ! & 1 ? L memccpy.o/ 1207848656 1026 1026 100664 2648 ` ELF 4(VS΋\$D$A8D$u BKu1Z[^% : ; I$ > $ > .? : ; ' I@: ; I4: ; I 4: ; I   I & &I1 5SL 0int? 1dst Dsrc bc 7n %q Qp chs   G  [? ../include/bitsizememccpy.cstddef.h OH| 1AA Ci ttt .t.1t P%-P%R%.R Q V%0V/S/1.R>memccpy1unsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)memccpy.cmemccpycharsize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack41!h'h,h>: N_J ( ^<4Z 0  kpzWv @  u  H 0.II| |     1memccpy.cmemccpy   ! & 1 D OSW f u     Lmemchr.o/ 1207848656 1026 1026 100664 2296 ` ELF4(8tIu1% : ; I$ > $ > .? : ; ' I@ : ; I: ; I 4: ; I   I & &I QJ 0int5 tsc7Rn%Qsp    <T> ../include/bitsizememchr.cstddef.h2I|  PP>memchrunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)memchrunsigned charsize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libmemchr.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!D'D,D>: XpNXJ ^$Z  kzv  7  0W.D D    memchr.cmemchr   ! & 1 D OSc  Kmemcmp.o/ 1207848656 1026 1026 100664 2544 ` ELF4(VSΉÉ1)‰uCANu[^% : ; I$ > $ > .? : ; ' I@: ; I4: ; I4: ; I  I & &I#Go 0int7#s1,s2?n%]c1 {c2 Qd 7   xW> ../include/bitsizememcmp.cstddef.hKge-m| #AA tt#t PR#RQ"V!S P P>memcmp#memcmpunsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)memcmp.cunsigned charsize_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4#!X'X,X>: ( N[J ^ 0Z  k<zv    0%.      #memcmp.cmemcmp   ! & 1 D OSW e s     Kmemcpy.o/ 1207848656 1026 1026 100664 1192 ` ELF4( VW։ljsft_^A memcpy.S!"4/0=!0/0=/"!!fmemcpy.S/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU AS 2.17.50.0.18%.symtab.strtab.shstrtab.text.data.bss.rel.debug_line.rel.debug_info.debug_abbrev.rel.debug_aranges4!P'P0PE, p @j< x L^ Z  8m  h memcpy, mempcpy.o/ 1207848656 1026 1026 100664 1204 ` ELF4( VW։ljsft_^C  mempcpy.S!"4/0=!0/0=/"/!!gmempcpy.S/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU AS 2.17.50.0.18%.symtab.strtab.shstrtab.text.data.bss.rel.debug_line.rel.debug_info.debug_abbrev.rel.debug_aranges4!T'T0TG, | @k<  L^  Z  @m  p  mempcpy- memmem.o/ 1207848656 1026 1026 100664 3076 ` ELFT4(UWVSD$ϋl$09wD$AD$8D$tD$D$XD$D$)T$1T$D$:T0tt$$\$MSGuT$:tt$;t$v1[^_]% : ; I$ > $ > .? : ; ' I@: ; I: ; I4: ; I 4: ; I   I & &I@h  0intPn%om%yx j% k%6 l%V    ql> ../include/bitsizememmem.cstddef.hM%rJ hzJ | $AA AAC0ttt ttt0PX:R>ZRRQ(W(:Q:>W>sQsWQU:>VVV0>dFd8>hNh>memmemunsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)memmem.cunsigned charmemmemhaystacksize_tneedleGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4  %+0Bz>  RcpN b<^  ov~z    0`.       memmem.cmemmemmemcmpz   ! & 1 D OSW \ f s x       Kmemmove.o/ 1207848657 1026 1026 100664 1244 ` ELF4( VWlj9rt1|9у_^P  memmove.S%!"/0/1/=>//01KL/=>!//==/#!!g;memmove.S/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU AS 2.17.50.0.18%;.symtab.strtab.shstrtab.text.data.bss.rel.debug_line.rel.debug_info.debug_abbrev.rel.debug_aranges4;!p'p0pT,  @k<  L/^H Z  hm    ;memmove- memset.o/ 1207848657 1026 1026 100664 2724 ` ELF(4(WVS$Ήiً<$$Z[^_% : ; I$ > $ > .? : ; ' I@: ; I4: ; I  I08 0kintx1 0dstPc7on%q nl % W> ../include/bitsizememset.cstddef.hYt| $0AA ACfttt t,t,0tP0l,RQ.V!/W -Shmemset0size_tmemset.cunsigned charshort unsigned intmemset/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack40!d'd,d~>: N[J t ^<Z |  kTzv  7  0W7.ee      0memset.cmemset   ! & 1 ? F M T [ b n y}       Kmemswap.o/ 1207848657 1026 1026 100664 2448 ` ELF\4(VSƉ VCFSIFCu[^% : ; I$ > $ > .? : ; ' @: ; I: ; I 4: ; I 4: ; I   I 5NG 0int? m1 ,m2 Un %Qp q tmpR  Y? ../include/bitsizememswap.cstddef.h =g9| AA ttt PVPRSR>memswapunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)memswap.cmemswapsize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libcharGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!T'T,T>: N]J ` ^0Z h  k(~zv x    0j.     memswap.cmemswap   ! & 1 D KOS a o  Lexit.o/ 1207848657 1026 1026 100664 2288 ` ELF4( % $ > $ > .? : ; ' @: ; I' I4: ; I? <  I 5I| IP7int[D' rv&, g,($t z [3 exit.c&=|  Ct t P3exit GNU C 4.1.2 20070925 (Red Hat 4.1.2-33)__exit_handlerunsigned intexitexit.c/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4  H%@+@0@B> PpRA7N bx(^  o3~z    0. ,     exit.cexit__exit_handler   ! & 9 @DH V h *onexit.o/ 1207848657 1026 1026 100664 3440 ` ELF4(VSÉָ …upBD1Z[^ÍvVSƋ S[u% $ > $ >  : ;  : ; I8  : ; I8 ' I   I .? : ; ' I@ : ; I : ; I4: ; I.: ; ' @4: ; I 4: ; I 4: ; I? < 5I^h]int/  X #arg # #,   ] B,A XD argbas, Dh rv ,apSJ I,  V \=O+ onexit.catexit.h/>hftwsx| AAA Cy D$AA Cttt >t>At P?SR@VDEtEFtFIt IhtDSPShVbon_exithnexton_exit_exitunsigned char__exit_handlershort unsigned inton_exit__atexit_listfctn/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intonexit.clong long intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)atexitshort intsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4h 8%+0Bb> 0 RSN 0 bXT^ 8  o~z X    ` 0.\ P  I D$   %A-4Conexit.c__atexit_liston_exit_exiton_exitmalloc__exit_handler_exit$-37Md !&4;BIPWbj       -9J8 8 <perror.o/ 1207848657 1026 1026 100664 2524 ` ELF 4( 5Phj% $ > $ > .? : ; ' @: ; I I&I4: ; I? < v @I5inta| s a\g%:3M5 ../includeperror.cerrno.h =/%s: error %d | $CFAEB @.It t t ttt tPz:perrorunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)charerrnoperror.c/home/hpa/syslinux/release/syslinux-3.63/com32/libperrorGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4  %P+P0PqBz> 4 xR;QN ^2q<m  ~oG d  0.550     perror.cperrorerrnofprintf    ! & - @ GKO \ m B printf.o/ 1207848657 1026 1026 100664 2440 ` ELF 4(L$$L$T$ % : ; I I$ > $ > .? : ; ' I@: ; I  4: ; I &IQa +06LDi%int OZ  ap =x rv OP 6rZ /usr/lib/gcc/x86_64-redhat-linux/4.1.2/includeprintf.cstdarg.h @| C tt Vprintfunsigned int__gnuc_va_listGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)va_listcharprintf.cformat/home/hpa/syslinux/release/syslinux-3.63/com32/libprintfGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %T+T0TB> RvN X b(^ `  o  ~@z p  ]  x 0}.FF     printf.cprintfvfprintf   ! & 7 > I \ gko t gputs.o/ 1207848657 1026 1026 100664 2380 ` ELF4( x % $ > $ > .? : ; ' I@: ; I I&Im/ ?F5inte:3/se k%5 puts.c=;Y | /Ct/t Pq:puts/unsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)charputsputs.c/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4/ %d+d0dbBq> pR79N  ^2pqt(m $  ~3 4   < 0 y.H0 x   / puts.cputsfputs_fwrite $   ! & - @ KOS ` * qsort.o/ 1207848657 1026 1026 100664 3184 ` ELF4(UWVSD$T$ ͉k 1Í@w ut$ō<D$D$'T$0~D$D$D$ )9D$u̓w|$z[^_]% : ; I$ > $ > .: ; ' I : ; I.? : ; ' @: ; I : ; I 4: ; I 4: ; I 4: ; I 4: ; I 1X Y 1 ' II I&AEy 0int[m %gap %P%o% 1 gap% i%d j% p17 p27 7h>8O*7**0=td= ../include/bitsizeqsort.cstddef.hv.fʻ+C| $AA AAC0ttt ttt0P`R\QU8S8SVX^RfmRE[qsortsizeunsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)newgapcharqsort.ccomparswappedbasenmembsize_tqsortGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 X %+0BE> ` R hN @ b<^ H  o~z X    ` 0.0  @     qsort.cqsortmemswapi   ! & 1 C a hlp u           > Jrealloc.o/ 1207848657 1026 1026 100664 4004 ` ELF4(UWVS ʼnT$uЃ [^_]|$u p~\$9r 9N>9u39u.AD$9r!AFp QABAPL$N9rlC 9)ىJ^FBVBP r 9vBBBPOBBBP2D$Åu1GL$9v݉ [^_]% : ; I$ > $ >  : ;  : ; I8  : ; I8  I .? : ; ' I@ : ; I : ; I 4: ; I 4: ; I 4: ; I? < <%f 0int//=%#;%##J#  a2h#@3#%3# }^ }< ptr }P ; % ah nah } %@ P%^ X%q6K ../include/bitsizerealloc.cstddef.hmalloc.h K.tZu@?=g=gL=gY?g=g?OugugY | $<AA AAC ttt tt<t PU+P+0U0FPF;URh)Q)<h39VTQQR2<R SP8S: S28S6:WQ Q2<Qrealloc<size_tnextfree_arena_headernewptrprev_freeunsigned charshort unsigned intoldsizexsizerealloc/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intarena_header__malloc_headlong long intnewsizeGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)typeshort intrealloc.csigned charsizenext_freeprevGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4< X%p+p0pBJ> ,HRN tbp<^ | o~Fz  d  0O.` @  4    <-realloc.creallocmallocfree__malloc_headmemcpy'%,   ! & 1 ? F M T [ b m u            - < A K P Z _ i n x  Xseed48.o/ 1207848657 1026 1026 100664 2660 ` ELF`4(fff@f% $ > $ > .? : ; ' I@ : ; I4: ; I  I&I I !I/ 4: ; I? < 2L!int5. 2t  OO O !  8 seed48.c #|  2&P]seed482long long intshort unsigned intunsigned intseed48long long unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned charxsubi__rand48_seedoldseedsigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)seed48.cshort intGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack42 D 8%h+h0hB> | R<N 4 b$^ <  o,~?z L  \  T 0|l.   ,    2seed48.coldseed.1561seed48__rand48_seed(-   ! & 4 ; B I P W c nrz     , snprintf.o/ 1207848657 1026 1026 100664 2620 ` ELF4(D$,D$ PL$8T$4D$0,% : ; I I$ > $ > .? : ; ' I@: ; I : ; I  4: ; I &I$#oz+06\Ti%h SintKZ$ nHa ap =x rv ZP6 6{ ../include/bitsize/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includesnprintf.cstddef.hstdarg.h@M| $C K,A0L.I tt t,$t0$$t asnprintf$unsigned intbuffer__gnuc_va_listGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)snprintfva_listcharformatsize_tsnprintf.c/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4$ t %X+X0XB> | RN bT4^   oD~z $    , 0 .D T     $snprintf.csnprintfvsnprintf   ! & 7 > I T g rvz   sprintf.o/ 1207848657 1026 1026 100664 2716 ` ELF4(D$(D$ PL$4D$0,% : ; I I$ > $ > .? : ; ' I@: ; I  4: ; I &I#B3+06+i%uint  O# ap =x rv OP6 6r[ /usr/lib/gcc/x86_64-redhat-linux/4.1.2/includesprintf.cstdarg.h@@| #C K,A0K.I tt t,#t0##t sprintf#sprintf.cunsigned charshort unsigned intva_list__gnuc_va_list/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intformatlong long unsigned intlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intbuffersigned charsprintfGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4# %X+X0XB> RvN l b84^ t  olD~z    0.|      #sprintf.csprintfvsnprintf   ! & 7 > I W ^ e l s z     hsrand48.o/ 1207848657 1026 1026 100664 2420 ` ELF4(f3ff% $ > $ > .? : ; ' @ : ; I I!I/ 4: ; I? < M!int6. t PO!8  srand48.c g|  ]srand48long long intshort unsigned intunsigned intsrand48long long unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned charsrand48.c__rand48_seedlong intsigned charseedvalGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %P+P0PsB> Rr<N D b$^ L  so \    d 0.55` `!   srand48.csrand48__rand48_seed    ! & 4 ; B I P W c jnv    -sscanf.o/ 1207848657 1026 1026 100664 2460 ` ELF 4(L$(L$T$$D$ % : ; I I$ > $ > .? : ; ' I@: ; I : ; I  4: ; I &ILh +06UDi%intaOstrZ ap =x rv OP 6pZ /usr/lib/gcc/x86_64-redhat-linux/4.1.2/includesscanf.cstdarg.h@| C tt Vsscanfunsigned int__gnuc_va_listGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)va_listsscanf.ccharformatsscanf/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %P+P0PB> RtN l b (^ t  o4 ~Tz  q  0,.ZZ     sscanf.csscanfvsscanf   ! & 7 > I \ gko  gstrcasecmp.o/ 1207848657 1026 1026 100664 2968 ` ELF4(SÊD$Ct t)u |$tBZ[% $ > $ > .? : ; ' I : ; I .? : ; ' I@: ; I 4: ; I 4: ; I 1X Y 1 1X Y  I&II!4: ; I? < J<w9intQ L,__cK,pn,__cm, l ,<s1 8s2 K c1 i c2 R ch )w d ,| Q c Q+ c+$);)0#H0h9 ../includestrcasecmp.cctype.hK5<B| <AC vtt:t :<tP7R9:R;SP-9PNpstrcasecmp<unsigned intislowertoupperunsigned charchar__ctypes/home/hpa/syslinux/release/syslinux-3.63/com32/libstrcasecmpGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)strcasecmp.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4< %p+p0pB]N> RlN h b0^ p  oH~!z    0#.\  l "   <strcasecmp.cstrcasecmp__ctypes!   ! & 9 W v       * < Fstrcat.o/ 1207848657 1026 1026 100664 2412 ` ELF4(VSƉ1Z[^% $ > $ > .? : ; ' I@: ; I I&I 5JintoCodstoDsrc|bu>u4 strcat.c| AA CU ttt tt PV R S3strcatunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)strcat.ccharstrcat/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %T+T0TbB> xR>8N < bx4^ D  o~,z T  I  \ 0i}.t      strcat.cstrcatstrchrstrcpy    ! & 9 DHL [ j v ,strchr.o/ 1207848657 1026 1026 100664 2172 ` ELF`4(u1@8u% $ > $ > .? : ; ' I@ : ; I: ; I  I&I} tAinth5htsuc,Rn<{n6 strchr.c0vm|  P P3strchrunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)strchrchar/home/hpa/syslinux/release/syslinux-3.63/com32/libstrchr.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!H'H,Hq>: hN::J L^t$Z T kzv d   l0}p.     strchr.cstrchr   ! & 9 DHX o ,strcmp.o/ 1207848657 1026 1026 100664 2512 ` ELF4(SÉъD$CA)‰u|$uZ[% $ > $ > .? : ; ' I@: ; I4: ; I4: ; I  I &I&@t inth,&s18s2Kc1 ^c2 Qch qd , o }6 strcmp.cKO| &AC `tt$t $&t PR%Sw$R$&w P#P3strcmp&unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)strcmpcharstrcmp.cunsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4&!\'\,\>:  N:J ^0Z  kzv    0.     &strcmp.cstrcmp   ! & 9 DHL Z h v     ,strcpy.o/ 1207848657 1026 1026 100664 2336 ` ELF4(SÉABu[% $ > $ > .? : ; ' I@: ; I4: ; I 4: ; I I &I :Cintv dst src >q Qp Rch Q5 8 strcpy.c <4gM| AttPS RP3strcpyunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)charstrcpy.c/home/hpa/syslinux/release/syslinux-3.63/com32/libstrcpyGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!H'H,H>: pNt<J ^,Z  kdz@v   ]   0}}.((\ \    strcpy.cstrcpy   ! & 9 DHL [ j   ,strdup.o/ 1207848657 1026 1026 100664 2392 ` ELF4(WVS1ӉDžt ى[^_% $ > $ > .? : ; ' I@: ; I4: ; I I&I/ tAintp5 p/s}8l ,d pv<v7 strdup.cYגK| /AA Attt /t P -V3strdup/unsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)strdupchar/home/hpa/syslinux/release/syslinux-3.63/com32/libstrdup.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4/ %d+d0doB> pR\;N ( b4^ 0  oV~"z @  ?  H 0_}.  h      /strdup.cstrdupmallocmemcpy%   ! & 9 DHL Y w ,strerror.o/ 1207848657 1026 1026 100664 2632 ` ELF4(S(D$'\$'K Й0…uL$()ىڸ([error % $ > $ > .? : ; ' I@: ; I4: ; I 4: ; I I I !I/ < T_intK<=,,D Xp `5  ;! strerror.cm/L!| <AC0tt<t0PR!%R%2P;S3strerror<unsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)messageerrnumnumbufstrerrorstrerror.c/home/hpa/syslinux/release/syslinux-3.63/com32/libcharGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4< h % +0B+> x R?N  b,^  oHs~z 0    8 0.  < )    <"strerror.cmessage.1413strerrormemcpy.3   ! & 9 DHL Q [ ` v {   . strlen.o/ 1207848657 1026 1026 100664 2264 ` ELF4(@8u)% : ; I$ > $ > .? : ; ' I@ : ; I4: ; I I &I QJ 0intv % tsvss v| ET> ../include/bitsizestrlen.cstddef.hMw|  P R P>strlen unsigned intstrlenstrlen.cGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)charsize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 !D'D,D~>: 0xNKXJ ^$Z  k1zv    06.     strlen.cstrlen   ! & 1 D OSc q  Kstrnlen.o/ 1207848657 1026 1026 100664 2296 ` ELF4(@Jt8u)% : ; I$ > $ > .? : ; ' I@ : ; I: ; I 4: ; I  I &I 5KD 0int~%tsn%Rss   ?U? ../include/bitsizestrnlen.cstddef.hM|  PQP>strnlenunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)strnlen.ccharsize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libstrnlenGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!H'H,H>: PxNiYJ ^$Z  k1zv  7  0W.  < <    strnlen.cstrnlen   ! & 1 D OSc |  Lstrncasecmp.o/ 1207848657 1026 1026 100664 3144 ` ELFd4(VSΉÉ3D$tt)‰u|$t CANu1Z[^% : ; I$ > $ > .? : ; ' I : ; I .? : ; ' I@ : ; I 4: ; I 4: ; I 1X Y 11X Y  I&II!4: ; I? < bLZ/ 0int\L7__cK7{6n7__cm7$# 7L s1$D s2$b n% c1 6 c2 6Q ch As d 7 \" n\%1 n*/L<A>SAQ#`HY ../include../include/bitsizestrncasecmp.cctype.hstddef.hum<+ |  LAA CD ttt ItILt P@HPR@IR Q KV JS P5HPf{strncasecmpLstrncasecmp.cunsigned intislowerstrncasecmpsize_ttoupperunsigned charchar__ctypes/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4L 0 %+0Bzf> @ RN  bp8^  o~w"z 0    8 0n.   $   Lstrncasecmp.cstrncasecmp__ctypes'   ! & 1 D b        0 B T fstrncat.o/ 1207848657 1026 1026 100664 2528 ` ELF<4(WVSlj։1ى[^_% : ; I$ > $ > .? : ; ' I@: ; I I&I BSL 0int5dst8srcVn%t=T? ../include/bitsizestrncat.cstddef.h| AA Attt tPW R VQS>strncatunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)strncatcharstrncat.csize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4  %T+T0ToB> ( RcXN b4^  o~z    0F.tt  "    strncat.cstrncatstrchrstrncpy    ! & 1 D OSW f u   Lstrncmp.o/ 1207848657 1026 1026 100664 2672 ` ELF4(WVSωƉ)‰ut FAOu1[^_% : ; I$ > $ > .? : ; ' I@: ; I4: ; I4: ; I  I &I+ ? 0intr7+s18s2Vn%tc1 c2 Qch d 7  z  X? ../include/bitsizestrncmp.cstddef.hYk-| +AA Attt +tP'PR+R Q *W)V SR'S'+R P'P>strncmp+unsigned intstrncmp.cGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)/home/hpa/syslinux/release/syslinux-3.63/com32/libstrncmpcharunsigned charsize_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4+!`'`,`>: N\J @ ^(4Z H  k\zSv X  q  ` 0%.SS      +strncmp.cstrncmp   ! & 1 D OSW e s       Lstrncpy.o/ 1207848657 1026 1026 100664 2500 ` ELF4(VSƉˉ tABKu[^% : ; I$ > $ > .? : ; ' I@: ; I4: ; I 4: ; I  I &I |I: 0intA dst ,src Jn %hq Qp Rch 5  Z? ../include/bitsizestrncpy.cstddef.h fPKI-m| AA ttt P VRRQS P>strncpyunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)charsize_tstrncpy/home/hpa/syslinux/release/syslinux-3.63/com32/libstrncpy.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!T'T,T>:  N^J ^0Z  k4zv    0 .     strncpy.cstrncpy   ! & 1 D OSW f u    Lstpncpy.o/ 1207848657 1026 1026 100664 2480 ` ELFl4(Sˉ tBAKu[% : ; I$ > $ > .? : ; ' I@: ; I4: ; I 4: ; I  I &I 5SL 0intD dst src >n %\q Qp Rch z ?  [? ../include/bitsizestpncpy.cstddef.h stpncpyunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)stpncpy.ccharstpncpysize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!P'P,P>: N_J ^,Z  k,zv    0}.     stpncpy.cstpncpy   ! & 1 D OSW f u    Lstrndup.o/ 1207848657 1026 1026 100664 2644 ` ELF4(UWVS ʼn1эA9vZDžt ى7 [^_]% : ; I$ > $ > .? : ; ' I@: ; I4: ; I4: ; I  I &II 5SL 0intD IsPn%nl 7d ?  Y? ../include/bitsizestrndup.cstddef.hKL | $IAA AAC ttt ttIt PHU,R,FV "S%ES>strndupIunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)strndup.ccharstrndupsize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4I %+0B > R]N $ b<^ ,  oL~z <    D 04.H  h !    Istrndup.cstrndupmallocmemcpy(7   ! & 1 D OSW d q ~  Lstrntoimax.o/ 1207848657 1026 1026 100664 2712 ` ELF4(% : ; I$ > $ > .? : ; ' I@ : ; I: ; I  I &IP 0int W)<3LE st  $ 7&n % nY ../include../include/bitsizestrntoimax.cstdint.hstddef.h |  PRQ~strntoimaxendptrint64_tsize_tunsigned charbaseshort unsigned intintmax_tstrntoimax/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlong long intnptrcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intstrntoimax.csigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %<+<0<~B> RrN h b $^ p  oD9~}!z    0 .T d $   strntoimax.cstrntoimaxstrntoumax   ! & 1 ? F M X _ f m t         fstrntoumax.o/ 1207848658 1026 1026 100664 3888 ` ELF4(UWVS$ʼnT$L$ EL$8|$8t)Uu-uEL$8D$+uED$|$ uc|$8v#}0u$E $ > .? : ; ' I : ; I.: ; ' I .? : ; ' I@ : ; I : ; I 4: ; I 4: ; I 1X Y 1 I&II!4: ; I? < r 0int 3AlT4a[7__cZ7^ 7ch 7Qs gQP ,cn 7 n% l7 vs d7 1QA4W\i\zS##od ../include../include/bitsizestrntoumax.cctype.hstdint.hstddef.h4!H^Z!YuvY*KuvY]>KLY/ 0RUN b<^  o<]~!z    0,.44   "   strntoumax.cstrntoumax__ctypes'   ! & 1 ? F M T [ b m t             & 3 <@K ] { qstrrchr.o/ 1207848658 1026 1026 100664 2292 ` ELF4(S18u@u[% $ > $ > .? : ; ' I@: ; I: ; I 4: ; I I &I 5Mintx?xs c,RG 3~ ~8  strrchr.c Nhm| AttPS3strrchrunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)strrchr.cstrrchrfound/home/hpa/syslinux/release/syslinux-3.63/com32/libcharGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!L'L,L>: DN]<J ^,Z  kFzv  ,  0L.0 0    strrchr.cstrrchr   ! & 9 DHL Y i s  -strsep.o/ 1207848658 1026 1026 100664 2524 ` ELFH4(VSƋtt@Z[^% $ > $ > .? : ; ' I@: ; I4: ; I I&I$@n int$wDhbs e 9 strsep.cu1MuKL0| $AA C\ ttt !t!$t P#VR!R "S P3strsep$unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)delimstrsep.cstringpstrsepcharGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4$ %X+X0XqB>  Rq=N b4^  o~z    0R.     $strsep.cstrsepstrpbrk   ! & 9 DHL Q [ ` j w   ,strspn.o/ 1207848658 1026 1026 100664 4252 ` ELF 4(Sщ [ÐUWVS ʼnӉΉ1 CЉuu1 1B *9uЃ [^_]fSù8u1[Ívvf1m% : ; I$ > $ > .: ; ' @: ; I : ; I I .: ; ' I : ; I : ; I .: ; ' I@ : ; I4: ; I 4: ; I&II!I/ .? : ; ' I@.? : ; ' I@ .? : ; ' I@ 4 0int,&y8Pbit0 g #7  bit0 5%z>s5map5 7GLn%;@WW>|s=5& =5Dss?5W@8%ts75u 752%ts15 15n> ../include/bitsizestrspn.cstddef.h=! <ثjx=uwXz| A$bAA AAC4|A ttRQttt ttzt4/P/yU3R3vS-Q-wVJLRWzR|}t}t|PS|RPPPRPR1^strpbrkstrcspnstrspnstrxspnacceptsize_tbitmapmatchmapunsigned char/home/hpa/syslinux/release/syslinux-3.63/com32/liblong unsigned intshort unsigned intrejectstrpbrkparitystrcspnstrspn.cunsigned intlong long unsigned intlong long intcharstrspnGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short inttest_bitsigned charset_bitGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!',F>&: lNArJ ,^Z 4P k@z5v  6  0V@. @ 81 b   |" *strspn.cset_bitstrxspnstrpbrkstrcspnstrspn !&1?FMT[bmtx|      0 AXdosw        K 0 4X \p t strstr.o/ 1207848658 1026 1026 100664 2508 ` ELFL4(UWVSʼnT$1وNJVL$[^_]% $ > $ > .? : ; ' I@: ; I I&I?@ intoho?t|h}|uou6 strstr.c*| ,?AA AAC,e0F.M,ttt tt,t,,?t0??t,P>URW?h3strstr?unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)strstrcharhaystackneedlestrstr.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4? %t+t0tbB>  R^:N bD^  o~z    0V.     ?strstr.cstrstrmemmem3   ! & 9 DHL Q [ ` j v ,strtoimax.o/ 1207848658 1026 1026 100664 2712 ` ELF4(j% $ > $ > : ; I.? : ; ' I@: ; I I&I:b&int LF3A h! 83 K] ,^M6 ../includestrtox.cstdint.h =u| CB @.Ittt t P R Qsstrtoimaxlong long intshort unsigned intnptrunsigned intendptrstrtoimax.clong long unsigned intbase/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned charcharstrtoimaxint64_tsigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)intmax_tshort intGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %D+D0DoB> RQN h b0^ p  oq~ z    0.T d "    strtoimax.cstrtoimaxstrntoumax   ! & 4 ; B M T [ b i y         Cstrtok.o/ 1207848658 1026 1026 100664 2376 ` ELF4(t% $ > $ > .? : ; ' I@ : ; I: ; I4: ; I  I &I NWint}G}ts}5; }B 6 strtok.c KZ |  PR3strtokunsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)delimholdercharstrtokstrtok.c/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 x%H+H0HB> R^:N  b$^  o&~z 0    8 0.4  T$    strtok.cholder.1414strtokstrsep    ! & 9 DHX ] g l x , strtol.o/ 1207848658 1026 1026 100664 2624 ` ELFt4(j% $ > $ > .? : ; ' I@: ; I I&I-6iintv  8 K ,^6 strtox.c =u| CB @.Ittt t P R Q]strtolendptrunsigned charbaseshort unsigned intstrtol.c/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlong long intnptrcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intlong intsigned charstrtolGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 8 %D+D0DbB> @ Rt:N  b0^   oq~Qz (  n  0 0.       strtol.cstrtolstrntoumax   ! & 4 ; B I P W c nrv {        ,strtoll.o/ 1207848658 1026 1026 100664 2608 ` ELFh4(j% $ > $ > .? : ; ' I@: ; I I&IV&int: A! 83 KQ ,^6 strtox.c =u| CB @.Ittt t P R Q]strtolllong long intshort unsigned intnptrunsigned intendptrlong long unsigned intbase/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned charcharstrtoll.csigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)strtollshort intGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 0 %D+D0DbB> 8 Rm:N b0^   oq~Iz   g  0s.      strtoll.cstrtollstrntoumax   ! & 4 ; B I P W c nrv {       ,strtoul.o/ 1207848658 1026 1026 100664 2640 ` ELF4(j% $ > $ > .? : ; ' I@: ; I I&IQint$7  8 K ,^?6 strtox.c =u| CB @.Ittt t P R Q]strtoulendptrunsigned charstrtoul.cbaseshort unsigned intstrtoullong unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlong long intnptrcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 H %D+D0DbB> P Rt:N b0^ (  oq~Qz 8  o  @ 0. (     strtoul.cstrtoulstrntoumax   ! & 4 ; B I P W c nrv {        ,strtoull.o/ 1207848658 1026 1026 100664 2612 ` ELFl4(j% $ > $ > .? : ; ' I@: ; I I&I:a&intE V! 83 K\ ,^6 strtox.c =u| CB @.Ittt t P R Q]strtoulllong long intshort unsigned intnptrunsigned intendptrstrtoull.clong long unsigned intbase/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned charcharsigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intstrtoullGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 4 %D+D0DbB> < Rm:N  b0^  oq~Iz   h  $ 0v.      strtoull.cstrtoullstrntoumax   ! & 4 ; B I P W c nrv {       ,strtoumax.o/ 1207848658 1026 1026 100664 2712 ` ELF4(j% $ > $ > : ; I.? : ; ' I@: ; I I&I:p&int]aF4Vf h! 83 K ,^M6 ../includestrtox.cstdint.h =u| CB @.Ittt t P R Qsstrtoumaxlong long intshort unsigned intnptrunsigned intendptrstrtoumax.clong long unsigned intuint64_tstrtoumax/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned charcharbasesigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)uintmax_tshort intGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %D+D0DoB> RQN h b0^ p  oq~ z    0.T d "    strtoumax.cstrtoumaxstrntoumax   ! & 4 ; B I P W b i y         Cvfprintf.o/ 1207848658 1026 1026 100664 3160 ` ELF@4(VSÍt$QѺx=~ى‰[^% : ; I I$ > $ > < .? : ; ' I@: ; I : ; I 4: ; I 4: ; I &I I!I/D/VG+06:i%int a  ODB V t ap = rvO  }V 6 6r ../include/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includevfprintf.cstdio.hstdarg.h 0zg | ,DAA FGI.HV.ttt t t DtPBSRQQ"6P6;R;;P#vfprintfD_IO_fileFILEunsigned charshort unsigned intvfprintf.cva_listfile__gnuc_va_list/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intformatlong long unsigned intlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intbuffervfprintfsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4D %x+x0xB/#> 0 RRN ( bD^ 0  o(~z @    H 05J.xx   '    Dvfprintf.cvfprintfvsnprintf_fwrite7   ! & 7 > I W b h o v }             vprintf.o/ 1207848658 1026 1026 100664 2440 ` ELF4(щ¸% : ; I I$ > $ > .? : ; ' I@ : ; I: ; I &I` +06LDi%intQ OtYap= 6o[ /usr/lib/gcc/x86_64-redhat-linux/4.1.2/includevprintf.cstdarg.h/ |   P RRQVvprintfunsigned int__gnuc_va_listGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)va_listcharvprintfformat/home/hpa/syslinux/release/syslinux-3.63/com32/libvprintf.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %D+D0D~B> R^sN X b$^ `  o<~4z p  R  x 0r.==     vprintf.cvprintfvfprintf    ! & 7 > I \ gks }  hvsnprintf.o/ 1207848658 1026 1026 100664 10008 ` ELFx4(UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$XЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$lT$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$DD$DD$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u1I|$Xt ;L$X~L$X9L$\~ $ >  : ; ( .: ; ' I : ; I : ; I 4: ; I 4: ; I 4: ; I &I.? : ; ' I@: ; I: ; I4: ; I 4: ; I4: ; I : ;  : ;1X Y11 1 414141 4: ;I I!!I/ N2n+06U>i% Sint044keO\ /H q- n-H val- - .Z e.Z .Z qq0 o1H oo1H 4 )5 6Z 7Z 7Z F8Z 8Z '27 z3L66 KZ2nH'sGap=ep~ch6,qoHvalCWZeZ8ZZ ZszH *C`> 06gZZ`Lcpa/$:DMWbm x)schr6JisZh'pady6 06!0  L6!0< ../include/bitsize../include/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includevsnprintf.cstddef.hstdint.hstdarg.hEK/uKYKK fuKY2A  Y$Y1[  0}<m\HKuuH%g/LZ/(Lx H/>"H=!LH Z5~֟u(null)ro           "'0Av0123456789ABCDEF0123456789abcdef| d2AA AAFHAAD.HAAAPSAAAPttt t t RtRStSTtT`t` t ttt t 3t34t45t56t6FtF2t^P^2~^R^2~^QQ^^^V^PPP>@P@QQXPXXVorPPVPP#'P/2^8QAQQQQQQQQQP#'P! P 1R5 R)2RN[RuRR)#L#iRqRR9^@^BFJQSX]PSbgQSA^^PPPorPPPSgPPPPPP#'PI^^2Q^^^^*U,>UH~W~PPWUU1U^SSYtU[2^FS*S>.S^*U,>U1UQQQ^^W^WHWWWuWW W4W;WWW W0W1Q?QPPP P))Q)1PNNQNePmQQ*,U>U^^^2T'SS^PPPorPP%_PP#'P%PRvsnprintf2stateuint64_tshort intsize_tb4ticklcdigitslong long intva_listtickskipFL_TICKrankFL_SPACEwidthFL_ZEROformatucdigitsis_unsignedFL_HASHbaseFL_SIGNEDncharsdigitsminusst_modifiersst_flagsunsigned charis_stringvsnprintf.csigned charflagslong long unsigned intunsigned intst_normaluintmax_tsargst_precvsnprintfcharis_integerFL_MINUS/home/hpa/syslinux/release/syslinux-3.63/com32/libbufferst_widthFL_PLUSshort unsigned intndigitsformat_intFL_UPPERprec__gnuc_va_listslenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)tmpvalcargGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack42 0"X%h+h0hB R> "8RZN %^2qm %( }|y &   '  '035h. ` !G     )3=2vsnprintf.clcdigits.1611ucdigits.1612__udivdi3__umoddi3vsnprintfn   r   Y?  !&7>ITbipw~%0Xcny      * E R _ n s}        ) .5:AFMZ^        1  $(,048<@DHLPTX\`dhlptx| vsprintf.o/ 1207848658 1026 1026 100664 2760 ` ELF4(Qу% : ; I I$ > $ > .? : ; ' I@: ; I: ; I &I8)+06!i%kint O8xKap=i6 6q\ /usr/lib/gcc/x86_64-redhat-linux/4.1.2/includevsprintf.cstdarg.h=| CA E.Ittt tP R QQvsprintfunsigned charshort unsigned intva_list__gnuc_va_list/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intformatlong long unsigned intvsprintf.clong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intbuffersigned charvsprintfGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %H+H0H~B> RuN b0^  oH|~z    0.33      vsprintf.cvsprintfvsnprintf    ! & 7 > I W ^ e l s z        iasprintf.o/ 1207848658 1026 1026 100664 2968 ` ELF4(VSD$(D$D$ PL$411pËD$0u t$L$4[^% : ; I I$ > $ > .? : ; ' I@: ; I: ; I  4: ; I 4: ; I 4: ; I &I]!fw+06ZIi%intQ O]  _  ap =p ap1 =l rv O q O p6 6|\ /usr/lib/gcc/x86_64-redhat-linux/4.1.2/includeasprintf.cstdarg.h ^L!=?| 0]AA C O,A0H.Z L,D0P ttt t t,7t07Ct CGt,GWt0W]t ;;>P>@@OPO]>@PWWPOTPVasprintf]unsigned intbufp__gnuc_va_listGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)va_listasprintfcharformatasprintf.cbytes/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4] %+0BB> R-N h bH^ p  o~z     0*.`   &    ]asprintf.casprintfvsnprintfmalloc(P   ! & 7 > I \ gko t ~     ivasprintf.o/ 1207848658 1026 1026 100664 2936 ` ELF4(UWVS(ÉՉΉL$$Q11xu V[^_]% : ; I I$ > $ > .? : ; ' I@: ; I: ; I 4: ; I 4: ; I 4: ; I &IM!Qy+06]Ii%intb OM  l ap = ap1 =h s O p 6 6x] /usr/lib/gcc/x86_64-redhat-linux/4.1.2/includevasprintf.cstdarg.h L| 8MAA AAC<K@F.T0L R|N H bP^ P  o~ z `    h 0.@  ` (    M!vasprintf.cvasprintfvsnprintfmalloc#>   ! & 7 > I \ gko t ~     jstrlcpy.o/ 1207848658 1026 1026 100664 2588 ` ELF4(VS։19s@A1u[^% : ; I$ > $ > .? : ; ' I@: ; I: ; I4: ; I 4: ; I 4: ; I 4: ; I  I &I! @^W 0intO %!dst,srcJJ%h: %Q q p ch R 5  Y? ../include/bitsizestrlcpy.cstddef.hfQK>{>| !AA tt!t PP R VQS P>strlcpy!unsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)charbytesstrlcpy.csizestrlcpysize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!!X'X,X>: L N]J ^@0Z  kpz v   '  0G.8 8     !strlcpy.cstrlcpy   ! & 1 D OSW f u z     Lstrlcat.o/ 1207848658 1026 1026 100664 2600 ` ELF4(VS1@A9t8u9s@ABu[^% : ; I$ > $ > .? : ; ' I@: ; I: ; I4: ; I 4: ; I 4: ; I  I &I, =^W 0int5 %,dst,srcUR%sL %Q q P p R ch G  \? ../include/bitsizestrlcat.cstddef.hJQ!K>{>| ,AA tt,t P P)PR RQ+V*S>strlcat,unsigned intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)strlcatstrlcat.ccharbytessizesize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4,!`'`,`> : X N`J ^@0Z  kpzv   2   0R.D D     ,strlcat.cstrlcat   ! & 1 D OSW f u z     Lvsscanf.o/ 1207848658 1026 1026 100664 8424 ` ELF4(BuSщ [ÐUWVS\$ΉT$D$D$ D$D$1D$D$D$ D$$D$+[D$N$%u"D$ D$D$ t D$, D$8@D$*t |HC< wA L$Ã0D$L$C< wkT$ ÍTЉT$L$ltEht5jt#L tt ztqu. D$ bD$ UL$ LD$ CD$ ~D$ }D$ itw7Xta%PRcdtg[pt1nt=o+ut=xts(D$ 1D$+$‰K D$À8u D$YT$X t$щ‹D$hD$9<D$ D$j|$ tK|$ t&|$ O|$ t%|,|$ 6f!HD$uD$N6t$T$T$BT$D$L$|$u^6t$AD$L$|$tD$t t9L$u@D$ {T$|$81D$$D$8%@D$;^uD$u D$$ӍD$8e]tg-uD$+-ӍD$8]uD$8--|$+1 D$8GED$+D9|uT$T$X|$tC|$GCtʉD8;D$$u܉\$|$;\$Xt D$ #D$8t1D$ 1D$T$t |$|$u|$ uD$ D$ 1ɋD$ \[^_]% : ; I I$ > $ >  : ; ( .? : ; ' I : ; I .: ; ' I@ : ; I &I .: ; ' @: ; I .: ; ' I : ; I.? : ; ' I@: ; I4: ; I 4: ; I4: ; I : ; 4: ; I 4: ; I : ;  : ; 4: ;I I!I/ !!4: ; I? < "W+06Hi%?int 2w(_4y +8n*[O __cZO !3!t p2!' 6 a@;+P:aP bit:H>gBOPAa bitAH]GO,"\F!F! apF=pH!chI6qJ!SqqK!hvalLeMONHOOPQUL)Y_WiZ]u [\O]O^cH_O`kRKZjDGsp]=jiSOy6sgs?k !B# z } ../include/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includevsscanf.cctype.hstdarg.hstdint.h2KA=! <LK' uMA|NtYY3N6i ȓms=i# Z@YI(g=h}Jt I(|  A8,AA AACpD|DB.Tpf.PRt+t$R$+Q,-t-.t./t /0t03t3wtw{t{t"t,P",RR,QVQMVRRQR`VQVGJVJLSLRQVVQVQVQ#V((Q(;V==Q=QVSSQSVVQVQVVSVSVSV"QSPSPbSJSFSFLRLSPPPS@PPP"P;PbgSgPSPP(1P=FPSXPjPSPPPSS PSPKRRQRQRQRQHPPP"P;FPR[P P7TP[jP|PPPP(1P=FPSXPjPPPPP"WBWc}W WXG "ZDUc!Ub-W/9W;@WBWWWBWc WQMQR`QQGQQ#Q(;Q=QQSQQQ Q"Q-W/9W;@WBWWW}W Wvsscanf"test_bitbailFL_WIDTHuint64_tshort intisspacelong long intset_bitva_listbitmap/home/hpa/syslinux/release/syslinux-3.63/com32/libsignrankmatchmapwidthFL_INVformatFL_SPLATbasest_modifiersrange_startstateflagsbail_errst_flagsvsscanf.cunsigned charsigned charst_match_initlong long unsigned intunsigned intst_matchst_normaluintmax_tsargbail_eofshort unsigned intconvertedcharmatch_runFL_MINUSscan_intbufferst_widthlong unsigned intvsscanfmatchinvskipspace__gnuc_va_listGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)st_match_rangebail_none__ctypesset_integerGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4" P(%X+X0XB&> xR $N ` b ^ h 8 n xj 0 {x F d  0W.  P 9   &,.vsscanf.cskipspaceset_bit__ctypesvsscanfstrntoumax  ~u !&7>IW^elsz  18<@ E\ hs       $. 3= BL Q[ hntz   #,0? EIW t  ( ,@ D__ashldi3.o/ 1207848658 1026 1026 100664 1204 ` ELF4( s1F) libgcc__ashldi3.S=0=/#//!plibgcc/__ashldi3.S/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU AS 2.17.50.0.18%.symtab.strtab.shstrtab.text.data.bss.rel.debug_line.rel.debug_info.debug_abbrev.rel.debug_aranges4!H'H0HJ, | @t<  L^  Z  @m  p  __ashldi36 __udivdi3.o/ 1207848658 1026 1026 100664 2584 ` ELFt4(jt$t$% $ > $ > : ; I.? : ; ' I@: ; I: ; I Xyintk+Oa8! Vnum VPden VW@ libgcc../include__udivdi3.cstdint.h =|  CBDD @. Itt t t t tPRh__udivdi3long long intshort unsigned int__udivdi3unsigned intlong long unsigned intuint64_tlibgcc/__udivdi3.cunsigned char/home/hpa/syslinux/release/syslinux-3.63/com32/libsigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 @ %L+L0LlB> H RX[N b8^  oh~T z  t   0~.   $    __udivdi3.c__udivdi3__udivmoddi4   ! & - ; B I P W b j uy}  M__negdi2.o/ 1207848658 1026 1026 100664 1180 ` ELF4( ؃@( libgcc__negdi2.S//=olibgcc/__negdi2.S/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU AS 2.17.50.0.18%.symtab.strtab.shstrtab.text.data.bss.rel.debug_line.rel.debug_info.debug_abbrev.rel.debug_aranges4!<'<0<D, d @s< l L^ Z  (m  X  __negdi25 __ashrdi3.o/ 1207848658 1026 1026 100664 1204 ` ELF4( sЙF) libgcc__ashrdi3.S=0=/#//!plibgcc/__ashrdi3.S/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU AS 2.17.50.0.18%.symtab.strtab.shstrtab.text.data.bss.rel.debug_line.rel.debug_info.debug_abbrev.rel.debug_aranges4!H'H0HJ, | @t<  L^  Z  @m  p  __ashrdi36 __lshrdi3.o/ 1207848658 1026 1026 100664 1204 ` ELF4( s1F) libgcc__lshrdi3.S=0=/#//!plibgcc/__lshrdi3.S/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU AS 2.17.50.0.18%.symtab.strtab.shstrtab.text.data.bss.rel.debug_line.rel.debug_info.debug_abbrev.rel.debug_aranges4!H'H0HJ, | @t<  L^  Z  @m  p  __lshrdi36 __muldi3.o/ 1207848658 1026 1026 100664 1204 ` ELF4( VRt$^^I( libgcc__muldi3.S  /!/Y/!=0!olibgcc/__muldi3.S/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU AS 2.17.50.0.18%.symtab.strtab.shstrtab.text.data.bss.rel.debug_line.rel.debug_info.debug_abbrev.rel.debug_aranges4!L'L0LM, | @s<  L ^  Z  @m  p  __muldi35 __udivmoddi4.o/ 1207848659 1026 1026 100664 3180 ` ELF4(UWVS Ɖ׋D$ T$$ t 1$D$Tۅy$D$!9wr9w ) $\$ uك|$(t D$(0x$T$ [^_]% $ > $ > : ; I.: ; ' .? : ; ' I@: ; I: ; I 4: ; I 1X Y  IXint!Ja3VnumVPdenV .V SV h"5 V` libgcc../include/klibc../include__udivmoddi4.cdiverr.hstdint.h1 .KHPKvgzf fu| $AA AAC ttt ttt PR VRVW5P5=PR=APAPRR35`P` "QS5RQSguQSq__udivmoddi4long long intshort unsigned intunsigned intquotlong long unsigned intuint64_tqbit/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned char__divide_errorrem_p__udivmoddi4libgcc/__udivmoddi4.csigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!',>p: T N_J < ^<Z D  k0Sz#v T    \ 0.4  4    __udivmoddi4.c__udivmoddi4   ! & - ; B I P W b i w         m__umoddi3.o/ 1207848659 1026 1026 100664 2628 ` ELF4( L$Qt$,t$,D$ T$$,% $ > $ > : ; I.? : ; ' I@: ; I: ; I 4: ; I !Xint!Oa8. V!num VPden Vv VPtX@ libgcc../include__umoddi3.cstdint.h ?|  !C$E(D,D0@. Q$tt$ t( t,!t0!!t$PRh__umoddi3!long long intshort unsigned intunsigned int__umoddi3long long unsigned intuint64_t/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned charlibgcc/__umoddi3.csigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4! l %X+X0X{B> t R\N  b8^   oh~ z ,    4 0.8 H $    !__umoddi3.c__umoddi3__udivmoddi4   ! & - ; B I P W b j uy}  M__divdi3.o/ 1207848659 1026 1026 100664 2964 ` ELF4(VSӋD$T$x1 ك۾y ؃ڃjRPȉt؃Y[^% $ > $ > : ; I.? : ; ' I@: ; I4: ; I4: ; IU.]int E!F :Unum :den :@ 3 v :(^? libgcc../include__divdi3.cstdint.h Ku?uw| 0UAA CqBAA D.HL ttt 6t68t89t9:t:Ft FRtRUt PR QR CQSP<PR<>R>UV%TVOQPRh__divdi3Ulong long intshort unsigned intunsigned intlibgcc/__divdi3.cminuslong long unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned charsigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)int64_tshort int__divdi3GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4U %+0{B> RbN d b(H^ l  op@~z |    0.  h  x "    U__divdi3.c__divdi3__udivmoddi4?   ! & - ; F M T [ b j uy}      L__moddi3.o/ 1207848659 1026 1026 100664 2952 ` ELF4(WVSÉ֋T$ L$$x1 ۃ޿y ڃكD$PQR؉t \$T$ \$ D$T$ [^_% $ > $ > : ; I.? : ; ' I@: ; I4: ; I4: ; I jTint E!=. :jnum :den :7 3 v :h`? libgcc../include__moddi3.cstdint.h $Ku?/uM| 0jAA AC u$A(A,A0D.H ttt t;t ;<t$<=t(=>t,>Jt0Jjt PR SRgSVRBRQBGQGjW&iWh__moddi3jlong long intshort unsigned intunsigned int__moddi3minuslong long unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned charlibgcc/__moddi3.csigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)int64_tshort intGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4j %+0{B> RdN X b<H^ `  o(~z p    x 0.d  t "    j__moddi3.c__moddi3__udivmoddi4C   ! & - ; F M T [ b j uy}     Lintcall.o/ 1207848659 1026 1026 100664 3696 ` ELF 4(QRP% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I&.? : ; ' @: ; I4: ; I? < *RintLN\^foplewbSA~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ x0#(!1 F Ge# H # I=# eJC# ,Ke# CL[# M# %,A,7 2  [e,7 E{3e{e  ayAPa,c\7v;N[F sys../includeintcall.cstdint.hcom32.h=|  CAAD @. Jttt t t tPRQ__intcallcs_sysargscs_cmdlinecs_intcallcom32sys_tcs_bounce_size__com32cs_farcallunsigned charoregiregshort unsigned int__intcallreg32_t_unused_esp/home/hpa/syslinux/release/syslinux-3.63/com32/libcs_cfarcallunsigned intlong long unsigned intuint8_tlong long intsys/intcall.cvectorcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tcs_bounceuint32_teflagssigned charcom32_sys_argsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %H+H0H BS> PR0_N @b8^ H o~Q z X q  `0+.YY       intcall.c__intcall__com32    ! & - ; B M T _ f q x   ;                     Sfarcall.o/ 1207848659 1026 1026 100664 3732 ` ELFL4(t$QR% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I&.? : ; ' @: ; I: ; I: ; I 4: ; I? < cx=intLXG^pZplewbSA~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ q0#(+1 F Ge# H # I=# PJC# 6Ke# ML[# M# ,A,7 2  [e,7 E{3e{e  a! csSPipSck,vf7EN\F sys../includefarcall.cstdint.hcom32.h==|  CDAI @. Jttttt tPRQ__farcallcs_sysargscs_cmdlinecs_intcall__farcallcom32sys_tcs_bounce_size__com32cs_farcallunsigned charoregiregshort unsigned intreg32_t_unused_esp/home/hpa/syslinux/release/syslinux-3.63/com32/libcs_cfarcallunsigned intlong long unsigned intuint8_tlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tcs_bounceuint32_tsys/farcall.ceflagssigned charcom32_sys_argsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4  %P+P0P)By>  HRb`N db8^ l o~ z |   0X.       farcall.c__farcall__com32   ! & - ; B M T _ f q x   ;                    Scfarcall.o/ 1207848659 1026 1026 100664 3752 ` ELF`4(t$QR% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I&.? : ; ' I@: ; I: ; I: ; I 4: ; I? < ~rEintLYO^gbplewbSAz~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ k0#(!1 F Ge# H # I=# XJC# ,Ke# CL[# M# ,A,7 2  [e,7 E{3e{e  aN 3csSPipSc{v e;N]G sys../includecfarcall.cstdint.hcom32.h==|  CDAI @. Jttttt tPRQ__cfarcallcs_sysargscs_cmdlinecs_intcallcom32sys_tcs_bounce_size__com32cs_farcall__cfarcallunsigned charshort unsigned intreg32_t_unused_espstack/home/hpa/syslinux/release/syslinux-3.63/com32/libcs_cfarcallunsigned intlong long unsigned intuint8_tlong long intstack_sizecharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tcs_bounceuint32_teflagssigned charsys/cfarcall.ccom32_sys_argsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 ( %P+P0P+B{> 0 HRhaN xb8^  o~!z    0j.       cfarcall.c__cfarcall__com32   ! & - ; B M T _ f q x   ;                    Tzeroregs.o/ 1207848659 1026 1026 100664 2356 ` ELF4( % $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8 &I 4: ; I?  RintL^+plewbSA>~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# F*# ebx+# edx,# ecx-# eax.#$ 0#(1  MG sys../includezeroregs.ccom32.hstdint.h$__com32_zero_regscom32sys_t__com32_zero_regsunsigned charshort unsigned intreg32_t_unused_esp/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intuint8_tsys/zeroregs.clong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tuint32_teflagssigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.debug_line.rel.debug_pubnames.debug_str.comment.note.GNU-stack4!4'4,4>: dJQZ(V , j0 *u6.~ddt  D   ,zeroregs.c__com32_zero_regs   ! & - ; B M T _ f q x   ;      entry.o/ 1207848659 1026 1026 100664 1704 ` ELF4( L!1)t$g;vARPsXZW" sysentry.S%[#/YY/=1KYY=///!1g!/Y#Zg//=3!!Ygidsys/entry.S/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU AS 2.17.50.0.18%d.symtab.strtab.shstrtab.text.data.bss.rel.init.rel.debug_line.rel.debug_info.debug_abbrev.rel.debug_aranges4!4'4 04d, (H:[6 pJmF x V`hx d  w0  h  d!.<HM\_start__bss_start_end__com32__parse_argv__ctors_start__ctors_endmain__exit_handler__entry_esp    5 = CIY_/ exit.o/ 1207848659 1026 1026 100664 1436 ` ELF4( PsX%=! sysexit.S$Zg//=2$ghsys/exit.S/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU AS 2.17.50.0.18%.symtab.strtab.shstrtab.rel.text.rel.data.bss.rel.debug_line.rel.debug_info.debug_abbrev.rel.debug_aranges4 D)T% \/X8XA4 dHlD l Tf  b  @u8 <  !-_exit__dtors_start__dtors_end__entry_esp__exit_handler   . argv.o/ 1207848659 1026 1026 100664 3524 ` ELF(4(UWVSŠD$5<  uA A1ۀ:tBۍQUD$ZI9srZ:uBB9rC[^_]% $ > $ > .? : ; ' I@: ; I: ; I4: ; I 4: ; I 4: ; I 4: ; I  I &I I!I/ !4: ; I? < 4: ; I?   jMint'5 -3, Pstr,n.*kmem/ p0Rq1 r2Rarg3 43 53   ] % ] :]: L]H)A*kR! sysargv.c,  gLi^oX $ > : ; I : ; .? : ; ' I@ : ; I I;intS(n{tms  Hn"'ptbuf&hiS sys../include/sys../includetimes.ctimes.hstdint.h*u|  Ptimessys/times.cclock_tunsigned chartimesshort unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!<'<,<u>: NmmJ \ ^$Z d  kzv t  /  | 0O;.ii     times.ctimes   ! & - ; B I T [ b q |    `fileinfo.o/ 1207848659 1026 1026 100664 3088 ` ELF(4( % $ > $ > : ; I : ;  : ; I8 ' II  I  : ; : ; I8  &&I : ; I!I/ : ; !I/ 4: ; I?   G:int9LS\ Zw3D sz(c8H#9H#:3#;P#V: xJZ"V  j0uj.~   x    fileinfo.c__file_info   ! & - ; B I T [ b i t          q y        % 3 A O ] k       opendev.o/ 1207848659 1026 1026 100664 4812 ` ELF0 4(UWVS ljօu1Pu1Ft Ѕt1;u{tE t(@\CC CtWt҅u*;t3Vt҅t uvus [^_]% $ > $ > : ; I I & : ; : ; I8 ' I I  : ; : ; I8 &I : ; I!I/ : ; .? : ; ' I@: ; I4: ; I4: ; I : ; 4: ; I? < !I/ intYSgu Z3 n( )8H# 9H# C:3# T;k# <# =# ! ! | ' k9(@- iopP# oopQ# i]!# ob# 3 !q) )AH# BH# CC3# D# E# F# G#  ! ~ @T U3# V# MW# XH# YH# gZ# 3[o# buf\#uh?` $a3# ba3#f*3Q(P))3fd+3fp,!x-3e.3` 34~5'hVe sys../include../include/sys../include/bitsizeopendev.cdev.hfile.hstdint.htypes.hstddef.herrno.h)ZxۿguhK1KY U X | $AA AAC ttt ttt PW!P!WRVQQQQ?UPDSPPPPopendevclosesys/opendev.cwriteshort introwsdev_magicdatapfile_infofileflagslengthreadlong long intlong long unsigned intdev_error_wopendevoffsetflagsunsigned charfallbackfiledesssize_tpukeunsigned intuint16_t_fillerodevshort unsigned intoutput_deverrnocharsize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libidev__file_infocolsnbytesinput_devokflagsblocklg2signed charopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)dev_error_rptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 \8%+08B@> RN b<^  o;~'z  E  0e= .k k P C    %1=opendev.copendeverrno__file_infodev_error_rdev_error_wclose0@_kr   ! & - ; B I T [ b i v           ,         + 9 G U c q           " 0 > C V [ ag t   read.o/ 1207848659 1026 1026 100664 4160 ` ELF` 4(VSi(@u SZ[^% : ; I$ > $ >  I & : ; : ; I8 ' I I  : ; : ; I8 &I : ; I!I/ : ; .? : ; ' I@: ; I: ; I4: ; I4: ; I? < !I/ [8ey 0BintT Mp[ 7A( 8e# 9e# 7:B# H;k# <# `=# ! ! %' k-(@- iopP# oopQ# i]!# ob# B !q) Ae# Be# 7CB# D# E# `F# G#  ! %@T KUB# rV%# AW%# Xe# Ye# :Z%# '[# buf\#~?` aB# 5aB#4H*8fd)BDbuf)b)%fp+!BQ'~)eA sys../include/sys../include/bitsize../includeread.ctypes.hstddef.hfile.hdev.hstdint.herrno.h)[VY| 8AA Cp ttt 5t58t P -P4R45R4Q48Q7V_read8closewriteshort intsize_tdev_magicdatapfile_infofileflagslengthreadlong long intlong long unsigned intoffsetsys/read.cflagsunsigned charfallbackfiledesssize_trowsuint16_t_fillershort unsigned intoutput_deverrnocharcount/home/hpa/syslinux/release/syslinux-3.63/com32/lib__file_infocolsnbytesinput_devblocklg2signed charopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)unsigned intptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack48 8%l+l0l-B_> PRN b4^  o~z (   00l.     8 read.cread__file_infoerrno"   ! & 1 8 J Q X _ f q x           ,         + 9 G U c q         ! / 5 R write.o/ 1207848659 1026 1026 100664 4164 ` ELFh 4(Si(@Xu SZY[% : ; I$ > $ >  I & : ; : ; I8 ' I I  : ; : ; I8 &I : ; I!I/ : ; .? : ; ' I@: ; I: ; I4: ; I4: ; I? < !I/ [1fH 0BintU Ypg 7B( 8e# 9e# 7:B# T;k# <# a=# ! ! %' k-(@- iopP# oopQ# i]!# ob# B !q) Ae# Be# 7CB# D# E# aF# G#  ! %@T LUB# ~V%# AW%# Xe# Ye# ;Z%# '[# buf\#~?` aB# 6aB#4*1fd)BDbuf)b)%fp+!BQ'~*eA sys../include/sys../include/bitsize../includewrite.ctypes.hstddef.hfile.hdev.hstdint.herrno.h)MVu=| 1ACj Att.t./t /1tP(P-R-.R-Q-/Q(P*-P_write1closewriteshort intsize_tdev_magicdatapfile_infofileflagslengthsys/write.creadlong long intlong long unsigned intoffsetflagsunsigned charfallbackfiledesssize_trowsuint16_t_fillershort unsigned intoutput_deverrnocharcount/home/hpa/syslinux/release/syslinux-3.63/com32/lib__file_infocolsnbytesinput_devblocklg2signed charopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)unsigned intptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack41 D%h+h0h-B_> TRN b4^  o~z ,   40u.   !    1write.cwrite__file_infoerrno   ! & 1 8 J Q X _ f q x           ,         + 9 G U c q         ! / 5 R ftell.o/ 1207848659 1026 1026 100664 3984 ` ELF4(Hi(@ % $ > : ; I$ > <  : ;  : ; I8 ' I I  I  : ; : ; I8  &&I : ; I!I/ : ; .: ; ' I : ; I.? : ; ' I@ : ; I4: ; I!I/ 4: ; I? < q;Q/ 7Iint>[h!Czr >(8}#9}#:I#;h#<~# c=~#  f , " f"(@- iopP# oopQ# i]%# ob#  ~I  n)A}#B}#CI#D#E~# cF~#G#    ,    @TUI#V,#W,#X}# Y}#4Z,#[# buf\# %%?`aI#aI#  %I__f$  PP8 Pt fd Ifp g",eW sys../include./sys../include/sys../include/bitsizeftell.cstdio.hfile.hdev.hstdint.htypes.hstddef.h |  Puftellsize_toffset_IO_filedataprowsfile_info__file_infoftellFILEunsigned char/home/hpa/syslinux/release/syslinux-3.63/com32/libcloseshort unsigned intfileflagsfiledesdev_magicptrdiff_tfilenostreamunsigned intflagssys/ftell.clong long unsigned intoutput_devwritefallbacklong long intcharnbytesGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)openshort intssize_tuint16_tcolsblocklg2long int_fillersigned charinput_devlengthreadGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %D+D0DEBu> RN `b$^ h o~z x   0#.t       ftell.cftell__file_info    ! & - 8 ? Q \ b i p w ~           '         / = K Y g u       !%- 7 Q h close.o/ 1207848659 1026 1026 100664 4280 ` ELF 4(VSi(@t~u ;P t҅u,ǃFP t҅u(@1҉1Z[^% $ > $ > : ; I I & : ; : ; I8 ' I I  : ; : ; I8 &I : ; I!I/ : ; .? : ; ' I@: ; I4: ; I4: ; I? < !I/ Xtyh intK}SYu Z3 U( 8H# w9H# 5:3# F;k# <# t=# ! ! | ' k+(@- iopP# oopQ# i]!# ob# 3 !q) AH# wBH# 5C3# D# E# tF# G#  ! ~ @T _U3# pV# ?W# XH# YH# NZ# %[o# buf\#uh?` a3# Ia3#$&3tfd%3Dfp'!brv(3u314N'h=e> sys../include../include/sys../include/bitsizeclose.cfile.hdev.hstdint.htypes.hstddef.herrno.h%\UuKMKN|  tAA Cl ttt qtqtt P&3PsV35PBQP^iPppP\closetclosewriteshort introwsdev_magicdatapfile_infofileflagslengthreadlong long intlong long unsigned intoffsetflagsunsigned charsys/close.cfallbackfiledesssize_tunsigned intuint16_t_fillershort unsigned intoutput_deverrnocharsize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libdev_error_r__file_infocolsnbytesinput_devblocklg2signed charopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)ptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4t 0%+0B\> R"N b8^  o~z    0., @ l4    t!-close.cclose__file_infoerrnodev_error_rmemset(FJj   ! & - ; B I T [ b i v           ,         + 9 G U c q         % 2 O open.o/ 1207848659 1026 1026 100664 5896 ` ELF44(S8L$D1ҸÅx] T$@ fD$0 ƒfT$fD$PD$PPj"D$4uf|$u5i(@fD$,BD$0BD$fBB B؃8[% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I& : ;  : ; !I/.: ; ' I : ; I5.: ; ' I .? : ; ' I@: ; I 4: ; I 4: ; I 4: ; I !1X Y "1# $4: ; I%4: ; I? < )intL&^IplewbSA~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ 80#(1 iF /Ge# FH # I=# <JC# ZKe# ?L[# M# m,A,7 2  [e,7 E{3e{e  ar pQ3  ( J8S# 9S# :3# ;n# <# =#$$C *nx(@- iopP# oopQ# i]$# ob#  3$ t \) JAS# BS# C3# D# E# F# G#${  @T U3# V# W# XS# :YS# Z# T[ # buf\#? ` 3a3# a3# jS__pi %SEGeS__pd63553[7Lfd83n fp9$R!5:E"#$BPS y,%g3%!N*%e sys../include../include/sys../include/bitsizeopen.ccom32.hstdint.hfile.hdev.htypes.hstddef.herrno.h5O"O>(tYX!ughuuw| (AC@IDEHALBP@.I@ttMtMRtRStSUtU^t^tS)P)SP%openclosewritecs_cfarcallpathname__com32short introwseflagscs_farcalldev_magicdatapcs_bounce_sizecom32_sys_argsfile_infofileflagslengthreadlong long intlong long unsigned intoffsetflags_unused_espcom32sys_tunsigned charfallbackfiledesssize_tuint32_treg32_tunsigned intuint16_tcs_sysargs_fillerblklg2short unsigned intoutput_deverrnocharsize_tfile_dev/home/hpa/syslinux/release/syslinux-3.63/com32/libsys/open.c__file_infoOFFScolsnbytesinput_devblocklg2signed charuint8_tcs_intcallopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)cs_bouncecs_cmdlineptrdiff_tregsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 H%+0B> PxRN b ^  n @j  {     0 `5 .c c  Y   &.4@Lopen.cfile_devopenopendev__com32strlcpyerrno__file_info__file_read__file_close  %*6Wo !&-;BMT_fqx;/.<JXft+6:> CQ`w     fileread.o/ 1207848659 1026 1026 100664 5776 ` ELF4(UWVSlÉΉՍ|$@ 1fD$d ƒfT$XfD$DD${C ;CCffD$LK@fD$`L$T$@"D$<tfD$ fCK+K K@v@KC C C9vNjS|$){{ ){@D$l[^_]% : ; I$ > $ >  : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I& : ;  : ; !I/.: ; ' I : ; I5.: ; ' I .? : ; ' I@: ; I: ; I4: ; I 4: ; I 4: ; I !1X Y "1# $4: ; I%4: ; I? <  vv/ 0JWBint%i+{G0lwbpJ^ ,! gs"p# fs#p# es$p# ds%p# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ 60#(1 gF 4G# 5H# IS# @JY# XK# =Lq# M# %kB^BM H  ,qBM [B  w  7 ( H8p# 9p# :B# ;n# <# =#$$Y% *n(@- iopP# oopQ# i]$# ob#  B$ t Z) HAp# Bp# CB# D# E# F# G#$%  @T UB# V%# W%# Xp# ?Yp# Z%# R[# buf\#%? ` &aB# aB# jp__pi %SEGep__pd)fp($Qbuf(Yop(%*@*+ n,%-%!"'1"#$xxI%$yyI%%eB%N sys../include../include/sys../include/bitsizefileread.ccom32.hstdint.htypes.hstddef.hfile.hdev.herrno.h(2 R% N `b <^ h oD ~ "z x ,  0L a .  8@ x7     *0fileread.c__file_read__com32__intcallerrnomemcpy#   ! & 1 8 J Q X _ j q |     Q           &         /         . < J X f t     + 6:> L [ ` j o }       fileclose.o/ 1207848659 1026 1026 100664 4880 ` ELF 4(W8fxt8D$ D$ 1|$fD$0BfD$PjD$Pj"18_% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I& : ;  : ; !I/.? : ; ' I@: ; I4: ; I 4: ; I? < #L intL-^Ip lewbS A~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ /0#(1 `F 6Ge# (H # I=# JC# QKe# 6L[# M# t,A,7 2  [e,7 E{3e{e  ay p33  ( A8S# 9S# y:3# ;n# <# =#$$C *no(@- iopP# oopQ# i]$# ob#  3$ t \) AAS# BS# yC3# D# E# F# G#${  @T U3# V# W# XS# AYS# Z# K[ # buf\#? ` *a3# a3# g(3Lfp'$n=)LN sys../include../include/sys../include/bitsizefileclose.cfile.hdev.hstdint.htypes.hstddef.hcom32.h'iuYu2| (LAC@oDBHELBP@.I@tt3t35t5:t:<t<EtELtPBREGPGLR'__file_closeLclosewritecs_cfarcall__com32short introwseflagscs_farcalldev_magicdatapcs_bounce_sizecom32_sys_argsfile_infofileflagslengthreadlong long intlong long unsigned intoffsetsys/fileclose.cflags_unused_espcom32sys_tunsigned charfallbackfiledesssize_tuint32_treg32_tunsigned intuint16_tcs_sysargs_fillershort unsigned intoutput_dev__file_closecharsize_t/home/hpa/syslinux/release/syslinux-3.63/com32/libcolsnbytesinput_devblocklg2signed charuint8_tcs_intcallopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)cs_bouncecs_cmdlineptrdiff_tregsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4L %+0AB'> RN b@^  o~#z    0B .5 5  "    Lfileclose.c__file_close__com32>   ! & - ; B M T _ f q x   ;                      /         . < J X f t         isatty.o/ 1207848659 1026 1026 100664 3896 ` ELF4(i(@u @% : ; I$ > $ >  I & : ; : ; I8 ' I I  : ; : ; I8 &I : ; I!I/ : ; .? : ; ' I@ : ; I4: ; I4: ; I? < !I/ 8+h 0BintW Zph 7D( *8e# 9e# D:B# U;k# <# c=# ! ! %' k:(@- iopP# oopQ# i]!# ob# B !q) *Ae# Be# DCB# D# E# cF# G#  ! %@T NUB# V%# NW%# Xe# Ye# =Z%# 4[# buf\#~?` aB# 8aB#+B+tfd*Bfp,!B.'~,e sys../include../include/sys../include/bitsizeisatty.cfile.hdev.hstdint.htypes.hstddef.herrno.h-Ku|  + P"P<isatty+closewriteshort intsize_tsys/isatty.cdev_magicdatapfile_infofileflagslengthreadlong long intlong long unsigned intoffsetflagsunsigned charfallbackfiledesssize_trowsuint16_t_fillerisattyshort unsigned intoutput_deverrnochar/home/hpa/syslinux/release/syslinux-3.63/com32/lib__file_infocolsnbytesinput_devblocklg2signed charopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)unsigned intptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4+ ` %`+`0`B|<> p RN bh$^  o~z    (0.  < #    +isatty.cisatty__file_infoerrno    ! & 1 8 J Q X _ f q x           ,         + 9 G U c q       / fstat.o/ 1207848659 1026 1026 100664 4124 ` ELF8 4(i(@u @t$AB1!B1% : ; I$ > $ >  : ;  : ; I8 ' II  I  : ; : ; I8  &&I : ; I!I/ : ; .? : ; ' I@ : ; I: ; I 4: ; I 4: ; I? < !I/ N;w 0BinthNzpdr 7 B% ,\-#%.#)(8e#9e#:B#;#H<# c=#C~C% I 2(@- iopP# oopQA# i]L# ob#  )BC )Ae#Be#CB#D;#HE# cF#+GA#4~C4% :  G@TUB#V%#W%#Xe# Ye#4Z%#[# buf\# ?`-aB#aB# _%'BNtfd&Bbuf&_Rfp(CQ BI<er sys../include/sys../include/bitsize../includefstat.cstat.htypes.hstddef.hfile.hdev.hstdint.herrno.h)Vggg|  N P(PfstatNoff_tsize_tstatoffsetdataperrnost_sizerowsfile_info__file_infocloseunsigned charst_modeshort unsigned intsys/fstat.cfileflagsfiledesdev_magicptrdiff_t/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intflagslong long unsigned intoutput_devwritelong long intfstatfallbacknbytesGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)openshort intssize_tuint16_tcolsblocklg2char_fillerinput_devsigned charmode_tlengthreadGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4N %+0-B> ,RAN b$^  o$~Bz  ^  0~E.ss   !    Nfstat.cfstat__file_infoerrno    ! & 1 8 J Q X _ f q x              N         V d r         ! ,0A f  openconsole.o/ 1207848659 1026 1026 100664 2816 ` ELF4(VSƉ1ډu8ډuډu0Z[^% $ > $ > .? : ; ' I@< : ; I I&Ia Dwint,',a&D?&bzG( sysopenconsole.c&u"u0u|  aAA CY ttt ^t^at P `VR_S]openconsoleaopenconsolesys/openconsole.cunsigned charshort unsigned intodev/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intoutput_devlong long intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intinput_devsigned charidevGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4a 0%+0kB>  RKN b 8^  oD~"z    0.55   )   a!openconsole.copenconsolecloseopendev %3?M   ! & 4 ; B I P W c nrv {      5line_input.o/ 1207848659 1026 1026 100664 4520 ` ELF 4(UWVSʼn։L$@@D$1T$T$0HtT$ tuA tYu5)tONT$KT$u)딋D$H9sT$GFw T$G[^_]% $ > $ > : ; I : ;  : ; I8 ' II  I  : ; : ; I8  &&I : ; I!I/ : ; .? : ; ' I@: ; I: ; I: ; I 4: ; I4: ; I 4: ; I l+LintK^S_ Zz3V s(u8H#9H#!:3#;P#Y RN x^2gqp<m  ~#   0 .  D  d)   line_input.c__line_inputsyslinux_idle.`s   ! & - ; B I T [ b i t          q y        % 3 A O ] k          ! & < W \  colortable.o/ 1207848659 1026 1026 100664 2488 ` ELF4(%  : ; (  : ;  : ; I8  I&I$ > I !I/ 4: ; I 4: ; I?  $ > !iJ# *+#],#-#+.# b/%# J  I J  intF@ sys../includecolortable.ccolortbl.hdefault0Cconsole_color_tableconsole_color_table_sizeunsigned intSHADOW_REVERSEnameGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)default_color_tableansishadow/home/hpa/syslinux/release/syslinux-3.63/com32/libsys/colortable.cSHADOW_NORMALconsole_color_tableconsole_color_table_sizecolor_table_shadowSHADOW_ALLargb_fgSHADOW_NONEcharcolor_tableargb_bgGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.rel.data.bss.debug_abbrev.rel.debug_info.debug_line.rodata.str1.1.rel.debug_pubnames.debug_str.comment.note.GNU-stack4%4! +P0PB> NJZ2L mVGi  }03.p pO    "6colortable.cdefault_color_tableconsole_color_tableconsole_color_table_size     ! * 2 8 > D O W e s         screensize.o/ 1207848659 1026 1026 100664 4136 ` ELF@ 4(SӃi(@u  @$@1[% : ; I$ > $ >  : ;  : ; I8 ' II  I  : ; : ; I8  &&I : ; I!I/ : ; .? : ; ' I@: ; I: ; I: ; I 4: ; I 4: ; I? < !I/ ]@ 0BintLF^pZV 7(8e#9e#m:B#;P#Tg0QfpR BBS :eC sys../include../include/sys../include/bitsizescreensize.cfile.hdev.hstdint.htypes.hstddef.herrno.h?V胦| @At@tP*PR?S?@R agetscreensize@size_toffsetdataperrnosys/screensize.crowsfile_info__file_infounsigned charcloseshort unsigned intfileflagsfiledesptrdiff_t/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intflagslong long unsigned intoutput_devwritedev_magiclong long intfallbacknbytesGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)openshort intssize_tuint16_tcolsblocklg2chargetscreensize_fillerinput_devsigned charlengthreadGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4@ (%t+t0t<Ba> @RN b,^  og~W$z  {  0M.{{   .   @(screensize.cgetscreensize__file_infoerrno   ! & 1 8 J Q X _ f q x          q y        % 3 A O ] k           7 T stdcon_read.o/ 1207848660 1026 1026 100664 4588 ` ELF\ 4(UWVS ƉL$1E~tF@FNE u*/^ h@ډF^uG;l$r [^_]% : ; I$ > $ >  I & : ; : ; I8 ' I I  : ; : ; I8 &I : ; I!I/ : ; .: ; ' I@: ; I: ; I4: ; I4: ; I4: ; I?  ^hz ( 0Binti_pm 7V( /8e# 9e# I:B# Z;k# <# u=# ! ! %' k?(@- iopP# oopQ# i]!# ob# B !q) /Ae# Be# ICB# D# E# uF# G#  ! %@T `UB# V%# SW%# Xe# Ye# OZ%# 9[# buf\#~?` aB# JaB#O<+hfp*!tbuf**%*,n-%ch./F sys../include/sys../include/bitsize../includestdcon_read.ctypes.hstddef.hfile.hdev.hstdint.h*mg=!w>vf | 0hAA AAC n,E0I.N ttt tt5t 5:t,:Qt0Qht PeVR/ARXhRQhhfWgUARWhRbOdev_stdcon_rhclosewritesys/stdcon_read.cshort intsize_tdev_magicdatapfile_infofileflagslengthreadlong long intlong long unsigned intoffsetflagsunsigned charfallbackfiledesssize_trowsuint16_t_fillershort unsigned intoutput_devcharcount/home/hpa/syslinux/release/syslinux-3.63/com32/libbufpdev_stdcon_r__stdcon_readcolsnbytesinput_devblocklg2signed charopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)unsigned intptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4h %+01Bb> R/N b^  nHj  {@^#   0Z .  D@ Eh  +8 stdcon_read.c__stdcon_read__rawcon_read__line_inputdev_stdcon_r6D !&18JQX_fqx,+9GUcq     %/ < J P] stdcon_write.o/ 1207848660 1026 1026 100664 4908 ` ELF 4(WVS0ΉӍ|$ 1D$)1; uD$ T$1ɸ!D$ CT$1ɸ!Ouɉ0[^_% : ; I$ > $ >  : ;  : ; II!I/  : ; : ; I8 : ; I8  I  & : ; ' II : ; &I : ; !I/.: ; ' I@: ; I: ; I4: ; I 4: ; I4: ; I4: ; I?  aC9 0Bintyi{0lwbp^ ,! gs"p# fs#p# es$p# ds%p# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ "0#(1 .   72( )8p# 9p# V:B# t;# <# =#LL% R9(@- iopP# oopQA# i]L# ob# 2BL !#) )Ap# Bp# VCB# D;# E# F# GA#;L% ! G@T UB# V%# mW%# Xp# Yp# Z%# 3[# buf\#? ` aB# aB# vl)afp(LEbuf(X3(% *D{+vn,% |`@G sys../include/sys../include/bitsize../includestdcon_write.ctypes.hstddef.hfile.hdev.hstdint.hcom32.h(3דYYuz f B|  aAA AC@ttt tatP/R;FRRaRQV_W ^Sdev_stdcon_waclosewriteiregshort intsize_teflagsdev_magicdatapfile_infosys/stdcon_write.cfileflagsdev_stdcon_wlengthreadlong long intlong long unsigned intoffsetflags_unused_espcom32sys_tunsigned charfallbackfiledesssize_tuint32_treg32_trowsuint16_t_fillershort unsigned intoutput_devcharcount/home/hpa/syslinux/release/syslinux-3.63/com32/lib__stdcon_writebufpcolsnbytesinput_devblocklg2signed charuint8_topenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)unsigned intptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4a %+0aB> RN bL^  nd8j  {Y# |  0 .  |0 6a  ) stdcon_write.c__stdcon_write__intcalldev_stdcon_w7N !&18JQX_jq|Q$WVdr  - < AK P^h  rawcon_read.o/ 1207848660 1026 1026 100664 5044 ` ELF 4(UWVSlT$͍|$@ 11AD$e \$t$@ى!|$8t#D$eى!D$8T$G9ul[^_]% : ; I$ > $ >  : ;  : ; II!I/  : ; : ; I8 : ; I8  I  & : ; ' II : ; &I : ; !I/.? : ; ' I@: ; I: ; I4: ; I 4: ; I4: ; I4: ; I?  s1F# 0Binti{0lwbp^ ,! gs"p# fs#p# es$p# ds%p# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ *0#(1 ;  p 7=( C8p# 9p# ]:B# {;# <# =#WW% ]S(@- iopP# oopQL# i]W# ob# =BW ,0) CAp# Bp# ]CB# DF# E# F# GL#FW% , R@T UB# V%# gW%# Xp# Yp# Z%# M[# buf\#? ` aB# ~aB#  ,sfp+WQbuf+d@+%-@-y.n/%0nI  sys../include/sys../include/bitsize../includerawcon_read.ctypes.hstddef.hfile.hdev.hstdint.hcom32.htimes.h+ؔYYxY׭u J | $sAA AACttt ttstP R sQrU"qW1__rawcon_readdev_rawcon_rscloseclock_twriteiregshort intsize_teflagssys/rawcon_read.cdev_magicdatapfile_infofileflagslengthdev_rawcon_rreadlong long intlong long unsigned intoffsetflags_unused_espcom32sys_tunsigned charfallbackfiledesssize_tuint32_treg32_trowsuint16_t_fillerstartshort unsigned intoutput_devcharcount/home/hpa/syslinux/release/syslinux-3.63/com32/libbufpcolsnbytesinput_devblocklg2signed charuint8_topenoregGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)__rawcon_readunsigned intptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4s L%+0cB > dRN |b^  n<j  {5   0 .  @ :  s#- rawcon_read.c__rawcon_readtimes__intcalldev_rawcon_r;U   ! & 1 8 J Q X _ j q |     Q           ! / b         a o }        #'+ 9 H M W \ j y     rawcon_write.o/ 1207848660 1026 1026 100664 4820 ` ELFL 4(WVS0΍|$ 1D$)ӉCD$ T$1ɸ!OCu0[^_% : ; I$ > $ >  : ;  : ; II!I/  : ; : ; I8 : ; I8  I  & : ; ' II : ; &I : ; !I/.: ; ' I@: ; I: ; I4: ; I 4: ; I4: ; I4: ; I?  HT9 0Bintli{0zlwbp^ ,! gs"p# fs#p# es$p# ds%p# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ "0#(1 .   72( )8p# 9p# C:B# g;# <# =#LL% R9(@- iopP# oopQA# i]L# ob# 2BL !#) )Ap# Bp# CCB# D;# E# F# GA#;L% ! G@T UB# V%# MW%# Xp# Yp# Z%# 3[# buf\#? ` aB# aB# rl)Hfp(LEbuf(X3(%v *D{+rn,% x RkN b$^  n<8j  {t# 6  0VM .{ { 40 d6H  ) rawcon_write.c__rawcon_write__intcalldev_rawcon_w4 !&18JQX_jq|Q$WVdr  - < AK P^~ err_read.o/ 1207848660 1026 1026 100664 4048 ` ELF4(% : ; I$ > $ >  I & : ; : ; I8 ' I I  : ; : ; I8 &I : ; I!I/ : ; .: ; ' I@ : ; I: ; I : ; I 4: ; I? < 4: ; I?  <tA 0Bintc \pj 7P( 8e# 9e# 7:B# W;k# <# o=# ! ! %' k-(@- iopP# oopQ# i]!# ob# B !q) Ae# Be# 7CB# D# E# oF# G#  ! %@T ZUB# V%# PW%# Xe# Ye# IZ%# '[# buf\#~?` aB# DaB# )tfp(!buf(R(%QB8/ sys../include/sys../include/bitsize../includeerr_read.ctypes.hstddef.hfile.hdev.hstdint.herrno.h*|   P@-dev_error_rclosewriteshort intsize_tdev_magicdatapfile_infofileflagssys/err_read.clengthreadlong long intlong long unsigned intoffsetflagsunsigned char__err_readfallbackfiledesssize_trowsuint16_t_fillershort unsigned intoutput_deverrnocharcount/home/hpa/syslinux/release/syslinux-3.63/com32/libdev_error_rcolsnbytesinput_devblocklg2signed charopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)unsigned intptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %D+D0D3Bw@> RN bd^  nx$j  {"   0. 0  )    err_read.c__err_readerrnodev_error_r !&18JQX_fqx,+9GUcq !.; err_write.o/ 1207848660 1026 1026 100664 4060 ` ELF4(% : ; I$ > $ >  I & : ; : ; I8 ' I I  : ; : ; I8 &I : ; I!I/ : ; .: ; ' I@ : ; I: ; I : ; I 4: ; I? < 4: ; I?  <v- 0Binte ipw 7R( 8e# 9e# S:B# d;k# <# q=# ! ! %' k=(@- iopP# oopQ# i]!# ob# B !q) Ae# Be# SCB# D# E# qF# G#  ! %@T \UB# V%# ]W%# Xe# Ye# KZ%# '[# buf\#~?` aB# FaB# G)tfp(!buf(R (%QB/ sys../include/sys../include/bitsize../includeerr_write.ctypes.hstddef.hfile.hdev.hstdint.herrno.h* B|   P@-dev_error_wclosewriteshort intsize_tdev_magicdatapsys/err_write.cfile_info__err_writefileflagslengthreadlong long intlong long unsigned intdev_error_woffsetflagsunsigned charfallbackfiledesssize_trowsuint16_t_fillershort unsigned intoutput_deverrnocharcount/home/hpa/syslinux/release/syslinux-3.63/com32/libcolsnbytesinput_devblocklg2signed charopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)unsigned intptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %D+D0D3Bw@> RN bh^  n$j  {"   0. 0  +    err_write.c__err_writeerrnodev_error_w !&18JQX_fqx,+9GUcq !.; null_read.o/ 1207848660 1026 1026 100664 3908 ` ELFh4(1% : ; I$ > $ >  I & : ; : ; I8 ' I I  : ; : ; I8 &I : ; I!I/ : ; .: ; ' I@ : ; I: ; I : ; I 4: ; I?  /o & 0Bint^hpv 7K( -8e# 9e# G:B# c;k# <# j=# ! ! %' k=(@- iopP# oopQ# i]!# ob# B !q) -Ae# Be# GCB# D# E# jF# G#  ! %@T UUB# V%# QW%# Xe# Ye# DZ%# 7[# buf\#~?` aB# ?aB# )tfp(!buf(R(%QX. sys../include/sys../include/bitsize../includenull_read.ctypes.hstddef.hfile.hdev.hstdint.h+|  P3 dev_null_rclosewritesys/null_read.cshort intsize_tdev_magicdatapfile_infofileflagslengthdev_null_rreadlong long intlong long unsigned intoffsetflagsunsigned charfallbackfiledesssize_trowsuint16_t_filler__null_readshort unsigned intoutput_devcharcount/home/hpa/syslinux/release/syslinux-3.63/com32/libcolsnbytesinput_devblocklg2signed charopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)unsigned intptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!8'8,8">Z3: l NJ ^0Z  jD$f  wh{! ,  40j.(  H $     null_read.c__null_readdev_null_r !&18JQX_fqx,+9GUcq !. null_write.o/ 1207848660 1026 1026 100664 3916 ` ELFl4(% : ; I$ > $ >  I & : ; : ; I8 ' I I  : ; : ; I8 &I : ; I!I/ : ; .: ; ' I@ : ; I: ; I : ; I 4: ; I?  /q*# 0Bint`vp 7M( ;8e# 9e# `:B# q;k# <# l=# ! ! %' kV(@- iopP# oopQ# i]!# ob# B !q) ;Ae# Be# `CB# D# E# lF# G#  ! %@T WUB# V%# jW%# Xe# Ye# FZ%# E[# buf\#~?` aB# AaB#  )tfp(!buf(R(%QK. sys../include/sys../include/bitsize../includenull_write.ctypes.hstddef.hfile.hdev.hstdint.h+B|  P3 dev_null_wclosewrite__null_writeshort intsize_tsys/null_write.cdev_magicdatapdev_null_wfile_infofileflagslengthreadlong long intlong long unsigned intoffsetflagsunsigned charfallbackfiledesssize_trowsuint16_t_fillershort unsigned intoutput_devcharcount/home/hpa/syslinux/release/syslinux-3.63/com32/libcolsnbytesinput_devblocklg2signed charopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)unsigned intptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!8'8,8">Z3: t NJ ^0Z  jH$f $ wl! 4  <0p.,  L &    null_write.c__null_writedev_null_w !&18JQX_fqx,+9GUcq !. serial_write.o/ 1207848660 1026 1026 100664 6972 ` ELF4(WVS0f=t7|$ 1D$)ӉCD$ T$1ɸ!OCu0[^_% : ; I$ > $ >  : ;  : ; II!I/  : ; : ; I8 : ; I8  I  & : ; (  : ; &I : ;  : ; I' II : ;  : ; !I/.: ; ' I .? : ; ' I@: ; I: ; I4: ; I 4: ; I 4: ; I!4: ; I? < "4: ; I?  Rg,iI 0Bint??iW{)0lwbp^ ,! gs"p# fs#p# es$p# ds%p# edi'# esi(# ebp)# x*# ebx+# edx,# ecx-# eax.#$ i0#(1 R  '0123(4D)/ 0p# M1p# 2# 3D# A4D# J s? @^# ahA^# C axDp# cxEp# dxFp# <Gp# H# I# J# _L M^# ahN^# O^# chP^# Q^# dhR^# <Sp# UT# U_# e W X^# ahY^# cxZp# q[p# <\p# `]# ^# W` a^# ahb^# c^# chd^# e^# dhf^# <gp# h# i_# P>cBOrKsVpxe_jisojJt up# vp# !wp# B# ptr# DB 7n( 8p# 9p# :B# :;# <# ==#% (@- iopP8# oopQ}# i]# ob# nB ]) Ap# Bp# CB# !Dw# E# =F# G}#w% ] @T UB# !V%# W%# Xp# Yp# Z%# [# buf\#? 8` aB# aB# > J}P V*Rfp)Ebuf)c)%'+D,D n-%!^7"mW!pz!D!"@ sys../include/syslinux../include../include/sys../include/bitsizeserial_write.cconfig.hstdint.htypes.hstddef.hfile.hdev.hcom32.h)ׯu{ B|  RAA AC@ttt tRtPIKP6RBRRQ)V)IWIPVPQQQ [__serial_write__syslinux_derivative_info dev_serial_wRrowsSYSLINUX_FS_UNKNOWNversionwriteiregsys/serial_write.cshort intsize_tsyslinux_derivative_infoeflags__syslinux_serial_console_info__serial_writedev_magicgsdiesbxsyslinux_ipappend_stringsinput_devoutput_devuint8_tspec_packetfileflagssyslinux_filesystemiobaselengthflowctlsyslinux_versionreadlong long intmax_apiptab_ptr__syslinux_versionapiver_unused_espcom32sys_tunsigned charnbytessigned charflagslong long unsigned intuint32_treg32_tSYSLINUX_FS_ISOLINUXsector_shift__syslinux_config_file_fillerfile_infoshort unsigned int_padcopyright_stringcharuint16_tpxenvptr/home/hpa/syslinux/release/syslinux-3.63/com32/libSYSLINUX_FS_SYSLINUXSYSLINUX_FS_PXELINUXbufpcols__syslinux_ipappend_stringsfilesystemcount__syslinux_derivative_infoblocklg2offsetSYSLINUX_FS_EXTLINUXopenssize_tsyslinux_serial_console_infoGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)datapdiskclosefssifiledesunsigned intversion_stringptrdiff_tfallbackdrive_numberdivisorstackdev_serial_wesdi_ptrGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4R t%+0B? > R_ N b8 ^  nP 8j  { H U $  ,0 .P p  R>H Userial_write.c__serial_write__syslinux_serial_console_info__intcalldev_serial_w__syslinux_derivative_info >   ! & 1 8 J Q X _ j q |     Q              ( 6 X        5 C Q s        - ; I \ v          ( 6 D R `      % 3 A O         * D a lpt              xserial_write.o/1207848660 1026 1026 100664 8456 ` ELF4(E<1ɺ !vUWVS f=׉t8r MB<w£#PЃ vk ‰Hub;}P"[0;k\ CumGN [^_]% : ; I$ > $ >  : ;  : ; II!I/  : ; : ; I8 : ; I8  I  & : ; (  : ; &I : ;  : ; I' II : ;  : ; !I/.: ; ' @ : ; I4: ; I .: ; ' I .? : ; ' I@: ; I 4: ; I!4: ; I" : ; #4: ; I$ %4: ; I? < &4: ; I?  U F'n 0mBintd{ig{A0*lwbpm^J ,! gs"p# fs#p# es$p# ds%p# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ 0#(1   z #3p> *  +># ,>#  -0#  .0#  /# Dt;'0<1V2R34e/ %0p# 1p# 2I# 3># 4># ? @^# ahA^# SC axDp# cxEp# dxFp# Gp# H# `I# J# L M^# ahN^# O^# chP^# Q^# dhR^# Sp# T# U#  KW X^# ahY^# cxZp# [p# \p# ]# ^# ` a^# ahb^# c^# chd^# e^# dhf^# gp# h# i# u>cBrKUVSpxe_isojKF t Oup# vp# ]wp#o B# ptro# u> 7( 8p# $9p# :B# v;J# Z<`# =`#z% J(@- iopP# oopQ# i]# ob# `B P) Ap# $Bp# CB# -D# ZE`# F`# G#z%  fz@T UB# V%# VW%# eXp# Yp# Z%# O[# buf\z#? ` aB# ~aB# Q,tch+R-  } +6z Ffp5cbuf55% k7>!n8%"9]#num$@2#chEi-W9k:B;B%> 2 %# 3B%7t&m%z%p>%F sys../include../include/syslinux../include/sys../include/bitsizexserial_write.ccom32.hstdint.hconfig.htypes.hstddef.hfile.hdev.hcolortbl.h.uZ@ v0hu͑gYu!vZ/ |  $ &AA AAC P !t!"t"#t #$t$'t'Ft GP2>P BR2FR 7Q7;U;VCUEFQ9DW@BRR'FR@BS@RRP'1P1FRAY __xserial_write __syslinux_derivative_infoFrowsSHADOW_NONESYSLINUX_FS_UNKNOWNversionwriteSHADOW_ALLconsole_color_tableiregstatest_tblshort intsize_tsyslinux_derivative_infoeflagsncolor__syslinux_serial_console_infodev_magicfileflagsesbxansisyslinux_ipappend_stringsinput_devoutput_devuint8_tspec_packetversion_string__xserial_writesyslinux_filesystemiobaselengthflowctlsyslinux_versionreadlong long intst_tblcmax_apiptab_ptrst_initSHADOW_REVERSEsys/xserial_write.c__syslinux_versionapiver_unused_espcom32sys_tunsigned charnbytesgsdisigned charflagslong long unsigned intuint32_treg32_tSYSLINUX_FS_ISOLINUXuint16_t__syslinux_config_file_fillerfile_infocolor_tableshort unsigned int_padcopyright_stringsector_shiftcharshadowpxenvptr/home/hpa/syslinux/release/syslinux-3.63/com32/libconsole_color_table_sizeSYSLINUX_FS_SYSLINUXemitSYSLINUX_FS_PXELINUXbufpSHADOW_NORMALcolsndigits__syslinux_ipappend_stringsfilesystemcount__syslinux_derivative_infoblocklg2offsetSYSLINUX_FS_EXTLINUXnameopenssize_tsyslinux_serial_console_infoGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)datapdiskclosefssifiledesunsigned intcolor_table_shadowptrdiff_tfallbackargb_bgdrive_numberdivisorstackargb_fgesdi_ptrGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4F %|+L 0BuY > PxR N b L^  o(l~Ez    0.X  , +8   DN &^}xserial_write.cemitireg.1875state.1888ndigits.1889ncolor.1890__intcall__xserial_write__syslinux_serial_console_infoconsole_color_table_sizeconsole_color_table__syslinux_derivative_info,Cbn) !&18JQX_jq|Q"0NV\bhny)7E\w!/=To*8KS{ ks &4BP^#1@EOT^tz   - 2 ? L  ( ,ansi.o/ 1207848660 1026 1026 100664 10920 ` ELF4(UWVS,ƈы@D$ ~ |$(T$^\$GD$/0G0$р w tXwfA<6w lrLG0D$(P<9/M)) KuXD$$GGG0t%`u T$'Wt$VE)w (#w%ci[t cP-G0D$(@4@8ǃ<1,D$(RRT$JRT$ JR11ҋ|$D$8@0D$+1_w KfJ mt'wlsu1D$)D$;D$|D$HD$;D$|R\$K)FD$;D$|\$K\$D$)y1D$1RC;D$| D$H=y1SG@H;D$| L$Iy1;T$|\$K\$ЅL1EtR\$t$NPPSVى|$T$ J9PPKD$0RV1|$\$PPCPD$ HP11҉t$_XD$0SJR1rVVD$HPD$ HP1>t"t@;L$SSQD$ HPL$RRQHP1҉\$L$PPQD$ HP1҉t$1ht G$G,D$(|$ WD<1$BB B BBBB B ~BuBlBcB ZBQBHB?B3BB#BBB B AT$(;J8D$G)W(O)L$o(G@\$(1#C0PЃ kG@ G@L$(A $ >  : ; (  : ;  : ; I8  I &I : ; I : ; I8 I !I/ ' I.? : ; ' @: ; I4: ; I 4: ; I4: ; I 4: ; I 4: ;I 4: ;I .? : ; ' @ 4: ; I? < +ZN1intX#!X*:+#V,#-%#.%# /3# 2 2 d< uBP x# y#,| xy#,#,#w,# ,#,#,# fg ,# bg!,# ",#$?##($,#,,%#0 pvt&,#4',#8!(,#< <, <,H-#j.#'/#v0# 1#,,,, B,,,,,g4S5,#5,#6,# ts7g# op8m#Bs C"HFtiGchGopImLstJg$SKPLTxyM nsp[,fN+p0,=y,X.y,s.Hx,HQx,Qjy,jy,x,%y,Nx,"set,"+i+,"a-,xIn%<pp|)  ,CHZttiB , < &  <[:  <2X3,!P sys../includeansi.cansi.hstdint.hcolortbl.huugu>[uعK 佽!hum 5u!@v! uuY=׼YA&_==Lg%Z@@  "N =KuuuuuuuJt. 5i?Kuvh˳^}C\+I6eqzٿ__ô³؜| FAA AAC@:LNPD.I@lDAHFLFP_@ DAHFLAPR@IDAHHLAPI@QDAHDLFPMLAHELGPF@ADAHFLFPD@XDAHFLFPB@PDAHALEPL@FDAHALFPM@p. Httt ttAtAOtO\t\tttttttt t t$t$%t%-t-.t.7t7HtHItIMtMStS`t`ataftfmtmststttutu{t{tttttttttttttttttFtPSV\V7]VssVVV V>CVRQVQ\QQQ0QHJQQQ Q7UQsQQQQQ Q+XQX\P\fQQ Q>FQh S "h"'S'FhS>BSSR R(@RHcSjSSR77R7GSssRsSRSRRSRR R+RSRRS R$P%)P6HPPPYjPuyPyPPPPP%.RRRR RPPPPQ" QQQ Q"PP PPORRR RSSHKP1/x__ansi_putchar__ansi_initZst_tblSHADOW_NONEargb_fgblinkSHADOW_ALLstateshort intconsole_color_tablecurxyansidecvt_to_cp437write_charst_escansi2pcsigned charlong long intcindexvtgraphicsnparmscharansi_opsst_tblcdefault_state__ansi_initst_initcolsSHADOW_REVERSEterm_infounsigned charcursor__ansi_putcharsys/ansi.clong long unsigned introwscolor_tableshort unsigned intintensitydisabledset_cursorreverseterm_statest_csishadow/home/hpa/syslinux/release/syslinux-3.63/com32/libconsole_color_table_sizeSHADOW_NORMALunderlineautocrparmsshowcursoruint8_tnamesaved_xyeraseGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)scroll_upunsigned intcolor_table_shadowansi_stateargb_bgGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4Z x$x%+0hB/> $R'%N (b` ^ ( nj p*  {5 *  *0.t" #   | %   2FAZnHzansi.cdecvt_to_cp437default_stateansi2pc.1615__ansi_putcharconsole_color_table_sizeconsole_color_table__ansi_initmemcpy?:2vQV !&8@FLR]es "G\jx=HP^lz#1?~     " +/BFS ]an x|     "0 59G SWe s y "]  $(,048<@DHLPTX\`dhlptx|  ansicon_write.o/1207848660 1026 1026 100664 10864 ` ELF4( ,1ÍvS‹H xtx uXzt ؃ ˉztz u [Ð fdYf`H]H\1ɺ@ vVSƉbQP9u9t-%1ɺ[^[^VSˋt$1 bf1ɺ[[^fx,u flf1ɺvVSӉf$i !D$D$1ɺ^[^WVSσ=t1։VKFu[^_ÍvS8Ã=,fd L$ @"|$%yfd1ɺ@"u@JebYL$ @D$,flT$( T$) P @$@,18[X`% : ; I$ > $ >  : ;  : ; II!I/  : ; : ; I8 : ; I8  I  & : ; ' II : ; &I : ; !I/ : ; ( ' .? : ; ' I@ : ; I.: ; ' I@4: ; I.: ; ' @4: ; I : ; I 4: ; I!4: ; I": ; I #.: ; ' @ $.? : ; ' I@%4: ; I&4: ; I '4: ; I?   5cd 0BintZin{0lwbp^ ,! gs"p# fs#p# es$p# ds%p# edi'# esi(# ebp)# N*# ebx+# edx,# ecx-# eax.#$ z0#(c1 4   72( 8p# 9p# :B# ;# c<# 0=#LL% R(@- iopP# oopQA# i]L# ob# 2BL !) Ap# Bp# CB# D;# cE# 0F# GA#;L% ! G@T UB# )V%# W%# wXp# Yp# Z%# ][# buf\#? ` aB# aB# 2 09|EW x^# y^#A| xy2# B# B# &B# B# B# B# fg B# bg!B# ""B#$ Z#2#( $B#, ?%#0 pvt&B#4 'B#8 (A#<QB, -# R.# /# D0# )1#BBBB W BB^  BBB u4 5B# 5B# 6B# ts7u# op8{# W Q/vB tfpuL^ _st~3bgBQfgBo0@`st*ԥ@xByB BI \!xy2*BVzxByBch^"st*ƥ#7Xtst*i stdx0Bwy0B"x1B"y1B*$ fpLbuf޿ ]%'% !n%  i$Y kOB |fpNL%QL*P@&ts2W&ti;$IB,8Kpl'3Q'LG# sys../include../include/sys../include/bitsizeansicon_write.cfile.hdev.hstdint.htypes.hstddef.hansi.hcom32.hhj=?>gY=Mg>g< $ >  I & : ; : ; I8 ' I I  : ; : ; I8 &I : ; I!I/ : ; .: ; ' I@: ; I: ; I4: ; I?  4l ' 0Bint[qp 7H( .8e# 9e# H:B# l;k# <# g=# ! ! %' k>(@- iopP# oopQ# i]!# ob# B !q) .Ae# Be# HCB# D# E# gF# G#  ! %@T RUB# V%# eW%# Xe# Ye# AZ%# 8[# buf\#~?` aB# <aB#%R.fp-!8buf-a-%3 sys../include/sys../include/bitsize../includeansiserial_write.ctypes.hstddef.hfile.hdev.hstdint.h-Yg;B| AA Attt tPWPRVRQSQ#8%dev_ansiserial_wclosedev_ansiserial_wwriteshort intsize_tdev_magicdatapfile_infofileflags__ansiserial_writelengthreadlong long intlong long unsigned intoffsetflagsunsigned charfallbackfiledesssize_trowsuint16_t_fillershort unsigned intoutput_devcharcount/home/hpa/syslinux/release/syslinux-3.63/com32/libcolsnbytesinput_devblocklg2signed charopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)sys/ansiserial_write.cunsigned intptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %P+P0PBc8> RN bH^  n`4j  {G' n  0P.~~8 ` w  '7G Xhansiserial_write.c__ansiserial_write__ansicon_write__xserial_writedev_ansiserial_w__ansicon_close__ansicon_open  !&18JQX_fqx,+9GUcq     &3  vesacon_write.o/1207848660 1026 1026 100664 9032 ` ELF4( 1ÍvWVSσ=t1"։VKFu[^_fH,PPfSɋ\$[\$[fVS։ˋL$ T$@D$T$ ډ[^vS8áuWfD L$ "|$%y 5t  @u  @$@18[N`hHX% : ; I$ > $ >  : ;  : ; II!I/  : ; : ; I8 : ; I8  I  & : ; (  : ; ' I&I' I : ;  : ; !I/.? : ; ' I@ : ; I.? : ; ' I@: ; I4: ; I4: ; I.: ; ' @ .: ; ' @!: ; I "4: ; I #4: ; I $4: ; I? < %4: ; I?  ;@KT 0dBintJip{0lwbp^ ,! gs"p# fs#p# es$p# ds%p# edi'# esi(# ebp)# Y*# ebx+# edx,# ecx-# eax.#$ [0#(e1 6   (~0 x^# y^#;| xy# B# B# B# B# B# B# fg B# bg!B# "B#$ ##( $B#, 0%#0 pvt&B#4 'B#8 D(#<Bc, -# .# /# 60# +1#BBBB  cBB^  BBB 44 T5B# 5B# "6B# ts74# op8:#  @ 7( 8p# 9p# :B# ;# V<+# F=+#E% (@- iopP{# oopQ# i]# obV# +B ) Ap# Bp# CB# D# VE+# FF+# G#E%  1E@T UB# !V%# W%# \Xp# Yp# Z%# @[# buf\E#V? {` TaB# aB# PhmB tfplFE FfpKbuftb%n% i@HWtstf~Xftst ~h~x|B8y|BKch|^^!st} 6wqstux0vBy0vB!x1vB!y1vB\xIB;fpH/"KL"+J #ts3`#op4#ti<"EB$ 6%$n FB sys../include../include/sys../include/bitsizesys/vesavesacon_write.cfile.hdev.hstdint.htypes.hstddef.hansi.hcom32.hconsole.hvideo.hhf^3zZ/dt!xt-QluB|   :AA A H XhA%AA AC@P t tt Ft -P2>P@BP (R2>R@FR Q"W"$S$2Q29W9>Q>CWHRPXaPhiti~th~Ph~Rh~Qttt PRVPQSRtt;tP:S[__vesacon_close__vesacon_write__vesacon_opendev_vesacon_w;st_tblblinkwriteoregvesacon_write_chariregstatevesacon_eraseparmsshort intsize_teflagscount__vesacon_close__vesacon_openinput_devssize_twrite_charst_escfallbackdev_ansicon_wfileflagsterm_infolengthcursorreadlong long intcindexvtgraphicsnparmsansi_opsst_tblcoffsetst_initcurxyscroll_upsys/vesacon_write.crows_unused_espcom32sys_tunsigned charst_csivesacon_showcursoransi_statesigned charflagslong long unsigned intuint32_treg32_tunsigned intuint16_t_fillerfile_infoshort unsigned intintensitydisabledset_cursorcharterm_stateopen/home/hpa/syslinux/release/syslinux-3.63/com32/libvesacon_scroll_upbufpdev_magicvesacon_countercolsunderlinereversenbytesdev_vesacon_wshowcursoroutput_devblocklg2uint8_tautocrsaved_xyeraseGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)datap__vesacon_writeclosefiledesptrdiff_t__vesacon_text_rowsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.rel.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4; )p(% 88/ 4FB p(V^ R " fh b "  r n "p 0M}_ 0#  8#0~. j !$H7XIh\%j , t`|w z  :.:N \vesacon_write.cvesacon_countertivesacon_showcursorvesacon_scroll_upvesacon_write_charvesacon_eraseireg.1937tsop__vesacon_close__vesacon_write__ansi_putchar__vesacon_doit__vesacon_set_cursor__vesacon_scroll_up__vesacon_write_char__vesacon_erase__vesacon_open__intcall__vesacon_init__ansi_init__vesacon_text_rowsdev_vesacon_wdev_ansicon_w).:"#$%$0Sbz  $ !&18JQX_jq|Q0>LZhv+9GU FU]ky6>LZhv )_m&*;ELPakrvz"&*8=KWhx& !'(,HLX\hl/20 1207848660 1026 1026 100664 4492 ` ELF 4(WVSlj։ى[^_% : ; I$ > $ >  I & : ; : ; I8 ' I I  : ; : ; I8 &I : ; I!I/ : ; .: ; ' I@: ; I: ; I4: ; I? < 4: ; I?  A}' 0Bintl^pl 7Y( .8e# 9e# H:B# Y;k# <# x=# ! ! %' k>(@- iopP# oopQ# i]!# ob# B !q) .Ae# Be# HCB# D# E# xF# G#  ! %@T cUB# V%# RW%# Xe# Ye# RZ%# 8[# buf\#~?` aB# MaB#%:/fp.!8buf.a.%84 sys../include/sys../include/bitsize../includevesaserial_write.ctypes.hstddef.hfile.hdev.hstdint.hconsole.h.Yg;B| AA Attt tPWPRVRQSQ#E2dev_vesaserial_wclosedev_ansiserial_wwriteshort intsize_tdev_magicdatapfile_infofileflagslengthreadlong long intlong long unsigned intoffsetflagsunsigned charfallbackfiledesssize_trowsuint16_t_fillershort unsigned intoutput_devchardev_vesaserial_wcount/home/hpa/syslinux/release/syslinux-3.63/com32/lib__vesaserial_writecolsnbytesinput_devblocklg2signed charopenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)sys/vesaserial_write.cunsigned intptrdiff_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 l%P+P0P$BtE> |RN <bt^ D  n4j d {s' t  |0.t p   '7G Xhwvesaserial_write.c__vesaserial_write__vesacon_write__xserial_writedev_vesaserial_w__vesacon_close__vesacon_opendev_ansiserial_w  !&18JQX_fqx,+9GUcq     &3@  initvesa.o/ 1207848660 1026 1026 100664 11580 ` ELF4(…u1Í@ÍvUWVS\t  l$0 f1҉VBE2fD$TO؃fD$8fD$4f|$TO5;VESAt Lf{w :ڸSЉD$fD$D$( f%fD$ 1҉fD$TOD$ fD$PfD$8fD$4T$0Ѹf|$TOV$T$N"L$F D$^VT$#f~fVȃ~fsfh~v ~Xx_fnJ@f~6,f9#Fuf~uFf~ |$# u4|$|$|$t}|$#u!tsuy|$ur|$uk|$tYb|$#u!tOuQ|$ uJ|$uC|$t5:|$#u3t5u)|$ u"|$u|$t1 ;\$(sL$ fL$\$(|$f|$f|$(u T$(fD$TT$0Ѹ"D$Xu"D$TtD$4T$H,8fD$T0fD$HT$0ѸD$4T$@,5D$$D$$ )1D$$  |$$ uы =yfL$@fD$TOfL$fL$H\$0ىڸf|$TOt fD$TfD$HfD$PfD$L1ɉڸ"|$(==kPǣu ""d$T$ T$ى1\[^_]% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I& : ;  : ; ( .: ; ' I : ; I.: ; ' : ; I5.: ; ' I .: ; ' I@ : ; I 4: ; I!4: ; I" #.: ;' I $4: ;I%4: ;I&.? : ;' I@'4: ;I(1X Y) *41 +41,41-1X Y .1/ U01X Y 1121X Y3 U41 54: ; I? < 64: ; I?  7!I/ agwintXL@^p- plewbS-A% ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ 0#(1  F IGe# BH# IH# WJN# Ke# Lf# ,M# 7A7B =  !fe7B P3ee  l  e#p]# $e# %S# &# '# (# g)e# +S# ,# -# t.# Q0p#$ O1#AAP7 8S# ^9P# M:S# F;S# <# %=# >S# K@S# AS# BA# CA# iDA# bppEA# FA# GA# 0HA# IA# JA# LA# MA# NA#! OA#" :PA## QA#$ RA#% SA#& TA#' V`#( DW`#, >XS#0 QZf#2`A AvA] gi^# mi_#  ,S R. ch/A# 0A# 1#6:MT@! 'ANA~ Get}N|S|Sstr{jS__pi SEGeS__pd$%ptr"*#$p 6F3txEp1\3 rm]!^`!9_S!#_S!_ gi` mia pxfb!b"""""""""""" S  N" K3miJ  iL3 L9dst8`src8`83 i:3#3$`~%ptr$"& Z.34'rv/3(r 625)2*G@+Q,\+g,r7,}Y,+,-6  ./+017%1,81!a)+B2L93 +^+j+v2(1415yN68-v6/263p5A) 5\B6  6/6136o13 A64q  e7766 F sys/vesa../include../include/bitsizeinitvesa.cfill.hcom32.hstdint.hdebug.hvideo.hvesa.hstddef.h/!Jx~.gjguؼ"$(u * XJ1.;((Fnt!u"uu;f~ؚKxrw!#[{uuu#0~tx|  $AA AACpP R P Rttt ttt-2PPP"'P`ePPPP"P'.P8`SSSS>VVV`SSSSSSSVUUUSSW __vesacon_init __vesa_info __vesacon_pixel_format __vesacon_bytes_per_pixel; __vesacon_text_displayM __vesacon_font_height_ __vesacon_text_rows __vesacon_graphics_font __vesacon_background char_widthattr_tversiondef_charbestmodecs_cfarcall__vesa_infooffscreen_ptrvesa_char__vesacon_format_pixels_list__com32size_teflagscs_farcallis_power_of_2GET_PTR__far_ptrrom_font__vesacon_bytes_per_pixeloem_vendor_name_ptrPXF_BGR24cs_bounce_sizecom32_sys_argsoem_software_revfill__vesacon_pixel_formatwin_sizeoem_datauint8_tncharstotal_memoryoem_product_rev_ptr__vesacon_text_display/home/hpa/syslinux/release/syslinux-3.63/com32/libinit_text_displayfar_ptr_tlogical_scangmaskpage_functionlong long int_fillerwin_schemebank_sizePXF_LE_RGB16_565h_resreserved__vesacon_initmemory_planesshort int__ptr__offsresv_mask_unused_esp__vesacon_backgroundcom32sys_tunsigned chargposresv_possigned charPXF_BGRA32long long unsigned intuint32_tmemory_layoutreg32_tunsigned intbmaskuint16_tcs_sysargsPXF_NONEvesa_general_info__vesacon_text_rowsvideo_mode_ptrunpack_fontvesa_mode_infoshort unsigned intwin_segoem_product_name_ptrchar__vesacon_graphics_fontbestpxfrmaskdebugheightmode_attr__vesacon_format_pixels_tmodeoffscreen_sizePXF_LE_RGB15_555win_attrsys/vesa/initvesa.cOFFSvesa_infoimage_pagesv_reschar_heightmode_ptrattrcountvesa_pixel_formatcapabilitiessignaturebanksMK_PTRrposbposcs_intcalllfb_ptr__fptrvendor_stringvesacon_fillvesacon_set_modecs_cmdlinewin_graincs_bounceGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)vesacon_paged_mode_ok__vesacon_font_height__segdcm_info__vesacon_format_pixelsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack4 &%0+404B > '8RJN ,bL^ -  o4~z $-   ,-800 .::"P  %    )6>EO [b|  '>E\v initvesa.cis_power_of_2__vesacon_initx86_init_fpu__com32memset__intcall__vesa_infomemcpy__vesacon_bytes_per_pixel__vesacon_format_pixels_list__vesacon_format_pixels__vesacon_font_height__vesacon_graphics_font__vesacon_text_rows__vesacon_init_cursor__vesacon_init_copy_to_screen__vesacon_pixel_formatmalloc__vesacon_text_display__vesacon_init_background__vesacon_background 4U8*5@E\s"Of !"# !&-;BMT_fqxF )7ESa*8Tbp~ &4B{ Q^iy!1 ;R]hs8Q_w          +  ; ? J  S  \  a e w {              * < I "N [ ` m     $ ( ,drawtxt.o/ 1207848660 1026 1026 100664 16716 ` ELF,4(1҃ ƒ)xƀ ƀ!f1ƀ ƀ!ÍvUWVS| É֡D$=f-T$ ȉL$4Ӎ PD$ σЍT$TDD$ D$D-DD$HL$IL$@$ PT$XD$(D$,D$2D$3D$<D$vL$HL$@D$9D$HK L$L$HAL$Du1҃؋L$X!1D$`D$HD$PT$T$ L$DL$LD$8D$\f|$8L$8|$3wT$ T$$|$2}\$,ֽ)D$$ T$$  l$l$ L$ ƊT$`D$3Ѕt ???D$\tp@D$\T$9D$ d$2d$`d$3D$8T$PL$@D$9D$P.L$PAL$Du1҃؈D$`0T$`D$PD$8|$3D$  D$$|$2f\$(~vT$LL$<D$2D$9L$LAL$B1Ƀ؈D$30L$3BD$(R T$,D$LD$8T$pD$TfD$ $ > : ; I : ; (  : ;  : ; I8  I &I I !I/   : ;  : ; I8 .: ; ' I : ; I: ; I4: ; I.? : ;' @ : ;I4: ;I 4: ; I  41.: ; ' @: ; I: ; I: ; I 4: ; I 4: ; I!4: ; I "1X Y #1$ %1X Y &!I/'.? : ;' @(.? : ; ' @).: ; ' *.? : ; ' @+: ; I ,4: ; I-1.41/41 0.? : ;' @1: ;I24: ;I31UX Y4 U51UX Y6: ;I 7: ;I 84: ;I91X Y:1X Y;1 <4: ; I? < k?intdLk^6p<5 p#p *+#,#.-p#.p# 9/#   #S #< :A # We#<@#t$e#%S#&&W#'*# (W#~)e#(+S#j,W#-W##.W# 0#$1)# )A # 9A #7a8S#9#Z:S#k;S#H<#=W# >S#@S#AS#*BA#KCA#EDA#bppEA#FA#GA#PHA#IA#JA#LA#MA# NA#!OA#" PA##QA#$RA#%SA#&STA#'RV #(W #,XS#0Z#2 A # A A #H<]gi^b#mi_9#,S}.ch/A#0A# 1H#{2Afg1Abg1AK1Atmp3pg.1tW-3r0/3P<efg;ebg;eK=A4>A?A@A@AABA{CA{;L4rowK3dcolK34K3QK3M;kN;O@kO@kOek BOe Pek Pek Pe)9QAk QAR QA!iR3kjR3!jxR3k~R3kR3kSFkSFkSFkSFk TpULVSkV@W~kshaXA"{## ${!,7BMXc%E###$% E###$"E###$ 3 e S de&#':(M%Fptr"F#S$p)$ row3col3F33y0px0py1px1p*0 Wx03y03$x13C+y13 Ha,y3!ptrF`S Q3% ku---"####$ . / P0 1x3Z1y3:32ptrF3 ####4.. / Q. '50&####4H . E. n0 s1x31y36chAQ7 H8ptrF93p####$3p / P/ R *:dst):src):)~* 7t43J H]FcF3S: - p- - : ;Q--9 ####$    A #\%  &Fr'3@I'3DZppHpipL<2  pLggzfJ=>ggYgYg4֠0/BJ=>gYg7fbJ> ~<~X\Z+|  1$4YAA AAFCB J.I(gACgE B.pCA$AA AAC (8AA AAClcAA twAA A P45t56t67t 78t8>t>t4GPGSPSUSVSZS4^R^VVWVZV4QOZQVSZSV/WVZVkPkkTRTgR R RR +R{RQ WWXWZWttt ttttt t  t ttttt ttt 0P0h+R+dEQQAAaWa_R7VpQSnWRttt ttKtKtPMVPVRKSKPRPSQOUOPQPUSPPkRRNWPW>PPhPP>PRkRRttst PrVRqS'6Ptutuvtvwt wttPtRQVWPWo__vesacon_init_cursord__vesacon_redraw_textz__vesacon_doit$ __vesacon_erase0 __vesacon_set_cursor __vesacon_write_char __vesacon_scroll_up00eeimage_pagesSHADOW_REVERSEvideo_mode_ptrchar_widthsize_tvesa_inforowsalphancols__vesacon_erase__vesacon_init_cursorvesa_charoffscreen_ptrlong long unsigned int__vesacon_redraw_textrowsptrlogical_scanupd_x1row_bufferlong long intsigned charpage_functionlong unsigned intoem_product_rev_ptr__vesacon_scroll_upchar_heightfont_heighttoptrupd_y1SHADOW_ALLalpha_valargb_bgrmaskmemory_layoutuint16_tchsbitsattr_tcsptrh_resbgrowptrcountbposconsole_color_tablevesacon_touchansireservedattr__vesacon_doitfg_b__vesacon_bytes_per_pixelunsigned intcursor_y__vesacon_graphics_fontoem_vendor_name_ptrpixrowbgvalpixsrowGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)v_resnamealpha_pixelcolswidthchxbitsshort unsigned int__vesacon_srgb_to_linearoem_datavesacon_update_charactersfg_rshadowbg_rmemory_planesdcm_infocursor_patternwin_sizesignaturetotal_memoryrowbufptrversionSHADOW_NONEoffscreen_sizeSHADOW_NORMALcolor_tableoem_product_name_ptr__vesacon_text_rows__vesacon_font_heightfillfar_ptr_tbgcoloroem_software_revchbitsvesa_general_infolfb_ptrupd_x0mode_attrunsigned char__vesa_info__vesacon_write_charshort intbytes_per_pixel__vesacon_linear_to_srgbresv_mask__vesacon_set_cursorwin_attrfromptrgposvesa_mode_info_filler__vesacon_backgroundargb_fguint32_t/home/hpa/syslinux/release/syslinux-3.63/com32/libcursor_xbg_bcolorcharbanksbg_gupd_y0dword_countrowptrfbrowptrsys/vesa/drawtxt.cresv_posrposcptrcursor_pointercapabilitiespixel_offsetcolor_table_shadowfg_gbmaskvendor_stringnrowsvisiblefgvalwin_segbank_sizewin_grainuint8_t__vesacon_text_display__far_ptrwin_scheme__ptrbgptrheightfgcolorvesacon_fillgmaskcopy_dwordGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack4 D5% +@P 0@3Bs o> 48xRN @b$^ @ o ~#z 4A $  GUcq '5CQ_m{$IXm{"-8CNYd-7<KZdix#.=Hfj{)-Mfnrv|* 1 5 9 G U c u               " 6 > B F T b g r           ! % ) 7 E W q z ~            # ( 3 > I \ ` l u ~            # ( 4 9 E J V [ g l x }         :](,PTlp background.o/ 1207848660 1026 1026 100664 25044 ` ELFD4(1ÐVSD$DŽ$j11Ҹ$D$ $‹$u|$d\t?$T$ $$$T$T$Bt$u $$u4T$t$$$L$A<u$<w $1 T @ L$;A|싄$1 T$,$L$q1C9|1ۃ$u$11؁Ĥ[^VSiЀ5Í[^fWVS=11҉Fu 1҉xF9|1҉kC~[^_fW=ti1ZY_ÍvVS=tXB@uҁ tA1[[^UWVS,=QŅu [\$,1҉uz|$|$T$ Et1t$DžuD$D$G^G9Åx}L$$T$(|$(wd|$$wZD$ T$ D$ T$11 ۾Elj,[^_]% $ > : ; I$ > < : ;I  I ' I I '  : ; : ; I8  : ; I8  : ;I8 I!I/ &I : ; : ;I8  : ; : ;  : ; ( .: ; ' I : ; I.? : ; ' I .? : ;' I@ .: ; ' I@: ; I4: ; I 4: ; I!4: ; I" : ; #!I/$.: ; ' @%: ; I&4: ; I'.? : ; ' I@(4: ; I): ; I* : ; + ,.? : ;' I@-: ;I.4: ;I/4: ;I0 : ;11X Y2131UX Y4 U5416417 181X Y 9 :41 ;1<1X Y=4: ; I? < aU8g 7vintPda27U~=  V t O  h h P  J8T U#  Vh# ]Ws# Y# Zh# [s#msg]# ^# `# a#$ b#( V d>#, Wes#0 fs#4%  R>#oga1K  a 'J 7= >D ,  ? 7# E 7# D 7# ' 7#  7# 7#Vva~ 'a &,@gjk@nRrpdj%7qE@R red# ## p #red# ## # red# ## #:#|:E red# ##:##! R: P o# #F#[# *X  % >#key%o#&o#f(#  01" rXXPYr#Z@# [#  ^#P`( a ~#O # ## #@# ##L# #h ##X ## # #   #(~ #, >#0J >#4#8#<h4#DK p#Hp#R2#\#`#d #h #ll#p0 F#t #x #| # #~  #j # # #= -o#.#/#0o# 1#2#J3#8#E =#8 >#JCo# Do#F#WG#L#M#.X#-Z#[#^o#L_o#|f#Zj#.n#o#p#q#1 r#s# t#Q u# x xUz,    ~##L## X # # {2    '  d4#n6v#<7v#8(# 9#$=:#(w;(#,>Q#0]I(#40 J#8 K#9O#<P#@(Q#DS#HT4#_ U# V>#g W>#$ X>#Y>#Z>#~\#O ]# ^# _#`#pa#p b# c#d4# e4#f4#g4#h4#i4#j #l#crcm#n#@o# p#qr#%r#2 s#s t#bu#v#Lw#x#ty#z#X {# |#}#w # # #p#p#>#  #  #n4#4#{ 4### ##~#h4#K p#S #T #v #$##4#m4#4#54##\ ## ##t#>#># #j#o#o#4#K4#0F#3o##5(#y#a ># 4## ##  ##Z#)# *#z+#0(#21#2#64# :4#!;4# =4# B#E#F# p 2  d X  d 4   d  > [  d 9  06 Q d 4  > ]c y d 4  > d ;' ( d  (  d (` 1& A  .#& u7 ,  -@#  .K#, #  $.#  %#  &A#  '# # (A#  ).# y +#  ,A#  -A# m .A#  0,#$ D 1<#<L   7 ; 8# _ 9 #  :#  ;# < <# z =A# T ># a @# A# B# C#  D#bpp E# 2 F# M G#  H# I# h J# E L# M# $ N#!  O#" d P## Q#$ R#%  S#& ' T#' D V#(  W#, A X#0  Z"#22[ ]gi ^u#mi _L#i 6,*%>__f${! O,__pN__sN,__nN,__fN{+>taT>fpS{z5 UdpaV p ~ W |\p D]>!i^>!rv_>"err4#$53% 4>_%(4>r%* 4>&6&77&8,.$P?!i@>& AP&rCP>'>rgb7= [ 7n'>((x>(y>!dx>!dy>!dy2> !k?>)len>$>fp{)len>&&&,&~7&O 7(rv>& &*err+p7#(,fp'{(st)L+A>:>__f9{+, >(/- d.fp {/ .rv >%0err#1Vh22221232(3?2e2Z2P45v555M5655782 9:L82;]22<#%24= 4=8 b2==[=G>7=KF>4.##=HR#=[L_A  sys/vesa../include../include/bitsize../include/klibc../include/sysbackground.cstdio.hstddef.hpng.harchsetjmp.hpngconf.hzlib.hzconf.hstdint.hstat.htypes.htinyjpeg.hvesa.hcom32.hvideo.h~J i:ZK!@K JI#O#-y<'ՆՔ;tNZY]uup Zfy˼~ !X?J<u? ~ 1.2.8r|  <AA FQI.m_.-RB.I`..AA vAA A%AC^ A lAA Cd $(AA AAC@tt t tStStttt&P&pIwRRRVVtPSZ_S~SSSttt PRVQttt t1GVGStttt tPPWQttt %t%(t "R"Q'V%SP"P()t)*t*+t +,t,/t/t(FPPPHLULcPchQhUUPXTTTQVVVVvVVVVVVSPSSSSPS RzPVVvVVV+hhhhh5ddddd?`````W\\\\\SxSSSe__vesacon_init_backgroundUvesacon_set_backgroundvesacon_default_backgroundAvesacon_load_backgroundbig_row_bufpng_write_status_ptrindex_to_palettemalloc_fnwarning_fn__vesacon_bytes_per_pixelpng_uint_32save_bufferoem_software_revpng_sPLT_entrypbit_depthrgb_to_gray_statusimage_pagesscal_s_widthjdec_privatepng_charpppaletterpostotal_outpng_sPLT_structflagsjpeg_filezbufgmaskPXF_LE_RGB16_565mode_attrpng_sPLT_entry_structnentries_IO_fileoem_product_rev_ptruint32_tpng_info_structentriessplt_palettescur_palettegamma_16_tablepush_lengthdummybluejpeg_sig_cmpzfreepng_row_info_structcompression_typePXF_BGR24read_jpeg_filetime_buffer__ebxrmaskshort int/home/hpa/syslinux/release/syslinux-3.63/com32/libpaeth_rowlength_of_filefrequencypng_read_status_ptrmodefilenamememory_planespng_uint_16pint_y_greenx_blueGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)video_mode_ptrx_offsetpng_malloc_ptriccp_namelogical_scaninfo_ptry_greenright_bordery_offsetbgptrdo_filterprev_rowpng_rw_ptrint_x_redpcal_unitsbuffer_sizeTINYJPEG_FMT_BGRA32current_buffer_ptrpng_textpiccp_proflenopaquesys/vesa/background.ctransformations__vesa_infopasses__vesacon_font_heightread_png_filez_streamfloatshiftavg_rowrowbytesvendor_stringpalette_lookupindexresv_possig_byteswrite_data_fnscal_pixel_heightgamma_16_from_1chunk_namelong long unsigned int__vesacon_backgrounduIntstatwin_seg__ebpz_stream_suLong__vesacon_linear_to_srgbusr_bit_depthpng_voidp__jmp_bufpng_struct_defpng_uint_16pprow_fnbackground__vesacon_init_backgroundpng_byteppsignaturezallocbytes_per_pixel__ptravail_outmng_features_permittedpng_error_ptrpng_fixed_pointpng_unknown_chunkpasssize_terror_fnio_ptrwidthrgb_to_gray_green_coeffpng_int_32vesa_infofilesize__eipzlib_strategyPXF_LE_RGB15_555save_buffer_sizeBytest_modebytesvesacon_load_backgroundint_y_white__esiscal_pixel_widthfclose__espdither_indexpng_unknown_chunk_tphys_unit_typepng_row_info__ediprocess_modey_whitepng_color_16win_grainfree_mewin_sizePXF_NONEerror_ptrcountzlib_mem_levelsub_rowdraw_backgroundsave_buffer_maxcapabilitiesstartscal_unitcharread_data_fnpcal_nparamsadlertotal_intext_lengthpng_const_charpmem_ptry_redtextpng_bytepjmp_bufdataend_fnup_rowjdecheaderpng_uint_16gamma_from_1uint8_toffscreen_ptrcurrent_textpng_unknown_chunkppcal_paramspng_sPLT_entryuser_transform_depthunknown_chunkswrite_row_fnh_reszlib_methodinterlacedend_ptrscreen_gammav_respng_user_transform_ptrlong long intpng_sPLT_tpnum_textBytefvaliddepthchar_widthnext_outnum_transx_pixels_per_unitoem_product_name_ptrnpixelsbanksunknown_chunks_numtrans_valueschannelsnum_chunk_listiwidthfillersrgb_intentpng_size_trow_bufbottom_borderbpossizepng_free_ptrusr_widthrgb_to_gray_red_coeff__far_ptrbackground_gamma_typeinternal_stateavail_inrgb_to_gray_blue_coeffint_x_greenlong unsigned intheightdata_typetinyjpeg_colorspace_tinfo_fnx_greendither_sortresv_maskrow_numbermmx_rowbytes_thresholdzlib_levelgreennum_rowsfree_funcpalette_to_indexusr_channelscomponentsint_x_blueuint16_tlinezlib_window_bitspng_ptrpcal_purposemax_textread_row_fnzbuf_sizevesa_pixel_formatgamma_to_1png_color_structchunk_listchar_heightuser_transform_channelspng_textpng_row_infopspare_bytelong intgamma_16_to_1next_ingraylocationpng_structpfreadpng_structfilterpng_progressive_end_ptrint_y_blueskip_lengthfilter_typealloc_funcpng_infopng_progressive_row_ptrvesa_mode_infogammay_pixels_per_uniticcp_profilepng_colorpng_color_8_structcurrent_text_sizevesa_general_infobank_sizebackground_1PXF_BGRA32png_charpoffscreen_sizenamepng_infopwin_attrpage_functionunsigned intpixel_depthidat_sizecurrent_text_ptrtinyjpeg_colorspacex_redgamma_shiftvesacon_default_backgroundpng_color_16_structbackground_gammay_bluevesacon_set_backgroundint_x_whitealphanum_palettescal_s_heightint_gammabmaskcurrent_text_leftrow_pointersgposx_whitefbptruser_height_maxunsigned charbytes_per_rowsave_buffer_ptrpng_color_8oem_vendor_name_ptrread_user_chunk_fntotal_memoryuser_width_maxdcm_infohistcurrent_bufferoem_datamemory_layoutpng_progressive_info_ptrcurrent_buffer_sizefar_ptr_tread_user_transform_fnint_y_redstatepcal_typepcal_X0pcal_X1st_sizeoffset_unit_typeinterlace_typeversion__vesacon_pixel_formatpng_colorpcompressionsigned charmode_toff_tshort unsigned intuser_transform_ptrirowbyteswin_schemereservedfree_fnvoidpfsplt_palettes_nummmx_bitdepth_thresholddoublerow_infodraw_background_linefilenopng_byteFILEzstreamjmpbufsig_bitpng_user_chunk_ptrpng_sPLT_tuser_chunk_ptrlfb_ptrcolor_typeiccp_compressiontransgamma_tableasm_flagspng_text_structGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack4 O%+0,Be> lQR&N Da^2Z(qd( m Lap ~p)0 a0  a0H00C.CC|H |LW .1v  A[r 1=N^s %6Mlh( (<LQbackground.cread_png_filedraw_background_linedraw_background__vesacon_init_backgroundpng_create_read_structpng_create_info_structsetjmppng_init_iopng_set_sig_bytespng_set_user_limitspng_read_infopng_set_palette_to_rgbpng_set_gray_to_rgbpng_get_validpng_set_tRNS_to_alphapng_set_add_alphapng_set_bgrpng_set_strip_16png_set_packing__vesacon_backgroundpng_set_interlace_handlingpng_read_rowspng_destroy_read_struct__vesacon_bytes_per_pixel__vesa_info__vesacon_copy_to_screen__vesacon_font_height__vesacon_redraw_textvesacon_set_background__vesacon_pixel_formatvesacon_default_background__vesacon_linear_to_srgbvesacon_load_backgroundfopen_freadpng_sig_cmpfstatmalloctinyjpeg_inittinyjpeg_parse_headertinyjpeg_get_sizetinyjpeg_set_componentstinyjpeg_set_bytes_per_rowTINYJPEG_FMT_BGRA32tinyjpeg_decodefreeclose"'3Cs4 @!W"i#n$%&'$( )'+.$.$01.=B2d3{45637 89;$K:c;i<p={>>?*, !&-8FQWbit#1?[iw (/:AL[cq)5GYp%CRaq +;G]fu -6ETc '6ETcr&5DSbq  - = M ] m }           - = M ] m }          ! 7 @ O ^ m |            - < K Z i x           $ 4 D T d t         4DTdt$4DTdt$4DTdt$4DTdt$4DTdt$4DTew%Rz+3BQYgzQZhv,:HVdr7`hntz  ! &4CM Rak x       $( 5 :E[fjn }         )D[qw(GSW[ `k z    # , 5 > L U cgsw 5S ( ,h l    alphatbl.o/ 1207848660 1026 1026 100664 6788 ` ELF4(% $ > $ > : ; II!I/ 4: ; I?  &I !I/ 4: ;I?  .intL^![S!BsA  rGA sys/vesa../includealphatbl.cstdint.h(<Pcw 9To2W}%SM2o/sG*z r y 2 U ^<!%Af,fLD P!""p#*$$%d&&''({)F*++,-a.:/001234i5U6B738%9:; <=>? @AB#C0D?EQFeG|HIJKLN9OaPQRSUPVWXY=[~\] _R`ab>def@hij[lm$opqfstJvw9yz2|}7Fу_P5ܓ2☔Iy9¦V%ʯ{W7Ҿ¥ĜƕȒʑ̔ΙСҭԻ.NqM3t  !!!!"""###$$$$%%%&&&&''''(((()))*****++++,,,,----.....////0000011111222223333344444555556666677777788888999999::::::;;;;;<<<<<<======>>>>>>>??????@@@@@@AAAAAAABBBBBBBCCCCCCDDDDDDDEEEEEEEFFFFFFFGGGGGGGGHHHHHHHIIIIIIIIJJJJJJJKKKKKKKKLLLLLLLLMMMMMMMMNNNNNNNNOOOOOOOOPPPPPPPPQQQQQQQQQRRRRRRRRRSSSSSSSSTTTTTTTTTUUUUUUUUUVVVVVVVVVWWWWWWWWWXXXXXXXXXXYYYYYYYYYZZZZZZZZZZ[[[[[[[[[[\\\\\\\\\\]]]]]]]]]]^^^^^^^^^^__________``````````aaaaaaaaaaabbbbbbbbbbbccccccccccdddddddddddeeeeeeeeeeeefffffffffffggggggggggghhhhhhhhhhhhiiiiiiiiiiijjjjjjjjjjjjkkkkkkkkkkkkllllllllllllmmmmmmmmmmmmnnnnnnnnnnnnoooooooooooooppppppppppppqqqqqqqqqqqqqrrrrrrrrrrrrrssssssssssssstttttttttttttuuuuuuuuuuuuuvvvvvvvvvvvvvvwwwwwwwwwwwwwxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz{{{{{{{{{{{{{{|||||||||||||||}}}}}}}}}}}}}}~~~~~~~~~~~~~~~H__vesacon_srgb_to_linear__vesacon_linear_to_srgblong long intshort unsigned intunsigned intsys/vesa/alphatbl.c__vesacon_srgb_to_linearlong long unsigned int__vesacon_linear_to_srgb/home/hpa/syslinux/release/syslinux-3.63/com32/libuint8_tunsigned charsigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)uint16_tshort intGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.debug_line.rodata.rel.debug_pubnames.debug_str.comment.note.GNU-stack4!4'4,4{>: JzKV bL^ | r0}7.ee  >    %alphatbl.c__vesacon_srgb_to_linear__vesacon_linear_to_srgb   ! & - ; B M T _ f m     screencpy.o/ 1207848661 1026 1026 100664 7444 ` ELFt4(=y)*,40<t 1f= < , 4 80fUWVSE܉e4EHE,E5F")čD$xE#EEE#E;0t=0<x.f$O 8f1ɺ]+]9vEEى)]܅uee[^_% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  I  & : ;  : ; &I' II.: ; ' I : ; I.? : ; ' @ 4: ; I4: ; I1X Y 1.: ; ' : ; I4: ; I .? : ; ' @: ; I : ; I!4: ; I"4: ; I#1X Y $1% &!I'4: ; I (4: ; I? < 2dPyintL<^u p)/ plewbS)A! ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ 60#(1   c e#E# T$e# %S# &# G'# W(# )e# +S# ,# -# .# G0#$ 1#AAxf7 8S# 9x# :S# ;S# <# ,=# >S# A@S# .AS# BA# 4CA# kDA# bppEA# ^FA# GA# 7HA# "IA# JA# LA# dMA# NA#! OA#" 6PA## iQA#$ RA#% SA#& TA#' nV#( !W#, XS#0 GZ#2A AA] gi^# mi_# @ ~ e[v$ %# &~# '~# (3# )3#v-3x,pE3tmi453[Jl PO~Q`d1dst_~]src_| _~a~=a~udb~uhc~uldup!le~ef~"@g!sh#3q$%3?xxs~yys~&'wi*,(b(m>p( A sys/vesa../include../include/bitsizescreencpy.cvesa.hstdint.hcom32.hstddef.hvideo.h6#Ydt<Ⱥ>K硑cZg//t<t|  AB FFHPJbPPttduPdu\RQ.P3BP`SaVbWM6v__vesacon_init_copy_to_screen__vesacon_copy_to_screendilog2char_widthversionwin_posoffscreen_ptrsize_teflagswin_off__vesacon_init_copy_to_screen__far_ptr__vesacon_bytes_per_pixeloem_vendor_name_ptroem_software_revwin_sizeoem_datauint8_ttotal_memoryoem_product_rev_ptr__vesa_infofar_ptr_tlogical_scangmaskpage_functionlong long intwin_schemebank_sizeh_resreservedsys/vesa/screencpy.cbytesmemory_planesshort intiregnpixelsset_window_pos__ptrwinnresv_mask_unused_espcom32sys_tunsigned chargposresv_possigned charlong long unsigned intuint32_tmemory_layoutreg32_tunsigned intbmaskuint16_tvesa_general_infovideo_mode_ptrvesa_mode_infoshort unsigned intwin_segoem_product_name_ptrcharrmask__vesacon_copy_to_screenmode_attr__vesacon_format_pixels_twin_numoffscreen_sizewin_attrwin_gshiftvesa_infoimage_pagesv_reschar_heightrowbufcapabilitiessignaturebanksrposbposlfb_ptrwin_infovendor_stringomask/home/hpa/syslinux/release/syslinux-3.63/com32/libwin_grainGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)win_basedcm_info__vesacon_format_pixelsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4d ,%+@ 0 B6> R N b D^   o ~ Qz  >  0^ ".   ,,   8D]wscreencpy.cwiireg.1757__vesacon_init_copy_to_screen__vesa_info__vesacon_copy_to_screen__vesacon_bytes_per_pixel__vesacon_format_pixels__intcallmemcpy )5MV^fmu|%/J !&-;BMT_fqxF '5CQ_m{ (6DR`|$2@N\j #1?M`|     ) .8 =G LZhv    ) ( ,fmtpixel.o/ 1207848661 1026 1026 100664 4816 ` ELF 4(ÐVSƉˉщABKu[^ÐUWVSʼnω։$Fff%fSOuЉ[^_]ÍvUWVSʼnω։$Fff%|fSOuЉ[^_]% $ > $ > : ; I I' II&  &I .: ; ' I@ : ; I : ; I .: ; ' I@4: ; I4: ; I4: ; I?  I!I/ Y\6int!@S@Ie eW@s  Z .t ptr- p-R n-sQT/5' ptr4? p4~ n4sq6T~kA(m ptr@ p@2 n@sPRBZyqCHQp ptrP pP nPs8RRZaqSS_>>haW .k sys/vesa../include../include/bitsizefmtpixel.cstdint.hstddef.hvideo.h-12fjejk=¢k=(p|  #AA  (EAA AA pEAA AAPtt't PR"V"$P$&VR Q %S()t)*t*+t +,t,mt(4P49S9fUfhPhiU(;RZmR(6Q6kWkmQ9HPPTPpqtqrtrst sttttp|P|SUPUpRRp~Q~WQPPK]__vesacon_format_pixelsE__vesacon_format_pixels_listsize_t__vesacon_format_pixels_tunsigned charformat_pxf_bgr24short unsigned int__vesacon_format_pixelsformat_pxf_le_rgb16_565format_pxf_bgra32/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlong long intsys/vesa/fmtpixel.cGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tuint32_tbgracharsigned char__vesacon_format_pixels_listformat_pxf_le_rgb15_555GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!',>]: N9J P^Z X  jf x@ wlO :  0Z .% % `  #/(EGpE   _ |fmtpixel.cformat_pxf_bgra32format_pxf_bgr24format_pxf_le_rgb16_565format_pxf_le_rgb15_555__vesacon_format_pixels_list__vesacon_format_pixels !&-;BIT[fmt ,9F_jnr*?FSx  ( ,D Hh lcfgtype.o/ 1207848661 1026 1026 100664 6004 ` ELFP4(S $$1Z[fUWVS1ɺ ƈ ÈD$ۈ؉t1 1|$Y[^_]à $ > : ; I : ; (  : ;  : ; I I !I/  : ; : ; I8 : ; I8 &I.: ; ' .: ; ' : ; I.: ; ' I 4: ; I.: ; ' I@4: ; I 1X Y 1X Y 1 414: ; I4141 .? : ; ' I@: ; I 4: ; I?  r VR%intdIL^p!&>r6Elewb S ~ A ~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ /0#(1cliEvApSinlepSve> &v%ep%SstiJkinbApSvAk36 et eQ     4+= #  #[#'4+>'3388AAcf8AcfaA?@$@J% GJT&XJTa*TW'VGWa(XWaatad)Gdi+XdiaGip,Xipakp{.{/>0c6 D5Q<P7 6o pci../include/sys../includecfgtype.ccpu.hio.hstdint.hpci.hcom32.h>JW zp<$JN[*tW ll<l<..g !iDNx%Y| 6AC p(8dAA AACXC@tt4t 46t89t9:t:;t ;<t<?t?ttTxVaSiQt tPP  PPP9vpci_set_config_typec__pci_cfg_type oldcfairegoutlpci_set_config_typeshort inteflagsPCI_CFG_TYPE2typeuint8_toregpci/cfgtype.clong long intPCI_CFG_AUTO_unused_espcom32sys_tunsigned charPCI_CFG_TYPE1signed charlong long unsigned intuint32_ttype2_okreg32_tunsigned intuint16_tshort unsigned inttype1_okcharpci_config_type__pci_cfg_typePCI_CFG_BIOS/home/hpa/syslinux/release/syslinux-3.63/com32/libPCI_CFG_NONEnewcf8oldcf8GNU C 4.1.2 20070925 (Red Hat 4.1.2-33)outbGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4  %T+T0TBv> HRyN $^` , j pf ,0 w -) = \f  d0 S .  ` pT 68d,    ';Ecfgtype.ctype1_oktype2_okireg.1778pci_set_config_type__intcall__pci_cfg_type  !&-;BMT_fqxm#p{ ".2FJ`dp{  37CGP _c}  (,0 5? DR^ dq| 4 8` dscan.o/ 1207848661 1026 1026 100664 11944 ` ELF4(@t ~ÐUWVS$M$fk{C 3AAu 3A Au C:Ar:AvF;t$| t$D$1ZY[^_]fUWVSD$T$Ƃ1l$D$ D$ fEƅT$ƂxD$t$ D$ ƋD$ Ɖǃ==t|txFyD$FÍF,L$ʉfJfJf:fBZD$kD$ "ȋL$TD$D$9D$(D$|$ uC uC C F9| D$6$'($"($($(D$<#< G uG C9|2Ņy$Z($J($*($:(D$<#< < $j1_1Iv=w7$$"$Z$J$:$*C$j1…u1ۉk$Z9uT$JW9u@$*yW!9u*$:cW!9u$G C9|\$!l[^_]% $ > $ > : ; I<  : ;  : ; I8 I !I/  : ;  I : ; I8 .: ; ' I : ; I.: ; ' I@ : ; I.? : ;' I@: ;I4: ;I4: ;I4: ;I : ; I4: ;I 4: ;I 4: ;I1X Y1.: ; ' @: ; I4: ; I 4: ; I !.? : ; ' @"4: ; I #4: ; I$ %4: ; I&!I/'4: ; I(I:JQ}\intwLC^ph% e"> ##7#~ ~ ? crS#S#/S#S#A#"c#   idS#r# A#  #r$#%A# "|()#*A#-i /-.# did/e#0e# sid1e# 2e#b3A#/3A#R4# - ~ %3__f$ 5tp4 '%{j&(3did)esid)em*br/  9bus7edev7e8ereg8e:M3"LAL`busNpdevNp`NpdoNphdidOesidOePAridPAaQR3r}n ,>AHK=hj?3 i@3PWF3DPtEC:3PVt__f9!X)"w"}"g"{"b"]"5X fw#3s$Dj%r$]%r$v%rr~&~ !M,:L"N{"O"[Pj"QZ"RJ"5S"T'fUM#V3$qL%r[# y#z3%r~ ~ (~ {[ pci../include/sys../includescan.cpci.hstdio.hstdint.h40. ֢zt3rh | .u}t&ڄ=K=[_fx2ת}=]ufg"K!rf/^$M&v/7DwK&'} <wKOx~ֽP>RVRWVW7V78WUP9U9:PHSS/6S+}R}RRR-Sjfind_pci_devicepci_scanget_name_from_pci_idsget_module_name_from_pci_ids:product_nameresultfilenoskipspacepciaddr_trid_maxlinux_kernel_modulestringfilenamedelimsrid_minlistmaxfuncuint8_tpci_device_listpci_device_countlinepci_devdid_maskcfgtypepci_busvendorfunclong long inthex_to_inthexaget_name_from_pci_idsrevisionshort intsid_maskpci_dev_infosub_vendorpci_scanunsigned charpci/scan.csigned charlong long unsigned intuint32_tunsigned intuint16_tsub_product_idshort unsigned intpci_mkaddrcharvendor_nameproduct_idproducthdrtypemodule_name_IO_filefind_pci_devicecountpci_bus_listmatchsub_vendor_idfcloseGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)pci_device/home/hpa/syslinux/release/syslinux-3.63/com32/libsub_productvendor_idFILEfieldremove_eolget_module_name_from_pci_idsnextGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4: X&`%p+p0p3B > ((RN -^2CqDm -( }Xy . \Mn .  .0."p h%%D (P   /z?H\fpx~X,scan.cskipspaceremove_eolhex_to_intfclosefind_pci_devicepci_scanpci_set_config_typepci_readlpci_readbstrtoulcloseget_name_from_pci_idscallocputsstrlcpyfopenstrcpystrchrstrstrfgetsget_module_name_from_pci_idsstrtok.BL{       ! ! !# (!n" ! ! ! #P"c ! ! ")"<Sp $: ]i n     ! ! ! !%&I y!&!$LR !&-;BMT_fqx+9GUn 2:Vr!,1<ALrw{3B\lq| 1<@HR\gk}'049IMRbfkw{.EJT]afrv{h (,X\readb.o/ 1207848661 1026 1026 100664 4836 ` ELF 4(UWVS št' ttG1 D$f D$fx} ƻ ljff%Ł [^_]% $ > $ > : ; I : ; ( .: ; ' .: ; ' I : ; I 4: ; I .: ; ' .? : ; ' I@ : ; I 4: ; I1X Y 1X Y 1 41414: ; I4: ; I? < tc8intL/B^=KpY eT>gZo"cliEinle pS ve & v%e p%S3inbA pS vAstiJ \ vA pS PA a~P rAZ:be:;;G;GGJ,JZ JZ)JZa3abjAAop!pz" pz)z# z)<$RI<%RIH& )f<'RI<(RI3) m ./pci../include/sys../includereadx.ccpu.hio.hstdint.hpci.hpci.h(;Q b<$tM (XC <l.X` w^| $AA AAC ttt ttt P LUjUUUGjhhZjQQzVWUU\pci_readboldcf8__pci_cfg_typepci/readb.cPCI_CFG_BIOSunsigned charshort unsigned intpci_readbPCI_CFG_AUTOPCI_CFG_NONE/home/hpa/syslinux/release/syslinux-3.63/com32/liboutbunsigned intlong long unsigned intuint8_tpci_config_typeoutloldcfalong long intPCI_CFG_TYPE2GNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tuint32_tcharpciaddr_tsigned charPCI_CFG_TYPE1GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %0+000<Bl> RN b<^  o~) z  I  0i} .  t0 F    "6readb.cpci_readb__pci_cfg_typepci_set_config_type__pci_read_bios 4   ! & - ; B M T _ f q x           A b mqu      & 59OS[_d o ~   %)59B QUos zreadw.o/ 1207848661 1026 1026 100664 4872 ` ELF 4(UWVS št' ttH1 D$f fD$fx| ƻ ljff%fŁ  [^_]% $ > $ > : ; I : ; ( .: ; ' .: ; ' I : ; I 4: ; I .: ; ' .? : ; ' I@ : ; I 4: ; I1X Y 1X Y 1 41414: ; I4: ; I? < Mhc,intL-6^;?pY eH>[No cliEinle pS ve & v%e p%S3inwS p S vSstiJ`inbA pS vA  vA pS S a~P rS~:ce:;;G;G$GJPJ[ J[)n[b3bckAApq!<q{"Mq{V<{#M{V"`$vm@`%vml& )`'vm`(vm3) m ./pci../include/sys../includereadx.ccpu.hio.hstdint.hpci.hpci.h(;Q i<$tM (XC <s .X` [^| $AA AAC ttt ttt P LUkUUUGkhh[kQQ{VWUUpci_readwoldcf8__pci_cfg_typepci_readwPCI_CFG_BIOSunsigned charshort unsigned intPCI_CFG_AUTOPCI_CFG_NONE/home/hpa/syslinux/release/syslinux-3.63/com32/liboutbunsigned intlong long unsigned intuint8_tpci_config_typeoutloldcfalong long intPCI_CFG_TYPE2GNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tuint32_tcharpci/readw.cpciaddr_tsigned charPCI_CFG_TYPE1GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %0+000<Bl> (R3N b<^  o<~M z  m  0} .8 8 0 F    "6readw.cpci_readw__pci_cfg_typepci_set_config_type__pci_read_bios 4   ! & - ; B M T _ f q x           e      -1=AJ Y]sw    +/IMY]f uy zreadl.o/ 1207848661 1026 1026 100664 4816 ` ELF 4(UWVS št' ttB1 D$f ɉŋD$ifxz ƻ ljff%Ł [^_] [^_]% $ > $ > : ; I : ; ( .: ; ' .: ; ' I : ; I 4: ; I .: ; ' .? : ; ' I@ : ; I4: ; I 4: ; I1X Y 1X Y 1 411X Y 4: ; I414: ; I? <  tc8intL9B^GKpY eT>gZo,cliEinle pS ve & v%e p%SstiJ<inbA pS vA \ vA pS ~e a~PreG:ee:;;G;GGJ,J\J\\eeAAjk!ku")ku2u#)u2 <$RI <%RI1&O<'RIm<(RI) m ./pci../include/sys../includereadx.ccpu.hio.hstdint.hpci.hpci.h(;Q p< w(XC <z.Xc RN b<^  o ~0 z  P  0p} .  x0 F    "6readl.cpci_readl__pci_cfg_typepci_set_config_type__pci_read_bios 4   ! & - ; B M T _ f q x           A b mqu      !15HLQ \ ko~  "&:>X\rv zreadbios.o/ 1207848661 1026 1026 100664 3328 ` ELF4(UWVS<ƍD$D$ 1ljىft$4fD$(T$L$ʸD$8tD$0<[^_]% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8 .? : ; ' I@ : ; I: ; I4: ; I \zint2*Ll^plewbSA~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# U*# ebx+# edx,# ecx-# eax.#$ #0#(a1 e @e\ PeQaors@z_ pci../include../include/sysreadbios.cstdint.hpci.hcom32.huYK| $\AA AACPttt tt\t P YV:R"__pci_read_bios\pci/readbios.cpciaddr_tshort inteflagsuint8_tlong long int__pci_read_bioscall_unused_espcom32sys_tunsigned charsigned charlong long unsigned intuint32_treg32_tunsigned intuint16_tshort unsigned intchar/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4\ %+0Bb> RR~N b<^  o ~&z    07 .99   &    \readbios.c__pci_read_bios__intcall@   ! & - ; B M T _ f q x   ;          lwriteb.o/ 1207848661 1026 1026 100664 4776 ` ELF 4(UWVSՈD$t' ttE1 D$L$f ҈D$qf ƻ D$|$ff%҉D$T$ [^_][^_]% $ > $ > : ; I : ; ( .: ; ' .: ; ' I : ; I 4: ; I .: ; ' .? : ; ' @ : ; I 4: ; I1X Y 1X Y 1 411X Y 4: ; I414: ; I? < pQe/intL#D^1Mp[ eV>DqcliEinle pS ve & v%e p%S / vA pSstiJ\inbA pS vA f9 vAP a~o9>l e>??K?KKNNc%cllAAuv8vIvR8 IR!%"%#%7$%U%%/& n ./pci../include/sys../includewritex.ccpu.hio.hstdint.hpci.hpci.h(>Q v< Jt+C X.Q`<yt_| $AA AAC0ttt ttt0 P c R UUlUUUQURKldddVkkt\pci_writeboldcf8__pci_cfg_typePCI_CFG_BIOSunsigned charshort unsigned intPCI_CFG_AUTO/home/hpa/syslinux/release/syslinux-3.63/com32/libPCI_CFG_NONEpci/writeb.coutbunsigned intlong long unsigned intuint8_tpci_config_typeoutloldcfalong long intPCI_CFG_TYPE2GNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intpci_writebuint16_tuint32_tcharpciaddr_tsigned charPCI_CFG_TYPE1GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %4+404IB}t> xRN xb<^  o.~!z  ?  0_ .  l0 I    $8writeb.cpci_writeb__pci_cfg_typepci_set_config_type__pci_write_bios8   ! & - ; B M T _ f q x            b imq ~      #':>C N ]apt  "&@DZ^g {writew.o/ 1207848661 1026 1026 100664 4824 ` ELF 4(UWVSfD$t' ttF1 D$L$f ҉fD$rf ƻ D$|$ff%҉fD$T$ [^_][^_]% $ > $ > : ; I : ; ( .: ; ' .: ; ' I : ; I 4: ; I .: ; ' .? : ; ' @ : ; I 4: ; I1X Y 1X Y 1 411X Y 4: ; I414: ; I? <  p_4intL0>^>GpU eP>^Qk#cliEinle pS ve & v%e p%S /k! v S p SstiJ\inbA pS vA | vA pS y vSP a~oY?n e?@@L@L LO>Oe%ennAAwx8xIxR8 IR\!ri\"ri9#%W\$riu\%ri/& n ./pci../include/sys../includewritex.ccpu.hio.hstdint.hpci.hpci.h(>Q 7]t+C X# ..`<yt_| $AA AAC0ttt ttt0PbRVUnUUUQURLndddVkk|pci_writewoldcf8__pci_cfg_typepci/writew.cPCI_CFG_BIOSunsigned charshort unsigned intPCI_CFG_AUTOPCI_CFG_NONEoutw/home/hpa/syslinux/release/syslinux-3.63/com32/liboutbunsigned intlong long unsigned intuint8_tpci_config_typeoutloldcfalong long intPCI_CFG_TYPE2GNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tuint32_tcharpciaddr_tsigned charPCI_CFG_TYPE1pci_writewGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %8+808IB> (RN b<^  o.~B!z  c  0 .5 5 0 I    $8writew.cpci_writew__pci_cfg_typepci_set_config_type__pci_write_bios9   ! & - ; B M T _ f q x            a        )-CGZ^c n }   $(BF`dz~ {writel.o/ 1207848661 1026 1026 100664 4756 ` ELF 4(UWVS D$աt' ttD1 D$f ɋD$D$of ƻ ljff%ҋD$T$ [^_] [^_]% $ > $ > : ; I : ; ( .: ; ' .: ; ' I : ; I 4: ; I .: ; ' .? : ; ' @ : ; I 4: ; I1X Y 1X Y 1 411X Y 4: ; I414: ; I? < pke/intL09^>Mp[ eV>^Qq#cliEinle pS ve & v%e p%SstiJ<inbA pS vA \ vA pS fB veP a~o9>k e>??K?KKNNbbkkAAtuu)u2 )2<!RI<"RI#7<$RIU<%RI& n ./pci../include/sys../includewritex.ccpu.hio.hstdint.hpci.hpci.h(>Q t+C < v.X`<yt_| $AA AAC ttt ttt P h R PUkUUUQURKkdddVWt\pci_writeloldcf8__pci_cfg_typepci/writel.cPCI_CFG_BIOSunsigned charshort unsigned intPCI_CFG_AUTOPCI_CFG_NONE/home/hpa/syslinux/release/syslinux-3.63/com32/liboutbunsigned intlong long unsigned intuint8_tpci_config_typeoutloldcfalong long intPCI_CFG_TYPE2GNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tpci_writeluint32_tcharpciaddr_tsigned charPCI_CFG_TYPE1GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %0+000IByt> xRN db<^ l o!~ !z | .  0N .  X0 I    $8writel.cpci_writel__pci_cfg_typepci_set_config_type__pci_write_bios8   ! & - ; B M T _ f q x           A b imq ~      #':>C N ]apt  "&@DZ^g {writebios.o/ 1207848661 1026 1026 100664 3376 ` ELF(4(UWVS<ʼn $D$D$ 1ۉljfl$4$fD$($D$T$0T$<[^_]% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8 .? : ; ' @ : ; I: ; I4: ; I U|intD+Ln^plewbSA~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# W*# ebx+# edx,# ecx-# eax.#$ $0#(c1 e 3U ReQveoars@{` pci../include../include/syswritebios.cstdint.hpci.hcom32.huYuK| $UAA AACPttt ttUtPTUCR Q U#__pci_write_biosUpci/writebios.cpciaddr_tshort inteflagsuint8_t__pci_write_bioslong long intcall_unused_espcom32sys_tunsigned charsigned charlong long unsigned intuint32_treg32_tunsigned intuint16_tshort unsigned intchar/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4U %+0B\> RUN b<^   o~'z     092.``   (    Uwritebios.c__pci_write_bios__intcallI   ! & - ; B M T _ f q x   ;           madler32.o/ 1207848661 1026 1026 100664 3708 ` ELF4(UWVSDՉL$ u ЉT$D$d|$ v D$D$ D$T$T$ED$UT$UT$T$ UT$ T$$UT$$T$(UT$(T$,UT$,T$0UT$0T$4UT$4T$8U T$8T$<U T$ : ;I$ > .? : ; ' I@: ; I: ; I 4: ; I  I &I}3x0.BfT%sint2I(/IQbuf0len17 s13T s24T k5n  [q; zlib../includeadler32.czconf.h1u=UKw s| $AA AACXttt tttPFPJ[P>WPm~PPR.U.S>SURQ"...W..V..`..D..H..L..P..T..X..\..d.WhWWSW_Q_PWVSQ)WW[PPP P PPPP P $P$(P(*P*,P,.P.0P0WPm~P.O@OzQuadler32adler32unsigned charlong unsigned intadleruInt/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intcharByteGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)uLongzlib/adler32.cBytefGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4!',>~: | NsuJ L^<Z T k$zv d &  l0F.44h  h     adler32.cadler32   ! & 1 8 C J U \ h {         Hcompress.o/ 1207848661 1026 1026 100664 4792 ` ELF 4( T WVSL׉L$T$\T$D$ D$$D$4D$8D$<t$j8T$dÃu4ÃtuD$É؃@[^_fjt$% : ; I$ > : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 .? : ; ' I@ : ; I.? : ; ' I@: ; I 4: ; I 4: ; I&I.? : ; ' I@B30sBjT%#intT I (O 7 7P  8T U# V7# WI# Y# Z7# J[I# msg]# D^# `# ya#$ b#( 1dn#, eI#0 (fI#4[g Rn#pgeLIt8KI[nr 8In errnu[;Bn >O ?b@u8AIvF zlib../includecompress.czconf.hzlib.hM KKiuvYuh =1.2.1|  ,AA AC\v`K.JPK.CBD @.IPttt tLtLatat*P R WQQ^eSelPlxSxzPzSPStttt tPRQ;compressBoundcompress2compresstotal_instreamzallocnext_outdestLenreserveddata_typecompressstatetotal_outuLongfcompress2compressBoundunsigned charfree_funcvoidpflong unsigned intdummyavail_outadleruIntzlib/compress.cdestinternal_state/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intcharalloc_funcBytesourceLenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)uLongz_streamzfreeopaquelevelnext_inz_stream_ssourceavail_inBytefGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 (0%+07B#> XR!zN h^2qtm p0 ~?   0 .  x` M    $19Dcompress.ccompressBoundcompress2deflateInit_deflatedeflateEndcompressMXm{   ! & 1 8 C J U \ h v         ! / K Y g u           #'+ 0 : ? I N X ] k y           S ( ,X \crc32.o/ 1207848661 1026 1026 100664 7132 ` ELF4(UWVS11) Bu1ɉ1Ҩt1BuAu11 %‰‰‰3 %‰‰‰FuGh[^_]Ã=tWVSÉ։υu1=tD$ |$ 413FOu3ʉ3 3F33ȉ3 3V3%3ʉ3 3F 33ȉ3 3V3%3ʉ3 3F33ȉ3 3V3%3ʉ3 3F33 Ћ 33%3 \93Ћ 33%3w…t13BOu%ځЉ13FOtuރ3Vʉ33F33ȉ33V 3%3ʉ33F33ȉ33V3%3ʉ33F33ȉ33V3%3 ʉ3333Ћ33%3 \93Ћ33%3w…t1ɉT113A9uщ%‰ [^_% $ > : ; I$ > : ;I: ; I.: ; ' @4: ; I 4: ; I 4: ; I .? : ; ' I@  I &I.: ; ' I : ; I4: ; I4: ; I.: ;' I : ;I4: ;I4: ;I.? : ; ' I@: ; I 4: ; I 1X Y 11411X Y I !I/ :>Hint3 3u4,y^c_>Dn`Lbk`L Za> pc  t  S8&>crc>buf8len,cfC > % I f_>crc>buf8len,cfC| 3 crc>buf8klen,1fl?Dx Dx#,}Nxxl`x%   |i  =9 zlib../includecrc32.czconf.hJ Jehp u7g+ X f_#L!Q:6:^H1!=$LK:6:_ggKK$ |  AA AA  AA AC ttt tt'QPQeQ'R'+QOXW'QRQZVS  t tt tt PFSFJP[yP PO\PoqPxSS 1R1V V%ROVR QWQZxRRFrSrRPRP7RMjPRPEPSpxVVSRP-RC`PvRPR,PuPQV*get_crc_tablecrc32get_crc_tablebuf4short unsigned intcrc32_littleuLongfunsigned charlong unsigned intpolycrc32_bigcrc_table_emptymake_crc_table/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intendiancharcrc_tableGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)uLongcrc32zlib/crc32.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %4+@ 0@B> R N ^ j lf 0 w /+. Y  0y.T` M   )   9G crc32.cmake_crc_tablep.1776crc_tablecrc_table_emptyget_crc_tablecrc32  @T%U+:IP]m|(/9Hg !0?FScry />EO^ !&-4?FT`u| -S #'09DH^bktF < @L Pgzio.o/ 1207848661 1026 1026 100664 20580 ` ELFh:4(t7z\ru1t/zlu&BlJh1z8BptB8B<Ðtx\rux<tÃx81Åtx8t@8@<ÍvUWVS Åu@8u @ust>u+C84CPtCTD$1|$ʉ)щCPu"STCPCPCP [^_]ÍvUWVS ÉՅx\w@1@+stK@CH9udCHC C@uGCChC8C)Chu {8uC8{u {8u 떿{8vC8u0C8 [^_]S5u S8tZY[ÍvWVSlj1ÉFu[^_WVSÅu @Pt{tC\CDCCdCCh1҉C8C)CdC)Ch{8uNK )CLCLs ;CL{8u0111CL{8u{<uNjCK )CLCL+C  [^_]ÍvUWVS ʼn׉΅t,~(NtډHuC< u9u~1 [^_]ÐT$HtD$fWVSÉ׉΅tBx\wu $ > < : ;I&  ' I I '  : ;  : ; I8  : ; I8 .? : ; ' I : ; I.: ; ' I : ; I&I.? : ;' I@ : ;I: ;I 4: ;I: ;I.? : ;' @ .? : ;' I@4: ;I.: ;' I@4: ;I1X Y 1!.: ;' @" #4: ;I $%I&!I/' U(.? : ; ' I@): ; I*4: ; I+1X Y ,.: ; ' I@-: ; I.4: ; I /4: ; I0!I/ 1.? : ; ' I@ 24: ; I34: ; I? <  C+06i%] Ssintl)s}(SErE   O  iP ' 8TU#V#$W#dY#  Z#$[#msg]#=^#Q`# a#$b#(;dZ#,e#0`f#46 RZ#g'2 /t78%#x9Z#8:Z#<6;/#@<5#Dd=5#Hcrc>#Lmsg?#P@#TAZ#XB6#\C;#`inD;#doutE;#hFZ#lGZ#parHCUH__pT__sTH__nTH__fT/.%Z__f$/-OH__pN__sNH__nNH__fN/6/5Z__m56_ZCtcZ60Rs_BmZDht604s_ht60Ps_& E]60J&m s_ZZH(60xZlenLZs_Mz  u j _!lZ__fk/4Z%$60hZs_errZ!zk(H6/x nZ+C:Z__f9/"fZH>se_verrgZzx 7XZ/60#errZWs_u50Z06-0buf.len/S3s1_rMZg=  u j _Z60sAZ60%cZ8#cc}{yYZ K6X0X$#bufZ_#va[=tlen\Z%6&s ~Zs_     ^ Cs_oxcZ! W"Ds!_ #Z*$ZHlen%fc&Zh/     Z60? buf] lenS s__  d5 ' n `l        % 3| 60 buf lenZJ b a Z 60 #c}{( QZ h )60 )sZF ) Z *s_ +M/ <   u j _, `0h )]S)^q-fd_Z*erraZ.sbZ/ cZ0*pdd*se_.f *mg+[ `   % 60O( 0  -fdZJ)~. \% 601G 0 t))%W Z02-b G 3OZ% 0 3:( t  zlib../include../include/bitsize/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includegzio.cstdio.hstddef.hzlib.hzconf.hstdarg.herrno.hzutil.h1K===J K^KgYv+ɟ=}"Z{tNgvKgivhkYhZLtt1:j{J[ؼgxK}tfLvjLjL/;Y|/\h|fxvggggpffrtYtggIpt=Lfyh!}ggg~=Kv#Z=twyz X=Y~t==YʽK?2ʃ؃u1f"Kz .=>=/==u=a$Qh=/=/=>}t[Y==?}=KuZggghh!>yuguA"K.6t0ʠ=R?}fh~fuvwg;Y~ uuuuuuuuuuvYv"ב>vN0_ɓv<X>Mi"u!ot: 1.2.1%c%c%c%c%c%c%c%c%c%c|  C D$ h$AA AAC $HAA AAC ACV A( AA AHAA A GACs ALA0AA A &AA AA&C ( kAF Y E N.M Z.gAC` A$OAA AAC D>AA A$AA AAC $KAA AAC "C  XAA Ah bAA AACpS|BEABBK. JpE.e|BL.HpL.@tBxB|BBBBBEBEA@.0OpD.0 8AA AC0M4A8E FRN N^2'q\m Np ~(#4 LP5  TP506UU9.99P> `B H( H!g*O2D>?h b  GCPD$Vhairw~G0&& k  -K4"; XGUcqw 8 gzio.cdo_flushputLongdestroyget_bytegetLongcheck_headergz_opengzungetcgzeofgzclearerrgzerrorz_errmsgfreemallocstrcpystrcat_fwritedeflategzflushfputcdeflateEndinflateEndcloseerrnogzclosegzwritecrc32gzputsgzputcgzprintfvsnprintf_freadgzreadmemcpyinflateinflateResetgzgetsgzgetcgzsetparamsdeflateParamsdeflateInit2_inflateInit2_fopenfprintfftellgzdopensprintfgzopen ', 6 !"7$cw%&'(c!"+ *T/{*(0(`(|0(H2h0(0(3 +<4G+t+118 !  +. @   9    :? (U ;  < =  ?*[ 8 !&7>ITbms~,4BP^lz &1=HP^lz!<CS!-1BGkw{ 1=AEJUZeuz /9AEINYgu $2=IMQVaq  .GSW[`o ' + / = K Y c k o s                # 3 A F Q V a j x              + 7 ; ? D O g r v z                  ! 0 5 D N [ h m              ! ) 3 8 B X h  (,8<HLpt <@`dtx 04X\lp PTuncompr.o/ 1207848661 1026 1026 100664 4036 ` ELF4(WVS@׉L$T$PT$ D$D$D$(D$,t$8ÅuCÃttu|$ uD$؃@[^_% : ; I$ > : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 .? : ; ' I@: ; I: ; I 4: ; I 4: ; I&Ik+0WBSTv%intK Io O 7 7eP  w8T oU# V7# WI# Y# Z7# A[I# msg]# ;^# `# ba#$ hb#( 1dn#, eI#0 (fI#4[g Rn#Yg]nRE ]Xcv!I err nui[lE zlib../includeuncompr.czconf.hzlib.hKKigLYu2hY 1.2.1|  AA ACPttt ttPRW7QEISIPPP\S\^P^vSvzPzSouncompresstotal_instreamzallocnext_outdestLenreserveddata_typestatetotal_outuLongfdestunsigned charfree_funcvoidpflong unsigned intdummyavail_outadleruIntuncompressinternal_state/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intcharzlib/uncompr.calloc_funcBytesourceLenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)uLongz_streamzfreeopaquenext_inz_stream_ssourceavail_inBytefGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 (%+0Bo> RBpN ^2q8m  ~!   0.l @  6    #+uncompr.cuncompressinflateInit_inflateinflateEnd8?Q_   ! & 1 8 C J U \ h v         ! / K Y g u             " , 1 ? X R deflate.o/ 1207848662 1026 1026 100664 26088 ` ELFM4(VSӉ΅t$PtH!f1[^fVSXp HT X[^VSÅtw@tpp*t qtu[PtC(S$CP5-x t8uxu{ut F~3C $k {*5{SCCDCDCDCDCDCDCDSKC| uH~1CDBCCq111K(!C|~1҃ƒ1  {dt CqQT$ȿ1)T$T$[{dtV2JV0?111F0{t~u~u ;,$uC=u~tFl~u{luV=kK| H@wCtu ~LJuUu . j11҉uKD{U0EdLfB @fE`MdETy1U0 )1ۃ|$SEdETEExu|$u ؍D1[^_]UWVSʼnT$D$}lw$El=w |$7}lv6E0udT0MPE@1#ULU@}<WM,!E8fH\$f4W|$tAUd+T$E$-9w. T$uJuT$EXEXMdPf+Mhf ^CIffw ff H9D$Ul+UXUlEX;Exw`v[HEXE0D$ MPL$udFudD$ T0E@L$1#ULU@}<WM,!E8fH\$f4WEXHEXuhEdEX]0UdE@MPT1#ELE@@E0f^SfH9D$MlEd|$MdETy1U0 )jEdETE-ExZMdETy1U0 )1ۃ|$SEdETEExu|$u ؍D1[^_]ÍvUWVS ÉՋx v{lw{lu ClCdClKTCdt9rB)ȉClKdCTy1S0 )jCdCT&xsdKT)ʋC$-9gy1S0 )jCdCTx.SKdCTy1S0 )VCdCTxu u D61 [^_]ÐSÉэBT A?…tCtx(uxHu[[fWSDžxx x$@@@@,XCCCCy؉C{G*C{u 111 111G0C C$C4KD{ : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ; : ; I : ;  : ; I : ; II!I/!I/  : ; ( .? : ;' I@: ;I.: ;' @: ;I 4: ;I.: ;' I@: ;I4: ;I 4: ;I!4: ;I".: ;' I #: ;I$: ;I%1X Y&1' U(41)4: ;I*&I+ , -.: ;' ..? : ; ' I@/: ; I04: ; I14: ; I2: ; I 34: ; I 44: ; I? < 5!64: ;I? < 74: ; I?  :480LBGKT%Sint4 Ou u 7 7P  u u 8T +U# KV7# WI# Y# Z7# m[I# msg]# :^# `# a#$ bu#( dn#, FeI#0 fI#4[gR Z# [n# (\# _]F# ^# _n# 3`n# a%# b%# cn# g7#$ ph7#( i7#, k#0 4uF#4 FzK#8 /K#< 7#@ 7#D ]7#H "7#L |7#P Q#T 7#X %@#\ ]n#` 7#d Q7#h 7#l 7#p 7#t 7#x n#| n# _7# un# X# p# b# # w# # # AŠ# n#( n#( Q̱#( F#- 7#- 7#- )#- WF#- F#- 7#- xn#- )#- n#-g@i uch"00#ush$4%)ulg&Tp:;)<)>dad?)len@) v9 fc=Q# dlAp#wB-I I n# g K L# Mn# N$#PosQ)sR*SB5Eii<Gi<i&)ini<i<;AS~iF,H, , n  z {)# |)# })# ~)# X#o2n6,@nJn~ 8Xs,Pb7RP5nXn5G T^7Hs\,]@_BPN`"a  lenbn2 cnPudnTe@cFjK\k7`hudv%w% 7]s,1@ONm" lennh( n`w@t!ds,!ss,#b 8  lenB" n#$buf#(B!lenBB SG\%sF,u nHB mHB pIKJB/;K7c%b & & &t '(  j=n\Xv:]; T<79!s>,L?7m n@7)A@ *[q  nX   nF_n!s,+V m  8797,p s *n   e n n !s,)X errn  g 0 se, fn h@\)in+ @7`, ( len )O +  cc , cc [0  s,z n @dnh+A len/ /) ,W ccT _ s, n F FjI`/OIx!s,I-)>6$s5,|gnf sh,7%?&.9nU//n/n/n/JnX/nx/9/n0s,13n1#[?*g.n4//n/92ni 3@*9i 4(*56**6+*&gi4758*] zlib../includedeflate.czlib.hzconf.hdeflate.hzutil.hgggYX/hػKZ}uL=g===ght+<X==D=hg@g>0}JZYK/>.iY  Ky8KM=B=0%$ʠ/g?$u?y uuggu%v =Y[ugɭɭ3x=}4"Y=ɠY uMg6vܭɃ #zK|L3uuvF72==%u=h7vR~ uMg6 Ƀj"u5=u <:=>LR~5ku4gwYY=:;My]$/Yfw&uv=uhuZvt\ɠuuuu|Y~t )uguvLiU!=0==hK"=Zu׼uL/s=M deflate 1.2.1 Copyright 1995-2003 Jean-loup Gailly 00 0       | 6AA 8 AA  XAA C $AA AAC4 AA AA$`cAA AAC  IAA CA $LAA AAC0$\AA AAC 4XmAA AAC Y,B0F.H ].$ AA AAC H AA AAC01MPSXPZV`atabtbct cdtdgtgt `qPqyVyPV`RRUUttt  t  t P V Sttt tt\t0 P YV$EQV|QQ Q0Q?\QbhRjmRRRYwPwP$WPPTZP[U\]t]^t^_t _`t`ctcXt \PSGTS\qRqURUGWUWXR\qQq)VGUVUXQSGUNWUXYtYZtZ[t [\t\_t_ t t, t0 t XPVP VXkRkUR U R ` `PQRRR R R R t t t t t  t  P p Wp u Pu } W R V R | V|  R Q ~ U+ - Q/ p Qu  Q t t t t t t0 t< t Bt0BFtdeflatePrimedeflateEnd deflateCopyB deflateSetDictionary deflateq deflateParamsdeflateBound)deflateReset|deflateInit2_DdeflateInit_&deflate_copyright4strstartbest_lenwindowstat_descoverlaynext_inwrapflush_pendingprevavail_indictLengthold_flushfinish_donenice_matchzfreez_streamopaquedyn_dtreew_sizepending_outlimitlevel_flagsBytefdata_typedyn_ltreez_errmsgfreqheap_lenmax_lazylookaheadputShortMSBdeflateInit_hash_maskcompress_funcstatebitslong intscanfill_windowpending_buf_sizew_bitsct_datadeflatePrimestream_sizeblock_startdeflate_fastins_hmax_chainmax_startscan_endmatch_lengthbl_descleveldummyreservedw_maskl_descdeflate_slowvalueblock_donedeflateParamszlib/deflate.cunsigned intlongest_matchbl_treedeflateSetDictionaryconfig_sdeflate_statedyn_treelong unsigned intwmaskbstatecur_matchstrmdestLenmethodlongest_match_fast/home/hpa/syslinux/release/syslinux-3.63/com32/libmatchsizestatic_tree_desclm_initadleruIntdepthopt_lengood_matchdeflateBoundd_descfinish_startedscan_end1prev_lengthbi_validheap_maxstatic_tree_desc_sdeflate_storedblock_statedeflateInit2_windowBitsversiondeflate_copyrightsourcealloc_funcpending_bufwindow_sizemax_insertuLongmatch_startmatch_availabletotal_outdesthash_shiftmoretotal_inhash_headunsigned charnext_outfree_funcmatchesinternal_statebl_countpendingmax_codez_stream_sdeflateCopysourceLen_length_codeavail_outd_bufheadvoidpfwsizeheapl_buflengthcharfuncdictionarystrendconfigct_data_sread_bufmax_chain_lengthByteIPoszallocbflushgood_lengthshort unsigned intbi_bufdistdeflatestatic_lenflushmax_block_sizeconfiguration_tablecodestatusprev_matchuchfdeflateEndz_streampmemLevelneed_morehash_bitstree_desc_sPosflast_eob_lenlast_litmax_lazy_matchdeflateResetGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)lit_bufsize_dist_codestrategynice_lengthlast_flushheaderhash_sizeushfchain_lengthGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack44 V%h+h0hBH>> X R+N Xdb. ^ `dP nX/j d  {p2%D eiE  eE 0E,L.MMQ  U 8 %8IFLR@x f s0O  6X`c\Xm  $/?`:LZ1gpF~5 deflate.cputShortMSBlongest_matchlongest_match_fastflush_pendingfill_windowconfiguration_tabledeflate_slowdeflate_fastdeflate_storeddeflatePrimedeflateEnddeflateCopymemcpyadler32crc32deflateSetDictionarydeflatez_errmsg_tr_align_tr_stored_blockdeflateParams_length_code_dist_code_tr_flush_blockdeflateBoundcompressBounddeflateReset_tr_initdeflateInit2_zcalloczcfreedeflateInit_deflate_copyright/?O]F "d @ "z  # $  % != G T a  & ' ' (I((5&N'^'(((('(*;,dn{+.?/",-*+ !&18CJU\hv#?M[iw+9GUcq '5CQ_m{.=L[jy5<Ze6ARj7?M[iw#'+0;@KUaeiw|  ' 2 7 B L X \ ` n s ~                 # - 5 9 = B M ] g u                6 H T X \ a l q |                 - 1 6 A F Q W [ ` k w                   " 1 A E J Y ] m r }               ,1<BFU`lpt /;?CHSajn %*4JUY]blq{'41jHT`lx48PTtx 48\` HLtrees.o/ 1207848662 1026 1026 100664 29524 ` ELFZ4(1fDŽBuf1fDŽ Bu0fDŽt BufǀǀǀǀǀÍ ǀ  ǀ$ t ( ǀ0 (fǀǀǀ0UWVS ÉՉϋT D$ t4$n}7BD$T T fDf9DruP:PwT$T fD4$f9r)ut$P:PvT ;H~D$T [^_]ÍvUWVSÉT$L$fBft  T$|$fDD$$1l$|$flfl$B9}9tu9} ft /t;$tft f   f f f|$u $1Ҿ9u$1Ҿ$1ҾD$|$9|$Y[^_]ÐUWVS ÉT$ $fBft  D$D$ 1|$ l$f|f|$ l$x|$9} 9l$9T$D$l$v )9D$t ~U fSC KfD S+ff L$|$]|$9t$l$v )9D$t ~U fSC KfD S+ff L$ )9 ~U fSC KfD S+ff |$w~T fSC KfD Sƹ+ff |$  )9 ~U fSC KfD S+ff  |$w~T fSC KfD Sƹ+f f  )9 ~U fSC KfD S+ff  |$w~Q fSC KfD Sƹ+f f f|$ ut$D$l$9l$ut$D$t$D$D$ D$D$D$<$9|$  [^_]VSÉ֋f4B @u f;Vfw  f H9[^ÍvUWVS$ÉT$L$$D$T$fPfD$D$BT$f|$uft$z)92 fSC KfD S+fPt$t$ D$z)92~U fSC KfD S+ff t$ < t$D$ +4)9~X fSC KfD S+ff D$HD$=w D$t$z$)92~S fSC KfD S)$ $ff < t$+4 )9~X fSC KfD S+ff t$;D$D$x)9T$~U fSC KfD S+ff t$F$[^_]ÐUWVSTƉT$D$Bx džHdžL=1D$9\$f<t"H@HT Ƅ2PT$ D$fDB9|RPH|$~1 D$@D$T \$fƄ0Pt D)H~T$D$PH؉љًT$KX HT X HHT$VX LP LT D$D$ L$,ffEL$f3P2P8rA@7Pf}\$ f{X T$H~G : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ; : ; I : ;  : ; I : ; II!I/!I/ &I.: ;' @ : ;I 4: ;I.: ; ' .? : ;' @ : ;I.: ;' @: ;I4: ;I 4: ;I !4: ;I"4: ;I# $ %4: ;I&.? : ;' I@'.: ;' (: ;I): ;I* +.: ;' I ,1X Y-1.41 /4104111X Y213.? : ;' @4 51 64: ; I 74: ; I?  g4sL0B~TH%s5int AO 7 7)P  i8T 1U# CV7# WI# Y# Z7# [I# msg]# "^ # `# a#$ b#( d#, eI#0 fI#4[s ;R hZ# [# L\# ]^# ^# v_# 9`# a%# yb%# c# g7#$ ;h7#( i7#, k#0 u^#4 >z#8 #< 7#@ 7#D 7#H 7#L 7#P g#T 7#X #\ #` 7#d 7#h 7#l 7#p 7#t 7#x #| ~# 7# # # # ## 7# 7# 7# J# # Ɔ#( dž#(  #( #- \7#- 7#- ##- ^#- m^#- 37#- #- IA#- #-gi%uch"0#+ush$L6%Aulg&T:;Adad?Alen@A 9 fc=i# dlA#_BI 7I ay5# z@# {# B|# }# n K 9Ln# `M# 'Nt#XO7PosQARSB-<<&A <+<6S+;Fz~lts~Pn)lts~~)}<s~nkvdjs~`n~`nh X!:" R"" s~fn`nX"!:"9"Y""# len$7%val# Slen$D%val# Wlen $x%val #D W%len $Bval #x hlen$%val# b%len$Mval# blen#$}%val$T%len$Dval6&[  QTs~\BlcBQ 2T? s/~0n51nT"\3Bslc4lx5B`"6B"7##  len=;$ %val=#W # lenBY$B %valB# B %lenF$ 3 %valF# j lenLl$ %valL# %lenP$ w valP$ ) lenZ$  %valZ' (s~) !n!`!5!@!0!%h%n%m!(!%fA!z'N*D)An)`B)JC#!tE!FA!(G%nH*%lenX+xB)vB(lenw%resyBQxm@ Lsk~l  nn"o5?"BpRnqpmq"`r 6sW, (-8 -. $(.D D.P @.\ .h .t / 0 0 0 J 0 h 0 / . 1 D2 - - $D.L00 0)Y 05w $=/@1N.[2l 2` $.0x yL s~ 3bl} s|~s #8%len~$#%val~#8len $\%val#5N%len$9%val$N%len$`%valb@ s~ '(s~(buf(lenB)g3g@# sc~< bufdp e^ eoff #UN%lenh$Y%valh1m-2 --' f(se~%ng!hB!iB+p$(s#~!%'PH(sF~)G)G)hG!I4K%lenO*%valO4k%lenP*%valP4%lenQ*%valQ*%lenT*%valT3$ s~h buf ^ eof "^"^8",oN-$N000, -$ /#\%len$gvalG#C%len$3valp1Zq5d5h2-$Zq0#fZ/0$k0=#?/P$/0]#?/p$Q0}$@/$!0/6P<  6m? 36BD #Y+6EjI6So6@6*v6{ 6Z6B6(++7~f=S+7IeBtf zlib../includetrees.cdeflate.hzlib.hzconf.hzutil.htrees.h2Y!==[ 6XɭD9*wsJOB%KKKɑYw>o$< Pz Li8gLhA6 fK//ftzXYuz|gY <=اt$F(0hgk~uu`v=)hLgr%YבYg"Lw H&  W?uY{<t=$Y/v}.szmyv=&K0}.lu "}t/f]!//~~/1  j~A!aQ1q I)iY9yE%eU5u M-m]=}   S S  3 3  s s    K K  + +  k k     [ [  ; ;  { {     G G  ' '  g g     W W  7 7  w w     O O  / /  o o     _ _  ? ?     @ `P0pH(hX8xD$dT4tC#c            (08@P`p   0@`  0@`|  l ld$AA AAC $AA AAC($DAA AAC4AA $TAA AAC8$@ AA AAChLpA("AA AAC`A @AA AA4${AA AAC$(H.F$ .R"*R4lRlPttt tt}t PySR|UQ{W{}QR}httt ttt(PSR`Q\PuWVVQQttt ttt4PSRPRPQL5VVWvVWVb{V`oV}VV\hP%`PWkPWvPbpPPPQQQWdQWbQmoQQQRMRRDRRBRRMR RDR WTW^W^W"BPTPoW-MPTPiW'DPTPttQt POSR V PRTUtUVtVWt WXtX[t[? t8TzPz; STrRr? PTrQr? LzG dG H P Vz \ n VzzUzh 7 UZ \ Uj  U UzW 2 W u W Wz2 Wd W2 Wu WS j P = W@ A tA B tB C t C D tD G tG Lt@ O PO V=IV@ q Rq LX 1 Q[ WWq R  R6 P SP S Ry  P  P  PU=KURR?]RWRPP[]S]sPPP?ZPZ_R`hPRP=HSRR]RRQ>LQPP>LPR=LRJWR9SQLQIVLMtMtLUPUSttt ttttP#V#(P(V?Ut@tP?S@AtABtBCt CDtD#t@[P[VP V@YRYWW@TQTU"U@YYS#S$%t%&t&'t '(t(+t+?t$?Mt(Mt$$7P7WPW$DRD`$DQDYUuUU$DD\'Q,AQRZQ'R*ERR}RRR3RR/gRR!VR'V.DVuVVLR`QN'S.eSS|SSPPuwP3PCNPYUUQVPP/P?LPPP!(PAXPcSk_tr_init _tr_tallyy_tr_align_tr_stored_block_tr_flush_block+_length_codeS_dist_codestrstartset_data_type_tr_flush_blockstat_descnext_inwrapprevavail_in/home/hpa/syslinux/release/syslinux-3.63/com32/libnice_matchzfreez_streamopaquedyn_dtreeinit_blockBytefgen_bitlendata_typedyn_ltreestreestatusheap_lenlookaheadnextlenbase_disthash_maskpending_outstatebitslong intnodew_bitsstatic_d_descsend_all_treesct_datablock_startzlib/trees.cmax_countins_hstatic_lenbbi_reversecountw_sizematch_lengthmin_countbl_descprevlenscan_treereservedw_maskascii_freql_desctr_static_initunsigned intbl_treedeflate_statedyn_treeelemslong unsigned intstatic_l_descstrmextra_dbitsmethodrankstatic_dtreelevelstatic_tree_descpending_buf_sizeadleruIntdepthopt_lendtreed_descextrawindowopt_lenbbin_freqltreestatic_bl_descheap_maxstatic_tree_desc_sbaseintfcurlenalloc_funcpending_buftree_descbi_windup_tr_alignpendinguLongbi_validmatch_startmatch_availabledescsend_treetotal_out_tr_initprev_lengthhash_shiftgood_matchextra_bitstotal_in_tr_stored_blockunsigned charnext_outfree_funcmatchesinternal_statebl_countstatic_ltreemax_codez_stream_snext_code_length_codeavail_outdcodesd_bufheadstored_lenvoidpfheapl_bufbl_ordercharct_data_shash_sizemax_chain_lengthBytepqdownheapextra_blbitsIPoszalloc_tr_tallybase_lengthshort unsigned intbi_bufextra_lbitsdiststatic_treestatic_lenbuild_treecodefreqwindow_sizemax_blindexprev_matchuchftreecharfz_streampxbitscompress_blockextra_basehash_bitstree_desc_sPosflast_eob_lenlast_litmax_lazy_matchgen_codesGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)lit_bufsizeblcodesbuild_bl_treestrategybi_flushmax_length_dist_codelcodeslast_flushheadercopy_blockushfoverflowGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.rel.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 b)<% Tc(/4FkB |cVO3xR dr b5l nL@j lr {BB^R  IN Yk z           $ )  5  @ E  P U  ` e  p y }                * . > I M ] b f }                 # ' + 9 >  I `  h l p ~                 ( , < A E \ ` q u                %  9  E  Q  ]  i  u            * S a         /3EI  ,5:>GV ^bft  #6:KOg osw    !*.?CZ^o              ! ,9=JNW`ix| %/3<EISW`koy}  4 @Z f        , 9%T a&s(,8<`d 48`dx|zutil.o/ 1207848662 1026 1026 100664 4044 ` ELF4(fU f)‹Ðʉ% $ > : ; I$ > : ;I .? : ; ' I@  I &I .? : ; ' I@ 4: ; I : ; I .? : ;' @ : ;I: ;I.? : ;' I@ I!I/ 4: ; I?  2Mb&>;int4 _t E $3t %3 t errL 9 't7Sptr8S&gZ0S(2t-S9.,L/,_ww  g^9 zlib../includezutil.czconf.h ./xf 1.2.1need dictionarystream endfile errorstream errordata errorinsufficient memorybuffer errorincompatible version!"-:EYf!|      ( P "P 'R(-P(2R(2QbhzlibVersionzlibCompileFlagszErrorzcfreezcalloc~z_errmsg2zcfreeshort unsigned intzlibVersionunsigned charvoidpflong unsigned intzlib/zutil.czcalloc/home/hpa/syslinux/release/syslinux-3.63/com32/libitemsunsigned intflagscharzErrorGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)uLongopaquez_errmsgsizezlibCompileFlagsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack42 %h+h0hB> XRbN ^2x{q( m P }(dy dP rf d  0.  @ Q    &-( 6 =B( Jzutil.czlibVersionzlibCompileFlagszErrorz_errmsgzcfreefreezcallocmalloc#. !&-4?FTbjuy   +/7B GR Wb xF  $ ( ,8 <H LX \inflate.o/ 1207848663 1026 1026 100664 24736 ` ELF0N4(tePt^B@@@BB B B$B0B4(BdBHBD1øÐVSÉ֋T$88t}C{ uC C({$uC$C(S …uXCy @@B/FvC(S$CrB,Y[^Z[^ÃQѺSÅt.@t'K$t P,tC(ыSC(S$C1[Z[ÍvUWVSƉՉϋ1# +8uBt1 )ЉC9tvԉ[^_]ÍvUWVSDžpxu~4w >t?N4f0f41F0An0n4~4T$ wF`F`BOF`5)Goo~`t_o_ 1[^_]Åt@t8 t1Ãx4øUWVS D$Ӆrz z$B(׉Džt+~,t,NC(S tC(S${18ڋD$((FD)ȍGDFH)ȍGHFd)‰WdtFV,ىo,D$x1 [^_]ÐUWVS ʼn֋X{,u#K@(U C,u{ uKC C(C$+uK 9rC,U )C(0C()9U wMC,))tC,U )s(C C(C(;C uC(C$;C sC$1C,)ʃ [^_]ÐUWVS ÉՉυpt}> ux111;Ft]St B^ 9vF,T=)ډF F$^,)~$F 1 [^_]fUWVS|D$T$ ]pRx H8u x9> u D$@ D$8T$RT$@L$ L$4\$[\$d~0n4\$$D$HVu+ ҃|$<L$|$<L$|$<KL$w-L$D;Ht$T$DD$tD$H|$d\$+{\$DD$+XxX^~t.t*~P Ft )ډ )ډFT$B0~Ѓ@1҃> F4ЋL$A,ut|$ u=|$Hu6D$H,D$H")D$RF8)D$RF8D$H|[^_]% : ; I$ > : ;I$ >   I' I I '  : ; : ; I8 : ; I8 <  : ;  : ; ( (  : ; &II!I/.? : ; ' I@ : ; I4: ; I.? : ; ' I@.? : ;' I@: ;I4: ;I.: ;' I@: ;I 4: ;I !4: ;I"4: ;I#!I/ $.? : ;' I@ %.: ; ' &: ; I'4: ; I (4: ;I ) : ;*1X Y+1x l09BT%int1  Ou u 7 7P  u u 8T iU# QV7# WI# dY# Z7# [I# msg]# B^# `# a#$ bu#( dn#, KeI#0 fI#4[g]gi0 op0# 0# val#)OSy+ /  b D LENmLIT?BADMEM7|Q R# Sn# Tn# Un# Vn# >WT# QXT# sZB# W[B# \B#$ ]B#( 2^#, `T#0 aB#4 lcB#8 8dB#< ffB#@ h#D i#H ZjB#L 4kB#P vmB#T =nB#X oB#\ !pB#` q#d r#h s# %t# ?inot\hBjynp@\}n~nynBgn@T6\nyn J>nT\=B?v B!|vXbuf}len~B gotBR!BBn\6"lenB"inT"outT bufhB0#$?Snt\BnaSU!B!&!22n-\0}out1B!B3!&4B!4BzNnb)\KyLHM7BO"idPT[%&B' L @'Wa ;  nd\1+nQB("putq!!B(EB!T!B "in B "out B !&!B, !"^q#$"len%BU ret&n(u(hj)&*(  +(*v L ; a #Q v #f n zlib../includeinflate.czlib.hzconf.hinflate.hinftrees.hinffixed.hKuguuuuuu"Y5Kuguv"=KuMg=u/;P=Jh#Y7ti=y  00[YguKGu=/=ugYu%0LgLHM3gKu=Yx?gwgux=uɔuuK=[v [u>Y{,Au(u&=>K)=uu));)))=-hKYKK>h˻YKKh˻YKKh)N(-g2Khg)Kx|uuuth˻)Y@=˃KKKK)Yu=hu)ucI=u#uu.u&'?0K00ɭUf1=u.ugu$uh%61%w2&hNvKgh(wi1u&9&hugh(vhuKu/[ugKK)u=K+5/h%YP%=1===*"~*KK 1.2.1incorrect header checkunknown compression methodinvalid window sizeunknown header flags setheader crc mismatchinvalid block typeinvalid stored block lengthstoo many length or distance symbolsinvalid code lengths setinvalid bit length repeatinvalid literal/lengths setinvalid distances setinvalid literal/length codeinvalid distance codeinvalid distance too far backincorrect data checkincorrect length check WV? }  9 T rk6     A@!  @a`10  @`Psp0  ` @ X ;x8 h( H T+t4  d$ D \ S|< l,  L R#r2  b" B Z Cz: j*  J V@3v6 f& F  ^ c~> n. N `Qq1  a! A Y ;y9 i)  I U+u5  e% E ] S}= m-  M S#s3  c# C [ C{; k+  K W@3w7 g' G  _ c? o/ O `Psp0  ` @ X ;x8 h( H T+t4  d$ D \ S|< l,  L R#r2  b" B Z Cz: j*  J V@3v6 f& F  ^ c~> n. N `Qq1  a! A Y ;y9 i)  I U+u5  e% E ] S}= m-  M S#s3  c# C [ C{; k+  K W@3w7 g' G  _ c? o/ O |  o pAA C M@CA G.ITAACz A EAA AA$AA AAC$ $$AA AAC $AA AAC $AA AAC ldAA AAC$JDDG.L@DDASbMDDQT.]PinPpqtqrtrut u0t0=t =@tpP1S17P7>Sp}R}2V7?VpQ#Q7@QpR77<R<@@CtCDtDTt TTt@PP@KRKPQ@FQTUtUXtXtt tTaPaSttt ttPVPVRUQWQSttt ttt$ P W.P.WPW,VQf{P}PjUUSSPPttt ttt PhPhRSRSSRelRBERglP;=UNUUttt ttt PUR+V+8RHTRVS+dVdVVMWttt ttbt PSUZPZ^SRaUabRQ`W`bQPPdeteftfgt ghthktk t t t t t ttttt2t2?t?CtCGtGXtXtdPd{R{~XTWPaWWW WjlWWe We P PQ W5PgP)+PQxPPWP1U<KUWUJUVU U r U} J UV U U % U1 'U3UU`UU!U!5QYkUkQDU?UKU>UJUUUUGWW,Q<PQQQ3KQWQQQ&JQV|QQQ Q$ t Q Q  Q B QZ m Q} Q Q  Q2 J QV i Q Q9 d Q Q % Q1 QQrQQQ?QKVQeuQQQQ "Q26QQQ Q Q!ZQtQQ6CQRSQS QRS~PSPSRRSR,,R,aSaaRRS&&R&ESVVRVcSRSRR S  P  R  S$ 9 P9 9 R9 B ST T R R S R R  S  R  R 0 S0 0 R< S R R S R E SE E RV V RV S R R S R, < S< H PH J RN P RV b Rb h S S R S RT T RT W SR+5RuRSRrrRrSRSRSPSRR!SkkRknSRSRSR*2P2;R;;P;=RZ\StPSRSRRSRRSRRSRP66R6CSCCRSPSRRSPS,Q<PQQQ3KQWQQQ&JQV|QQQ Q$ t Q Q  Q B QZ m Q} Q Q  Q2 J QV i Q Q9 d Q Q % Q1 QQrQQQ?QKVQeuQQQQQQQQ6CQQQQQQ| inflateResetinflateInit2_inflateInit_inflateEnd|inflateSyncinflateSyncPoint?inflateCopyinflateSetDictionaryinflateopaqueholdinflateworkByteftotal_outFLAGSDICTdistbitsnlenstatedictLengthinflateSyncPointnext_outDISTEXThbufinflateSetDictionaryCODELENSwrapmodedistfixinflateInit2_NAMELENGTHuLongwriteinflateCopyDONEBytedictionaryTABLEzlib/inflate.cdistcodeDISTbitsMATCHordercodesflushvoidpfoffsetCHECKleftinflateEndsourcestrmdestextralengthwbitsEXTRAunsigned charLENLENSdata_typezallocflagslenfixfree_funcndistunsigned intLENEXTcodez_stream_slastdistCOPYshort unsigned intalloc_funcnextchar/home/hpa/syslinux/release/syslinux-3.63/com32/libavail_inlenbitsTYPEDOnext_inthisncodeinflate_statez_streampz_streamHCRCinflateInit_stream_sizelong unsigned intTYPEwindowBitsfixedtableslensinflateResethavedictTIMEsyncsearchupdatewindowhavecopyDICTIDwindowuIntcheckSTOREDadlertotalwsizeinternal_stateGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)avail_outinf_leavelencodezfreereservedtotal_inCOMMENTHEADSYNCfromEXLENinflateSyncwhaveversioninflate_modeGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 U%D+D0DRB| > W`R$N ^^2'q(@ m ^ }2y _ 3~FH `H  `0I !M.OMOM@R` T E #@ / <&  GoTpbjq@~TA$dinflate.csyncsearchupdatewindowlenfix.1893distfix.1894order.1945inflateResetinflateInit2_zcalloczcfreeinflateInit_inflateEndinflateSyncinflateSyncPointinflateCopymemcpyinflateSetDictionaryadler32inflatecrc32inflate_tableinflate_fastLZh;^q!!+C U#s# !m##}## #y # #3 G # !   # m  :  b  $ $M$c% j#!]}#!3 !&18CJU\hv#?M[iw(.4?EKQW]ciou{,:HVdr (6DR`n}%)-2<AKPZ_in#(3CSfq #.3EQUY^iny~ ".26;FKV[fk     2 7 B G W b g r               ) 6  {  $(,048<@DHLPTX\`dhlp(,LPhl 48\`infback.o/ 1207848663 1026 1026 100664 15972 ` ELF14(WVSÉ։ϋT$8|$8t}~xsC{ uC C({$uC$C(S …u3CpB z,B(B$1 [^_ÐSÅtPtH$t@(C1ZY[ÍvUWVS\D$T$ L$ p @ FF$D$Xu D$, L$IL$,F,D$(V T$HD$01 w$q g ~tNl$0|$,uT$XD$T$ D$, L$,T$XD$0BT$XvD$0FD$0tr t3uG4 =FD FL FHFPT$BD$0l$0:|$,uT$XD$T$ D$,Q L$,T$XD$0BT$XvT$0D$059tD$@*V8|$,uT$XD$T$ D$, |$Hu!V,T$(N L$HN$D$tT$p D$,9v؉;D$Hv\$HT$XًD$()\$,\$X)\$H\$()^8^8v |$,uT$XD$T$ D$,S L$,T$XD$0BT$X vD$0FXD$0@F\l$0 D$0FTl$0~Xw~\vD$@6_F`b|$,uT$XD$T$ D$,L$,T$XD$0BT$XvF``T$0fTNh@F`l$0F`;FTr`fDFhBF`V`v㍆(D$FdFDFLT$NLL$FdD$ VhT$$Rt$QPT$41tL$AZF`GNLH#D$0FDfX@D$:9v<|$,uT$XD$T$ D$,L$,T$XD$0BT$XfvT$;D$7D$@\$;L$@ٸH#D$0T$>FHfxPD$79v<|$,uT$XD$T$ D$,L$,T$XD$0BT$X녈l$0D$;)l$0)T$7@tD$@[ljF<ЃF@u : ;I$ >   I' I I '  : ; : ; I8 : ; I8 <  : ;  : ; ( (  : ; &II!I/.? : ; ' I@: ; I: ; I 4: ; I.? : ;' I@: ;I.: ; ' : ; I4: ; I : ; I!: ; I "4: ; I#4: ; I$4: ;I%4: ;I& : ;'1X Y(1)4: ;I *!I/ L 0SBT^%int Ou u 7 7P  u u 8T U# V7# LWI# @Y# !Z7# [I# msg]# :^# s`# =a#$ bu#( idn#, eI#0 CfI#4[g3gB 0 )n  Bb op0# 0# val)#0)]!OSlMuU< ' p   aZLENILIT#zBADMEMb7m%Q hR)# Sn# cTn# Un# zVn# WT# XT# GZB# [B# r\B#$ ]B#( ^#, `T#0 aB#4 @cB#8 dB#< .fB#@ 5h#D i#H jB#L ,kB#P mB#T 5nB#X oB#\ pB#` q#d r#h s# t# bb)?)%bA"n)8unVx R!n:#g4dn)cDJ:I | mWk4nL x) in!outQ:"#put$"B"B%"T7"B"Bg"gab$b%lenB%retn&+\ 'X6+()`|bkb*)*n zlib../includeinfback.czlib.hzconf.hinflate.hinftrees.hinffixed.h![uguv"===uXg"YY}t.3uguugu%g?gx~uuuth?K`>KKKKu<?uuYɄ孳?I=u6uu<>FgYʻFF孆Uf1u=uugu$ujK)u6$<i:<ʭN,KvKggAl"u<5<ʑigAh(ggYg}JYtǭ 1.2.1invalid block typeinvalid stored block lengthstoo many length or distance symbolsinvalid code lengths setinvalid bit length repeatinvalid literal/lengths setinvalid distances setinvalid literal/length codeinvalid distance codeinvalid distance too far backf }     A@!  @a`10  @`Psp0  ` @ X ;x8 h( H T+t4  d$ D \ S|< l,  L R#r2  b" B Z Cz: j*  J V@3v6 f& F  ^ c~> n. N `Qq1  a! A Y ;y9 i)  I U+u5  e% E ] S}= m-  M S#s3  c# C [ C{; k+  K W@3w7 g' G  _ c? o/ O `Psp0  ` @ X ;x8 h( H T+t4  d$ D \ S|< l,  L R#r2  b" B Z Cz: j*  J V@3v6 f& F  ^ c~> n. N `Qq1  a! A Y ;y9 i)  I U+u5  e% E ] S}= m-  M S#s3  c# C [ C{; k+  K W@3w7 g' G  _ c? o/ O | AA A1ACj AhX AA AACptDxA|AK.HpV.2tGxD|DI.HpbtQxD|DMpn.ttt tPS R VVQ9W9sQsWQxRxRtttt tPSPSttt tttttttwtw~t~ttttttttL t7P7   P L RL QL ; h L h[llQQQQfhQrQQ)Q5BQP`QxQQQ: K Qb Q Q L GIT  L blXlRRRRJRWRRRr}RR!R5=RPdRxRRRR " R$ D Rb h R R R L Xbl@lnPfPPP*P L @bUUUBUPbUpUUUUQ U "Qx U S Ua U g Uu U U K UbbPblRlS(*P.DP\_Sr(SANSSS S  S h Sh ~ R R R S R S  P  S H Rb2WVvWW: WB J WQ7NQ"zQlnPRR PPVYPPPP R R  RB L RF%inflateBackInit_inflateBackEndinflateBackL opaqueholdworkByteftotal_outFLAGSDICTdistbitsnlenstatenext_outDISTEXTout_descCODELENSwrapmodedistfixNAMELENGTHuLongwriteDONEBytezlib/infback.c/home/hpa/syslinux/release/syslinux-3.63/com32/libTABLEout_funcdistcodeDISTbitsMATCHorderin_desccodesvoidpfoffsetCHECKstrmextrainflateBacklengthwbitsEXTRAunsigned charLENLENSdata_typezallocflagslenfixfree_funcndistunsigned intLENEXTcodez_stream_slastleftCOPYshort unsigned intalloc_funcnextcharavail_inlenbitsTYPEDOnext_inthisncodein_funcinflate_statez_streamHCRCinflateBackInit_stream_sizelong unsigned intTYPEwindowBitsfixedtableslenshavedictTIMEhavecopyDICTIDwindowuIntcheckSTOREDadlertotalwsizeinternal_stateGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)inflateBackEndavail_outinf_leavelencodezfreereservedtotal_inCOMMENTHEADSYNCfromEXLENwhaveversioninflate_modeGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4L  7% + 0 'B> 8RSN =^2q@ m = }`#y >0  $`,J L>,  T>0,w0.005 X7    $`&  /@HO1^X jqinfback.clenfix.1866distfix.1867order.1888inflateBackInit_zcalloczcfreeinflateBackEndinflateBackmemcpyinflate_tableinflate_fastSgy  + ME\  8N  1  !&18CJU\hv#?M[iw*Fcv| #*9BP^lz"0>LZhv+6:>CMR\akpz  $(,1;INXky.3:GKYf {  $(,048<@ 8 <X \inftrees.o/ 1207848663 1026 1026 100664 7184 ` ELF4(UWVSD$ T$1fDDl@u1L$QfDDlB9u$(D$T$f|Tlu JT$W|$Jf||luGu1ɍDLn)‰Au~|$  D$l)HfD$NAT$LfDJfDLjfJu14T$fZft&$fTDLʉL$$fHB $fTLLC9uȋL$9v9s̓|$ t |$ uI$D$4$T$,D$d$D$HD$(T$4T$0D$8$ L$,D$d$D$HD$(D$0D$4@D$8DD$0D$4$T$,D$ D$HD$(D$8|$$T$@D$D$ D$$t$$D$@\$Ht$$*L$L$?D$@f0;D$8}D$>  1D$>`T$4T$>L$0f4+L$T$|$ډT$D‰+T$D$ L$L$,fpL$>L$?HT$DL$ u̍KT$ uu D$ B#D$ ЉD$ fT\lfJt\$H;\$SL$@AL$AD$HfT\l9l$Ht$ #t$(;t$$|$ul$|$H+|$D$LTl)B~ G;T$rD$|$ u|$L$D$,$ $L$D$,)fD)|$t+D$ #D$(;D$$t$T$,L$?D$D$ L$T$,f@@L$?HKT$ uu\$ B#D$ ЉD$ |$ uD$$$)1 Č[^_]% $ > $ >  : ;  : ; I8  : ; I8 : ; I : ; ( .? : ; ' I@ : ; I : ; I 4: ; I4: ; I 4: ; I4: ; I4: ; I  I&II!I/ 4: ; I?  /&dwint-op%#X%#valH#O/   KQ3 'A !!Q "q #, @$ X% g& len(, sym),U min*,~max*,~+,Z,,Tr-,F.AS/,T]0,1,2, low3, N4,N(567l8 end9A>:L ;"<_?BbF@H,HHHH:.  - 4 zlibinftrees.cinftrees.h&<.s\=Y]-3$f0דi ̻HjɊ/?)-hum:^ZK!8nrJKM-hAffumfɟ  inflate 1.2.1 Copyright 1995-2003 Mark Adler @@ !1Aa  0@`LB #+3;CScs| $AA AAFttt t t tP~R~Q5VFWVVQ/P5@PQ%Q5S5HwS}SSS%NRSSsWWB%U%'Q+-Q-1U1hWQWQW59U9WUWUWU5WFWnyWW#5~F`~~f~o~~PRPR5BSwSRSSRf~~~~+5~R,RBPRk}RR~399WVQVVu^}Q63inflate_tableinflate_copyrightdbasenextinflate_copyrightLENSlbasethisshort unsigned inttableleftDISTScodetypecurrlextunsigned chardroplong unsigned intinflate_tablecountcodesrootcodezlib/inftrees.cbase/home/hpa/syslinux/release/syslinux-3.63/com32/libfillunsigned intcharoffsincrCODESlenstypeGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)maskusedbitshuffdextworkextraGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 x %+0+B/3> HRb N ^@ > j <f  w z6: p  0r.00`  V @ @@ !> ,>    6D/ inftrees.cdbase.1806dext.1807lbase.1804lext.1805inflate_tableinflate_copyright     !&-4;Ie 1@Ocmr| (7<JYe jv {  )A inffast.o/ 1207848663 1026 1026 100664 8392 ` ELF4(UWVSH$@D$ $K\$AÉ\$ q NA)‰)щL$D$\$[ \$D$@$D$T$R(T$ L$I,L$$\$[0\$ : ;I$ >   I' I I '  : ; : ; I8 : ; I8 <  : ;  : ; ( (  : ; &II!I/.? : ; ' @: ; I4: ; I 4: ; I4: ; I 4: ; I4: ; I : ; : ; Wp08}B{T-%int Ou u 7 7kP  u u 8T U# V7# WI# FY# Z7# [I# msg]# @^# ^`# a#$ bu#( Ndn#, eI#0 fI#4[ggi0 op0# 0# val# !XOS+(b - ?   F]LENOLIT BADMEM%7Q kR# Sn# fTn# OUn# eVn# WT# XT# %ZB# [B# \B#$ ]B#( i^#, `T#0 aB#4 cB#8 dB#< fB#@ h#D i#H jB#L 2kB#P mB#T ;nB#X uoB#\ ]pB#` q#d Jr#h s# t# ?{TpFDQEBq@GTinHIoutJbegKendLMBNB@OBDiPHQTRBXSLWTP'UBTVBXWopXBxlenZBC[Bb\D1 ` zlib../includeinffast.czlib.hzconf.hinflate.hinftrees.huKɭuuu/YY=V!>v=K0CvuK/>!K1YY=V!>v=K/=YK/=K/y< <=K0gguggKgYgNgKTzjhgKYuYY^~<?Ygxgm"/>invalid distance too far backinvalid distance codeinvalid literal/length code| $AA AAC\ttt ttt P ]RP`{P)ORqR*Vz`RtRUS6U?dUdnSUU0U0OQqQQWRQRQQ 6S?FQWWSWdQQSQQ W P @RVfQffWfpPRQQQWPRQW/RENPQQ  Q  R  Q "PO[Q[[P[^R"\".Ph REGRdQRQRQRQDVQzQQQ/Q/ERG|R|QRQ  R  Q  R )Q[inflate_fastopaqueholdworkByteftotal_outFLAGSlmaskDICTdistbitsnlenstatenext_outDISTEXTdcodeCODELENSwrapmodezlib/inffast.cNAMELENGTHuLongwriteDONEBytedmask/home/hpa/syslinux/release/syslinux-3.63/com32/libTABLEdistcodeDISTbitsMATCHcodesvoidpfoffsetCHECKstrmextralengthwbitsEXTRAdodistunsigned charLENLENSdata_typelcodezallocflagsfree_funcndistunsigned intLENEXTcodez_stream_slastdistCOPYstartshort unsigned intalloc_funcnextcharavail_inlenbitsTYPEDOnext_inthisncodeinflate_statez_streampz_streamHCRClong unsigned intTYPEdolenlenshavedictTIMEhaveDICTIDwindowinflate_fastuIntcheckSTOREDadlertotalwsizeinternal_stateGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)avail_outlencodezfreereservedtotal_inCOMMENTHEADSYNCfromEXLENwhaveinflate_modeGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 p%+0Bz[> R $N ^2 PqL<m  ~# 2  0R2.H X    inffast.cinflate_fasta   ! & 1 8 C J U \ h v         # ? M [ i w         ( . 4 ? E K Q W ] c i o u {                  , : H V d r             ( 6 D R ` n }         ' , E h w               ) . 8 = DI Om png.o/ 1207848663 1026 1026 100664 30552 ` ELF T4(@,ÉP,ÃZfYfZfYf'fǀƀÃÃHWVSׅut6~,XډuC Nt1[^_ÐVSƉӃvtJwEv)D$ D$ PD$ND$GD$ D$ D$D$ T 1[^Ð 1 WVSƉӃufC=1ɉf׉?RfC<f׉?RfCfщʃRPCH љ@RCPh [^_ÐvUWVS lj։ͅ%@th|$ u1@B8tV\$ TtGF8D3 S@C;^0|V8F8F0% tVDfFD%tf%dždžtND$1D$9D$|ωdžft5dždžf |$ tG\$ TDStC1 S C;|⋖dždžf%t}|$ t*tlk\$ TDLtC1 SC;|⋖dždžtVtFtf%tVFffF@tZtJD$1D$D$;F|Ӊdžf|$ t߽! [^_]ÍvSËD$t-t)u u ! [[fWVSÉ֋x@19vF1 C@Ήʉ{@[^_fSËw1[[[SÉT$T$jt!ǃǃD$XZ[Ív D$D$1 fWVSƉׅt&t [^_Ívt0D$tD$D$ÐS t@@%=u@AuY[[ÐS111XZ[ÐVSƉӃ~ iڅy1҈Y[^% : ; I$ > : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 < I!I/ &I : ; : ;I8  : ;.? : ;' I@ : ;I.? : ;' @ : ;I : ;I .? : ;' I@.? : ;' I@ 4: ;I.? : ; ' I@: ; I : ; I!4: ; I"4: ;I #.? : ; ' @ $.? : ;' @% &4: ;I ' (4: ; I)4: ; I*4: ;I+4: ; I ,.? : ; ' @-4: ; I?  r C0B T F %int  Ou u 7 7^ P  u u 8T i U# l V7# WI# a Y# HZ7# [I# msg]# ^# +`# a#$ bu#( dn#, eI#0 ifI#4[g ] Rn#g B# 'u z  B#  B#  B# ] B#  B# B#& GTR A 0 &gjkQnp'-g qxJcu red#O ##D ? #red#O ## #N red#O ## #G#K  red#O ##G#.#h! q   2#[ #I## '1 q n#key%2#&2#(# 0 01_FqG#,H#dayI# J#K#L#MNw_X Y#.Z# [#  ^#`}gaR &# #U ## #M#j #x#-## ## # #G #R #  b #( #,= n#0 n#4#8#<x#D ?#H?#R#\#`#dt #h% #l#p0  #tb #xb #| b #b # b #b #b #&b # -2#.#/#F02#z1{#2#3#8#=# >#C2#7 D2#F#]G#QL}#M#X#cZP#H[P#^2#Y_2#fW#gj#;n#Qo#<p#q# r#^s# t# u#b  x z i {    ##-#x#  #  #  9    + 4z#6#<7#18# 19#$:#(;#,>#0:I#4J#8 K#9LO#<P#@Q#DS#HT# U#; Vn#Wn# Xn#;Yn#Zn#\# ]#U ^#" _#`#Va# b# c#(d# e#Sf#:g#h#$i#j # l#crcm#n#Mo#j p#jq#r# s#t#u#v#-w#xx#y# z# {#y |#'}# #B #b #?#y ?# n# b #b #~#M# #ti#Zi#[ i###x# ?# (#P# \##3##S#t#5## #2#[#Q#x#n#hn#a #v#Z2# 2###0 #2#### n# ##, ##u  #R#g#)#$ *#+#0#21#2.#6# :#!;#h =#B#!E#F#  r   1  (   84: P   n 4_hn   u  h      n     n  '.   (:@ Q  Zt Ygt fPfpf>R2 ?2R ~A62 * pj2,6  8>t @\t Pk,n\`t n`ht Snh" Zjinp onsign {n3 n\!fpR z#n 8signumn:s28 rs rk"t/@#qnt uptru$S|K  IIu X I1numJn%I|ibn% N&ind%Bin%9in0'C&row(nh$! :N 8n8u 9nX 9/u& uL 7j  7(ptr(p!) $z&(X% 9%W*'u u$CX BBu $, u L $+k    *u fFu ? ( +u x, @{F  ptr 2 )F n,| I ,D]g \ \n /g Dg-9V4kn-7}[-:[-=[--@[-8M[-q P[-tR -M-5-_ L-!c- "z-`#-_$-]%-&- '- (-?)-J*2-+I-,`-V-w-i.-/-L 0-H1-2 libpng../include../include/klibc../include/bitsizepng.cpngconf.hpng.harchsetjmp.hstddef.hzlib.hzconf.hstdio.h> =? C AAA  "t Jnx"!d{XM[vt (|YJy|XZuu|N{ {3ɟOu{ɟ{vɣɟ{vɟ ͟u JuNlO]uyw}vYYvZ~Jw?<fg2Y2u;Xɟ}tv`fxK0Lw3hUt@LKKVXikdXgXY libpng version 1.2.8 - December 3, 2004 Copyright (c) 1998-2004 Glenn Randers-Pehrson Copyright (c) 1996-1997 Andreas Dilger Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. 1.2.8 libpng version 1.2.8 - December 3, 2004 (header) %d %s %d %02d:%02d:%02d +0000Unknown freer parameter in png_data_freer.Potential overflow in png_zalloc()Too many bytes for PNG signature.1.2.8PNG  IHDRIDATIENDPLTEbKGDcHRMgAMAhISTiCCPiTXtoFFspCALsCALpHYssBITsPLTsRGBtEXttIMEtRNSzTXt"U3UJanFebMarAprMayJunJulAugSepOctNovDec|    CF CF CF, CF 8 @ \ `hKAA AkAA C  C<8AA AvWWD W$H(E,F0@. N TAA AAC ],A0I.I J.,A0I.I P.p,A0I.I P.:ABAA A(0ACe A(XYACL E.HQ.h AC5AA A;C @;ACt A|ACT A*AA Cb P t ttPtttP #t#)t)*t (P,/t/5t56t,4P`cPhitijtjkt kthPQPQhsRsWR}VSttt t PVRSRQQ lnprlnpr #t#8t ,P 'R',Q89t9:t:;t ;qtqtttt t$t(t,t0t8RPRV8HRHSPRttt ttLt LMt,M_t0_t t,t0t t,t0t  P WPRV1R1VRQU<Q<IUIRQRdUdnQnUQSI SNSSBnSSASSnSSASSASSttPSPSRRQQPPttt &tP#SR$VQ Q P""PPP%W()t),t,QtQRt RXt(0P0QS(=RIPR0=PIXPXYtY\t\hthut utt tXrPrSXrRrtttPxttt tPVPRWRSt?t P;;P@AtADtDxtxyt y{t@RPR`S`fPfySy{P@qRw{R@qQwxQ|}t}ttt t|PSttt tt PVPRSQpng_get_io_ptrpng_init_iopng_get_copyrightpng_get_libpng_verpng_get_header_verApng_get_header_versionppng_access_version_numberpng_init_mmx_flagspng_mmx_supportpng_reset_zstreampng_handle_as_unknownSpng_sig_cmppng_check_sigpng_convert_to_rfc1123:png_zfreeqpng_free_dataSpng_data_freerpng_zalloc/png_info_init_3zpng_info_destroypng_info_initpng_destroy_info_struct+png_create_info_structfpng_calculate_crcpng_reset_crcpng_set_sig_bytesDpng_libpng_verkpng_pass_startpng_pass_incpng_pass_ystartpng_pass_yincpng_pass_maskpng_pass_dsp_maskpng_sig png_IHDR#png_IDAT:png_IENDQpng_PLTEhpng_bKGDpng_cHRMpng_gAMApng_hISTpng_iCCPpng_iTXtpng_oFFs png_pCAL png_sCAL7png_pHYsNpng_sBITepng_sPLT|png_sRGBpng_tEXtpng_tIMEpng_tRNSpng_zTXtbig_row_bufpng_write_status_ptrindex_to_palettemalloc_fnwarning_fnpng_uint_32save_bufferpng_gAMApng_sPLT_entrypbit_depthrgb_to_gray_statusscal_s_widthpng_charpppalettetotal_outpng_sPLT_structflagszbufpng_info_struct_sizepng_pass_startpng_sPLT_entry_structnentries_IO_filepng_info_structpng_get_header_verentriessplt_palettespng_IENDcur_palettegamma_16_tablepush_lengthdummypng_convert_to_rfc1123bluezfreepng_row_info_structcompression_typepng_init_iotime_buffer__ebxshort intpng_get_io_ptrpng_info_destroypaeth_rowfrequencypng_read_status_ptrmodepng_uint_16pint_y_greenpng_get_header_versionx_blueGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)x_offsetpng_malloc_ptrpng_timepiccp_nameinfo_ptrsave_flagsy_greenpng_info_init_3png_pass_incy_offsetdo_filterprev_rowpng_rw_ptrint_x_redpcal_unitsbuffer_sizepng_hISTpng_signaturecurrent_buffer_ptrpng_textpiccp_proflenopaquetransformationspng_FILE_ppng_zTXtz_streamfloatshiftpng_sBITavg_rowrowbytespalette_lookupindexpng_access_version_numbersig_byteswrite_data_fnpng_pCALscal_pixel_heightgamma_16_from_1chunk_namelong long unsigned intuInt__ebpz_stream_suLongusr_bit_depthpng_infopppng_voidp__jmp_bufpng_struct_defpng_uint_16pprow_fnbackgroundpng_byteppsignaturepng_get_copyrightzalloclengthpng_libpng_veravail_outmng_features_permittedpng_sRGBpng_error_ptrnum_to_checkpng_fixed_pointpng_unknown_chunkpasspng_zallocsize_terror_fnio_ptrwidthrgb_to_gray_green_coeffpng_int_32png_iCCPpng_time_struct__eipzlib_strategymonthsave_buffer_sizeBytepng_tRNSint_y_white__esiscal_pixel_widthpng_sigpng_free_data__espdither_indexpng_unknown_chunk_tphys_unit_typepng_row_info__ediprocess_modeshort_monthsy_whitesecondpng_color_16hourinfo_ptr_ptrfree_mepng_check_sigerror_ptrzlib_mem_levelpng_sCALsub_rowsave_buffer_maxpng_mmx_supportstartscal_unitpng_pass_ystartcharread_data_fnpcal_nparamsadlertotal_intext_lengthpng_const_charpptr_ptrmem_ptry_redpng_get_libpng_verpng_timetextpng_bytepjmp_bufdataend_fnup_rowpng_uint_16gamma_from_1current_textpng_unknown_chunkppcal_paramspng_sPLT_entryuser_transform_depthunknown_chunkswrite_row_fnpng_IDATzlib_methodinterlacedpng_PLTEscreen_gammaminutepng_user_transform_ptrpng_iTXtlong long intpng_sPLT_tpnum_textBytefpng_tIMEvaliddepthnext_outnum_transx_pixels_per_unitpng_init_mmx_flagsunknown_chunks_numtrans_valueschannelsnum_chunk_listiwidthfillersrgb_intentpng_size_trow_bufpng_calculate_crcsizepng_free_ptrusr_widthrgb_to_gray_red_coeffbackground_gamma_typemaskinternal_stateavail_inrgb_to_gray_blue_coeffint_x_greenlong unsigned intheightdata_type/home/hpa/syslinux/release/syslinux-3.63/com32/libinfo_fnx_greendither_sortitemsrow_numberpng_oFFsmmx_rowbytes_thresholdzlib_levelneed_crcgreennum_rowsfree_funcpalette_to_indexusr_channelsint_x_bluezlib_window_bitspng_ptrpcal_purposemax_textread_row_fnzbuf_sizegamma_to_1png_color_structchunk_listpng_sig_cmpuser_transform_channelspng_data_freerpng_textpng_row_infopspare_bytelong intgamma_16_to_1next_inpng_pass_dsp_maskgraylocationpng_structppng_structfilterpng_progressive_end_ptrint_y_blueskip_lengthfilter_typealloc_funcpng_infopng_progressive_row_ptrpng_bKGDgammay_pixels_per_uniticcp_profilepng_colorpng_color_8_structcurrent_text_sizeptimebackground_1png_charppng_reset_zstreamnamepng_infopunsigned intpixel_depthidat_sizecurrent_text_ptrx_rednum_bytesgamma_shiftpng_color_16_structbackground_gammay_bluepng_pass_yincint_x_whitealphanum_palettescal_s_heightint_gammayearcurrent_text_leftrow_pointersx_whiteuser_height_maxpng_handle_as_unknownpng_destroy_info_structunsigned charpng_pHYssave_buffer_ptrpng_color_8read_user_chunk_fnuser_width_maxhistcurrent_bufferpng_set_sig_bytespng_sPLTpng_progressive_info_ptrcurrent_buffer_sizepng_reset_crcread_user_transform_fnint_y_redstatepcal_typepcal_X0pcal_X1offset_unit_typeinterlace_typepng_tEXtpng_colorpcompressionsigned charshort unsigned intuser_transform_ptrpng_IHDRirowbytespng_cHRMreservedlibpng/png.cfree_fnvoidpfsplt_palettes_nummmx_bitdepth_thresholddoublerow_infopng_byteFILEzstreamjmpbufsig_bitpng_user_chunk_ptrfreerpng_info_initpng_sPLT_tuser_chunk_ptrcolor_typepng_pass_maskpng_create_info_structiccp_compressionpng_zfreetransgamma_tableasm_flagspng_text_structGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 a%+0B > bR)N u^2b+m-p yp.u u l1 ^= @wy G~ P _ l |   png.cshort_months.3649png_get_io_ptrpng_init_iopng_get_copyrightpng_get_libpng_verpng_get_header_verpng_get_header_versionpng_access_version_numberpng_init_mmx_flagspng_mmx_supportpng_reset_zstreaminflateResetpng_handle_as_unknownmemcmppng_sig_cmppng_check_sigpng_convert_to_rfc1123png_mallocsprintfpng_zfreepng_freepng_free_datapng_data_freerpng_warningpng_zallocpng_info_init_3png_destroy_structpng_create_structmemsetpng_info_destroypng_info_initpng_destroy_info_structpng_destroy_struct_2png_create_info_structpng_create_struct_2png_calculate_crccrc32png_reset_crcpng_set_sig_bytespng_errorpng_libpng_verpng_sigpng_IHDRpng_IDATpng_IENDpng_PLTEpng_bKGDpng_cHRMpng_gAMApng_hISTpng_iCCPpng_iTXtpng_oFFspng_pCALpng_sCALpng_pHYspng_sBITpng_sPLTpng_sRGBpng_tEXtpng_tIMEpng_tRNSpng_zTXtpng_pass_startpng_pass_incpng_pass_ystartpng_pass_yincpng_pass_maskpng_pass_dsp_mask $0(N" #8%W&j%%%%%@%k%x%%%&*%u%&%% $I%s%("9+C,n&%**.133*m558d%(T- !&18CJU\hv#?M[iw &4BP^l{ 3?QXj|!0@Phw ,5DSbr~2AP`l"1@O^m|!0?N]l{  " 2 B R b r           " 2 B R b r           " 2 B c j v            0 : I X g v            + ; K [ k {          +;K[k{ +;K[k{ +;K[k{ +;K[k{ +;K[k{ +;K[k{)Q]/Wcgoz      $(, 1< GSW[ `k r~   " '2 @ N Ydhl {         # (5 @GKS] l w       "&4 :>Yaei ny ~          $5=AE JU Ze ju         & 1<@D IS Xlsw{         ER9lyPQRSTU: ;$1<;H=R_>iv?@ABCDE F!.G8EHO\IfsJ}KLMNO ( ,8 <P Th l        , 0l p|     , 0X \l p    pngset.o/ 1207848663 1026 1026 100664 39124 ` ELFr4(ttJ\D$B`D$BdJÍvD$D$ t!tɈݚݚJ@fttJhD$BlD$BpJÍvtt J,JÐS˅t!tx;}kD$D [ftЃ ÉÍvt t!JfÍvÍvÍvVSӉ΅t7t3t9t j@tKX[^UWVS ƉӉ͋|$ tmtit= j CDPCD |$$tCH T$$uff{K [^_]fttB : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 I!I/ &I : ; : ;I8  : ;.? : ;' @ : ;I: ;I .? : ;' @4: ;I.? : ; ' @: ; I4: ;I4: ;I4: ;I 4: ; I 4: ; I!: ; I "4: ;I# $.? : ;' I@% &: ;I'.? : ;' @;"f=0 3B WT ! %yint  Ou u 7 7N P  u u >8T U# j V7# WI# @ Y# MZ7# [I# msg]# ^# ?`# a#$ cbu#( dn#, eI#0 fI#4[g [ Rn#g BMa i  B#  B# 8 B# Y B#  B# B#t Te +0 &gjkFnpg q@Rd red#? ##f j4 #red#? ## #j4p red#? ## #w#):, # red#? ##w###p" r   !#: #W#9# M( r  n#key%!#&!#(# . 0L1BX YB#Z# [#  ^#R`QajR B# #' ## #y#I #### ## # #Z # # A  #( #, n#0 n#4#8%#<#D #H#R#\#`#dS #hG #l#pa #t #x #| # #  # #_ #d # -!#.#/#0!#d1X#2#3#8#=^# >#C!#Y D!#VF#G#_L~#M#gX#_Z-#[-#^!#_!#f4#j#kn#Mo#p#q# r#Ss#v t# u#  xp z  j  ####  #  #  L  j   44i#6F#t7F#$8# 9i#$~:i#(;#,>!#0tI#4J#8 K#9AO#< P#@jQ#DS#HT# U#4 Vn#Wn# Xn#.Yn#Zn#\# ]#E ^# _#`#a# b# c#d# e#Of#$g#h#i#jj # l#crcm#n#yo#I p#qB# r# s#t#u#v#w#x#xy# z# {#i |#}# #@ #S ## #(n#A  # ##7# #yF#F#n F#%### # ## #####9#f## #,#W###n#mn# ##D!#!###a#!##X#5I# n# ##" ##s  #W##)# *#+#0#j1p#2#6# :#Y;#X =#B#HE#F# @ yRX i 4 u{  4  -  4  nDu  4  )  ! 4   n-3 I 4 v - U[pn 4 ^'| 4  (  4 }d!t b4b RcQcWcn $Vt 4P R nQ- - Xyt 4 R Q&Wn( 4|t 34P3 R3nQ< 4\ zIn nt 47 nOt M4PXMR5NIQD vt u4Pu RV unQt 4PR$ t 4PR Q9t 4PHRQe7Y h X4{X X4@nh l4l mI mn2 m(| ' t %4t% R%&Q\ 1 4 ( #4F !4R!n " H"n$(p$i%nR %n;@N 4 aIin  4 X A '  4< ! - A - YP U4 U V  V =V? CW  W  W XG Xg =&Pp  #4 # !$-! $-!=$-!C$-! %- ! %-(%- %-/ `q @pE O  >4> )?nh C FK  K =K CK  K  K K K  Ne N'NNgNsOBOnOH d  4 ^Tn"np^inh# / "to^^$0nd 9  4) H  nind% pqn#-  z9Wu<  r4r s!.&X0sM&X1smsn8 snt!tXFv="iwnE   4 W~?9n"np~sinh#y"to~~   4 M !nY!1I! !G!]E) 4   n"retn!- H4 4 ! n+nKnn n' 4V yn libpng../include../include/klibc../include/bitsizepngset.cpng.harchsetjmp.hpngconf.hstddef.hzlib.hzconf.h=uuggh2=uu;==>Q2Lgg$J- Jgg JggJ=gKu~JRLvKK}{XKtvvYgZɠWhyvz"tr<]=MxX LwahKKu;YGXʿvb>-Ku;uf31& it\ggggg呟K,#\xUthQ@Ah㈵>Q@PG?PG?|  ! $2 X! |*A     ( HAA C]B G.HR 4hAA AAC Y,B0E.s S.  %AC^ A$4AA AAC ,AA A_B E.ZR.(gAA CxFY H$AC AIADAA AAC@pDF@aDF@HDF@HDF@HDF@P C pAA CZAEE D.VEEE E$E(E,E0I. HEEEE E$E(E,E0E4E8Et>@t@_t _tJPJpVpvPvVP)R)-S-9R9;S;JRJoSvSR)Q)qWqvQvWQegRvRttt tttt tPVPVPPRSRSRSSRQQQ t  t tt ttT(P(9QPQPPQR S 2R2PSPRSRSttt ttt!t!BtBHtHPtPVtV^t^dtdltlrtrPtPP\RRPRQPQPDSLSLPVMVMP W NWNP UOUOPPXPTPStSpt PPUQU\Q\lPlpQPRKRUpRP0phP8p`pqtqrtrut uttttt tttt t$t(t,t0tttt t   t$ t(  t,  t0  t4  t8 $ t<$ ) t) + t+ 0 t0 5 t5 A tA B tB E t pPB VB E PpRSRC SC E RpQA E QH I tI J tJ K t K L tL O tO d t H Y PY U P c UH d Rd l Vl v Rv V a Va d RH d Qd S S6 ` S` d QH d d d ` P b Wd e te f tf g t g h th k tk 9 t0d P 9 `d { R{ V R V R 6 V6 9 Rd { Q{  U I Q , Q, 8 U8 9 Q W K W 7 W- K W W 7 W- = UT 8 U- 0 Sf s S 5 S< = t= > t> ? t ? @ t@ C tC t< O PO  U  P U< W RW  V V< _ Q_ d<  `<  \<  X  X X<  T  TE T<  P<  L R Q  R ) Q R Q  h_ h t t t t t t0 P\ R 7U<U Q4S<}SSOTPy}SSttt  t #t#t0t<tt0/P/VPVKRKSSSvRvSSRKQKhKKdKK`KK\Rt t &t&.t .:t:;t ;BtBCtCET+P+;S;APADS+R+Q22E|09PABPHItIJtJKt KLtLOtOt HP V PHaRaiSiyRy S RHaQamWmQ W QHHaaU H  HHttt tt,t ,.t,.t0t 8P8VP%R%)S)8R8SR%Q%UQ%%W?"png_set_oFFspng_set_sCALpng_set_pHYspng_set_sRGB(png_set_unknown_chunk_locationpng_permit_empty_pltepng_set_read_user_chunk_fnpng_set_invalidDpng_set_asm_flagspng_set_mmx_thresholdspng_set_user_limitspng_set_rowsepng_set_tRNSpng_set_sBITpng_set_bKGD\png_set_keep_unknown_chunkspng_set_hIST@png_set_gAMA_fixedpng_set_gAMApng_set_cHRM_fixedpng_set_cHRM=png_set_sRGB_gAMA_and_cHRM`png_set_unknown_chunkspng_set_text_2png_set_pCALpng_set_sPLTE png_set_iCCP png_set_textG!png_set_IHDR!png_set_PLTEbig_row_bufgreen_yint_red_ytextpsettable_asm_flagspng_set_rowspng_write_status_ptrindex_to_palettemalloc_fnwarning_fnpng_uint_32fromsave_bufferintentpng_sPLT_entrypbit_depthrgb_to_gray_statusscal_s_widthpng_charpppalettetotal_outpng_sPLT_structflagszbufblue_xblue_ypng_sPLT_entry_structnentriespng_info_structkeepentriessplt_palettescur_palettegamma_16_tablepush_lengthdummybluezfreepng_row_info_structcompression_typetime_buffer__ebxshort int/home/hpa/syslinux/release/syslinux-3.63/com32/libpaeth_rowfrequencypng_read_status_ptrmodepng_uint_16pint_y_greenx_blueGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)x_offsetpng_malloc_ptriccp_namewhite_xinfo_ptry_greenpng_set_PLTEy_offsetdo_filterprev_rowpng_rw_ptrint_x_redpcal_unitsbuffer_sizeoffset_xint_red_xproflencurrent_buffer_ptrpng_textpiccp_proflenopaquetransformationskey_lenz_streamfloatshiftavg_rowrowbytespalette_lookupindexpng_set_cHRMsig_bytespng_set_bKGDwrite_data_fnscal_pixel_heightgamma_16_from_1chunk_namelong long unsigned intuInt__ebpz_stream_snew_iccp_nameuLongpng_set_textpng_color_16pusr_bit_depthunknownspng_voidp__jmp_bufpng_struct_defpng_uint_16pprow_fnbackgroundpng_set_read_user_chunk_fnpng_byteppsignaturepurposepng_set_sRGBnew_listpng_set_invalidpng_set_text_2zalloclengthavail_outmng_features_permittedint_blue_ypng_error_ptrparamspng_fixed_pointpng_unknown_chunkpasssize_terror_fnio_ptrwidthrgb_to_gray_green_coeffpng_int_32png_set_unknown_chunks__eipzlib_strategyres_xres_ysave_buffer_sizeByteint_blue_xint_y_white__esiscal_pixel_widthold_textnum_palette__esplang_key_lendither_indexpng_unknown_chunk_tpng_set_unknown_chunk_locationphys_unit_typepng_row_info__ediprocess_modey_whitepng_color_16free_meerror_ptrzlib_mem_levelred_xred_ychunksub_rowsave_buffer_maxscal_unitold_maxcharread_data_fnpcal_nparamsadlertotal_intext_lengthpng_const_charpmem_ptry_rednum_unknownspng_permit_empty_pltetextpng_set_sPLTpng_bytepjmp_bufdataend_fnup_rowpng_uint_16gamma_from_1current_textpng_unknown_chunkppcal_paramspng_sPLT_entryuser_transform_depthunknown_chunkswrite_row_fnzlib_methodinterlacedscreen_gammapng_user_transform_ptrsettable_mmx_flagslong long intpng_sPLT_tpnum_textBytefvalidpng_set_IHDRdepthnext_outnum_transx_pixels_per_unitint_white_ypng_set_sRGB_gAMA_and_cHRMunknown_chunks_numtrans_valueschannelsnum_chunk_listiwidthfillersrgb_intentpng_size_twhite_yrow_bufpng_set_sCALsizepng_free_ptrusr_widthrgb_to_gray_red_coeffnparamsbackground_gamma_typemaskinternal_stateavail_inrgb_to_gray_blue_coeffint_x_greenlong unsigned intold_num_chunksheightdata_typepng_set_keep_unknown_chunksunitinfo_fnx_greendither_sortrow_numbermmx_rowbytes_thresholdpng_set_gAMAzlib_levelgreennum_rowsfree_funcpalette_to_indexusr_channelsint_x_bluefile_gammazlib_window_bitspng_ptrpcal_purposetext_ptrpng_set_pHYsmax_textread_row_fnzbuf_sizegamma_to_1green_xpng_color_structchunk_listuser_transform_channelspng_textempty_plte_permittedpng_row_infopspare_bytelong intgamma_16_to_1png_set_sBITnext_ingraylocationpng_structppng_structnew_iccp_profilefilterpng_progressive_end_ptrint_y_blueskip_lengthfilter_typealloc_funcint_white_xpng_infopng_progressive_row_ptrgammay_pixels_per_uniticcp_profilepng_colorpng_color_8_structcurrent_text_sizebackground_1png_set_cHRM_fixedpng_charppng_set_gAMA_fixednamepng_infopunsigned intpixel_depthidat_sizecurrent_text_ptrx_redpng_set_hISTgamma_shiftpng_color_16_structnum_chunksbackground_gammay_blueint_x_whitealphapng_set_oFFsscal_s_heightint_gammacurrent_text_leftrow_pointerspng_set_mmx_thresholdsx_whitepng_set_pCALuser_height_maxtypelang_lenunsigned charsave_buffer_ptrpng_color_8read_user_chunk_fnuser_width_maxunit_typehistcurrent_bufferpng_progressive_info_ptrcurrent_buffer_sizeread_user_transform_fnint_y_redstatepcal_typepcal_X0pcal_X1png_set_asm_flagsoffset_unit_typeinterlace_typepng_colorpcompressionpng_color_8ppng_set_user_limitssigned charprofileshort unsigned intuser_transform_ptrirowbytesreservedfree_fnvoidpfsplt_palettes_nummmx_bitdepth_thresholddoublerow_infooffset_yunitspng_byteint_file_gammapng_set_iCCPzstreamjmpbufsig_bitpng_user_chunk_ptrpng_set_tRNSpng_sPLT_tuser_chunk_ptrint_green_xint_green_ylibpng/pngset.ccolor_typeiccp_compressiontransgamma_tableasm_flagspng_text_structGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rodata.cst8.rodata.cst4.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 |%+0&B?"> t`R-7"N Ԗ^2O: m`>(z>>L ܖ B\ }_  Ę0_tq.qqv @zl     !$2$X!1|>*] s    Hh" %/4KTaq}gP pH d <  ' '4)AKHXepngset.cpng_set_oFFspng_set_sCALpng_set_pHYspng_set_sRGBpng_set_unknown_chunk_locationpng_permit_empty_pltepng_set_read_user_chunk_fnpng_set_invalidpng_set_asm_flagspng_set_mmx_thresholdspng_set_user_limitspng_set_rowspng_free_datapng_set_tRNSpng_mallocmemcpypng_set_sBITpng_set_bKGDpng_set_keep_unknown_chunkspng_freepng_set_hISTpng_malloc_warnpng_warningpng_set_gAMA_fixedpng_set_gAMApng_set_cHRM_fixedpng_set_cHRMpng_set_sRGB_gAMA_and_cHRMpng_set_unknown_chunksstrncpypng_set_text_2png_set_pCALpng_set_sPLTstrcpypng_set_iCCPpng_set_textpng_errorpng_set_IHDRpng_set_PLTEmemsetL !!%! !%!5FR'h( " .5(U ] '   G  *)+: , '  ! % / '  ( ! ' % ! % 't } ( ' ! ! ! '  ! ' % !7 'F  '  !'(P!_% 3 !y'3'%!'03u|666(6 6:A6MT6`g6sz64@ R9b!r((((Q( ( (8((=6 !&18CJU\hv#?M[iw #1?M[j ".5GYo )?Wfu -6ETcs$3S_u$3BQ`o~#2AP_n}  - = M ] m }           - = M ] m }           . = L [ k w            * 9 H W f u           $ 4 D T d t        $4DTdt$4DTdt$4DTdt$4DTdt$4DTdt$5Gj"Jq $,08FTbq  .6:> CN S^ cn s  (6JRV^lz  (,0 5@ EP U` ksw{      "&* /9 >H MW bjnr w        $. ; FMQU Zd is x       % *4 9C HR Wa fp u     ) .8 CKOS Xc hs x  $0<HTfnrv {       & +6 ;F Kkot        ) 8 G LW \g lw |         $ 3  8 K S W [  ` k  p {                 ! !! !"! '!2! B! M!T!X!\! a!k! p!z! !! !!! !! !! !! !! !!!! ! " "" ")" ."9"  ( ,8 <H LX \p t       4 8D Hd h    X \l p  @ Dh l    pngget.o/ 1207848664 1026 1026 100664 33100 ` ELF[4(t t#B1ÍvttB 1Ðt t1ftt1fttB1Ðt tB1Åt tB1Åt tB1Åt tB1Åt tB1Åttzy zpuBh1Ðttzy zpuBl1ÐttzyzpuBh;Blt1Ðt,t(zy"JhtBl1RP,$1RQ,$ÐttB t zduB\1ÐttB t zduB`1ÐttB t zduB\1ÐttB t zduB`1Ðt tB1ÅttB 1ÐttB tt BR 1UWVS\$t$|$ l$$t}BtwtBxtB|tقtقt ق]|$(t قD$(|$,t قD$,|$0t قD$01Z[^_]UWVS\$t$|$ l$$Bt}ttttt E|$(t L$(|$,t L$,|$0t T$01Y[^_]fttBtt B(1ÅttBtt1ÐttB tt B,1ÍvVS\$t$tBt>B t8t4t0t,D$ 1[^Ívtt tÐttB@tt Bt@1VS\$ t$t-t)B t#tttB\B`Bd1[^UWVS\$t$|$ l$$tvtrB tlthtdt`t\tX|$(tQ|$,tJEL$(T$,1[[^_]Ívt1t-B @t'݂D$݂D$@1VS\$ t$t3t/zy)t BhtBlɀt Bpɀ1ɉ[^Åt#tBttBRD$1fttBtt B<1SˋL$t!tz0~tB8tB0B0 t1[fWVSˋ|$t$tXtTBtNzuu1 BDt#BHu1 BHtt B1ɉ[^_Ívtt tÐtÅtÐtÐ%Ð%tÍvtÅtÐtÐtÐUWVS ƉӉϋl$ T$$|$(CECCH<v CT$({v |$0t CT$0|$4t CT$4|$,t CT$,? %} 9;~v N1 [^_]% : ; I$ > : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 I!I/ &I : ; : ;I8  : ;.? : ; ' I@ : ; I: ; I .? : ; ' I@.? : ;' I@ : ;I: ;I .? : ;' I@: ;I4: ;I.? : ;' I@#+X:0QBT  %1int !Ou u 7 7N P  u u i8T y U# V7# VWI# 7 Y# .Z7# [I# msg]# ^# '`# a#$ #bu#( dn#, PeI#0 fI#4[g | Rn#tg BPN q: i H B# b B# c B# K B#  B# B#toTb 0 &jgjknkp"(gqEXj| red#? ##r4 #red#? ## #L4|red#? ## #f#R0"W red#? ##f## :"  -# #.#m# D@  n#key%-#&-#_(# @ 0 1luXYl#Z# [#  ^#|z`"a|b v# # ## #l#@ ##^#+### ##W # # M #( #, n#0 n#4#8)#<#D 4#H4#R#\_#`#dJ #hS#l#pL #t #x #| # #  #W # #S # --#.#/#0-# 1p#2#C3#8#D =# >#<C-#eD-#F#iG#L#M#'X#QZE# [E#^-#x_-#fL#j#Zn#?o#p#q# r#s#v t# u# },xz8    ##^##  # # > I     p"4i#6#W7#8# 9#$6:#(;#,>]#0I#4 J#8( K#9O#<-P#@*Q#DS#H3T# U#4 Vn#` Wn# Xn#Yn#Zn#\# ]#E ^# _#`#a# b# c#d# e#f#g#h#i#j #l#crcm#n#lo#@ p#/ql#r# s#l t#u#v#^w#x#y#z# {#i |#}# #f #B #4#4#n#M #  ### #^#^#k ^#)### 4# #S # #0#$####Q## #)###y#n#n###-#-##h#L#<-##O## n# ##$ ##  #8##)# *#+#{0#M1#2#6# :#<;#X =#+B#'E#F# | O  p   p    p  n'`  $ p ,   5<B ] p   n io  p 1 n p -' p  (  p <t pN, R QuM #t pN, R' #L$6t "p<N", R./8Ft .pZN., R 9HWt 8pxN8, RYzCXht BpNB, R Mhxt LpNL, RWxt VpNV, Rat `pN`, R= kt jpNj, Rvut tp,Nt, Rtt pJN, Rht phN, R$w  3 pN, ]\ 4Ot pN, R Pkt p<N, Rlt pZN, R:t pxN, RD8Vt UpNU, R_t ^pN^, RCjt hpNh, RiQ@{| ypLNy, Fz?Q z?z?G z? {? {?I{?P{?F1 >J pN, F9: 9c9G 9 9 9I9P9g@`t pN, R ?Q`t p-N, R 9Q$ t pKN, R$Qnu i pN, pQ+$\pt p'N, R Q: <t pEN, RL:Q: G<|c EpNE, RFQFBF$V]Z| Wp_NW, }XVX0XX1XX$ ^ X$: =YVY\-p rPt ppe Np, R q$Qq? q?GbP  p N, R #" B$M  x t p N, Ql$t p N, R)QU d  p N, R U D  $b  V   p N, R @ $B  m   (!t p N, RQV! )t (p !1t 0p ! Ct Bp1 !Jt6InO Kb <"Rht6gnu g$R i j" t p "t p "t p "'t p (+ pcN,  $^$$ +$$ libpng../include../include/klibc../include/bitsizepngget.cpngconf.hpng.harchsetjmp.hstddef.hzlib.hzconf.hOi4D[Ai3w%w%w%w%w%ihl3ihl3i 4iw4ihl3ihl3ihl3ihl.w%i5$1 g#KYKYKKKuuuNng[KKKKKuuuN $1'$16$1R=1n5$15 YY1Dg0/1 ّ!1 LLY>Lgx_$Y1B$1'uKYKYZKJhKxKhLgx5'.6 .QlP&62|.K3KggguuuYgPInvalid bit depthInvalid color typeInvalid image widthInvalid image heightWidth too large for libpng to process image data.|    $ 8 H X h x      3[A FCA F 4 P l     (AA AAC(AA AAC @ `# !UAA    <@AA (|AA AAC 8PHAA  *  :A qAA A           $(AA AAC  PPP "P$2P35P8BPCEPHSPTVPXdPegPhtPuwPxPPPPPPPPPPPPtt"t "%t%&t&,t ,3tP03PR03R4KPLNPPgPhjPlPPPPPPPPPPttt ttttUPWhPj{P}PPRSVW U ttt tt9t9>tPPPPPP P)P/4P68P-R/>RQ Q9Q:S:>;V;><W<> =U=> @\P]_P`xPPPPttt PPRRSVPP1P9;P<=t=>t>|t <cPwyP<JJzSz|<JJ{V{||}t}~t~t tttt|P P|R R|Q Q|S|V|W| U -PMOPPQtQRtRt PoPv}PPPPvQvQQQQP^^SP^^VvQQPPRRPPttP P PPQSQ !t!"t"#t #t LPSZP^iPpPP 1Q1ESEGQGISISQSS 11W 11VGIQS^QdfQpQQPPPPPPPPPPPPPPPPPP&P&&P()t)*t*+t +,t,/t/+t (rPr!V!#P#(V(=R='S(EQEUWUQ)W)+Q(EE*U*+(EER!!#R#+c#png_get_valid<png_get_rowbytesupng_get_rowspng_get_image_widthpng_get_image_height png_get_bit_depthYpng_get_color_typepng_get_filter_typepng_get_interlace_typepng_get_compression_type=png_get_x_pixels_per_metervpng_get_y_pixels_per_meterpng_get_pixels_per_meterpng_get_pixel_aspect_ratio$png_get_x_offset_microns]png_get_y_offset_micronspng_get_x_offset_pixelspng_get_y_offset_pixelspng_get_channelsDpng_get_signaturepng_get_bKGDpng_get_cHRMpng_get_cHRM_fixedFpng_get_gAMApng_get_gAMA_fixedpng_get_sRGB*png_get_iCCPpng_get_sPLTpng_get_hIST@png_get_oFFspng_get_pCALbpng_get_sCALpng_get_pHYsGpng_get_PLTEpng_get_sBITpng_get_text[ png_get_tRNS png_get_unknown_chunks(!png_get_rgb_to_gray_statusV!png_get_user_chunk_ptr!png_get_asm_flags!png_get_asm_flagmask!png_get_mmx_flagmask<"png_get_mmx_bitdepth_thresholdj"png_get_mmx_rowbytes_threshold"png_get_user_width_max"png_get_user_height_max"png_get_IHDR+big_row_bufgreen_ysettable_asm_flagspng_write_status_ptrindex_to_palettemalloc_fnwarning_fnpng_get_pHYspng_uint_32png_get_cHRMsave_bufferpng_get_x_offset_pixelspng_sPLT_entrypbit_depthrgb_to_gray_statusscal_s_widthpng_get_sPLTpng_charpppalettetotal_outpng_get_hISTpng_sPLT_structflagszbufpng_get_channelsblue_xblue_ypng_sPLT_entry_structnentriespng_info_structpng_get_validlibpng/pngget.centriessplt_palettescur_palettegamma_16_tablepush_lengthdummypng_get_user_height_maxbluepng_get_IHDRzfreepng_row_info_structcompression_typetime_buffer__ebxshort int/home/hpa/syslinux/release/syslinux-3.63/com32/libpaeth_rowpng_get_user_width_maxfrequencypng_read_status_ptrmodepng_uint_16pint_y_greenx_blueGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)x_offsetpng_get_sCALpng_malloc_ptriccp_namewhite_xinfo_ptry_greeny_offsetpng_get_pixels_per_meterpng_get_interlace_typedo_filterprev_rowpng_rw_ptrint_x_redpcal_unitsbuffer_sizefile_srgb_intentoffset_xproflencurrent_buffer_ptrpng_textpiccp_proflenopaquetransformationspng_get_y_offset_pixelspng_get_mmx_flagmaskpng_get_gAMAz_streamfloatshiftavg_rowrowbytespalette_lookupindexpng_get_mmx_rowbytes_thresholdsig_bytespng_get_image_heightwrite_data_fnpng_get_signaturescal_pixel_heightgamma_16_from_1chunk_namelong long unsigned intuIntpng_get_tRNS__ebpz_stream_spng_get_y_pixels_per_meteruLongpng_color_16pusr_bit_depthunknownspng_voidp__jmp_bufpng_struct_defpng_uint_16pprow_fnbackgroundpng_byteppsignaturepurposepng_get_sBITzallocavail_outmng_features_permittedpng_error_ptrpng_get_pCALpng_fixed_pointpng_unknown_chunkpasspng_unknown_chunkppsize_terror_fnio_ptrwidthrgb_to_gray_green_coeffpng_int_32png_get_unknown_chunkspng_sPLT_tpp__eipzlib_strategyres_xres_ysave_buffer_sizeByteint_y_white__esiscal_pixel_width__espdither_indexpng_unknown_chunk_tphys_unit_typepng_row_info__ediprocess_modey_whitepng_color_16free_meerror_ptrzlib_mem_levelred_xpng_get_x_pixels_per_metersub_rowsave_buffer_maxscal_unitcharread_data_fnpcal_nparamsadlertotal_intext_lengthpng_const_charpmem_ptry_redtextpng_get_asm_flagmaskpng_bytepjmp_bufdataend_fnup_rowpng_uint_16gamma_from_1current_textpng_unknown_chunkppcal_paramspng_sPLT_entryuser_transform_depthpng_get_cHRM_fixedunknown_chunkswrite_row_fnzlib_methodinterlacedpng_get_pixel_aspect_ratioretvalscreen_gammapng_user_transform_ptrpng_get_asm_flagssettable_mmx_flagslong long intpng_sPLT_tpnum_textBytefflagvaliddepthpng_get_rgb_to_gray_statusnext_outnum_transx_pixels_per_unitpng_get_x_offset_micronspng_get_iCCPpng_get_compression_typeunknown_chunks_numtrans_valueschannelsnum_chunk_listiwidthfillersrgb_intentpng_size_twhite_yrow_bufsizepng_free_ptrusr_widthrgb_to_gray_red_coeffpng_get_oFFsred_ypng_get_rowbytesnparamsbackground_gamma_typeinternal_stateavail_inrgb_to_gray_blue_coeffint_x_greenlong unsigned intheightdata_typeunitinfo_fnx_greendither_sortrow_numbermmx_rowbytes_thresholdspalettespng_get_rowszlib_levelgreennum_rowsfree_funcpalette_to_indexusr_channelsint_x_bluefile_gammapng_get_mmx_bitdepth_thresholdzlib_window_bitspng_ptrpcal_purposetext_ptrmax_textread_row_fnzbuf_sizegamma_to_1green_xpng_color_structchunk_listuser_transform_channelspng_textpng_row_infopspare_bytelong intgamma_16_to_1next_ingraylocationpng_structppng_structpng_get_color_typepng_get_y_offset_micronsfilterpng_progressive_end_ptrint_y_bluepng_get_sRGBskip_lengthfilter_typealloc_funcpng_infopng_progressive_row_ptrgammay_pixels_per_uniticcp_profilepng_colorpng_color_8_structcurrent_text_sizebackground_1png_charpnamepng_infopunsigned intpixel_depthidat_sizecurrent_text_ptrx_redpng_get_PLTEgamma_shiftpng_color_16_structpng_get_image_widthbackground_gammay_blueint_x_whitealphanum_palettescal_s_heightint_gammacurrent_text_leftrow_pointersx_whiteuser_height_maxpng_get_gAMA_fixedtypeunsigned charcompilerIDsave_buffer_ptrpng_color_8read_user_chunk_fnuser_width_maxflag_selectunit_typehistcurrent_bufferpng_progressive_info_ptrcurrent_buffer_sizeread_user_transform_fnint_y_redstatepcal_typepcal_X0pcal_X1offset_unit_typeinterlace_typepng_get_user_chunk_ptrpng_colorpcompressionpng_get_filter_typepng_color_8punitspng_get_bKGDsigned charprofilepng_get_textshort unsigned intuser_transform_ptrirowbytesreservedfree_fnvoidpfsplt_palettes_nummmx_bitdepth_thresholddoublerow_infooffset_yparamspng_byteint_file_gammazstreamjmpbufsig_bitpng_user_chunk_ptrpng_sPLT_tuser_chunk_ptrcolor_typeiccp_compressionpng_get_bit_depthtransgamma_tableasm_flagspng_text_structGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4+ gR-N ,~^2/q00m 4~ ~4aaCg 4G  <0GZ.ZZd_  c    )$68JH_Xqhx324KPdl| @ `#!U+ 8<@E|R8_PHl*y : q    % D c z (pngget.cpng_get_validpng_get_rowbytespng_get_rowspng_get_image_widthpng_get_image_heightpng_get_bit_depthpng_get_color_typepng_get_filter_typepng_get_interlace_typepng_get_compression_typepng_get_x_pixels_per_meterpng_get_y_pixels_per_meterpng_get_pixels_per_meterpng_get_pixel_aspect_ratiopng_get_x_offset_micronspng_get_y_offset_micronspng_get_x_offset_pixelspng_get_y_offset_pixelspng_get_channelspng_get_signaturepng_get_bKGDpng_get_cHRMpng_get_cHRM_fixedpng_get_gAMApng_get_gAMA_fixedpng_get_sRGBpng_get_iCCPpng_get_sPLTpng_get_hISTpng_get_oFFspng_get_pCALpng_get_sCALpng_get_pHYspng_get_PLTEpng_get_sBITpng_get_textpng_get_tRNSpng_get_unknown_chunkspng_get_rgb_to_gray_statuspng_get_user_chunk_ptrpng_get_asm_flagspng_get_asm_flagmaskpng_get_mmx_flagmaskpng_get_mmx_bitdepth_thresholdpng_get_mmx_rowbytes_thresholdpng_get_user_width_maxpng_get_user_height_maxpng_get_IHDRpng_errorpng_warning@@@@A   ! & 1 8 C J U \ h v         # ? M [ i w              # 1 ? M [ j             . F M _ q          % 5 A W o ~          # / E N ] l {          ' 0 ? N ] }           $ 3 B Q ` o ~           # 2 A P _ n }            )  9  I  Y  i  y             )  9  I  Y  i  y            !  -  C  L  [  j  y              *  9  H  W  f  u              0  @  P  `  p             @ P ` p            0 @ P ` p            0 @ P ` p            0 @ P ` p            0 @ P ` p            0 @ P ` q      % 1 ^        " / B MQY c h {            & 15= G L _ jnv            ! + 0 C NRZ d i |              * 59A K P c nrz            & 1 6 J VZb m r              ( - 8 = H M X ] l {                  ( 7 L X\d o t            0 <@D I T Y d i w              , F RVZ _ j o }                # ( 3 8 G h tx              " ' 2 7 B M Y]e p u               "  '  5  @  E  P  a  m q u  z                ! ! ! .! :!>!F! Q! \! h!l!t! ! ! !!! ! ! !!! ! ! ! ! """ " " ," 7" B" N"R"Z" e" p" |""" " " """ " " """ " " ## # # # # *# /# :# ?# J# O# Z# _# n# }# #  ( ,8 <H LX \h lx |          , 0< @L P\ `l p|        $0 4@ D\ `         , 0< @L P\ `l p|    pngrutil.o/ 1207848664 1026 1026 100664 64992 ` ELF4(@QQÍv@QQÍvf@fVSƉÅy Z[^fUWVS @LCDu$5J 2+ 1 H+1<vȍA-ȍA@sDtwtW<ufɃ ;uft#<uftȉՙt/<t u <u ~@ @tJftuu <u~$ <t<t0 @ tS9C89}ы~ @QT@ u $B BR1ɉ‰K@@[^_]ÐVS t$t@@%=u@At1!;[^UWVS΋L$4K$zB CBABC9r)R1 \$01A9uB HZ)1 |$0:2B9ul$0͉,$<11,$)‰нD$9A9uB HRT$)L$1 \$02B9u|$0ω|$ L$1`,7l$D$ D$L$0,)L$)…yډ˅yȅy9 9L$ 9L$\$ G;|$u R[^_]fUWVSlPDGL$ËD$D$ \$C <<<A\$ St$ƃӃD$D$D$&փӃD$D$D$A,D$ HD$ lED$D$$4)ٸ!D$ ˆ;\$uO\$\$D$$D$9D$$|;t$uMt$t$D$ L$ T$; rWA\$ St&,D$,D$0D$4(Ѓ,҃D$,D$0D$4AD$(D$ H4D$8eT$(D$?11)ٸ??!D$? ˆ;\$0uN\$,\$4G;|$|;l$0u L$(l$,l$4D$8T$8D$;r_A\$ St.,D$DD$HD$L0Ѓ,҃D$DD$HD$LAD$@D$ H4D$PeT$@D$W11)ٸ!D$W ˆ;\$HuN\$D\$LG;|$|;l$Hu L$@l$Dl$LD$PT$PD$;r\؍AÍ,D$ HD$X-D$dى1T$dى)F;t$|)D$XD$XL$;rNjL$ T$ B <v D$ D$ \$Cl[^_]ÐUWVSLÉ։L$ u8<vHBL[^_]<<|<T$!CFtD$D$D$D$D$D$x\$D$1TL$ L$t")ٸ" Ј;\$uGF\$\$|$u D$|$E;l$uT$0CFtD$ D$$D$(D$ D$$D$(x\$ D$,1TL$ L$,t")ٸ??" Ј;\$$uGF\$ \$(|$,u D$,|$,E;l$0uT$DCFtD$4D$8D$<D$4D$8D$ًT$1҉u8D$\$C;u9tCƅu_T$ [^_]D$F^1IN jT$ËT$t [^_] [^_]fUWVS,ÉՉ΋@<u/tt B @tVDžuH‰1҉47t$ T$$G\$D$$8u#8puT$$D$$8t غH9t$ rD$؞vwغn&$t$t$,[^_]UWVSƉT$ˋ@<u8t|$t&D$@ tډ[^_]SDžu ى‰1҉\$C;uC 9D$wYCD$CD$C D$C D$|$u<!|$t|$u|$ |$u|$t!v  \$C;uT$Ņt1FH[^_]C\C;t;\$v;\$v0BD$9|RRUt$$PD$"Pt$,t$,T$$ [^_]vWVSƉ׉ˋ@<uc,t|tB tډT t\$ ډ1҉u)ÍD$ QQT$RPى[^_WVSƉ׉ˋ@<u,ttzyډT t \$ ډ1҉u)ÍD$ RRT$RPى[^_UWVSƉT$͋@<u't@&t X|$t$D$@ tp Ulj‰1҉t/À;Cu9r{t )PD$PSU1҉ŋD$(9w )߃w6LQ A A 9rv SWQjT$[^_]fWVSÉ։ϋ@<ut0t Ht F t`tuߍT$1҉|$~Ft-ȯ=v F->v=w~-|=wl-=wZ-}=wH-Hq=w6 -x=w$-6=w-=v [^_UWVS,ÉT$΋@<ut.9t F|$tT$B%u_ ttt$(D$D$ |$8w=8w D$=vCD$D$|$8w=8w D$=vD$Ł|$8w=8wT$=vzǹƁ8w=8w 8=v D$@ D$->v=wkD$ -|=w[D$-=wKD$-}=w;D$-Hq=w+=wP=wx=V $$W $$U $,\$(L$X\$ L$P\$L$T\$L$L\$L$H$T$D : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 I!I/ &I : ; : ;I8  : ;.? : ; ' I@ : ; I4: ; I.? : ; ' I : ; I.1@ 141.? : ; ' I@: ; I4: ; I .? : ;' @!: ;I"4: ;I#4: ; I $4: ; I%: ;I&: ;I ' (4: ;I)4: ;I* +4: ;I ,4: ;I-4: ;I .: ; I /4: ; I04: ; I 1.? : ; ' @24: ;I? < -+:0BDT } %int: } Ou u 7 7 P  u u 8T U# V7# WI# Y# Z7# [I# msg]# 8^# `# a#$ bu#( $ dn#, eI#0 )fI#4[g  Rn#@g B0S  i * B#  B#  B#  B# + B# yB#>tDwT^ p0 &gj4knpgqjI@)Rd red# ## j u#red# ## #F red# ## ##(@ red# ###w#N  !# #~#V#  a fNc n#key%!# &!#(#  0l1XY#FZ#_ [#  ^#.`aF. _@# # #]# ## ##+# #q #i# #a# #T #   #( #,t n#0J n#4 #8#<G#D #H>#R#\P#`X#d #h #l#p #tK #x> #| # #Q  #; # # # -!#H.#P/#0!#1X#>2#3#S8#=:# >#C!# D!#F#6G#LZ#AM#X#Z-#[-#^!#_!#.f4#j#n#o#p#.q# r#s# t#Z u# I xL!z  F  @#]#+##  # a#   ^ F  p 4i#06"#l7"#[8# 9E#$:E#(9;#,>#0 I#4J#8 K#9O#<P#@Q#DS#HT#_ U# Vn# Wn# Xn#eYn#Zn#@\# ]# ^#q _#]`#a# b#e c#nd#- e#f#Rg#Uh#mi#qjF #ml#crcm#n#o# p#q#r#; s# t#u#dv#+w#x#y#az# {# |#{}# # # #>##n#  ##  #M#|#i #F#F# F##O#G# #S m##B #7#K######e #####1n#n# ##!#w!#f###!#S##%# n# ##{ #F#  ###S)#p *#Y+#0#b1L#22s#6#Y :#Q;# =# B#E#SF# d .4 E  wQW m   y    n,y   B       n0   %  R  17Ln  :'X^s  d (   4!tbuf3i5oC$EtbufBiD'PbufOiQJH\t<~*\Z )buf)i+ +z ! y l" n"t 33 nl  #3pcrc=$ nC , lP! ~ !q~ R %row~ 4&n !;  nR'(i " (bpp )rp )lp '@(i >" \)rp )pp '((i z(rp (pp )lp (bpp "  *((i ((rp g(pp )lp )cp (bpp " *e(a n(b n(c n(pa nC(pb na(pc nt(p n I  !  C+q R (row a, n" *+ 'MC(sp (dp "m  n&"Y nZ" n" n"  n,> n(v  (i U (j nw 'nC;(sp  (dp  "m  n "Y n " nA " np "  n ,> n(i  *&(v  (j n* '*;>(sp# H (dp$ h "m % n "Y% n "& n "& n " & nF (i' r ,>( n*,(v?  (j@ n *>" Z  (sp[  (dp\  ,>^ n-i_ X*a-vc d(jd n ? 3 !  %row ! n.'O (sp(dp" n"n1"n`(mn"On(i,? * ,%n': (sp (dp !" n?" nk"  n(m n"O n(i "?  5,% n' p (spE U(dpF s"G n"G n" G n(mH n"OI n5(iJ i"? K ,%L n*p (spx (dpy " z (i{ ,? | (m}  z  ! >!rx! 0 5 n !5.. .c/ !U/1'\1 retn 'A tmp!*9+'z$+>0msg9-g11[0LB ZzbufZZA %fnL e-eaig/h .  7!   * + 8 gs(ret9 n**[+C 3o "!r_8g! ^!(^ <!^["`y*V+.X !Qh! I!( g!"* " !" !""5 nV(retnv,A"Y+A h "@! ?!(? e!?"* A(keyB!" C!,D,AE(retFn -#;! !( !"!Q(ep!z+@-P+ -[(vp!,A $ ! !(  !1 "l! -X0`-X1d"m "  (buf! +!h,!"X!,A(in^! $!! "!( %"!Y"-buf$g"""z", n$ 5%H"! 3#!( Q#!#-buf$g"#" #, n &H#! $!( $!$" !%, )pC"!Y%,"%"t %,A"^%+G h &# tL%! s&!(s 3&!sQ&"unz&-bufv&o*v,J & 'L| &! '!( '!'-buf3h,  ,%  ,t ,z , ,  ,# ,* "(,,,., ,, ,Z " 0(" g( G(| !(!  )!( +)!I)" g)(buf3) (9!"*! 8y*!(8 *!8*"J :*+ < [-buf>3l )`"""*! !@+!(! ^+!!}+ ) "<$+! ,!( 1,!Q,+)y)numn(inz,,I*##-buf)i)) *Q<$z%,! PN-!(P l-!P--bufR*_+@SX" S-"Tn-"+Tn-" Tn.,q Tn"iUn.* ,+;|%V&).! z.!( .!.(numB!/(iB?/+3 ,+{*%,&(buf<+]/<+L+ + /X&(/! ./!(. 0!.0" 0=0-buf1+j+ X,i()f0! 0!( 1!>1+3 X,}'>,e(((buf<+\1*(6)-buf+hh, 9-H)+1! F2!(F 2!F>2" Ir2"J2+KN\,G On"On2(iOn2,P,AQ**+)ppI-gY-n21g-I-2Cz-I-2-I-2-I-2  -I libpng../include../include/klibc../include/bitsizepngrutil.cpngconf.hpng.harchsetjmp.hstddef.hzlib.hzconf.h3.R.P.U uKuYg$,&w%LLL=ݠLL  {Z f zg ? XKhyjuf=4d z SX6XJ/m `t&?}wgD"Yuj֑<!iwvJ iwkJ#J"glJ[!iwvJ tihJ&J"$l$<]!iwvJ tiiJ g <z+|,~t]" fw8.i!wLiJlv8.i!wKlJlv8.i!wKlJvh~JJt~>CvZoXͅ/wuvLuL["LLZm?Lhhu>LL桃v~Yg; XZ,jLkJtɽʟɄ(+h *̦uw!u=Ku=ZLyK1KOw弄Kytim K٭KΖ} gu fLxjM]h0ivgBuv>u~ gu fLiK"Lfmt[gz=>uusY~uLxܻLxt ~ uLxJt^Lmzuz.w0pjtdt_#@hu#Ks~uLxZy!ˑgtuLxZy!ˑg{t uLxL ּڠLhYMLrLZyKM01"~uLxLZyZZ f" }t uLxLzyZx!׮׮׮׮גٻגג {e%~>uLxMvyggggggh~t uLxLZy!˒Lzg hLL~J  uuLxKL Zz_/y1v~gYL!YYY[ggji蓓y")uLxL٠yKi t/`~uLx˻٠yLyvLL2uuw~uLxڢ/#/Li1Lwɔ~ uL ּڮLxiKwwQo t!//Zn<,JL>PNG unsigned integer out of range. Row has too many bytes to allocate in memory.Ignoring bad adaptive filter typeinvalid chunk typeNot enough memory to decompress chunkNot enough memory to decompress chunk.Not enough memory to decompress chunk..Buffer error in compressed datastream in %s chunkData error in compressed datastream in %s chunkIncomplete compressed datastream in %s chunkNot enough memory for text.Unknown zTXt compression type %dCRC errorNot enough image dataExtra compressed dataDecompression ErrorExtra compressed data.Extra compression dataunknown critical chunkMissing IHDR before zTXtOut of memory processing zTXt chunk.Zero length zTXt chunkUnknown compression type in zTXt chunkNot enough memory to process zTXt chunk.Insufficient memory to store zTXt chunk.Missing IHDR before tEXtNo memory to process text chunk.Not enough memory to process text chunk.Insufficient memory to process text chunk.Missing IHDR before sCALInvalid sCAL after IDATDuplicate sCAL chunkOut of memory while processing sCAL chunkmalformed width string in sCAL chunkmalformed height string in sCAL chunkInvalid sCAL dataMissing IHDR before pCALInvalid pCAL after IDATDuplicate pCAL chunkNo memory for pCAL purpose.Invalid pCAL dataInvalid pCAL parameters for equation typeUnrecognized equation type for pCAL chunkNo memory for pCAL params.Missing IHDR before oFFsInvalid oFFs after IDATDuplicate oFFs chunkIncorrect oFFs chunk lengthMissing IHDR before pHYsInvalid pHYs after IDATDuplicate pHYs chunkIncorrect pHYs chunk lengthMissing IHDR before iCCPInvalid iCCP after IDATOut of place iCCP chunkDuplicate iCCP chunkMalformed iCCP chunkIgnoring nonzero compression type in iCCP chunkProfile size field missing from iCCP chunkIgnoring truncated iCCP profile. Missing IHDR before sRGBInvalid sRGB after IDATOut of place sRGB chunkDuplicate sRGB chunkIncorrect sRGB chunk lengthUnknown sRGB intentIgnoring incorrect gAMA value when sRGB is also presentIgnoring incorrect cHRM value when sRGB is also presentMissing IHDR before cHRMInvalid cHRM after IDATMissing PLTE before cHRMDuplicate cHRM chunkIncorrect cHRM chunk lengthInvalid cHRM white pointInvalid cHRM red pointInvalid cHRM green pointInvalid cHRM blue pointMissing IHDR before sBITInvalid sBIT after IDATOut of place sBIT chunkDuplicate sBIT chunkIncorrect sBIT chunk lengthMissing IHDR before gAMAInvalid gAMA after IDATOut of place gAMA chunkDuplicate gAMA chunkIncorrect gAMA chunk lengthIgnoring gAMA chunk with gamma=0No image in fileIncorrect IEND chunk lengthMissing IHDR before PLTEInvalid PLTE after IDATDuplicate PLTE chunkIgnoring PLTE chunk in grayscale PNGInvalid palette chunkTruncating incorrect tRNS chunk lengthTruncating incorrect info tRNS chunk lengthOut of place IHDRInvalid IHDR chunkMissing IHDR before hISTInvalid hIST after IDATMissing PLTE before hISTDuplicate hIST chunkIncorrect hIST chunk lengthMissing IHDR before bKGDInvalid bKGD after IDATMissing PLTE before bKGDDuplicate bKGD chunkIncorrect bKGD chunk lengthIncorrect bKGD chunk index valueMissing IHDR before tRNSInvalid tRNS after IDATDuplicate tRNS chunkIncorrect tRNS chunk lengthMissing PLTE before tRNSZero length tRNS chunktRNS chunk not allowed with alpha channelMissing IHDR before sPLTInvalid sPLT after IDATmalformed sPLT chunksPLT chunk has bad lengthsPLT chunk too longsPLT chunk requires too much memory($%%$ %%%'7'7|  ! $! H\&AA C^ 4AA AAC ],H0F.Q dAA C $lvAA AAC0$AA AAC$AA AAC` UAh AA AAC`dGhElEpB`RdAhElB`AdAhElAp@.H`F.rdAhElEp@.c`0AA ALAA A,kAA C u,N0D.H .<8/AA AAC@LFPB@CLBPH.H@F.HhPAA AAC04E8AAA AAC04A8FiRRRCUUCWWaVV!CVVfSSCSSqCyCCPCCC;;VV[{UU;UUa{SS;SSi{;q{;y{;; P ;;WW>@@>VVW{UU>UUa{SS>SSi{D>DDq{H>HHy{L>LL>PPWP>WW>WWDSMUWWaVttt tt tP% S- S N S  Sp } SR& V& - P- V V H VN V VQ   Q - - Q  Z QZ   Q p p Q  W W V Vc u }  k u   s u      S S S S U UJ W WZ V V / @7 @ @% / D? D D- / HG H HV L LN i Su S S SX U U P P p W W p V V T p T T X p X X \ p \ \ p ` ` # S/ : S@ p S S p U U p d dv W V} S U k P k t  t P  S  P  S R  R  t  t  t  t # t# AtAHtHMtMRtRTtTftfgtgltlntnotoptputuvtv~t~tttt$t$0t 1 P1 -V p R$cRv{RRR 1 Q1 0Y h Wh k S P Q WQ W PW W S P nSuSPW$$W$,S[ eUnU$/Uc $001t12t23t 3Lt0>P>GWGLP0>R>FVFLR0>Q>ESELQLMtMNtNOt OtLnPntStPSLgRp~RRYVWWttt t t, t0 7t P6VP[jPPPP P%(P89t9:t:;t ;<t<?t?,t,2t24t47t79t9ItIgt8XPXcS8RRRgH8RQReWQV_Qhitijtjkt kltlotot0#t4#$t8$%t<%EtEzt0z|t<|tt0hPWh}R}Th}Q}4UW`UU~QRRR'2Q4WUW^R^^UPS PPXXSSSttt ttt t,t0t P_U_dPdUPURdQ'SR\SSQR RVdRR'\SdSSSttt ttttt t tPSRU R UQWVVV V<CRR Ry{PPPrwdwyPy{d{PdPdttt ttt0t4t8t<tttttt0&P&iVipPp|V|PVP*R*T*Q*hShpRpS*1Su{SSR,1RipRQRRPSVRBSH{SS_cUckPk~UURegRRRttt tt t$t(t,t0t PV R (W(3R3W Q USUZQSySPttt t+t +,t$,2t(23t,3At0AHt PFVRWRGWQSQAES!ES39PHItIJtJKt KLtLOtO't0',t4,-t8-.t<.BtBt0t4t8t<tt0HZPZVH^R^XH^Q^;UUU;W;HUO_WWW$SSSgRRHW$SSttt tLt PISRJVQZWEKWZKWLMtMNtNOt OPtPStSttttt t F tF G tG H tH I tI M tM Q tQ U tU Y tY k tk | tL^P^x SLbRb| DLbQbVQm t Rt y V] h QCHCT X z W\L\PUP!U!0V03P3y V| } t} ~ t~  t  t !t | P !S| R !W| Q !V P !P!!P B!lnB!R! PRnR!d!lRPod!! PRn!! lRn!!ln!!t!!t!!t !!t!e"t e"k"t$k""t0""t !!P!"S!!R!"W!!Q!"V""Q""V""Q""t""t""t ""t""t ""P""S""R""p""Q""V""t""t""t ""t""t"#t##t##t#<$t""P"8$S""R"<$y""Q"#V1$9$V}#;$U<$=$t=$>$t>$?$t ?$@$t@$C$tC$W%t0W%X%t4X%^%t8^%_%t<_%`%t`%a%ta%b%tb%c%tc%z%tz%z%t0<$Z$PZ$w%V<$P$RP$z%P<$P$QP$s$Ss$x$Q$y%U$$Wb%x%W$$Sa%v%S$g%Q$k%R|%}%t}%~%t~%%t %%t%%t%V&t|%%P%R&S|%%R%%U%%R%U&U|%%Q%%W%%Q%%W% &Q-&:&QK&T&W%%V%S&V%%W%T&W%&jR&-&j-&3&jR3&V&jX&Y&tY&Z&tZ&[&t [&^&t^&(t X&g&Pg&(SX&k&Rk&(WX&k&Qk&(V&&P&&P&&P( (t ( (t ( (t ((t()t))t))t))t))t))t((P()S((R(;(W;(F(RF()W((Q()V((P))nR))n))t))t))t ))t))t)+t0++t<++t++t0))P)+W))R)+P))Q)*V**V++V%*+UT*f*Rt*~*R~**S*+Qu++Q**Q**Q**Q**X*+X-png_get_uint_32png_get_int_32'png_get_uint_16Jpng_get_uint_31png_read_start_rowpng_crc_errorCpng_read_filter_rowpng_do_read_interlacepng_combine_row?png_check_chunk_namezpng_decompress_chunkpng_crc_readpng_crc_finishA png_read_finish_row png_handle_unknown"!png_handle_zTXt!png_handle_tEXt"png_handle_sCAL-#png_handle_pCAL$png_handle_oFFs$png_handle_pHYs5%png_handle_iCCP&png_handle_sRGB&png_handle_cHRM'png_handle_sBITG(png_handle_gAMA(png_handle_IEND )png_handle_PLTE)png_handle_IHDR*png_handle_hISTL+png_handle_bKGD+png_handle_tRNSh,png_handle_sPLT+big_row_bufgreen_ygreen_xpng_handle_IHDRpng_write_status_ptrslengthpal_ptrindex_to_palettemalloc_fnwarning_fnpng_uint_32s_startsave_bufferintentpng_sPLT_entrypbit_depthrgb_to_gray_statusscal_s_widthfinal_widthpng_charpppalettetotal_outpng_sPLT_structflagsbufferzbufblue_xblue_ypng_pass_startpng_sPLT_entry_structnentriespng_info_structpng_get_int_32entriessplt_palettescur_palettegamma_16_tablepush_lengthdummypng_combine_rowistopendptrbluepng_handle_gAMAzfreepng_row_info_structcompression_typetime_buffer__ebxshort int/home/hpa/syslinux/release/syslinux-3.63/com32/libpaeth_rowfrequencypng_read_status_ptrmodepng_uint_16pint_y_greenlibpng/pngrutil.cx_blueGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)x_offsetpng_malloc_ptrunit_typeiccp_namewhite_xinfo_ptrtext_sizey_greenpng_pass_incy_offsetprefix_lendo_filterprev_rowpng_rw_ptrpng_check_chunk_nameint_x_redpcal_unitsbuffer_sizepng_handle_sBITprofile_sizeoffset_xcurrent_buffer_ptrpng_textpiccp_proflenopaquetransformationschunk_lengthpng_read_filter_rowz_streamfloatshiftavg_rowrowbytespalette_lookupindexsig_byteswrite_data_fnscal_pixel_heightgamma_16_from_1chunk_namelong long unsigned intuIntskip__ebpz_stream_suLongusr_bit_depthpng_voidp__jmp_bufpng_struct_defpng_uint_16pprow_fnbackgroundpng_byteppsignatureprefix_lengthpurposerow_bytespng_get_uint_31zallocpng_get_uint_32lengthavail_outmng_features_permittedpng_handle_oFFspng_error_ptrparamspng_fixed_pointpng_unknown_chunkpasssize_tpng_handle_pCALerror_fnio_ptrwidthrgb_to_gray_green_coeffpng_int_32png_handle_tRNS__eipzlib_strategyres_xmax_pixel_depthsave_buffer_sizeBytenew_paletteint_y_white__esiscal_pixel_width__espdither_indexpng_unknown_chunk_tphys_unit_typepng_row_info__ediprocess_modey_whitepng_color_16free_meerror_ptrzlib_mem_levelred_xred_ychunksub_rowsave_buffer_maxscal_unitpng_pass_ystartcharread_data_fnpcal_nparamsadlertotal_intext_lengthpng_handle_iCCPpng_const_charpmem_ptry_redtextpng_crc_finishpng_bytepjmp_bufdataend_fnup_rowdshiftpng_handle_IENDpng_uint_16gamma_from_1current_textpng_unknown_chunkppcal_paramspng_sPLT_entryuser_transform_depthunknown_chunkswrite_row_fnpng_pass_yincpng_IDATzlib_methodinterlacedscreen_gammapng_user_transform_ptrdata_lengthlong long intpng_sPLT_tpsshiftnum_textBytefvaliddepthnext_outnum_transx_pixels_per_unituint_xuint_yunknown_chunks_numtrans_valueschannelsnum_chunk_listiwidthfillers_incsrgb_intentpng_size_twhite_yrow_bufcomp_typerow_widthpng_do_read_interlacesizepng_free_ptrusr_widthrgb_to_gray_red_coeffchunkdataextranparamsbackground_gamma_typeprefix_sizemaskinternal_stateavail_inrgb_to_gray_blue_coeffint_x_greenlong unsigned intheightdata_typepng_read_finish_rowinfo_fnigammax_greendither_sortrow_numbermmx_rowbytes_thresholdpixel_byteszlib_levelpng_handle_PLTEneed_crcgreennum_rowsfree_funcpalette_to_indexusr_channelsint_x_bluefile_gammazlib_window_bitspng_ptrpcal_purposetext_ptrpng_crc_errordata_lenmax_textread_row_fnzbuf_sizegamma_to_1profile_lengthpng_color_structchunk_listres_yuser_transform_channelspng_textpng_row_infopspare_bytelong intgamma_16_to_1next_ingraylocationpng_structppng_structpng_handle_sRGBreadbuffilterpng_progressive_end_ptrint_y_blueskip_lengthfilter_typealloc_funcpng_infopng_progressive_row_ptrgammay_pixels_per_uniticcp_profilepng_colorpng_color_8_structcurrent_text_sizetruelenbackground_1png_charpnamepng_infoppng_read_start_rowjstopunsigned intpng_handle_zTXtpixel_depthidat_sizecurrent_text_ptrx_redgamma_shiftpng_color_16_structbackground_gammay_bluepng_handle_sPLTint_x_whitealphanum_palettescal_s_heightint_gammapng_handle_bKGDcurrent_text_leftrow_pointerspng_handle_hISTx_whiteuser_height_maxnewlengthtypepng_handle_unknownunsigned charsave_buffer_ptrpng_color_8read_user_chunk_fnuser_width_maxumsghistcurrent_bufferpng_progressive_info_ptrcurrent_buffer_sizeread_user_transform_fnint_y_redstatepcal_typepcal_X0pcal_X1offset_unit_typeinterlace_typepng_decompress_chunkpng_colorpcompressionunitspng_handle_sCALsigned charpng_get_uint_16profileentry_sizeshort unsigned intpng_handle_pHYsuser_transform_ptrirowbytesreservedfree_fnvoidpfsplt_palettes_nummmx_bitdepth_thresholddoublerow_infooffset_ys_endpng_bytepng_handle_cHRMcrc_bytespng_crc_readchunklengthzstreamjmpbufsig_bitpng_user_chunk_ptrpng_handle_tEXtentry_startpng_sPLT_tuser_chunk_ptrvaluecolor_typeiccp_compressiontransgamma_tableasm_flagspng_text_structGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.rodata.rodata.cst4.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4+ 8 % ,+,,0,,B.-> R\MN P^2b qp0m X` yppl ,w 39   0s.    !%$!4HD\&T^qdlv!7>N Ucs 0Lk )08/CY`whPD!H~1>NiL0y| !"D"d<$>#0|%@MX&]j(z)pngrutil.cmsg.3512png_get_uint_32png_get_int_32png_get_uint_16png_get_uint_31png_errorpng_read_start_rowpng_init_read_transformationspng_pass_yincpng_pass_ystartpng_pass_incpng_pass_startpng_mallocpng_memset_checkpng_crc_errorpng_read_datapng_read_filter_rowpng_warningpng_do_read_interlacememcpypng_combine_rowpng_check_chunk_namepng_chunk_errorpng_decompress_chunkinflateinflateResetpng_malloc_warnpng_freesprintfpng_crc_readpng_calculate_crcpng_crc_finishpng_chunk_warningpng_read_finish_rowpng_reset_crcpng_IDATmemcmppng_handle_unknownpng_handle_as_unknownstrcpypng_set_unknown_chunkspng_handle_zTXtpng_set_text_2png_handle_tEXtpng_handle_sCALstrtodpng_set_sCALpng_handle_pCALpng_set_pCALpng_handle_oFFspng_set_oFFspng_handle_pHYspng_set_pHYspng_handle_iCCPpng_set_iCCPpng_handle_sRGBpng_set_sRGB_gAMA_and_cHRMpng_handle_cHRMpng_set_cHRMpng_set_cHRM_fixedpng_handle_sBITpng_set_sBITpng_handle_gAMApng_set_gAMApng_set_gAMA_fixedpng_handle_IENDpng_handle_PLTEpng_set_PLTEpng_handle_IHDRpng_set_IHDRpng_handle_hISTpng_set_hISTpng_handle_bKGDpng_set_bKGDpng_handle_tRNSpng_set_tRNSpng_handle_sPLTpng_set_sPLTfqx=!O!V #j%{% % s *  # + , -   %  %G ,X -] d z % % , - -   % - %Ihqw.#,-%+-. #:!j// 2(;K1 !"46/@5G6PW/*#!#)+^5c6|'8(9/ 8-%(B:P-[1~,#/1# #.)<,JQ#Z-<--, /1<,GN#<--#1',2?/H1f?|#?#-@-+2=U\#v,/1&#4;#Y,l-q#B- /6#?1K_/h1s~D#1/1&:F_fq|##1/1--#5)T-Y-#H-##1.@/I1`g##/6#AJcju##//#4/;M/Ty#//#//;# ? Ld Mp 1     #  # 1! !/)!1!O!!!!!#!!#!1""/!"1,"7"Q"X"#`" y"Q"R""""#"1""####*##3#1[#b#i##/#1#U$$#$%$#Q$V$`$g$}$/$1$$$ n%W%%%%%#%1%% &/6&1G&Yl&s&~&&&#&1&&&/&1.'5'#'[(&(1(B(I(#R(1}(/(/A)H)#`)n)u)#)/))1)]))**#*1*,*/5*1B*-i*-n**-**#**,*+_+-+-) % (H0`-#l1#- !&18CJU\hv#?M[iw #1?M[j ".5GYo -ETcr !0?O[qz/;Q[jy-<KZix,;JYiy  ) 9 I Y i y           ) 9 I Y i y           ( 7 G S e u            $ 3 B Q ` p            0 @ P ` p         0@P`p 0@P`p 0@P`p 0@P`p 0@P`p#Fn&Mt  04@ P[_c hr         # (IQUY ^i ny       % EIW f u         # 1 ? N ] l z       ' ,7 <G LW \g lw |          ) .C HLZ h sw         $ +/4? N ] b{       # (3 8C Q Va o t         ) .?CR a fq v          $9 EMQU Ze ju       $ -1BFKaej            -  2 <  G O S W  \ g  l p u                ! ! !!(!0!4!8! =!H! M!X! ]!h! m!x! }!! !! !! ! !!! !!!!! "" "" #"." 3">" N" S"^" c"o"" """" "" "" "" "" " "## !#3#;#?#C# H#S# X#c# h#s# x## ## ## # #### #$ $'$+$/$ 4$?$ D$O$ T$_$ s$~$ $$ $$$$$ $$ $$ $$ %% %$% )%;%C%G%K% P%[% `%k% p%{% %% %%% %%% %% %%% %&& &$& )&4& 9&D& I&T& Y&d& x&|&&&&&& && && && &'''('4'@'L'X'c' h't'''''''' '' '''' '( (( ("( '(2( B( M(U(Y(]( b(m( r(}( (( (( ((((( (( (( () ))) ) %)0) 5)@) E)P) U)z) ))))))) )) )) ) * *-*8* =*H* M*X* ]*h* m*y** **** ** ** ** * * +++&+ R+Z+^+b+ g+r+ w++ ++ ++ ++++ ++ ++ , , ,%,),9, ?,C,n,v,z,~, ,, ,, ,, ,, ,, ,,,, - --$-(-Z-m----  $(, ( ,8 <H Lh l    8 <P T   , 0l p  ( ,t x  4 8X \    , 0h l   8 <pngtrans.o/ 1207848664 1026 1026 100664 22540 ` ELF?4(HDÍvuHDfw HDƀÍvwHDÍvHD IRMfuÃHDÍvHDffIu H@`@uƀuvƀÐSKD[ÍvHDÁHDÃHD Ívxu@1A9uËHfu@19rfu@1 T9rÐVSӀx up 01KDKKTKA9u[^ÐSH w6Xu!uu B9r[ÍvUWVSƉ͋8@<t<@~ ~ u\x1=ѻADADAC9rDADADAC9uF x1gѻ-ڈADADADA DA DA C9r2DADADADADADAC9uF 0kFF t<@~ u~~ u0x11ZC9u DZC9uF ~Dx1,JDDJA9rDJDDJA9uF ?FF @tf[^_]ÐVSӊP0@ <u?u1 QAAQC9u{uv1DTA9u]<uYu(1QAAQQAAQC9u,u'1ˊDˈTTDDTA9u[^ÉP4H8T$P9f@4@ `P0pH(hX8xD$dT4t L,l\<|B"bR2r J*jZ:zF&fV6vN.n^>~A!aQ1q I)iY9yE%eU5u M-m]=}C#cS3s K+k[;{G'gW7wO/o_?@P `0pDT$d4tHX(h8x L\,l<|AQ!a1qEU%e5u IY)i9y M]-m=}BR"b2rFV&f6v JZ*j:zN^.n>~CS#c3sGW'g7w K[+k;{O_/o? 0@P`p!1AQaq"2BRbr#3CScs$4DTdt%5EUeu&6FVfv'7GWgw(8HXhx )9IYiy *:JZjz +;K[k{ ,N^n~/?O_o% : ; I$ > : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 I!I/ &I : ; : ;I8  : ;.? : ; ' @ : ; I : ; I.? : ; ' I@ .? : ; ' @: ; I  4: ; I4: ; I4: ; I  4: ; I !4: ; I ": ; I#.? : ;' @$: ;I%: ;I&4: ;I '4: ;I(4: ;I): ;I *4: ;I+.? : ;' @ ,: ;I -.? : ;' I@ .4: ;I LHI0 B T %Sint~ # Ou u 7 7 P  u u 8T U# V7# xWI# Y# nZ7# [I# msg]# ^# [`# oa#$ +bu#( ( dn#, reI#0 mfI#4[g R^n#Bg B1= i   B# q B#  B# Z B#  B# $B#t ZT 0o&gjk(npg qF@&RdG red# #j#t j E w#red# #j# #~ red# #j# #} # ( red# #j#} ##;`   !##!## x`U  n#key%!#&!#(# { 0~10X Y0#Z#[#  ^#@`aX@ #! ##_# # ##### # #=# # #Q # O  #(c#,n#0 n#4#8#<9#D0#H;#Rp#\#` #d #hU #l#pE  #t  #x #|"  # #d  # #A #j  # -!# .# /#0!#/1X# 2#e3#8#l=L#>#C!#g D!#F#(G#)Ll#M#DX#`Z-#[-#^!# _!# f4# j#q n#No#p# q# r#5s# t# u# K. x^ z  X u #_### =#  #   p X   "4i#64#O74#8# 9W#$X:W#(;#, >#0PI#4JJ#8c K#9#O#<P#@2Q#DS#HT#" U# Vn#Wn# Xn#Yn#*Zn#\#! ]# ^#_#_`#ca#Ub#x c#d#ze#f#g#Wh#i#jX # l#crcm#n# o#p#q0# r# s#t#u#v#w#x#y# z#={# |#}}#\##Y  #;# #( n#O  # #?##, #CF#F# F##Q#9#0# #{#\ #4## #f##J #R# #8###r #n#7n# # #!# !#h#w#E #!#### 7#Fn#X #### #x# #)# *#K+#0#E1^#v2#6#l :#4;# =#B#6 E# F# .v @F W " ci  "    "  nY   "  7   "   n! 7 " d  CI^n " Ly'jp " (  " %t "P_t "P '-t &"P@4 50At 4"Pur?DZt >"P> Jn\ut I"^xt ]"P\]R9]n1*~D }"d\}9}nP t "Pv t "Pt "PeN Ctd rowR rpid8&rpid-Crp i̋Q!d͋PbDo(d T"rowrNlrp iQdYg tR#R)`p$_d %row_y&rphR'endh (h#F$d )rowR$z*sp*dp(U'ih#,8$d +%rowI5(&}m*rp+'i,(N0*rp7'i8(N< *rpF'iG(NK&5*rpU&iVQ0(NZO+2 m8Ft, k"P$Plm,JlnQ,c ln-HLt$ "!7 . .: libpng../include../include/klibc../include/bitsizepngtrans.cpng.harchsetjmp.hpngconf.hstddef.hzlib.hzconf.hK J tK  K < Ju={z">Yu Xu u(KJjx:lx:yx=GLn=uF_J&8`Z[w[`1%iOgupuuoK JguuuustuuuuurtKhid tq^K\g tu~_KhLLmP8/v=g8=uF|L=g==gy< =uKKyJ X <==z 4GR%N Vb&p^ V  o(~-z W A/  W0a/e>.>>TC@ E} ,   =IVf0wD\xOO D+pA';F8bHpngtrans.conebppswaptabletwobppswaptablefourbppswaptablepng_set_bgrpng_set_swappng_set_packingpng_set_packswappng_set_shiftpng_set_interlace_handlingpng_set_fillerpng_set_add_alphapng_set_swap_alphapng_set_invert_alphapng_set_invert_monopng_do_invertpng_do_swappng_do_packswappng_do_strip_fillerpng_do_bgrpng_set_user_transform_infopng_get_user_transform_ptr !&18CJU\hv#?M[iw #1?M[j ".5GYo -ETcr$3BQam!AMcm|!0?N]l{ />M\k{  + ; K [ k {           + ; K [ k {           + : I Y e w            ' 6 E T c r           " 2 B R b r        "2BRbr"2BRbr"2BRbr"2BRbr"2BRbr#5X8_  '+3FMQYfp {     % 07;CV]ai|    $ )3 9=Wkrvz       < AL X`dh mx       ( 15N SW\g rv    $ 2:>FT_ dr  ( ,8 <H LX \h lx |        8 <T Xd hpngwutil.o/ 1207848664 1026 1026 100664 1596 ` ELF4( % $ > $ > = intke short int/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)floatlong long unsigned intcharlong long intlong unsigned intlong intunsigned intunsigned charsigned charshort unsigned intlibpng/pngwutil.cdoubleGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.debug_line.debug_str.comment.note.GNU-stack4!4'4,4*>^:  JV0a.j44z     pngwutil.c !&-4;IPW^elszpngread.o/ 1207848664 1026 1026 100664 37536 ` ELFb4(`ÐUWVS,ʼn˅tt ډ,04t Ѐ t PЀ߉t 8t2+ 1 C98|<t2+ 1 C9<|@t2+ 1 C9@|EHxD$]u} D$1҉]u} D$T$,[^_]UWVSD$T$L$ u1D$0|$u1D$|$ u D$ D$ D$L$ډt+ j@ډD$ |$t/ j@T$(D$(D$D$[^_]UWVSƉ1\$ډډljډuuډt^uuF<tN<N<u$uF<t Ou*uuuuuquLu'uuuuu qu Ou -u F<[^_]Ív@@@uUWVSƉՉ@@@uFD<$tyPuK@Ѓt_tO1u*Ѓt>t.u w't u F<u FTFX~Ltk1҉\$ډډډt 7tFLFH9vFLNLFL)FHu+~Xu~Lu t MN<N@ !tV`uc~X<vt!QQJP@P @P~DuFB@ttGFDtAwt t6 tt`tӃ[^_]ÐUWVS ƉT$D$1D$1ɉC9uG;|$}1 [^_]fUWVS ʼn׉΅t7u1'1 C;\$ u01ɉC;\$ ut1 1҉C;\$ u [^_]ÐVSÉ@@@u w[[^UWVSƉT$<woؽ)݉׃ Ɔډt2w!Mډt+wN<\$ډډljډuT$뤹uT$뀉ډuN<T$u N<+F< uT$u6F<uuu N<[uT$HuT$!uT$uT$uT$uT$uT$^uT$7uT$uT$uT$uT$uT$tuT$MuT$&T$[^_]fUWVSƉ׉t?v &tttt+vtt t@t*tL$T$ytt j@uRW@D$1#‰D$D$;G|ԋO[^_]fUWVS,Ɖϋ1Ɋ:tAl$ډwÉ1҉ǃ@Bǃ@Bǃ ChCl[pCH8t,u3*CW : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 I!I/ &I : ; : ;I8  : ;.? : ;' @ : ;I .? : ;' @: ;I4: ;I 4: ;I 4: ;I : ;I4: ;I 4: ;I! U" U#4: ;I $.? : ; ' @%: ; I&4: ; I '4: ; I(4: ; I)4: ; I *.? : ; ' I@+: ; I ,4: ;I? < Qq@ 0 8B NT %int  Ou u 7 7 P  u u C8T U# V7# WI# Y# Z7# [I# msg]# ^# `# a#$ Gbu#(  dn#, eI#0 fI#4[g  Rsn#tgc B<H! uw  B#  B# = B#  B# Z B# B#\ GTq w05 &<gmjRkQn'p"(g qL^p red#p ##c v(6 #red#p ## #um red#p ## #n #4/ red#p ##n ##hl   -## ## 9"l# n#key%-#M&-#(# O 001<*X Y<#dZ#f [#  ^#LL`adL z# ### #t ##x#`## ## # #f # # >  #() #,n#0 n#4M#8#<#D(#H(#R#\#`#d#hD #l>#p= #t  #xm #|  #G #&  # #j #[  # --#.#/#0-#1d#2#3#8#=X#>#C-#V D-#:F#yG#5Lx#M#X#Z9#[9#^-# _-# f@# j#b n#o#p#q# r#^s# t# u# } xj z  b{  v  z##`#x#  #  # M X  v   @4u#j6R#<7R#8# 9u#$:u#(s;#,>-#0[I#4J#87 K#97O#<P#@NQ#DS#HT# U#e Vn#Wn# Xn#Yn#Zn#z\# ]#v ^# _#`#wa# b#: c#d#Q e#f#pg#h#i#jv # l#crcm#n#t o#p#q<##r# s#+t#^u#v#`w#xx#Ty# z# {# |#}#" # #J  #(# (#* n#>  #? ### #XR#R#z R####(# # # ##i# #S##B#g# #####`n#Ln# # #-# -###=#-##D#U# n#, ## ##  ## #)#N *#+#?0#21|#2#6#. :#!;# =#B#.E# F# L !^d u @   @  #  @  n u  @     - @   nL9? U @ & ag|n @ X' @ w (  @ QLt @P R'0 @Q o uTjR<RH/inyn98jinbynsinyn=0;^; }<  >@? ? A?B*h= @ gh,V<"t !@(,'  +@row++ret2n ghKc_( v P ^@ ^@i`Y `^anhjanrpb@/x  -@frow-@.@v .i0erp1@dp2@ : ; B IZ   @ Z= : <@< !k B/C"ghf  @  #n #rownX8Pnh$ G %7A %S_ % } &uT'in ( @ $F H % @ %S %  %  o)msgFVgO$ 5> % @v *9 !@8 %Sy % %jR % R +?+2 |% & $@'i,n1`)msgsF*r@Z%S%%jR+ Rg,n,k, ,n <, <,C <,6 2<,5  E<, X<,_ k<, ~<, <,E  <, <, <,  <, <,Q <, <, )<, <<,^ O<B libpng../include../include/klibc../include/bitsizepngread.cpng.harchsetjmp.hpngconf.hstddef.hzlib.hzconf.h g~. KZKˑ Y Y|[w[v[y˄==>==>~ .hhgiM2wMα~>t!u@KKLKOKKKKKKKKKKKKKKKKϭ{gm gY#fhw t ֠ ֠K'Zg!u=Kt=ZLKiK1) xvKhK&KKv gU  z}gvK;~Xˠ=vvLtYt!uDKKKKKLK!LuuʼgK#K#K#K#K#K#K#K#K#K#K#K#K'K#K'"Y^Y{YtY tY$ tY|kɳKzYzY t012wvN z#u۟"uu>Tu+uu1@LLvvQ>~t%} J^ץ  v4>Lvuu>-uuɒ ~?Too many IDAT's foundInvalid attempt to read row dataNot enough image dataExtra compressed dataDecompression errorIgnoring extra png_read_update_info() call; row buffer not reallocatedNot a PNG filePNG file corrupted by ASCII conversionMissing IHDR before IDATMissing PLTE before IDATImage is too high to process with png_read_png()Application uses deprecated png_read_init() and should be recompiled.1.2.1zlib memoryzlib versionUnknown zlib errorApplication was compiled with png.h from libpng-%.20sApplication is running with png.c from libpng-%.20sThe png struct allocated by the application for reading is too small.The info struct allocated by application for reading is too small.1.0.6 or earlierIncompatible libpng version in application and libraryzlib memory errorzlib version error "5CVz|  $(AA AAC@<0AA AAC0f ( R6FN H^291q<m P8 }=y  @Nl _P  P00P}a.aaf nj    "(3DMWbip0  )9OXbu~ $-=FV_ox -g:L\px( Nx k ,*6N z\hu +8CT3dsH 8H&-<MSpngread.cpng_set_read_status_fnpng_read_destroypng_info_destroypng_freepng_zfreeinflateEndmemcpymemsetpng_destroy_read_structpng_free_datapng_destroy_struct_2png_read_endpng_crc_finishpng_read_datapng_get_uint_31png_reset_crcpng_crc_readpng_IHDRmemcmppng_handle_IHDRpng_IENDpng_handle_IENDpng_handle_as_unknownpng_IDATpng_errorpng_handle_unknownpng_PLTEpng_handle_PLTEpng_bKGDpng_handle_bKGDpng_cHRMpng_handle_cHRMpng_gAMApng_handle_gAMApng_hISTpng_handle_hISTpng_oFFspng_handle_oFFspng_pCALpng_handle_pCALpng_sCALpng_handle_sCALpng_pHYspng_handle_pHYspng_sBITpng_handle_sBITpng_sRGBpng_handle_sRGBpng_iCCPpng_handle_iCCPpng_sPLTpng_handle_sPLTpng_tEXtpng_handle_tEXtpng_tRNSpng_handle_tRNSpng_zTXtpng_handle_zTXtpng_start_read_imagepng_read_start_rowpng_read_rowpng_pass_dsp_maskpng_combine_rowpng_read_finish_rowinflatepng_read_filter_rowpng_memcpy_checkpng_do_read_transformationspng_do_read_interlacepng_pass_maskpng_read_imagepng_set_interlace_handlingpng_read_rowspng_read_update_infopng_warningpng_read_transform_infopng_read_infopng_sig_cmppng_read_pngpng_set_invert_alphapng_set_strip_16png_set_strip_alphapng_set_packswappng_get_validpng_set_expandpng_set_invert_monopng_get_sBITpng_set_shiftpng_set_bgrpng_set_swap_alphapng_set_swappng_mallocpng_get_rowbytespng_read_init_3png_libpng_verpng_destroy_structpng_create_structpng_zallocinflateInit_png_set_read_fnpng_read_init_2sprintfpng_read_initpng_create_read_struct_2png_create_struct_2png_init_mmx_flagssetjmppng_set_mem_fnpng_set_error_fnabortpng_create_read_struct%2?LYfs+Tf$&8A J!^"h#o$~%&$'()$*+,$)$$7>*GV,]$l-{.$/0$12$34$56$%748;$J9Y:`$o;~<$=>$?@$AB$CD$(E4F;$JGVH]$lIxJ$K+M  kOtPQ* !") $*X"nR**N So T U V O P W P P Q6 YZ N N N N M  \> P _e _n u   *   ! " # $ % & $ ' (- )4 $I +S ,Z $q )x $  * , $ - ) $   *- .4 $E /T 0[ $l 1{ 2 $ 3 4 $ 5 6 $ 7 8 $9:$/;><E$V=e>l$}?@$AB$CD$EF$G(H/$@IOJV$gKy+a^*bcdefg0eAhLiWjckolx[mnmX(pGVq`rrmst\ *;uw\pw\**o(-vVzg{|}~p;pJpfpw{\pw\*mst&-6*Yub|kyM ] !&18CJU\hv!/KYgu!/=KYgv.:ASe{ )9Q`o~'0?N]my-MYoy-<KZix,;JYhw  ' 7 G W g w           ' 7 G W g w           + : I X g w            ' 6 E T c r            0 @ P ` p          0@P`p 0@P`p 0@P`p 0@P`p 0@P`p 0ASv.V} $ )4 9D IT Yhs x       ! -59= BM R] bm r}          2:>FQ \dhl q|         #; QY]a fq      %-15 :E JU `hlp u         * /MQVlsw{           ( -1\cgk pz        $?JNR Wa fp u %8K^q /B  ( ,P T    8 <` d    X \t x pngrio.o/ 1207848664 1026 1026 100664 15748 ` ELF,4(SÉP,tH(@({$t"C$AY[[XZ[ÍvSX(tXZ[úsY[[fVSƉЉˋN,9t[[^Y[^% : ; I$ > : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 < I!I/ &I : ; : ;I8  : ;.? : ; ' @: ; I.? : ; ' I : ; I.? : ; ' @4: ; I1X Y 1. 0 B TY,%int0  9 Ou u 7 7P  u u 8T U# -V7# WI# >Y# 6Z7# [I# msg]# ^# (`# Wa#$ bu#( rdn#, eI#0  fI#4[g RFn#g By    y z  B#  B#  B#  B# \ B# B#. GT I p 0&egj$knp'-g q` Wi{W red##L#  3% .#red##L# #w red##L# #] # ? red##L#] ##_e   2#8#  ##  }e   n#key%2#&2#(#  015,X Y5#6Z#[#  ^#Eu`oa]E #k#2## #c #G#o# #q#- # ## # # # e  #(#,#n#0- n#4#8 #< #Dv3#H3#RF#\p#` #dQ#hk #l@#p   #t  #xo #|  # # #h # #J  # -2# .# /#02#1o# 2#3#8#=Q#c>#^C2#} D2#F# G#Lq#7 M#X#ZD#L[D#^2#o _2# fK#} j#Q n#o#p# q#Mr# s#t# u# D xc z  ] ] ## #o# #  # O  u ]   ' 4z#69#<79#8# >9\#$:\#(;#,k >#0 I#4J#8s K#9O#<P#@Q#D~ S#HT#B U#Vn#Wn# Xn#Yn#Zn#\#k]#^#_#`# a#b#c#d#e#f#Bg#h#i#g j] # l#crcm#n#c o#Gp#nq5# r# s#t#u#yv# w#ox#y# z#{#|#4}###9  #3# 3# n#e  # # #U#L #+]#^]# ]# ## #v3#6 ##|##;# #S## #:#! ####W #bn#n# # #b2# 2###  #2## # <#n#h #y###6 #@#} #I )#*# +#0#21c#( 2#6#:#!;#=#qB# E# F# 3{ WEK \ ' hn  '    '  n >   '  M   '   n & < ' i   HNcn ' QO'ou ' (  '  E '[\;Hf '&6D/bz O__pN__sN__nN__fN>,h +'6+/+"Q-;s}6ncXM libpng../include../include/klibc../include/bitsizepngrio.cstdio.hpng.harchsetjmp.hpngconf.hstddef.hzlib.hzconf.hg?KZzhu{y<_~tLu1IY; t$jKu;YIt's an error to set both read_data_fn and write_data_fn in the same structure. Resetting write_data_fn to NULL.Call to NULL read functionRead Error|  EACv AGA HACJ AHA h,AA C\ Htt:t:;t ;BtBCtCETP;S;APADS+RACR2QAEQHItILtLVtVWt W_t_`t`fTHUPYfPHURY^RHUQY_Qhitijtjmt mtt thqPqVPVhxRx}PhvQvSSNpng_set_read_fnpng_read_datazpng_default_read_databig_row_bufpng_write_status_ptrindex_to_palettemalloc_fnwarning_fnpng_uint_32save_bufferpng_sPLT_entrypbit_depthrgb_to_gray_statusscal_s_widthpng_charpppalettetotal_outpng_sPLT_structflagszbufpng_sPLT_entry_structnentries_IO_filepng_info_structentriessplt_palettescur_palettegamma_16_tablepush_lengthdummybluecheckzfreepng_row_info_structcompression_typetime_buffer__ebxshort int/home/hpa/syslinux/release/syslinux-3.63/com32/libpaeth_rowfrequencypng_read_status_ptrmodepng_uint_16pint_y_greenx_blueGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)x_offsetpng_malloc_ptriccp_namey_greeny_offsetdo_filterprev_rowpng_rw_ptrint_x_redpcal_unitsbuffer_sizecurrent_buffer_ptrpng_textpiccp_proflenopaquetransformationsz_streamfloatshiftavg_rowrowbytespalette_lookupindexsig_byteswrite_data_fnscal_pixel_heightgamma_16_from_1chunk_namelong long unsigned intuInt__ebpz_stream_suLongpng_default_read_datausr_bit_depthpng_voidp__jmp_bufpng_struct_defpng_uint_16pprow_fnbackgroundpng_byteppsignaturezalloclengthavail_outmng_features_permittedpng_error_ptrpng_fixed_pointpng_unknown_chunkpasssize_terror_fnio_ptrwidthrgb_to_gray_green_coeffpng_int_32__eipzlib_strategysave_buffer_sizeByteint_y_white__esiscal_pixel_width__espdither_indexpng_unknown_chunk_tphys_unit_typepng_row_info__ediprocess_modey_whitepng_color_16free_meerror_ptrzlib_mem_levelsub_rowsave_buffer_maxscal_unitcharread_data_fnpcal_nparamsadlertotal_intext_lengthpng_const_charpmem_ptry_redtextpng_bytepjmp_bufdataend_fnup_rowpng_uint_16gamma_from_1current_textpng_unknown_chunkppcal_paramspng_sPLT_entryuser_transform_depthunknown_chunkswrite_row_fnzlib_methodinterlacedscreen_gammapng_user_transform_ptrlong long intpng_sPLT_tpnum_textBytefvaliddepthnext_outnum_transx_pixels_per_unitunknown_chunks_numtrans_valueschannelsnum_chunk_listiwidthfillersrgb_intentpng_size_trow_bufpng_read_datasizepng_free_ptrusr_widthrgb_to_gray_red_coeffbackground_gamma_typeinternal_stateavail_inrgb_to_gray_blue_coeffint_x_greenlong unsigned intheightdata_typeinfo_fnx_greendither_sortrow_numbermmx_rowbytes_thresholdzlib_levelgreennum_rowsfree_funcpalette_to_indexusr_channelsint_x_bluezlib_window_bitspng_ptrpcal_purposemax_textread_row_fnzbuf_sizegamma_to_1png_color_structchunk_listuser_transform_channelspng_textpng_row_infopspare_bytelong intgamma_16_to_1next_ingraylocationpng_structpfreadpng_structfilterpng_progressive_end_ptrint_y_blueskip_lengthfilter_typealloc_funcpng_infopng_progressive_row_ptrgammay_pixels_per_uniticcp_profilepng_colorpng_color_8_structcurrent_text_sizebackground_1png_charpnamepng_infopunsigned intpixel_depthidat_sizecurrent_text_ptrx_redgamma_shiftpng_color_16_structbackground_gammay_blueint_x_whitealphanum_palettescal_s_heightint_gammacurrent_text_leftrow_pointersx_whiteuser_height_maxunsigned charsave_buffer_ptrpng_color_8read_user_chunk_fnpng_set_read_fnuser_width_maxhistcurrent_bufferlibpng/pngrio.cpng_progressive_info_ptrcurrent_buffer_sizeread_user_transform_fnint_y_redstatepcal_typepcal_X0pcal_X1offset_unit_typeinterlace_typepng_colorpcompressionsigned charshort unsigned intuser_transform_ptrirowbytesreservedfree_fnvoidpfsplt_palettes_nummmx_bitdepth_thresholddoublerow_infopng_byteFILEzstreamjmpbufsig_bitpng_user_chunk_ptrpng_sPLT_tuser_chunk_ptrcolor_typeiccp_compressiontransgamma_tableasm_flagspng_text_structGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 |1P%+0zBB> 1h R/N 4=^2qm <=0 ~4KR l=  t=0 *.)+)+/`  1[    Eh,0<HJTpngrio.cpng_set_read_fnpng_default_read_datapng_warningpng_read_datapng_error_fread'.3Zy=b   ! & 1 8 C J U \ h v         # ? M [ i w               & 4 B P ^ l {             3 E L ^ p          $ 4 D \ k z           ) 8 G V f r           & F R h r            & 5 D S b q            % 4 C R a p             0  @  P  `  p              0  @  P  `  p              !  0  ?  N  ^  j  |               ,  ;  J  Y  h  w              '  7  G  W  g  w           ' 7 G W g w           ' 7 G W g w           ' 7 G W g w           ' 7 G W g w           ' 7 G W g w           ( : ]       = d                ' , 6 A |          < @` dpngwio.o/ 1207848665 1026 1026 100664 1592 ` ELF4( % $ > $ > = intke short int/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)floatlong long unsigned intcharlong long intlong unsigned intlong intunsigned intunsigned charlibpng/pngwio.csigned charshort unsigned intdoubleGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.debug_line.debug_str.comment.note.GNU-stack4!4'4,4*>^:  JV0a.j22z     pngwio.c !&-4;IPW^elszpngwrite.o/ 1207848665 1026 1026 100664 1596 ` ELF4( % $ > $ > = intke short int/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)floatlong long unsigned intcharlong long intlibpng/pngwrite.clong unsigned intlong intunsigned intunsigned charsigned charshort unsigned intdoubleGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.debug_line.debug_str.comment.note.GNU-stack4!4'4,4*>^:  JV0a.j44z     pngwrite.c !&-4;IPW^elszpngrtran.o/ 1207848666 1026 1026 100664 80316 ` ELFD4(HDÁH@@ÉD$D$ %wuuID ٙ$ٙ(ÍvHDÁHDÁHDÁHDÁHD@ÁHDP0ÐVSƉ@Et|$ T$(1 B;T$(|t$([,UT$3DD$ \$ \$T$ fBf;Zs\$ ]T$3TD$LA9||$LuN;t$$| D$L1|$t\$(1Rt$,l$(DŽ$2;D$$|)TKJ;D$$} v[l$,f*f)D*D)F;t$$|$ ;D$$|cTMJ;D$$}DmD$,HX$ffVPN^$$(ꋌ$$\$$9$kDŽ$$t$4;D$$@D$,(l$8PT$<@D$@L$,A)‰хyً\$,t$8)Ɖyыl$,ET$@)…yڍ,L$,D$PCA\$<)ÅyAT$8)…yAT$@)…yڍ9}ʼnt$PF;t$$|L$P\$4 $t$(9$LJl$$l$(kT$(T$( 1 B;T$(| D$\T$\D@=ul$(DŽ$D$XD$T`$A$k$D$,D$DƉL$`\$DSF)‰хyًD$DF)‰Ѕy\$DSF)‰Ѕy؍;\$T:D$XD$\L$X$YD$`A D$`9l$`i|$X~$$E9$|$XUDŽ$4$\$\ L$d\m\$D$dH9\$dS9tˉT$hӉL$hMl$@t$L$,ffTT|$uC19:u D$h9u F;t$(| ( ) (;l$$~*L$d L$d$\$T9$t$\TtD$XT$XT$\DCu;l$$~D$T`DŽ$ : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 I!I/ &I : ; : ;I8  : ;.? : ; ' @ : ; I .? : ;' @ : ;I: ;I .? : ;' @: ;I 4: ;I4: ;I  4: ;I!4: ;I "4: ;I#4: ;I $.? : ;' I@%: ;I &.? : ; ' @': ; I(.: ; ' I ): ; I*4: ; I+4: ; I,4: ; I-4: ; I. Un8lPo R0BFTN  %int  Ou u 7 7 P  u u ;8T B U#  V7# *WI# Y# Z7# N[I# msg]# ^# `# a#$ bu#( g dn#, $eI#0 fI#4[g  Rn#Fg_ B1H I ir B B# 7 B#  B#  B# z B# B#tT+ 0c &+ghjvkn?pg^q@R.d red# ##j {#red# ##J #L4'red# ##J #I#:  red# ##I##" rX { !# ### ,( r n#key%!#q&!#3(#  01BJX{YB#Z# [# O ^#RH`ajR v#` # #c# F#O# ##^#%# ### ## # #   #(W #, n#0 n#4q#8#<z#D #H#R;#\#`#d #h #l^#p& #t #x #| #k #y  # #  #  #U -!#.#/#0!#1X#2#3#8# =^# >#]C!#D!#F#iG#L~#M#X#Z-#[-#!^!#[_!#f4#ij#6n#o#p#q#7 r#s# t# u# O xpz  j  v#c#^## # # # m   j d  4| 4i#f6F#7F#8# 9i#$:i#(o;#,v>!#0\I#4J#8 K#9O#<hP#@6Q#DS#HsT# U# Vn#7 Wn#< Xn#Yn#Zn#v\#` ]# ^# _#c`#xa#; b# c#d#n e#f#g#[h#i#jj #l#crcm#Fn#Oo# p#qB#r# s#C t#Zu#v#^w#x#Zy#z## {# |#}#B # # ##Q#n#  #m  ### #F#F#4 F##U#z# # # #q ######+## ####b#n#n#:#s#!#!#l#=#&#6!##7#I#, n# ## #|#  ##i#)# *#+#^0#1p#2#6# :#t;# =#%B#E#F#X @ RX i 4 u{  4    4  n,I  4    ! 4   nz -3 I 4 v  U[pn 4 ^N'| 4  (  4   # L# g #DC    J%otM n4PpxtM w4PI UtM 4v - -A&X`tM %4P <`htM ;4P0DhptM C4PXLpxtM K4PUxtM T4PxtM 4Pv!RM  4b}  ~v row~!i `+d sps dpUd sp dp U@ spi dp|!UQ v row)oR!U\# np cn! Xbp i *bp iHf REbp! i"#Ebp- i./nCBv 0rowBdspKdpL iMNpyxv rowxN! h! spdp i!i spdp"p i10t spOdpm i spdp"p iN Fv row9D x  spdp i?  spdp iq-spdp i -D#spPdp #i!Rh9H! 7v q row7 B 8 h8e i:  ; ! =P > dy spL/ dpM  sp[ dp\  spl dpmI B sp~} dp X sp dp @ sp! dp? l4 sp] dp{ 4#spQ#dpR v row iE  sp dpA sp dpm& T sp dpCT spa#dp Q$$Nn /M L4Lv rowL iO9! QRn ##rc[#gc\#bc]@ o spf* dpgo redk lm3! \ sp{S dp| K red ]! spdp red  wL r """B1"  spdp red H[B"N spdpN red " spdp  red7 J]#D[spdpDK red  w." " " B [sp dp [ red -  K ^B |v$< 0; nF; O= n.> nm#i? nQ#v@ nP% T v row  9 F nsp  i X!  `"%K v S>%m v Z% v@ % aO n bP n  cQ n+ dR n>% msba nQ lsbb noE vw &g Tk v row F Xz   nU nw" n sp  dp Oi    e'#lc v qrowj (UnnZ spx dpC in! !J '!\(Pdm!v 2"rowP"l""spdp i# g#)(rngnbnpnFrngnbnpnf) Cp"z#M B4%( iIn% gJ-&" g~-V& in& jnN'Un' numn'n' ig(fin-"-'( max(P,"0-)M 4g-"0"^n)## in-n-)$9$ in- kn-*i$)""F4.Onh. in.y*$( g)-. gs)-/l(K)v`w`*l((9c>/*((9gQ/);)9kd/'+)- m{-w/ g|-/ gs}-/_+-J."FOn+0 inT0+]./ in}0n0""F+./90+/U/90U//90/l0 i 1*1 srnL1 sgnn1 sbn1'2+ 0A1" v 2row" 12 # ( 3% (Q% (& &   & @' F' F4 ( F* n04 sp, t4 dp, 5 i- M6! . ~U/ n8-2X2pf gg -O33p g -44 v 9-5;5v *.S6h7rF gG bH 6h7 vV 9V.78rh gi bj ._88 a 988v w 889 #:.8(9 a 6:8(99 j:b/i9:: a :/99 v :9::g  v ; w $;9:9 M;/J:: a `;::g  v ;::9 ;J0(;d< a ;y;d<v& w& 0y;;9) ;.0;<9, <'<O<9/ =<0w<\= a; P<0<<9K y<0<1=9L <1=\=9N <z1=? a^  =0=3> vb 4=p>?vz  wz ~= xz =@1p>>9} =^1>4?9 =]??9  >?5A a >T@5A v ^>r  g > b >1@@9 > 2@@9 >A)A9 >2nAlB?M l4K?;lni?redm? m?BeB!Q ?3dlBB@M b4$@;bn7@%redb- c-"en" fn&3) OBOCJ@'M L4@'M(@'^Mn@'v Nn A'N-bA&3PCCA'M 4A'nA'nB)4CGABM 4C4CD#msg)4BDDnD94g1(V4absn)__nn&J8'GlPPD'M 4D'FD'OnD'On"E'CE'=ndE4G H*inE5#HJ*inE;5NHH+nnkF*jnFHH,tŶV5H(I*jnF(IJ*jnG5CII- IJ nJG knhG n{G"b n\JJ d nG6JVN i%nG!:&n 'nG#t(!f)p6wKQL jPn HK'L dTn.H6LM#pnLM jwnmH!wnMQM knHMM pH. inH H"Sn"#n"n"n"+N2P irnI ignI ibn1I rnOI gndI bnxI)O#P drnI>nIwOP dgnIdtndmn"KnO P"b n dbnI"Fn dnJZ8n! 9l8J8  libpng../include../include/klibc../include/bitsizepngrtran.cpng.harchsetjmp.hpngconf.hstddef.hzlib.hzconf.hstdlib.hu(u 'ugg Ju u'u'u(u uC.hwRggKlhKg3iNhPNgNMug=gMg@$?gQh=@Xk0K[["u K[[>u K1Au Kh X8 h0ZOq`y > t t%E XkldfXKhlzYh/Kz. /=YggK=u.[hYK* Y=K=y. &/hdt=ct[h, =cXR058w/U]|/wG]KKv=gYE_g|=wYE_lwvgYgE_|gwgE_KKvggYggggwJ Xg|gwggggYwJ XKKh1lLZKwKY =KYYYYy L[KYY} ȯKggYgYgw KKXn8,נY2tf/uY%u< 7k^fJ&J؟בtJJء"Y3w=KKY"x %gv`[Kd'YבKtK& 5M4==8K>Kr<%z>K>Kt< F YY>yf> ƖF t 1@Y[[["r 䑃[[>t $[[>t KK>YZw  KKKj==KKuKP5AKM[["r ~׃h[>s ȑMAt K?KKz L>w=j=LKrXK'0Y'ZKY~f I=j=vYYgj~ttK"#5j)p+XKKg&^Al˼Ol#l#w׾hw_V&U0EX$ X[qz˼[myJ[mye¢1w4ٖ \6,KwvgZg!hɰksk'L#3?;?9c%Ke"qyuefL2">=s7Ngv$~6 #j)(+i=0Mwr .0=Pv=Mwj< fi=0Mwr<.0=Pv/Mwj< fi=0Mwr<.%x /qJ.Zx"ujruxt-K9!uu=u=uf<%u:uurt.LLMwJ0mJLZ[Lq,1j%^MaJ+h]ט=h<"3LLMuDv9(cJ(.LLYuhLuD8k+>j׃=u=[uuS>I>AR<:#gh"ZuuZZG=%=%]<,9guh&kּʒv t\uu"Mt?I;{XvLXkt\uuDg[gxz۱wJwh*ݭO=Lu&$ V(&g$hʟg$gyg$g$g%$u"g$g$g$hu uguh")vf5LNMxشO tn2uwX Xmt.'?!y!gp +q5z jtfPzM+aiup.h"./j/MgزLx tZ[Pfz gtfLɟ$ #'g#0#4)/uxfz<y'hZ ??ư>p?>??p???C?;GC?PG?### ####3########3#311nA2nAnAnA 4nAnAnAnAnAnAnAv4!BHPignoring out of range rgb_to_gray coefficientsApplication must supply a known background gammaCan't discard critical data on CRC error.NULL row buffer for row %ld, pass %dpng_do_rgb_to_gray found nongray pixelpng_do_dither returned rowbytes=0|    E X ` h p x {AA Cs AA AA$AA AAC4=AA (AA AACzA$HKAA AAC0 8AA AA$ cAA AAC0lAA $AA AAC($TAA AAC0$lAA AACD(d AA AACpKAA AAF_DGFC.Hu.RDGFC.H\.vDGFC.HB._DAFO.HRAF.hDCAL.H.SDCAL.H.SDCAL.Ht" AA AAFDRFC.HZDLFKJDLFONDRFKZDLFKJDLFOAFfGOFMAHRGAALrGKFKNGOFONGOFMAHNGOFKNGDDHNGAAH .$0 AA AAF AAA AC lBTC $BAA AAC  PCAA C CAA CPSTFXE\E`@.QPjTFX@.FTAPj.\Y`FdFhFlFpFtFxG|G@.0HPATFX@.FTAPS.dT@.FPP.\W`@.HPS.$GAA AAF.P.UQttt tt PVRSRSR t  t  t  t tPWBRd~RRRRS4dVV8BUBdRUR;VQXdQQmVVq~U~RRU|QQQVURttt ttt4PS"SENSSRWR~QQQSVfVV|PP~QQ5Q?PQPUPwPQRRQQRRVVUU"ESSEUUNSIUttt PQPQRVRSRttt ttttP5PbPPPRFRbRRRS!RSR!QQ!WW#-V-iRVR+iUUvQQRR~VVVRUtFtPP P-2PDFPRR R-4RDFRESPDFPRDFR PDFP RDFR-RDFRHItIJtJKt KLtLOtOt0HUPUVH~RRRRBaRRR4=RRH{QQQQB^QQQ4:QQHyBXWWWBWfWW4W?WSS]U{QPQPQQQ~RRRQPQPQQRRQ<BQQQR<BRRRBQQQBRRR^QQQaRRRQQRR4QyQ4RyRttt t tP W PRR - RT [ R RS U/ T S] S U S VR RQ Q S S Q Q1 3 PK T P P* T Q Q_ a P P t t t t t /t P / R / Q -W-/Q   U  U L L S QQ?[U[QQSQ U 0 5 m ? K \    /c Q R Q QQyQL[QQ Qe V V.hV,Vo s S S S L S S#S+So E /Eo F /F ? QA \ Q R Q QQyQL[QQ Q ? SC \ S L S S#S+S + R7 ? RK \ R 0 RQRLxRR ? K \  / ? GK \ G /G~ H /H  / R R , Um U ?U[.U R Rh R 0 RQRLxRRM a R  Q R Q QQyQL[QQ Q  V V.hV,V R  S L S S#S+S R  R 0 RQRLxRR_ QN N/NN O/O P R SS+SD[/iRRD[P/PDQRR)[RR"R[V,VxR[S+S[xRRR01t12t2t 0>PB^PjPP0RRRQXVZ^VcjVovV{VVXS\^ShjStvSSttt ttTt(PT\RSUQTXSKQKKSRSR|SSRShVRLSLLQLLRLLSLLRLLSLLRLLSLPVKYRd~RRRLTRR9R@ZRa|RLTRRRLTRBSVQV W!RQLTQR,R7TRTUtUVtVWt WXtX[t[kt0TrPriWikPToRoUU8jUjkRToQokTQQQQ2JQLQQckQVVVhRVcVcchccVchRdR`R&6\6ZRZZdZZRZ`QQRcPccRccQckRegSlmtmntnot optpstsctlPcLlRMUU?rU$bUbcRlQHQcHQQ3@S_gSi}SQ>qPRS \VS\ S3QBHSQSVUw$`$[[[\[[V[_SVR(5h5VdSRhV 3RFHQRVR$R9URjwSwRR$S$(R[[d[[h[[V[[S[_RHVr[U[`VaWZZ[cZdeteftfgt ghthktkhthmtd{P{iSdRVRVRjVjmRdvQvmhdQQFFgQgmUQFUVgRggUghQxkWpqtqrtrst stttztzttttt|t|tttt*t*.t.5t5;t;FtFtttt t tt"t" t  t " t" # t# 7 t7 !t!!t!!t!!t!0!t0!"t"#"t#"&"t&"'"t'";"t;""tpP"VxS&S""Scc$$""""""{H H !@!"""""H""@""UUU U !"""""U""!W!"W""W""W"""J"""RPP,PS! S! 4 SR4 S !S!-!SR-!!S"%"S%"8"SR8""S""SS S!!S""S""SWW !W!"W""W""W""t""t""t ""t""t"U%tU%Y%tY%k%tk%q%tq%|%t|%%t%%t%%t%%t%%t%A&tA&E&tE&Q&tQ&W&tW&f&tf&&t&&t&&t&&t&&t&5't5'9't9'E'tE'K'tK'V'tV''t''t''t''t''t')t))t))t)*t**t***t**0*t0*=*t=*>*t>*F*tF**t**t**t**t**t*+t+&+t&+1+t1+7+t7+B+tB++t++t++t++t++t+ ,t ,,t,,t,%,t%,2,t2,3,t3,;,t;,,t,,t,,t,,t,,t,,t,-t- -t - -t --t-c-tc-j-tj-k-tk-l-tl-t-tt-0t""P"0W##Rl0x0R##Ql0}0Q$N$RJ.q.R//R00R$c$S- .SJ..S//S00So$(VK))V//V00Vz$)~/l0~00~()~/l0~00~$$~$$~%)~/l0~00~%)~/l0~00~((Q((R;)I)R)-~/l0~00~))~))~)-~/l0~00~))~ *-~/l0~00~.J.V//V00V .J.S//S00S. 0U00Uk.l0~00~ /#/RG/[/P..P//P00P 0l0U00U/l0~00~/l0~00~/E0V`0l0V00V/Z0S`0l0S00S00t00t00t 00t00t0At00P0A~00R0D1V11V1]2Vc2}2V22V23V33V33V 45V5p6Vq77V 8:V:=V??V?y@V2ArAVAAVAAR00Q0'8U'88Q88Q88Q+9-9Q899Q99Q:::Q::Q:#;U#;c;Qy;;Qa<<Q\=b=Qb=f=Uf=u=Qu==U==Q3>>Q?`@Q2AIAQIARAURAAQAAUAAQ04 4h7 q7-: ;:? ?A 511S11S1}2V}22S22S 33V3 4Sa5h5Rj55R5&6R26B6QF67~7#8QJ::S::S=?U?IA\PAnA\nAnAVnAnARnAnASnAnA~nAnAVnAnASnAnARnAnASnAnAQnAnASnArAUAAVJ::V::V!;w<Ww<b=Wd=u=W=?W?IAURAnAUnAnAWnArAVAAW=11~11@1}2}22@22H33D3 4H44R4Q4QQ4v4R44Q45~5G5Qc5h5Ql55S5&6Q=6B6PN67L7#8P]88S8+9Q-989Qd9J:W::W#;w<Uf=u=U=?T?IAX]AnAXnAnAPnAnATnAnASnAnAnAnA@nAnADnAnAHnAnAQnAnARnAnA~nAnAQnAnALnAnAUnAnASnAnAQnAnAWnAnAUnAA~AAWB1N1Wb1|1W11W11W11W11W1 2WK2a2Wc2}2W}22W22W22W22W22W33W-3G3Wx33W33W33W33W33W3 4WnAAWAAW44R45RnAARS6a6R717R87U7R\77RnAAR_88Q88QnAAQ88R89R(9+9R-989RnAAR88P88P88P9+9P-989PnAuAPz99P99P99Pi9x9R99R-:J:RnAAR::Pi9x9R-:J:RnAAR::RY:b:Pg:x:P::PJ:W:R::R::RnAAR::P,;4;PX;g;Py;;P(;w<~nAA~(;w<~nAA~O<^<Q{<<P<<P<<Pw<b=~f=u=~nAA~w<b=~f=u=~nAA~w<{<PN=b=Pf=u=PnAuAP==P3>D>Pp>>P==R=>R >'>R.>3>R??RnAAR>>P4?C?P??P==R>>RQ?d?R??RnAAR>>R*?7?R??S??R@%@RT@@R5AIAR]AAR??P@@P@AP)AIAP]AuAPj@@Q@AS@@R@AQAIAS]AaASAAtAAtAAt AAtAlBt AAPAiBSAARA BR/B4BR;BlBRA$BQ/B;BQ;B@BQAAAjBVjBlBEB^BPlBoBtoBBt lBBPlBBRBBtBBtBBt BBtBBtBOCt BBPBBSBBPBKCSBBRBBVBLCVBBQBBQBCWBBBBUBBBNCUNCOCBBBOC`PCQCtQCRCtRCUCt UCCtCCt PC^CP^CCSPCCRCCRPC^CQ^CCVCCQCCVCCQCCtCCtCCt CCtCDtDDtD Dt DDtDGDtGDMDtMDSDtSDTDtTD/Et/EHEtHENEtNETEtTEZEtZE`Et`EfEtfElEtlEsEtsEzEtzEEtEEtEEtEEtEEtEFtF Ft FFtFFtFFtFGtCCPCGVDDPDDPDEPEBEPEEPGGtGGtGGt GGtGGtGlPtGGPG[PW[PaPPaPjPWGGRGlP~GGQGN~NaP~GGGlP~GGGlP~GGGlP~G'HRJJRVNNRaPlPR6HLHRLHZHVHHRHHVHHdHHVI(IR(I.IdIIRIIhJJRJJVVNVNVVNVNdVNmNhNHJVNlPNHIQI5IQI JQJJQHHSH(ISJJSVNcNSiNNS>PYPSaPhPSHHU(IIUIIUJJUIIUIJJURJJV\JJIIP\J`JPJJPK/KRbKwK\wKlP`WKMUMNUaPkPUwKwKXwKlPwKKSKLS'L|LSMMSMMSLLSLLSLMSMMS|LLVMMVMMRMMRNaPNaPNaPNaPNLOVYOZPVNaPNaP@NaPDNaPHNaPLNPOUYOOUOOPO\PUOOQOOQNNR)O~OROPR PPPRr8$png_set_strip_16Jpng_set_strip_alphappng_set_gammapng_set_expandpng_set_palette_to_rgbpng_set_gray_1_2_4_to_80png_set_tRNS_to_alphaXpng_set_gray_to_rgbpng_set_read_user_transform_fnpng_read_transform_infopng_do_unpackpng_do_unshiftpng_do_choppng_do_read_swap_alphapng_do_read_invert_alphapng_do_read_fillerpng_do_gray_to_rgbpng_do_rgb_to_gray$png_build_grayscale_palettev$png_do_gamma%png_do_expand_palette&png_do_expande'png_do_dither\(png_build_gamma_tablef)png_init_read_transformationsP,png_do_background'2png_set_rgb_to_gray_fixed2png_set_rgb_to_gray3png_set_background3png_set_crc_action3png_do_read_transformationsV4png_set_ditherlPNRP\PaPbig_row_bufhi_fillerbackground_colorlastpng_write_status_ptrpng_set_expandpng_do_ditherbackground_gamma_codeindex_to_palettemalloc_fnwarning_fnpng_do_rgb_to_graypng_do_read_transformationspng_uint_32num_bluesave_bufferpng_sPLT_entrypbit_depthrgb_to_gray_statusnum_greenscal_s_widthpng_charpptempindex_rpalettetotal_outpng_sPLT_structflagsdonezbufpng_set_read_user_transform_fnnextnentriespng_info_structentriessplt_palettescur_palettegamma_16_tablepush_lengthdummyred_intistopbluezfreepng_row_info_structcompression_typetime_buffer__ebxshort int/home/hpa/syslinux/release/syslinux-3.63/com32/libpng_set_rgb_to_graypng_do_gray_to_rgbpaeth_rowpng_do_unpackfrequencypng_read_status_ptrmodepng_uint_16pint_y_greenpng_do_chopx_blueGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)x_offsetpng_dsortpng_malloc_ptriccp_namepng_do_expand_paletteinfo_ptry_greenpng_set_strip_alphay_offsetdo_filterprev_rowpng_rw_ptrint_x_redpcal_unitsbuffer_sizergb_errorcurrent_buffer_ptrpng_textpiccp_proflenopaquepng_set_strip_16transformationsz_streamfloatshiftavg_rowrowbytespalette_lookupindexcolor_incsig_bytesfoutwrite_data_fnscal_pixel_heightgamma_16_from_1chunk_namelong long unsigned intpng_set_tRNS_to_alphauIntpng_do_background__ebppng_build_grayscale_palettez_stream_suLongpng_color_16pusr_bit_depthpng_voidp__jmp_bufpng_struct_defpng_uint_16pprow_fnpng_set_gray_to_rgbpng_do_gammabackgrounddither_lookuppng_byteppsignaturezallocvalueavail_outmng_features_permittedpng_error_ptrpng_fixed_pointerror_actionpng_unknown_chunkpasssize_terror_fnio_ptrwidthrgb_to_gray_green_coeffred_1png_int_32__eipzlib_strategysave_buffer_sizeBytepng_do_read_swap_alphaint_y_whitepng_set_rgb_to_gray_fixed__esiscal_pixel_widthnum_rednum_entries__espdither_indexpng_unknown_chunk_tphys_unit_typepng_row_info__ediprocess_modey_whitepng_color_16free_meerror_ptrzlib_mem_levelred_fixedsub_rowsave_buffer_maxhistogramscal_unitsavecharread_data_fnpcal_nparamsnext_jadlertotal_intext_lengthpng_const_charpmaximum_colorsmem_ptrhashy_redtextpng_bytepjmp_bufdataend_fnup_rowpng_uint_16gamma_from_1current_textpng_unknown_chunkppcal_paramspng_sPLT_entryuser_transform_depthunknown_chunkswrite_row_fnpng_set_palette_to_rgbzlib_methodinterlacedpng_do_read_invert_alpharightscreen_gammapng_user_transform_ptrlong long intpng_sPLT_tppng_dsortppnum_textBytefmin_dvaliddepthmin_knext_outnum_transx_pixels_per_unitunknown_chunks_numtrans_valueschannelsnum_chunk_listiwidthfillerpng_set_gammasrgb_intentpng_size_trow_bufneed_expandlo_fillerrow_widthpng_do_unshiftsizepng_free_ptrusr_widthrgb_to_gray_red_coeffpng_build_gamma_tablebackground_gamma_typemaskinternal_stateavail_inrgb_to_gray_blue_coeffint_x_greenpng_dsortplong unsigned intheightdata_typeinfo_fnx_greendither_sortrow_numbermmx_rowbytes_thresholdgreen_fixedzlib_levelpng_sPLT_entry_structgreennum_rowsfree_funcpalette_to_indexusr_channelsint_x_bluefile_gammapng_set_backgroundzlib_window_bitspng_ptrpcal_purposed_indextrans_valuescrn_gammamax_textread_row_fntmp_colorzbuf_sizegamma_to_1num_new_palettepng_color_structchunk_listuser_transform_channelspng_gamma_shiftpng_textpng_row_infopspare_bytelong intgamma_16_to_1next_ingraylocationpng_structppng_structlibpng/pngrtran.cdistancefilterpng_progressive_end_ptrint_y_blueskip_lengthfilter_typealloc_funcpng_infopng_progressive_row_ptrgammay_pixels_per_uniticcp_profilepng_colorpng_color_8_structcurrent_text_sizeleftbackground_1png_charppng_do_read_fillernamepng_infopunsigned intpixel_depthidat_sizecurrent_text_ptrx_redgamma_shiftpng_set_crc_actionpng_color_16_structpng_read_transform_infobackground_gammay_bluepng_set_ditherint_x_whitegray16alphanum_palettescal_s_heightint_gammacurrent_text_leftrow_pointersx_whitepng_dsort_structuser_height_maxpng_set_gray_1_2_4_to_8back_1unsigned charsave_buffer_ptrpng_color_8read_user_chunk_fnuser_width_maxhistcurrent_buffermax_dgamma_16png_progressive_info_ptrcurrent_buffer_sizeread_user_transform_fnint_y_redstatepcal_typepcal_X0pcal_X1png_init_read_transformationsoffset_unit_typeinterlace_typepng_colorpcompressiongreen_intpng_color_8ppng_do_expandsigned charfull_dithershort unsigned intuser_transform_ptrsig_bitsirowbytesancil_actioncrit_actiongreen_1reservedbackfree_fnvoidpfsplt_palettes_nummmx_bitdepth_thresholddoublerow_infopng_bytezstreamjmpbufsig_bitpng_user_chunk_ptrpng_sPLT_tuser_chunk_ptrdmaxindex_gtotal_bitscolor_typeiccp_compressiontransgamma_tableasm_flagsblue_1png_text_structGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.cst8.rodata.cst4.rel.rodata.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack4lP < `%P+P0PB)Sr8> 'R N 6^PPk | x 6 2`X 7؝:J 9(  9H0` .;;0 =    -AEOX^`uhpx {=5zNHKa8t c0lTld pK" %0 7AQ]lBTqBPCCG&6pngrtran.cpng_gamma_shiftpng_set_strip_16png_set_strip_alphapng_set_gammapng_set_expandpng_set_palette_to_rgbpng_set_gray_1_2_4_to_8png_set_tRNS_to_alphapng_set_gray_to_rgbpng_set_read_user_transform_fnpng_read_transform_infomemcpypng_do_unpackpng_do_unshiftpng_do_choppng_do_read_swap_alphapng_do_read_invert_alphapng_do_read_fillerpng_do_gray_to_rgbpng_do_rgb_to_graypng_build_grayscale_palettepng_do_gammapng_do_expand_palettepng_do_expandpng_do_ditherpng_build_gamma_tablepng_mallocpowpng_init_read_transformationspng_do_backgroundpng_set_rgb_to_gray_fixedpng_warningpng_set_rgb_to_graypng_set_backgroundpng_set_crc_actionpng_do_read_transformationssprintfpng_errorpng_do_strip_fillerpng_do_invertpng_do_bgrpng_do_packswappng_do_swappng_set_ditherpng_freepng_malloc_warnmemset (./  k./  .0?/N T `..  /.  ( 0 /D  J  . .  !!)!/9! ?! !!!.!." ,"4"/D" J" # #$J$-%#%b%u%/~% % %/_&/&&/& & O'/'/?*/L* */;+/H++/+4,/A,,/,-/-m-/z-~00/1 0B 7B3uB }B B CC C3D D8D9ND*D+D:D'D D3D D9E&{E1E)E"F,F F96F;TF!lF F<F=F&F%F$G#+G>G.*H.J@J.K.2K.KAM@N@)N@6N@N.NBN.NBB2B3]P@ !&18CJU\hv#?M[iw #1?M[j ".5GYo )?Wfu -6ETcs$3S_u$3BQ`o~#2AP_n}  - = M ] m }           - = M ] m }           . = L [ k w            * 9 H W f u           $ 4 D T d t        $4DTdt$4DTdt$4DTdt$4DTdt$4DTdt$5Gj"Jq*15=PW[cv~"6>BJ^fjr ',0?JSWfuz $49DIMRalz  $=BMSWpu "&+6FKOTgkz+15DTi!:DHlrv )4=AP_im|,;EIXgmq-<FJYhnr    J N ] l q u               ! !!!)!9!=!M!R!]!b!m!{!!!!!!!!!!!!!!" """ "+"6":"U"Y"i"n"y"~"""""""""""""##%#*#5#:#E#S#X#\#a#m#y############## $$$$$)$.$9$>$I$N$Y$|$$$$$$$$$$$$$ %%%'%+%9%C%G%U%_%c%q%%%%%%%%%%%%%%%& &&"&-&2&A&P&[&`&v&&&&&&&&&&&&&&&& ''('6';'F'K'O'T'_'k's'w'{'''''''''''''*(.(b(j(n(r(w(((((((((((((()))#)')8)D)O)_)l)t)x)|)))))))))))))))** **!*,*1*<*J*S*W*e*t*z*~***************++"+,+0+5+A+L+Z+d+h+v+{++++++++++++++++++ ,,,+,:,I,V,^,b,f,k,v,,,,,,,,,,,-----<-J-O-_-j-s-w----------..$./.3.[._.m.r.v.............../////4/B/G/K/P/[/g/k/y/~//////////////0 0000)0/03080C0O0S0a0j0n0s0~0000000000000000011'1+101;1E1I1N1Y1_1c1h1s1{1111111111111112 2222-25292=2B2M2R2]2m2r2}22222222222222233!3(3,30353?3D3N3S3]3b3l3q3{3333333333333333333444#4\4c4g4k4p4z4444444444444444455 55#5(5,5@5D5Q5W5[5h5q5u5z555555555555555566-6A6E6S6X6\6j6u6y666666666666667 77!7-797E7I7X7g7v77777777777778 88&8+8@8[8h8   $(,048<@DHLPTX\`dhlptx| ( ,8 <H LX \h lx |      4 8` dx |    0 4X \    @ Dd hx |  \ `pngwtran.o/ 1207848666 1026 1026 100664 1596 ` ELF4( % $ > $ > = intke short int/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)floatlong long unsigned intcharlong long intlibpng/pngwtran.clong unsigned intlong intunsigned intunsigned charsigned charshort unsigned intdoubleGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.debug_line.debug_str.comment.note.GNU-stack4!4'4,4*>^:  JV0a.j44z     pngwtran.c !&-4;IPW^elszpngmem.o/ 1207848666 1026 1026 100664 19228 ` ELF 54(T$ÐÐЉʋL$vЉʋL$vt tà ttt ÍvVS$Éօtt$D$$[^Ð11vt t1fVSƅt1t-tÅuFBu1ۉZ[^VSËp@ C@s@Y[^fWVS0Ӄu Ht10t$D$…t 1׉Ё0[^_f11% : ; I$ > : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 I!I/ &I : ; : ;I8  : ;.? : ;' @ : ;I : ;I.? : ;' I@ : ;I4: ;I.? : ;' @ 4: ;I 4: ;I.? : ;' I@ 4: ;I!4: ;I "4: ;I#.? : ;' I@ . 0 Bd Tq%int   Ou u 7 7O P  u u 8T ? U# V7# !WI# Y# AZ7# [I# msg]# - ^# -`# Ua#$ bu#( dn#, eI#0 fI#4[g RJn#g B N  i  B# - B#  B#  B# p B# B#std TT( 0&pgjikn6pgK q@Rd red#@ #P# jt  I#red#@ #P#G # red#@ #P#G # # ( red#@ #P# ##lN U  !## ## K\fN  n#key%!#T&!#*(#  0l1@XU Y#{Z#I[# L ^#.`aF. ###1# # ##|#y#o# #e ##q # ## #   #(#,hn#0 n#4T#80#<#D#H #RV#\#`T #d#h #lT#p  #t@  #x #|  #N # # #' #  # -!#- .#L /#0!#1X#3 2#3#8#=:#>#nC!# D!#F#G#LZ# M#X#Z-#g[-#^!# _!#3 f4# j# n# o#p## q#r#s#w t# u#  xLZ z  F [ #1#y#|# # q # c  ^ F a p )4i#6"#I7"#8# Y9E#$:E#(;#, >#0 I#4J#8 K#9O#<P#@Q#D!S#HT# U#5 Vn#Wn# Xn#Yn#Zn#\#]#F ^#[_#1`# a#b# c#d#e#f#g#)h#i#jF #} l#crcm#n# o#p#q# r#l s#t#u#v#yw#|x#y#q z#{#j |#O}##{#  # #> # n#  #* ### #/F#yF#1 F#0##### m##### #`## #># #### #vn##n#, #! #!# !#:#3# #!##V# %#n# ##e## #K# # )# *#+#F0#?1L# 2s#6#:#.;#Y =#oB# E#H F#U d b.4 E  QW m   y    ny    s       n7  %  R 8 17Ln  :_'X^s  N(   = Dt BPFB?CLQ CsPt OX 2 -t 0&s10940nW:1I3 %0=t #us1#s2#:$I&"i @Pt ptr]Pu  ptrI xrw sF? d { #|tw{hB6t {Iret IE retnY2 I!ptrP"xeP4*z Ono?OLFO"IR"wS[l _d { `#Ftz En<  libpng../include../include/klibc../include/bitsizepngmem.cpng.harchsetjmp.hpngconf.hstddef.hzlib.hzconf.hgg6h`.lO f=N;YtMNu \a? tAXxLufv>u>~fNu KR Out of Memory!|    0 @P%Cx3AA F DAA C| "AA CZ 4ZAA AF  RP "P $R$-P (Q(-R02P04R4=P08Q8=R@JPOPP@OROPRPStSutPgPiqPquPPgRiqRquRxytyztzt txPSPSPxRVRVRVRxQQQPPPRRttt t t PVPV P VRR RSPS Sttt /t/2t P0S+R1V45t56t67t 7=t=t4LPWfPlnP4DRDS4jQlsQQIKVWVQPRRuyRy|P|RPpng_set_mem_fnpng_get_mem_ptrpng_memset_checkpng_memcpy_checkpng_free_default"png_free]png_destroy_struct_2png_destroy_structpng_malloc_defaultBpng_mallocpng_malloc_warnpng_create_struct_2png_create_structbig_row_bufdummy_structpng_write_status_ptrindex_to_palettemalloc_fnwarning_fnpng_uint_32save_bufferpng_sPLT_entrypbit_depthrgb_to_gray_statusscal_s_widthpng_charpppalettetotal_outpng_sPLT_structflagszbufpng_sPLT_entry_structnentriespng_info_structentriessplt_palettescur_palettegamma_16_tablepush_lengthdummybluezfreepng_row_info_structcompression_typetime_buffer__ebxshort int/home/hpa/syslinux/release/syslinux-3.63/com32/libpaeth_rowfrequencypng_read_status_ptrmodepng_create_structpng_uint_16pint_y_greenx_blueGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)x_offsetpng_malloc_ptriccp_namesave_flagsy_greeny_offsetdo_filterprev_rowpng_rw_ptrint_x_redpcal_unitsbuffer_sizecurrent_buffer_ptrpng_textpiccp_proflenopaquetransformationsz_streamfloatshiftavg_rowrowbytespalette_lookupindexsig_byteswrite_data_fnscal_pixel_heightgamma_16_from_1chunk_namelong long unsigned intuInt__ebpz_stream_suLongusr_bit_depthpng_voidp__jmp_bufpng_struct_defpng_uint_16pprow_fnbackgroundpng_byteppsignaturezallocvaluelengthavail_outmng_features_permittedpng_error_ptrpng_fixed_pointpng_unknown_chunkpasssize_terror_fnio_ptrwidthrgb_to_gray_green_coeffpng_int_32__eipzlib_strategysave_buffer_sizeBytepng_freeint_y_white__esiscal_pixel_width__espdither_indexpng_unknown_chunk_tphys_unit_typepng_row_info__ediprocess_modey_whitepng_color_16free_meerror_ptrzlib_mem_levelsub_rowsave_buffer_maxpng_get_mem_ptrscal_unitcharread_data_fnpcal_nparamspng_memcpy_checkadlertotal_intext_lengthpng_const_charpmem_ptry_redtextpng_malloc_warnpng_bytepjmp_bufdataend_fnup_rowpng_uint_16gamma_from_1current_textpng_unknown_chunkppcal_paramspng_sPLT_entryuser_transform_depthunknown_chunkswrite_row_fnzlib_methodinterlacedscreen_gammapng_user_transform_ptrlong long intpng_sPLT_tpnum_textBytefstruct_ptrvaliddepthnext_outnum_transx_pixels_per_unitpng_mallocunknown_chunks_numtrans_valueschannelsnum_chunk_listiwidthfillersrgb_intentpng_size_trow_bufpng_destroy_structpng_malloc_defaultsizepng_free_ptrusr_widthrgb_to_gray_red_coeffbackground_gamma_typeinternal_stateavail_inrgb_to_gray_blue_coeffint_x_greenlong unsigned intheightdata_typeinfo_fnx_greendither_sortrow_numbermmx_rowbytes_thresholdpcal_X0zlib_levelgreennum_rowsfree_funcpalette_to_indexusr_channelsint_x_bluezlib_window_bitspng_ptrpcal_purposemax_textread_row_fnzbuf_sizegamma_to_1png_color_structchunk_listuser_transform_channelspng_textpng_row_infopspare_bytelong intgamma_16_to_1next_ingraylocationpng_structppng_structfilterpng_progressive_end_ptrint_y_blueskip_lengthfilter_typealloc_funcpng_infopng_progressive_row_ptrgammalibpng/pngmem.cy_pixels_per_uniticcp_profilepng_colorpng_color_8_structcurrent_text_sizebackground_1png_charpnamepng_infopunsigned intpixel_depthidat_sizecurrent_text_ptrx_redgamma_shiftpng_color_16_structbackground_gammay_bluepng_destroy_struct_2int_x_whitealphanum_palettescal_s_heightint_gammacurrent_text_leftrow_pointersx_whiteuser_height_maxpng_memset_checkpng_free_defaulttypeunsigned charsave_buffer_ptrpng_color_8read_user_chunk_fnuser_width_maxhistcurrent_bufferpng_progressive_info_ptrcurrent_buffer_sizeread_user_transform_fnint_y_redstatepcal_typepng_set_mem_fnpcal_X1offset_unit_typeinterlace_typepng_colorpcompressionsigned charshort unsigned intuser_transform_ptrirowbytesreservedfree_fnvoidpfsplt_palettes_nummmx_bitdepth_thresholddoublerow_infopng_bytezstreamjmpbufsig_bitpng_user_chunk_ptrpng_sPLT_tuser_chunk_ptrpng_create_struct_2color_typeiccp_compressiontransgamma_tableasm_flagspng_text_structGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 ;h%+0B> \< RrN ,J^2q,m 4J ~O $ K(%  K0H% 4.74748  :    ) :A0 RY@joP%xx3 D"4Z pngmem.cpng_set_mem_fnpng_get_mem_ptrpng_memset_checkmemsetpng_memcpy_checkmemcpypng_free_defaultfreepng_freepng_destroy_struct_2png_destroy_structpng_malloc_defaultmallocpng_mallocpng_errorpng_malloc_warnpng_create_struct_2png_create_struct'o)9Km    ! & 1 8 C J U \ h v         # ? M [ i w              # 1 ? M [ j             " . 5 G Y o           - E T c r           ! 0 ? O [ q z          / ; Q [ j y            - < K Z i x            , ; J Y i y            )  9  I  Y  i  y             )  9  I  Y  i  y             (  7  G  S  e  u                $  3  B  Q  `  p              0  @  P  `  p            0 @ P ` p            0 @ P ` p            0 @ P ` p            0 @ P ` p            0 @ P ` p           # F n      & M t            +/7 B Q V a f u            ( 048 = H X c kos x             ! & 1 H TX\ a l q |               ( - 8 = H M X ]af v     ( ,8 <H LX \h l|        $pngerror.o/ 1207848666 1026 1026 100664 17840 ` ELF14(S@@ t:#u< t Bt1ҋXtXZ[ÍvP HT$Pf@ Ét @@%!ЉA@UWVS ʼn։11+CB9wBw*[D1D1D1]Auu :D1 Y?D? [^_]ÐVSdÉэt$\d[^ÐWVSNj@@ tN:#u7< tCut1D1AC9| t $0D$OtѺVSdÉэt$d[^% : ; I$ > : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 I!I/ &I : ; : ;I8  : ;.: ; ' : ; I.? : ; ' @: ; I4: ; I.? : ;' @ : ;I : ;I.? : ;' I@ .: ; ' @4: ; I !4: ; I " #1X Y $1%4: ; I d0c Bs Tp%int   Ou u 7 7b P  u u 8T ^ U# V7# WI# Y# ;Z7# [I# msg]#  ^# "`# Oa#$ bu#( dn#, eI#0 fI#4[g vRDn#g Bz M { i  B# 7 B#  B#  B# z B# B#^ts GTG y0&jgjTkn1pgZ q  @Rd red#S #J# jQ  0#red#S #J#f #( red#S #J#f # # ( red#S #J# ##_N d  !#|### J[fN\  n#key%!#O&!#%(# % 0l1JXd Y#fZ#[# k ^#.z`aF. ##v## # ##o#d#i# #B ## #< # #   #(#,gn#0 n#4O#8/#<#D#H#R>#\h#`1 #d#h #l^#p  #t:  #x #|  #I #  #` # #  # -!#! .#) /#0!#1X# 2# 3#8#=:#>#VC!# D!#F#oG#LZ# M#X#&Z-#N[-#^!# _!#- f4# j# n#o#p# q#r#s# t# u#  xLi z  F U ##d#o# #  # m . ^ F  p (4i#6"#<7"#8# @9E#$:E#(;#, >#0 I#4J#8 K#9O#<P#@Q#D S#HT# U#8 Vn#Wn# Xn#Yn#Zn#\#]#Y ^#._#`# a#b# c#{d#e#f#rg#h#i# jF # l#crcm#n# o#p#pq#\ r# s#t#u#qv#dw#ox#y# z#{#} |#6}##N#  ##M # n#  #) ### #)F#`F#P F#/#### m####k#q #S## #8# #### #n#n#; # #!# !#!#=# #z!##U# %#n# #y#8## #E# # )#! *#+#A0#21L# 2s#6# :#!;#l =#iB# E#B F#t d \.4 E  QW m   y    n y           n6  %  R 7 17Ln  :G'X^s  !(       Q9 PD P bRnVR  <Jt  P  "Q< "LPt  Pdt R7h sd q^q!|r tniintn ucxn~ K  i!msg~gQ)  F!   !msg#F`"+4f(n Kbi.n%#G$$VgC C | !msg~%kF libpng../include../include/klibc../include/bitsizepngerror.cpng.harchsetjmp.hpngconf.hstddef.hzlib.hzconf.hieu[t==u <>&/L~OKɢtJXKiKY!Z teisjNvKzuJHȒ0123456789ABCDEF| 9ACr A < L P$dAA AAC #AA Cp wAA AC #AA Cptt6t67t 79t5P56PRQR5Q59Q'R)3R57R<FRLOPPYPYdQdeteftfgt ghthktkt duPuUduRuVdsQsWsQQuSSuRRttt tPSRQttt tt #P#WRR4fSvSIbQv{Qttt tPSRQpng_warningpng_set_error_fnVpng_get_error_ptrpng_set_strip_error_numbers7png_chunk_warningpng_errorVpng_chunk_errorbig_row_bufpng_write_status_ptrindex_to_palettemalloc_fnwarning_fnpng_uint_32save_bufferpng_sPLT_entrypbit_depthrgb_to_gray_statusscal_s_widthpng_charpppalettetotal_outpng_sPLT_structflagsbufferzbufpng_sPLT_entry_structnentriespng_info_structentriessplt_palettescur_palettegamma_16_tablepush_lengthdummybluezfreepng_row_info_structcompression_typetime_buffer__ebxshort int/home/hpa/syslinux/release/syslinux-3.63/com32/libpaeth_rowfrequencypng_read_status_ptrmodepng_uint_16pint_y_greenx_blueGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)x_offsetpng_malloc_ptriccp_namey_greeny_offsetdo_filterprev_rowpng_rw_ptrint_x_redpcal_unitsbuffer_sizecurrent_buffer_ptrpng_textpiccp_proflenopaquetransformationsz_streamfloatshiftpng_erroravg_rowrowbytespalette_lookupindexsig_byteswrite_data_fnscal_pixel_heightgamma_16_from_1chunk_namelong long unsigned interror_messageuInt__ebpz_stream_suLongusr_bit_depthpng_voidp__jmp_bufpng_struct_defpng_uint_16pprow_fnbackgroundpng_byteppsignaturezallocpng_default_erroravail_outmng_features_permittedpng_error_ptrpng_fixed_pointpng_unknown_chunkpasssize_terror_fnio_ptrwidthrgb_to_gray_green_coeffoffsetpng_int_32__eipzlib_strategypng_get_error_ptrsave_buffer_sizeByteint_y_white__esiscal_pixel_width__espdither_indexpng_unknown_chunk_tphys_unit_typepng_row_info__ediprocess_modepng_chunk_warningy_whitepng_color_16free_meerror_ptrzlib_mem_levelsub_rowsave_buffer_maxscal_unitcharread_data_fnpcal_nparamsadlertotal_intext_lengthpng_const_charpmem_ptry_redtextpng_bytepjmp_bufdataend_fnup_rowpng_uint_16gamma_from_1png_default_warningcurrent_textpng_unknown_chunkppcal_paramspng_sPLT_entryuser_transform_depthunknown_chunkswrite_row_fnzlib_methodinterlacedscreen_gammapng_user_transform_ptrlong long intpng_sPLT_tpnum_textBytefvaliddepthnext_outnum_transx_pixels_per_unitunknown_chunks_numtrans_valueschannelsnum_chunk_listiwidthfillersrgb_intentpng_size_trow_bufwarning_messagesizepng_free_ptrusr_widthrgb_to_gray_red_coeffbackground_gamma_typelibpng/pngerror.cinternal_stateavail_inrgb_to_gray_blue_coeffint_x_greenpng_digitlong unsigned intheightdata_typepng_set_strip_error_numbersinfo_fnx_greendither_sortrow_numbermmx_rowbytes_thresholdzlib_levelpng_chunk_errorgreennum_rowsfree_funcpalette_to_indexusr_channelsint_x_bluezlib_window_bitspng_ptrpcal_purposepng_warningmax_textread_row_fnzbuf_sizegamma_to_1png_color_structchunk_listuser_transform_channelspng_textpng_row_infopspare_bytelong intgamma_16_to_1next_ingraylocationpng_structppng_structfilterpng_progressive_end_ptrint_y_blueskip_lengthfilter_typealloc_funcpng_infopng_progressive_row_ptrgammay_pixels_per_uniticcp_profilepng_colorpng_color_8_structcurrent_text_sizebackground_1png_charpnamepng_infopunsigned intpixel_depthidat_sizecurrent_text_ptrx_redgamma_shiftpng_color_16_structbackground_gammay_blueint_x_whitealphanum_palettescal_s_heightint_gammacurrent_text_leftrow_pointersx_whiteuser_height_maxpng_set_error_fnunsigned charsave_buffer_ptrpng_color_8read_user_chunk_fnuser_width_maxhistcurrent_bufferpng_progressive_info_ptrcurrent_buffer_sizeread_user_transform_fnint_y_redstatepcal_typepcal_X0pcal_X1offset_unit_typeinterlace_typepng_colorpcompressionpng_format_buffersigned charshort unsigned intuser_transform_ptrirowbytesreservedfree_fnvoidpfsplt_palettes_nummmx_bitdepth_thresholddoublerow_infopng_bytestrip_modeioutzstreamjmpbufsig_bitpng_user_chunk_ptrpng_sPLT_tuser_chunk_ptrcolor_typeiccp_compressiontransgamma_tableasm_flagspng_text_structGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 70%+0B> 8 RN E^jf E w\! E"  E0!"0.005 87 d    (94<ELWPs{#w#pngerror.cpng_format_bufferpng_digitpng_warningpng_set_error_fnpng_get_error_ptrpng_set_strip_error_numbersstrncpypng_chunk_warningpng_errorlongjmppng_chunk_error    !&18CJU\hv#?M[iw #1?M[j ".5GYo -ETcr !0?O[qz/;Q[jy-<KZix,;JYiy  ) 9 I Y i y           ) 9 I Y i y           ( 7 G S e u            $ 3 B Q ` p            0 @ P ` p         0@P`p 0@P`p 0@P`p 0@P`p 0@P`p#Fn&Mt    )4 9G\hlt         $1 =DHL Q[ `j     % 04\cgk pz    8 <H LX \h l   pngpread.o/ 1207848666 1026 1026 100664 39220 ` ELFk4(ǀÍv|Ð htу Ð ptу ÐVSËlt PփX[^Ív@,ÉhL$lL$pSÅt [[ÐUWVS,ÉT$΍ u.tu |$f{@x|$D$ ‰t$$t8х# ut L$$j jT$T$ 1ǃ,[^_]fUWVS ÉՉϋu/9vƋt)D5))tt1t'9v֋|))| [^_]ÐWVSÉ׉΋@<Htt6V0ǃ[^_WVSÉ׉΋@<Ht)t6V0ǃ[^_WVSNjt!tx9  B9u ;v[9v ;xډxt-x|LJxtLJ[^_1+fVSË@;&ǃ @P1ɉ@<u <u  <uw&@<vH<ȋH+1<vȍA ȍA@CDu?H+1񉃤Z[^fVSÊ<vVVHP@P@${DuCB@tCDw0$1BFt t܀u$l1҉Ft tျu1Q1҉Ft tျ{1BFt t܀C1҉F$t1BFt t11҉Ft tျ1҉Ft1BFt t܀`A1҉FAt31BFt t11҉FtHt=1BFt tB1B[[^1҉1҉1҉1҉y1҉Y[^ÐWVSÉ׉@@ tt ]{HsLCHt;u%{Lt t{XuK<Ktj{XuXt v(;u{Lt K@ CXCTV[^_ÍvVS@=M\$ډډN<t%džF@ tN9vӋtىF@ utى)))ttWtt9vË|ىF@ u|ى)))|u'w 1҉F<F<[^ÐVSËt99v֋t)))ttBt^9vƋ|)))|u&w Z[^1҉ǃX[^UWVSljT$ t-t09vËى)ow[^_]B:u9tztLJBGH)D$+D$GLGTGXD$D$1;D$D$v5D$GLLJT$[^_]GXt|$u|$uYB)T$D$D$+OXL$D$+GXT$4D$0TB)ÉT$T$3+OX+GX3\$|$tGTGXD$GL*LWHT$GL|$LJD$CD$C jًT$ƋT$(ډt[^_][^_]UWVS ljT$t-t09vËى)w [^_]F>u9tFhp jT$ƉډLJt [^_] [^_]WVSƉ@=uL\$ ډN<u#A;&*u6A;džډ;uN<u N<sZF<u?7&u#A;F<uuu F<tt 1N<džFXFTWu#A;u#A;u#A;u#A;lpu#A;48u#A;u#A;u#A;u#A;TXu#A; u#A;u#A;uA;wxuA;wGNuA;wA;v f<[^_fUWVS )9vƍj T=t/wNtGV؃ [^_]v ǃ [^_]Éw7$ǀÍvVSÉ։ȋL$‰ uY[^% : ; I$ > : ;I$ >   I' I I '  : ; : ; I8 : ; I8  : ;I8 I!I/ &I : ; : ;I8  : ;.? : ;' : ;I.1@ 1 .? : ;' @ : ;I .? : ;' @: ;I: ;I.? : ;' I@ 4: ;I !4: ;I "1X Y#1$4: ;I% &4: ;I' U(4: ;I) U*.? : ; ' @+: ; I,4: ; I -4: ; I..? : ; ' @ /: ; I 04: ;I? < d1T0B] Td  %eintg  Ou u 7 7 P  u u 8T U# 8 V7# WI#  Y# GZ7# [I# msg]# p^# `# a#$ bu#( } dn#, eI#0 VfI#4[g ) Rn#g Bn i  B#  B#  B#  B#  B# /B#t] GT 0 &gjkxnpg' q@Rdt red# ## j #red# ## # red# ## #2#( red# ##2#U#,hN C  !# #N#.# fNN n#key%!#&!#(#  0l1XC Y#Z# [#  ^#.` aF. 7#v # ## #8#( #x### ##d #j # # #   #( #, n#0J n#4#8#<2#DW #H#R#\ #`#d2 #h #l#p #t{ #x #|  # #  # # #  #4 -!#.#/#;0!# 1X#v2#w3#8#e=:#D >#C!# D!#F#!G#VLZ#nM#KX#Z-#A[-#^!#D_!#nf4#Rj#&n#uo#1p#fq#X r#s# t#a u#  xLH z  F  ###x# d # j #   ^ F  p 4i#6"#<7"# 8# *9E#$j:E#(;#,O>#0I#4;J#8 K#9sO#<P#@Q#DS#HT#_ U# Vn#Wn# Xn#Yn#5Zn#\#v ]# ^# _#`#Ca#| b# c#d# e#3f#g#h#Ki#jF #v l#crcm#n#8o#( p#cq#r#B s#t#u#v#w#xx#y#j z#d {# |# }# # #  ## # n#  # #8##i #F#SF# F###2#W #S m#t# ####S#p###y #C#;#F#3#n#wn# #\#!# !# ###!###%#m n# ## ##A  #Q#R#)# *#D+#0#21L#_2s#6# :#!;# =#B#E#F# d q.4 E  &QW m   _y    n y   I       n  %  R  17Ln  :'X^s   (   1 , tPR%/3t, PRQ` 4G,   > H[\, |  \,  row>"t, !\lt, o  ,   G %JC,  G= .5!-.X"##[,g[, ++G+$ptr-1 *2Z%@_Bx(~h, || G} sP >, v GR , Q EP$iW1&W$spXO$dpYx%g fR g9) f, $!h B,  '{$iDn'$icnb'0$iun'H$in ^$in%$in' S e [ ,    $retn bh X ,  y !l p - i  %  F 7 ,  + F  %b    9 ,     - '`A  ! $key! $retn+U&(%Z(tmp!d;|s, :: 1 s>P)A JK!$keyL!$retMn* |N+, @+ ^%,l l*` hP|+, g+g - i-j1.,1t+, +Z++ *4d+, S+ q+/Fn0  00U00C0 V0 i0 |0  0 0  0M 0_ 0R 0& 0  08 '0$ :0 M0  `0 s0h 0 0Y 0  libpng../include../include/klibc../include/bitsizepngpread.cpng.harchsetjmp.hpngconf.hstddef.hzlib.hzconf.hgJggg.=/\=/\uvt>u gnAKY<ʓm ɭLؼKxȟfx X/Kggh XgghJKggJJKgg|JY Xd^l!gɑhhtɽʟ'vu(+i*L~fu)$xhvqڑqq .q$q q5q$q q$q q5q .quR0:Xq qqqq<~X=?LZghwj[h"giu~txu=vLgggghggggh~tu gggh gggh5y<\JghВ.~t\vj hx>=0 !Zuft[vwv?hv G8uvgyv>uvrZ~ghϒ&.Zt\{i"gA>>uvrZxju!wOLOOKKKuuLLOuuʼvKKLOLOLOLOLOLOLOLOLOLOLOLOLLu|u5Lv twt\/\yyz{ ty@J莔unknown critical chunkOut of place zTXtOut of place tEXtPotential overflow of save_bufferExtra compression dataExtra compressed dataDecompression ErrorToo much data in IDAT chunksNot enough compressed dataInsufficient memory to store text chunk.Missing IHDR before IDATMissing PLTE before IDATToo many IDAT's foundNot a PNG filePNG file corrupted by ASCII conversionmy\ |   4CHC(\-AA CON B.EA  $A< AA AAC@LFPB@CLBPH.H@F.$AA AAC h\AA A\AA A AA A,JAA CuN D.H 8h+AA CnAMH B.eN.  AA Ah AA C  AA C [4 AA AAC0zV>_W_dVdgWhitijtjkt kthtPtShzRzWhzQzVttt  tPSRWQV !t!"t"#t #t HPHWPE\RR5SSS;VQQSVtt!t !VtVdtdpt pctcft )P)dShitijtjmt mttttt  t t thuPu S P SoVVVV V " V' < V VQVA V V V{VV[ p V V4V4\Vu V V^VV V VVV V V t t t e t P b S R d W Q V Q c V P P P # P+ 8 P= E Pa e Ph i ti j tj m t m t h P V! ' P' + S+ 7 PB s Ss y P Py  P S R S P t t t t t t  P S P S  V ) P) . Q. \ V V V\ ` V` h Rh V V t t t t t =t0=?tVoUt{U>mVtyV|}t}~t~t tNt |PLV|RMWPQtQRtRSt STtTWtWt PkPkSPSPzR`WWeVVVPQ Q QQQ&Q&1PR R RRR&R&1R45t56t69t 9atadt 4?P?bS4EREcV4CQCGPGLRipng_push_crc_skippng_push_restore_buffer%png_push_have_info`png_push_have_endpng_push_have_rowpng_get_progressive_ptrpng_set_progressive_read_fnlpng_progressive_combine_rowpng_push_handle_unknownJpng_push_fill_bufferpng_push_handle_zTXt(png_push_handle_tEXtspng_push_save_bufferpng_read_push_finish_row9png_push_process_rowpng_process_IDAT_dataSpng_push_read_IDATpng_push_crc_finishFpng_push_read_zTXtpng_push_read_tEXtpng_push_read_chunk png_push_read_sig`png_process_some_datapng_process_datado A {A [ {[ u ^u  w| p othbig_row_bufpng_write_status_ptrindex_to_palettemalloc_fnwarning_fnpng_uint_32save_bufferpng_gAMApng_sPLT_entrypbit_depthrgb_to_gray_statusscal_s_widthpng_get_progressive_ptrpng_charppprogressive_ptrpalettetotal_outpng_sPLT_structflagsbufferzbufpng_pass_startpng_sPLT_entry_structnentriespng_info_structlengthentriessplt_palettespng_push_read_tEXtcur_palettegamma_16_tablepush_lengthdummyistoppng_pass_yincpng_push_crc_finishbluezfreepng_row_info_structcompression_typetime_buffer__ebxshort int/home/hpa/syslinux/release/syslinux-3.63/com32/libpaeth_rowfrequencypng_read_status_ptrmodepng_uint_16pint_y_greenx_blueGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)x_offsetpng_malloc_ptriccp_nameinfo_ptrtext_sizey_greenpng_pass_incy_offsetdo_filterprev_rowpng_rw_ptrint_x_redpcal_unitsbuffer_sizepng_hISTpng_push_fill_buffercurrent_buffer_ptrpng_textpiccp_proflenopaquesave_sizetransformationspng_zTXtpng_push_handle_unknownz_streamfloatshiftpng_IHDRavg_rowrowbytespalette_lookupindexsig_byteswrite_data_fnpng_pCALscal_pixel_heightgamma_16_from_1chunk_namelong long unsigned intuIntskip__ebpz_stream_suLongusr_bit_depthpng_voidp__jmp_bufpng_struct_defpng_uint_16pprow_fnbackgroundpng_byteppsignaturezallocpng_progressive_combine_rowpng_push_restore_bufferavail_outmng_features_permittedpng_sRGBpng_error_ptrnum_to_checkpng_fixed_pointpng_process_IDAT_dataold_rowpng_unknown_chunkpasspng_push_save_buffersize_terror_fnio_ptrwidthrgb_to_gray_green_coeffpng_int_32png_iCCP__eipzlib_strategysave_buffer_sizeBytepng_tRNSpng_push_read_IDATint_y_white__esiscal_pixel_width__espdither_indexpng_unknown_chunk_tphys_unit_typepng_row_info__ediprocess_modey_whitepng_color_16free_meerror_ptrzlib_mem_levelpng_sCALchunksub_rowsave_buffer_maxscal_unitpng_pass_ystartcharread_data_fnpcal_nparamsadlertotal_intext_lengthpng_const_charpmem_ptry_redtextpng_bytepjmp_bufdataend_fnup_rowpng_uint_16gamma_from_1current_textpng_unknown_chunkppcal_paramspng_sPLT_entryuser_transform_depthpng_push_handle_tEXtunknown_chunkswrite_row_fnpng_IDATzlib_methodinterlacedpng_PLTEpng_set_progressive_read_fnscreen_gammapng_user_transform_ptrlong long intpng_sPLT_tpnum_textBytefvaliddepthnext_outnum_transx_pixels_per_unitunknown_chunks_numtrans_valueschannelsnum_chunk_listiwidthfillersrgb_intentpng_size_trow_bufpng_push_read_sigpng_push_have_endsizenum_checkedpng_free_ptrusr_widthrgb_to_gray_red_coeffnew_maxbackground_gamma_typeinternal_stateavail_inrgb_to_gray_blue_coeffint_x_greenlong unsigned intheightdata_typeinfo_fnx_greendither_sortrow_numberpng_oFFsmmx_rowbytes_thresholdzlib_levelgreennum_rowsfree_funcpalette_to_indexusr_channelsint_x_bluezlib_window_bitspng_ptrpcal_purposetext_ptrmax_textread_row_fnzbuf_sizegamma_to_1png_color_structchunk_listpng_IENDuser_transform_channelspng_textpng_row_infopspare_bytelong intgamma_16_to_1next_inpng_pass_dsp_maskgraylocationpng_structppng_structpng_read_push_finish_rowfilterpng_progressive_end_ptrint_y_bluechunk_lengthskip_lengthfilter_typealloc_funcpng_infopng_progressive_row_ptrpng_bKGDgammay_pixels_per_uniticcp_profilepng_colorpng_color_8_structcurrent_text_sizebackground_1png_charppng_push_crc_skipnamepng_infopold_bufferunsigned intpixel_depthidat_sizecurrent_text_ptrpng_push_have_infox_redgamma_shiftpng_sBITpng_color_16_structbackground_gammay_bluepng_push_have_rowpng_push_read_zTXtpng_process_some_dataint_x_whitealphanum_palettescal_s_heightint_gammacurrent_text_leftrow_pointersx_whiteuser_height_maxunsigned charpng_pHYssave_buffer_ptrpng_color_8read_user_chunk_fnuser_width_maxhistcurrent_bufferpng_push_process_rowpng_sPLTpng_progressive_info_ptrcurrent_buffer_sizenew_rowread_user_transform_fnint_y_redstatepcal_typepcal_X0pcal_X1png_push_handle_zTXtoffset_unit_typeinterlace_typepng_tEXtpng_colorpcompressionpng_process_datasigned charshort unsigned intuser_transform_ptrkey_sizelibpng/pngpread.cirowbytespng_cHRMreservedfree_fnvoidpfsplt_palettes_nummmx_bitdepth_thresholddoublerow_infobuffer_lengthpng_bytezstreamjmpbufsig_bitpng_user_chunk_ptrpng_sPLT_tuser_chunk_ptrpng_push_read_chunkcolor_typeiccp_compressiontransgamma_tableasm_flagspng_text_structGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack4d {`%+0B1> 4R9N ,^2=}q4?4m 4h }h?Dy  BdUm W  $W0X^i.%j%jLo ,v    64IH[\-m$ 1GW^ivh\\ J,:Jh+_s h !3B V iv| #,<EU^nw &6?OXaPsM40pngpread.cpng_push_crc_skippng_push_restore_bufferpng_push_have_infopng_push_have_endpng_push_have_rowpng_get_progressive_ptrpng_set_progressive_read_fnpng_push_fill_bufferpng_set_read_fnpng_progressive_combine_rowpng_pass_dsp_maskpng_combine_rowpng_push_handle_unknownpng_check_chunk_namepng_handle_as_unknownpng_chunk_errorstrcpypng_mallocpng_crc_readpng_set_unknown_chunkspng_freememcpypng_push_handle_zTXtpng_errorpng_push_handle_tEXtpng_push_save_bufferpng_read_push_finish_rowpng_memset_checkpng_pass_incpng_pass_startpng_pass_yincpng_pass_ystartpng_push_process_rowpng_read_filter_rowpng_memcpy_checkpng_do_read_transformationspng_do_read_interlacepng_process_IDAT_datainflatepng_warningpng_push_read_IDATpng_get_uint_31png_reset_crcpng_IDATmemcmppng_calculate_crcpng_crc_finishpng_push_crc_finishpng_push_read_zTXtinflateResetpng_set_text_2png_push_read_tEXtpng_push_read_chunkpng_IHDRpng_handle_IHDRpng_IENDpng_handle_IENDpng_handle_unknownpng_PLTEpng_handle_PLTEpng_gAMApng_handle_gAMApng_sBITpng_handle_sBITpng_cHRMpng_handle_cHRMpng_sRGBpng_handle_sRGBpng_iCCPpng_handle_iCCPpng_sPLTpng_handle_sPLTpng_tRNSpng_handle_tRNSpng_bKGDpng_handle_bKGDpng_hISTpng_handle_hISTpng_pHYspng_handle_pHYspng_oFFspng_handle_oFFspng_pCALpng_handle_pCALpng_sCALpng_handle_sCALpng_tEXtpng_zTXtpng_push_read_sigpng_sig_cmppng_process_some_datapng_process_data !B"K#Z$ !%&'I'{)#)#t{)#'&'i-./-0=134'5N6i y,,,%,,V],,,,,9@,ho,,,,  ,, 3 ,F M ,` g ,z  ,  ) 8  ) 2  )2 9 9F 2  ; < $ = >  )8 ?M 7 ? 7 + @* ?m ? @ $' A 8 C &#-'<'h#u'&'CC& #HDU&^&j$A#8DC&L&b;<$G> HI#>EJXf =>KL>=> ) L'>IMX=_>s))N>O.P5>WQfRm>ST>UV>WX>7YFZM>o[~\>]^>_`>a&b->Oc^de>ef>gh>*i>(1+<kk HSl , + + &x9+p9)jF :EB"A !&18CJU\hv#?M[iw #1?M[j ".5GYo -ETcr !0?O[qz/;Q[jy-<KZix,;JYiy  ) 9 I Y i y           ) 9 I Y i y           ( 7 G S e u            $ 3 B Q ` p            0 @ P ` p         0@P`p 0@P`p 0@P`p 0@P`p 0@P`p#Fn&Mt +37; @K P[ fnrv {      ) .9 >I N]rz~          37PX\` ep u        # .6:> CN S^ cn y        $ )4 ?GKO T_ hv         #. 3> N Yaei ny      & ,05@ LTX\ al q|        !)-1 6A FQ Z^cn ty        $. 3= BL Q[ fmqy      #6I\o-@Sfy  $(,0 ( ,8 <L P` d     , 0L Pl p    8 <\ `    ( ,tinyjpeg.o/ 1207848666 1026 1026 100664 21272 ` ELF=4(UWVSÉT$*K4AC4c8u yuAC4 C8C<C<v΍HC8T$4Bxk*S4 BC4c8u zuBC4 C8C<C<9rω)K<H!C8K<)K<H!C8vp1$} *K4AC4c8u yuAC4 C8C<K<9r)S8t$4$ 9tffuE$u1ZY[^_]ÍvUWVS,É֋zL$T$ V Hu?|$6t$$PJu|$vt$$u |$v t$$|$vt$$fCTfǃfǃfǃC8C<D$ ljD$ D$$ljD$$D$(ljD$($T$ЉT$T$ЉT$D$D$1fD$ $D$$C(D$(C,1-T$T$D$$D$(D$,4$;s rEC$19r1,[^_]ffSX @$[ÍvVSƉӃv1B9u1[^VSƉӃv1B9u1[^VSƉӃv1DB9u1[^ÍvVSƉӃv1DB9u1[^ÍvH(P(ÍvUWVSƉT$͹$CA9vBw1fDŽ(=u$1ɍ$t$AC9tB;udT$tT. w% )DUfpKu" f8uffpf@G<u[^_]UWVSLD$:zP,AL$A0D$D$$D$8ŊUEt]\$$st$E Ɖt$wuiu|$$O_WGD$GD$$D$ ǁ  Ɓ|$D$(T$(L* \* D* iT$D@ʃPL$ XD$(|$( uy q$\$\$ UmBTK|$816@P $CAu؃ Gl$ AA|$ DD$$xMϊQAÃiҘT$i\$VBLiBPD$$ 9uGC4|$t$]y D$;11ҊD|$;D:Bu"щЃtiD$ViT$ډ)L$A(t urL$L$VL$sb{L$jb\$ǃt$p9r69r,t9r 9rNuKu Iu u0"@1D$8L[^_]fUWVSiҘl@D$ 1U(ƅu,{S4 BC4c8u zuBC4 C8C<C<9rω)S8fT$ K<H!C8NuDfD$ D$ EfD$ fEEfD$ U L$ uT$ *S4 BC4c8u zuBC4 C8C<C<t$ 9r|$ )S8fT| K<H!C8NuDfD| D$ p?@1fDD fDUB@uČ[^_]VSþDtDFu[[^v 4 % $ > $ > : ; I I&I : ;  : ; I8  : ; I !I/ !I/ : ; I8 ' I' I.: ; ' I@: ; I4: ; I 4: ; I U .: ;' : ;I4: ;I.? : ;' I@: ;I4: ;I4: ;I4: ;I 1X Y!1"41#.? : ;' I@ $.? : ;' @%: ;I &4: ;I '.: ;' @(4: ;I).: ;' I * : ;+: ;I,1-41 . 1/1X Y04111UX Y2 U31UX Y4.? : ; ' @54: ; I E ktint88Z lJ40Ui#(j# k# r03#5#99# A t Z  5a  l=T>,#?,#)@#A# B#CA# DCTD# A ?H B4*RN#O-#P,# mP,#$DQ,#(T=#,U,#0W=#4X,#8bX,#<ZH#@[X#;\n# 3]n#^3# Ya~# Cra# Cba#"d#&I '' O =, CZ X5  n  ? ~  O  O ?   3,39hrұ&33,,939cCQ3z_cCcCaNrqis33< F,zdx,y,,,#`T(Ws  2!" , #StR$%$p)XW%WR%mWQ\^3 ]5R]S],q&i_3RZ2h3(gRg2g,&ii3R8t3(MqARr_s,}&iu3R3Pu}R~,&i3R,#H3xt!%D3R3Q'p 847=O7=z7i9,j9,9,9,;val9,Y9,l:p }hz:+; uhc;(\<3U >cvr3c9{ Z  , ) @3=(3(3(=3(K3(a=*) 3=i3(3(m3(3cid3(3()3c 5 u=(3(m3(3(h3)' 3=(3qi3(z @ =i3j3zz=C @) H)3((=i*,cid*,(z*,(+,)= G3FF=(tH,iH,(I= (J3(}J3 M Z h ]3b+buf=,ret3 , ! - " " - " . /  3 ! ! 3 "+ "5 "A "M "Y 0e  0q . 0} A 1 ! 280 j 0 " " 3 X! ! 2p- @0 " 1' !A ,5  20M [ 0W 0a /`  , D !  " 0 x 0 " / , ! 0 " - [0$  00 Q M 0![ 4L  l3 jZ 13= YZ~Z c &DCT~| c C  c&C$L } +oi3 (   !% 5+ BZ ?5;-S25;i= ~Z  5?n5Db= Z  5XHs5M= Z 5Q5j= 2Z 5oC"b jpeg../includetinyjpeg.ctinyjpeg.htinyjpeg-internal.hstdint.h2LH/rf8x7y?/g=uYuOu~.ut?ggzz!YY[fe[[fe[]fs[fs[=>{f .;>0 tjgx/y K@u^[I;h=Kct#1gx0uL~%tBY/YyX t=GLht~.=L <u. fu]1dv ??aHP1?oM?lb??;i$? {zQ?]rU? }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz| ,9AA AAC,A$<AA AAC@  A$AA $AA (%AA P%AA  x $AA AAF , AA AAC`dF`$AA AAFL 1AA Ce  Cttt tt3t34t49tP5SR9hQV V06VRR3RU8UW7WV0V9R9<P<MR]W07W_QPQPRPP<=t=>t>?t ?@t@CtCt<UPUS<RRRpV}VVVKVIU{}@@@@WWn}DDDDJjW}WWWt}HHHHPttPttt PVRSQQtt(t P'VR&SQ(Q()t)*t*Mt (3P3LV(3R3KS(8Q8MQPQtQRtRut P[P[tVP[R[sSP`Q`uQxPttt ttt PVRuQURQ"Q"&R/CRcQ2RPcmP"V&RRSJScS+VV"SmPttt tt\t\btbtPR|RRQ|QQPPPP|PQSPP P7W[8WW<WW|WWVt V|VVWP|PPVV?V|VV7W 8WFW<WW|W:Q Q+QQ|QUSUS||U|SUSW<W|WWRP|PDS'S|SSU)U|UUV!V|VV]RR|RRttt ttL tPH SRh h Vh ~ V I VVP> VI [ V[ ^ P^ h Vt y Ph k R R R * RK U Q P  Q Q P QL M tM N tN Q t Q v tv } t L X PX v Sv } P t tGItinyjpeg_decodetinyjpeg_get_errorstring)tinyjpeg_get_sizeptinyjpeg_get_componentstinyjpeg_set_components=tinyjpeg_get_bytes_per_rowtinyjpeg_set_bytes_per_rowtinyjpeg_set_flagsh tinyjpeg_parse_headertinyjpeg_process_Huffman_data_unittinyjpeg_freetinyjpeg_init U3Nq|Xe3Nq|Xe  K~K~privtinyjpeg_decodebits_ac_chrominanceQ_tablehuff_codeHTDCbuild_quantization_tablesize_valnbits_in_reservoirprint_SOFtinyjpeg_set_flagsparse_DQTval_dc_luminanceQ_tablesshort intdefault_huffman_table_initializedoldflagsbytes_per_rowextra_nbitsmarkerqtablelookupncomponentsvaluepixfmtHTACuint8_tparse_JFIFdht_marker_foundtinyjpeg_get_componentscounttableparse_DHTbytes_per_mcutinyjpeg_get_bytes_per_rownbitswidthchuck_lenfloatbitsbits_ac_luminanceref_tablelong long intparse_SOFbits_dc_chrominanceystride_by_mcuhuffcodetinyjpeg_colorspaceparse_SOScomponentstinyjpeg_parse_headerconvert_to_pixfmtdecode_MCU_fcthcodebits_dc_luminanceprevious_DCdecode_MCUbuild_huffman_tabletinyjpeg_freelengthjpeg/tinyjpeg.cstream_lengthinitializeunsigned charbytes_per_blocklinessigned charflagslong long unsigned intnext_chunckheightunsigned intval_ac_luminancecomponent_infosxstride_by_mcusampling_factorstreambuild_default_huffman_tablesshort unsigned intcount_0sizecharuint16_tget_next_huffman_codetinyjpeg_get_sizezigzagjdec_privatevalsHfactornext_free_entrycomponentrepeatindexerror_stringtinyjpeg_process_Huffman_data_unithuff_bitsVfactorreservoirtinyjpeg_set_bytes_per_rowval_ac_chrominancecode_sizestream_begintinyjpeg_initplanedecode_mcu_tableslowtableaanscalefactorbytesval_dc_chrominanceGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)/home/hpa/syslinux/release/syslinux-3.63/com32/libAC_tabledoublehuffsizecodebogus_jpeg_formattinyjpeg_get_errorstringnr_componentsDC_tableconvert_colorspace_fctsos_marker_foundresyncconvert_colorspaceprecisionhuffman_tabletinyjpeg_set_componentsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack4  pF% +  0 B I> G RN R^ !B jd#f R w,%3K S/5  SO506<.<<A `D 9"/C@ J@@ ^  o   s  b      < -$E$](%xP%x  L 1 tinyjpeg.cget_next_huffman_codeerror_stringbuild_huffman_tablezigzagaanscalefactor.2067val_dc_luminancebits_dc_luminanceval_ac_luminancebits_ac_luminanceval_dc_chrominancebits_dc_chrominanceval_ac_chrominancebits_ac_chrominancetinyjpeg_decodetinyjpeg_get_errorstringtinyjpeg_get_sizetinyjpeg_get_componentstinyjpeg_set_componentstinyjpeg_get_bytes_per_rowtinyjpeg_set_bytes_per_rowtinyjpeg_set_flagsmemsettinyjpeg_parse_headertinyjpeg_process_Huffman_data_unittinyjpeg_freefreetinyjpeg_initcalloc&@N&- a * ,y * !&-;BIP[bmt:BP^lz"0>LZhv  $)38BGQV`imz !,:HMX]hm|/7;?DOTbv!COSW\glw|',:MUY]bmr}  ' , < @ E P V Z _ j             6 B N f r            , 6 B m z           % 1 R \ n z ~               2 6 X a j s            $0:>LUimy#3>Leiw}".COYe 3?oHLpt @Dptjidctflt.o/ 1207848666 1026 1026 100664 7736 ` ELF4(UWVS@T$L$P@L$@D$CvZ \$ z@r`Z0\$$jPZp$\$ H@؈؈T$( \$4l$(\$0\$,D$H \$$H`E؈$؈   D$4l$4T$4ٙD$,Y l$,T$,ٙY@ٙD$0ٙl$0Y`L$tDfZf\$fZ \$ fz Z0\$$fz0z@r`jPT$\$@$ |$>fD$> fD$<̈l$<\$8l$>D$8=~BD$l$<\$8l$>D$8=YBl$T$l$<\$8l$>D$8s=BD$l$<\$8l$>D$8N=ɰBl$l$<\$8l$>D$89=xBD$l$<\$8l$>D$8=3Bl$l$<\$8l$>D$8q=B9 T$CCC \$\$\$CC CC   l$<\$8l$>D$8=̰1B9v@[^_]Ð11{$81|1u1 v Hv \v v v v v vz@fz@kjPfzPuir`fz`Zp$fzpQ Q@Q`ّّّٙ1v11r`Zp$% $ > : ; I$ >  : ;  : ; I8 I!I/ !I/  : ; : ; I8  I .: ; ' I : ; I: ; I.? : ; ' @: ; I4: ; I 4: ; I4: ; I  U1UX Y111UX YI\~ 7intH:Wpi033#5#9# 7W^  f=4>p#?p#@f#As# Bs#_C7# DCTDy# lB ~7 ? L fWxe>Ve>G#|{GQe{d{>U}l}<}lA}lF}lK}l]P}l^k}lbZ}l`p~l}v~l^|~l[~l\z5l\z10l[z11l^z12l]z13l_M$\fMfvctr>}S}Rl[q@(`g E+  ,l ?`T jpeg../includejidctflt.ctinyjpeg-internal.hstdint.h  =fmffK0g2ug/g0Mנ׭uv==< fvDc$~.===~<Y==~<u==~<Y==~<===~<Y==~<===Q<2=VJ0gj/0M~===>Q<5~z`-7L/===gggh==G'.?^?u='ԋ?| $AA AAFttt t t tPR}Q})})}})}})})}}R)RRP)PPQSK)S))QSQ)RRPPPPPPPPPPP,5P8EPEHPPPclPloP|P{PPPPPPk{PPPPPPP[fP P P PPKVPP P5>P>APNQP(2PPP"`jpeg_idct_float,Cc(,EH||l| \l L\N(2Q_tableshort intoutptrworkspacejpeg_idct_floatlookupuint8_tfloatlong long intshiftquantptroutput_bufunsigned charsigned charlong long unsigned intwsptrunsigned intcomponentjpeg/jidctflt.cshort unsigned intuint16_tcompptrint16_tstride/home/hpa/syslinux/release/syslinux-3.63/com32/libHfactortmp1tmp2tmp3tmp4tmp5tmp0tmp7previous_DCtmp6tmp10tmp11tmp12tmp13Vfactorcode_sizeinptrslowtableGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)AC_tabledescale_and_clampDC_tabledcvalhuffman_tableGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.cst4.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack4 P%+0SBC`> hR dN ^ o <k  |T l&   ((0 .      jidctflt.cjpeg_idct_float|} !&-8FMX_jqx .<Jm      $ )3 8ER_l{     -@ E[ l z           & 0 A a decode1.o/ 1207848666 1026 1026 100664 6100 ` ELF4(VSúY[^fVSú$,[[^fVSú^[^fSúp[[[% $ > $ > : ; I : ;  : ; I8 I!I/ !I/  : ; : ; I8  I ' I&I.: ; ' @: ; I4: ; I?  _jint:DZ lL0~3#,5#9# AjZa  b=>,#?,#@b#Ao# Bo#CA# DCTDu# h zA ?H   4*N#pO#P,# cP,#$FQ,#(6T#,U,#0W#4"X,#8(X,#<wZ#@;[ ##\!# ]!#N^3# Ya1# CraA# CbaA#Cd#  O,  Z  !h  ?1z AO QO ?ywbvDI\dm[DfC.hG- a jpeg../includedecode1.ctinyjpeg.htinyjpeg-internal.hstdint.hvu#u;Ztvu!!#u;Ytvu#u;_th[[/;hd|  bAA CV dAA C bAA CV hoACd Attt [t[bt P\S\bPdeteftfit itt duPuSPtt t _t_ft P`S`fPhitiltltt thxPxS2tinyjpeg_decode_mcu_1comp_tableprivdecode_MCU_2x1_1planeQ_tableHTDCnbits_in_reservoirQ_tablesshort intdefault_huffman_table_initializedbytes_per_rowlookupHTACuint8_twidthfloatlong long intcomponentsdecode_MCU_1x1_1planedecode_MCU_fctprevious_DCdecode_MCU_1x2_1planestream_lengthunsigned chartinyjpeg_decode_mcu_1comp_tablesigned charflagslong long unsigned intheightunsigned intcomponent_infosstreamslowtableshort unsigned intcharuint16_tjpeg/decode1.cjdec_private/home/hpa/syslinux/release/syslinux-3.63/com32/libHfactorcomponentVfactorreservoircode_sizestream_beginplanedecode_MCU_2x2_1planeGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)AC_tableDC_tablehuffman_tableGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 $% + 0 B> PRN Tb^ \  nj |@ {l 6 K  0k  .@ @ p l b!d7bMho  c decode1.cdecode_MCU_1x2_1planedecode_MCU_2x2_1planedecode_MCU_2x1_1planedecode_MCU_1x1_1planetinyjpeg_process_Huffman_data_unitjpeg_idct_floattinyjpeg_decode_mcu_1comp_table %1COq)5GSt^b !&-;BIP[bmt*8Fi &4BP_n~V]aejt~n  < @` d decode3.o/ 1207848667 1026 1026 100664 6264 ` ELF4(VSúp[[^VSú$,p^[^VSúp[[^Súp[[[% $ > $ > : ; I : ;  : ; I8 I!I/ !I/  : ; : ; I8  I ' I&I.: ; ' @: ; I4: ; I?  [,mint.tZrlZ0h3#5#"9# AZa  b=>,#?,#@b#TAo# ]Bo#CA# DCTDu# h zA ?H   {4*N#ZO#|P,# P,#$Q,#(T#,U,#0<W#4X,#8X,#<,Z#@%[ # \!# o]!#8^3# Ya1# CraA# CbaA#d#  O,  Z  !h  ?1z AO QO ?yCyxD\\b[fC\B.[&-j }a jpeg../includedecode3.ctinyjpeg.htinyjpeg-internal.hstdint.hvu#[/;VXvu!!#[/;VXvu#[/;^Xh[[/;\|  AA C AA C \AA C oACd Attt tt PSttt UtU\t PMS\]t]^t^at att \mPmSttTtTUt U[tPLS2tinyjpeg_decode_mcu_3comp_table[privQ_tableHTDCnbits_in_reservoirQ_tablesshort intdefault_huffman_table_initializedbytes_per_rowlookupHTACuint8_twidthfloatlong long intdecode_MCU_1x1_3planescomponentsdecode_MCU_fctprevious_DCstream_lengthunsigned charsigned charflagslong long unsigned intheightunsigned intcomponent_infosstreamdecode_MCU_1x2_3planesshort unsigned intcharuint16_tjdec_privatejpeg/decode3.c/home/hpa/syslinux/release/syslinux-3.63/com32/libHfactorcomponentVfactorreservoircode_sizestream_begindecode_MCU_2x2_3planesplaneslowtableGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)AC_tableDC_tabledecode_MCU_2x1_3planestinyjpeg_decode_mcu_3comp_tablehuffman_tableGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4[ %+0Bs> PRN bL^   n\j @ { 6 `  h0  .  lp  "9\Po  g decode3.cdecode_MCU_1x2_3planesdecode_MCU_2x2_3planesdecode_MCU_2x1_3planesdecode_MCU_1x1_3planestinyjpeg_process_Huffman_data_unitjpeg_idct_floattinyjpeg_decode_mcu_3comp_table %1COeq1=i0<XW !&-;BIP[bmt*8Fi &4BP_n~V]aejt~n  < @` d rgb24.o/ 1207848667 1026 1026 100664 10792 ` ELFd4(y1=~UWVS($T$T$T$T$@D$D$ $0 @$T$$D$BT$$D$ À@D$ iÜ0 ^iD$i)؍0 =GiD$0 #GEqD$D$D$D$ |$ t2D$T$DD$T$$D$D$$T$T$ |$1%([^_]ÍvUWVS,$T$T$(T$ T$@0D$ D$ $HB$T$$BT$$iМT$iѠi)T$iD$D$ D$ FD$ F_ D$ FD$ FD$ FE+D$(D$D$ D$|$t.T$D$ T0T$|$(D$ $T$T$$t$1,[^_]ÐUWVS4$T$0PL$0щL$,L$ L$$D$TT$D$$HB$T$(BT$(iМT$iѠi)T$iD$] ED$ D$ GD$ vG] D$ [D$ KFD$ :FD$ |$ %D$D$$D$|$t $ > : ; I I&I : ;  : ; I8  : ; I !I/ !I/ : ; I8 ' I' I.: ; ' I@ : ; I.: ; ' @: ; I4: ; I4: ; I 4: ; I  4: ; I4: ; I.: ;' @: ;I4: ;I4: ;I 4: ;I 4: ;I!4: ;I".: ;' I@#4: ;I?  $4: ; I? < {intu:ZRl10i#xj#Gk# C0z3#[5#9*# A  *Z  @a  ?=7>,#I?,# @#A# B#CA# DCTD# A ? H 4*N"#fO8#P,# P,#$Q,#(eTH#,9U,#0WH#4QX,#8X,#<ZS#@1[c#\y# ]y#D^3# Ya# Cra# Cba#rd"#I 22 O H, NZ c@  y  ?   O  O ?  3,+9Zti83bIA)HyYJHCbJHCrJHpKiL3PjL3 &M3T^y\3cb\3Xcr\31]3t]3]3r^3g^3b^3Z DDYHCbHCrHpi3Hj3&&3LUy39cb3Wcr3j3Pt3T3Xr3g3b3u4}YHCbHCrH!pBp2ai3@j3D&3Hy3cb3cr33Lt3P3Tr3g3b3146YH(CbHICrHjpp2i3Hj3L& 3Py3cb3cr3 3"t3T3X!r3!g3!b3"QQ38{5Nm`OP]#iz  $#s:_ jpeg../includergb24.ctinyjpeg.htinyjpeg-internal.hstdint.h9v=  t f/h"n = t fguf<' 7 tɟ Ju>vf<(HX87  tɟ Ju>V<7X;YgvYD48|  $)AA AAC<$DkAA AAC@$AA AACH$4AA AACH8CAA APPPttt ttAt<JP3^`^AD=^H^AhG^L^Ad)^\^?W^@U^>VSDEtEFtFGt GHtHKtKtDvP_hWi`@sDdU\VUSSQPttt tt4tPX3U\44`h2Wd1VWSWS iQ8P45t56t67t 78t8;t;6t4kP\\6f6ho@6dE`4WRD3VSYSYS2SQP5U89t9:t:;t ;{t8IPIxS8FRFyVy{R8FQFzWz{Q%TINYJPEG_FMT_RGB24{privadd_rQ_tableHTDCnbits_in_reservoirclampQ_tablesshort intdefault_huffman_table_initializedbytes_per_rowadd_glookupHTACuint8_tTINYJPEG_FMT_RGB24bytes_per_mcuwidthfloatlong long intformat_rgb24tinyjpeg_colorspace_ttinyjpeg_colorspacecomponentsdecode_MCU_fctprevious_DCoffset_to_next_rowstream_lengthinitializeunsigned charbytes_per_blocklinessigned charflagslong long unsigned intheightunsigned intcomponent_infosstreamshort unsigned intjpeg/rgb24.ccharuint16_tjdec_private/home/hpa/syslinux/release/syslinux-3.63/com32/libHfactorcomponentVfactorreservoircode_sizestream_beginplanedecode_mcu_tableslowtableYCrCB_to_RGB24_2x1YCrCB_to_RGB24_2x2GNU C 4.1.2 20070925 (Red Hat 4.1.2-33)add_bAC_tableDC_tableconvert_colorspace_fctconvert_colorspacetinyjpeg_decode_mcu_3comp_tablehuffman_tableinitialize_rgb24YCrCB_to_RGB24_1x1YCrCB_to_RGB24_1x2GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4{ $%+0B> $Ru>N p)b^ x)8 nj )` {) *  *0b.L" # )"Dk5H4[8C l  y rgb24.cclampYCrCB_to_RGB24_1x1YCrCB_to_RGB24_2x1YCrCB_to_RGB24_1x2YCrCB_to_RGB24_2x2initialize_rgb24format_rgb24mallocTINYJPEG_FMT_RGB24tinyjpeg_decode_mcu_3comp_tableQ !&-;BIP[bmt{EM[iw-;IWes#',6CQ_l %/<JXe~",9GUbp $(-8FUdr6BFJOZ_jozl (,PTx|bgr24.o/ 1207848667 1026 1026 100664 10784 ` ELF\4(y1=~UWVS($T$T$T$T$@D$D$ $ @$T$$xBT$$T$ D$BT$ i ^iנiD$) =FiD$ #FEqD$D$D$D$ |$ t2T$D$TT$D$$T$T$$D$D$ t$1%([^_]ÍvUWVS,$T$T$(T$ T$@0D$ D$$HB$T$$BT$$iМT$iѠi)T$iD$  D$ FD$ F_ D$ FD$ FD$ FE/D$(D$D$ D$|$t.T$D$ T0T$|$(D$ $T$T$$t$1,[^_]ÐUWVS4$T$0PL$0щL$,L$ L$$D$TT$D$$HB$T$(BT$(iМT$iѠi)T$iD$] E D$ GD$ ~G] D$ cD$ SFD$ BFD$ |$ )D$D$$D$|$t $ > : ; I I&I : ;  : ; I8  : ; I !I/ !I/ : ; I8 ' I' I.: ; ' I@ : ; I.: ; ' @: ; I4: ; I4: ; I 4: ; I  4: ; I4: ; I.: ;' @: ;I4: ;I4: ;I 4: ;I 4: ;I!4: ;I".: ;' I@#4: ;I?  $4: ; I? < sA&int:ZR+l10Gi#j#Gk# z0z3#5#9*# A  *Z  @a  |=t>,#?,# @#A# 'B#CA# DCTD# A ? H 44*N"#fO8#P,# P,#$Q,#(TH#,9U,#0WH#4X,#8X,#<ZS#@1[c#\y# ]y#D^3# Ya# Cra# Cba#d"#0I 22 O H, NZ c@  y  ?   O  O ?  3,+9Zti83IA)HyYJHCbJHCrJHpKiL3PjL3 &M3T^y\3cb\31cr\3X]3t]3 ]3r^3g^3b^3Z DDYHCbHCrHpi3Hj3&&3LQy39cb3Wcr3j3Pt3T 3Xr3g3b3,}YHCbHCrH!pBp2ai3@j3D&3Hy3cb3cr33Lt3P 3Tr3g3b31`,/YH(CbHICrHjpp2i 3Hj 3L& 3P|y3cb3cr33Tt3X 3"!r3!g3!b3"R30s5OmsPQ^#jz  $Zs:_ jpeg../includebgr24.ctinyjpeg.htinyjpeg-internal.hstdint.h9v=  t f4h"n = t fuhf<' 7 tɟ Ju愼>vf<(HX87  tɟ Ju>V<7X;YgvYD,0|  $)AA AAC<$DgAA AAC@$AA AACH$,AA AACH0CAA APPPttt ttAt<JP3^`^AD=^H^AhG^L^Ad)^\^>V^@U^=S^?WDEtEFtFGt GHtHKtKtDvP_hWi`@sDdU\VUSSQPttt tt,tPX+U\,,`h*Wd)VSSSSaQ4P,-t-.t./t /0t03t3/t,cPT|\|/^||/hg|@|/d=|`|-WJ|D|,V|SRSRS+SQP|.U01t12t23t 3st0APApS0>R>qVqsR0>Q>rWrsQ%TINYJPEG_FMT_BGR24sprivadd_rQ_tableHTDCnbits_in_reservoirclampQ_tablesshort intdefault_huffman_table_initializedbytes_per_rowadd_glookupHTACuint8_tbytes_per_mcuTINYJPEG_FMT_BGR24widthformat_bgr24floatlong long inttinyjpeg_colorspace_ttinyjpeg_colorspacecomponentsdecode_MCU_fctprevious_DCoffset_to_next_rowstream_lengthinitializeunsigned charYCrCB_to_BGR24_2x2bytes_per_blocklinessigned charflagslong long unsigned intheightunsigned intcomponent_infosstreamYCrCB_to_BGR24_1x1YCrCB_to_BGR24_1x2short unsigned intinitialize_bgr24charuint16_tjdec_private/home/hpa/syslinux/release/syslinux-3.63/com32/libHfactorcomponentVfactorreservoircode_sizestream_beginplanedecode_mcu_tableslowtableYCrCB_to_BGR24_2x1GNU C 4.1.2 20070925 (Red Hat 4.1.2-33)add_bAC_tablejpeg/bgr24.cDC_tableconvert_colorspace_fctconvert_colorspacetinyjpeg_decode_mcu_3comp_tablehuffman_tableGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4s $%+0B> $Rm>N h)b^ p)8 nj )` {) *  *0Z.D" # )"Dg5H,[0C l  y bgr24.cclampYCrCB_to_BGR24_1x1YCrCB_to_BGR24_2x1YCrCB_to_BGR24_1x2YCrCB_to_BGR24_2x2initialize_bgr24format_bgr24mallocTINYJPEG_FMT_BGR24tinyjpeg_decode_mcu_3comp_tableI !&-;BIP[bmt{EM[iw-;IWes#',6CQ_l %/<JXe~",9GUbp $(-8FUdr 6BFJOZ_jozl (,PTx|yuv420p.o/ 1207848667 1026 1026 100664 8484 ` ELF4(WVSÉ։σ8u@$C {uC$C C{uC$C C{uC C{uC C{uC CCCFCFGG;t{t 1{[^_UWVS Ë$1{Eu拋(1BAKFuꋋ,f1BAKFu [^_]fVSË$1BAKFuꋋ(f1,1(BABABACFuBABABACFu[^fUWVS Nj$1ډwEu拯(D$VCBAuGD$|$u6,D$4CBAuVGD$|$uʼn1뢃t1ă [^_]VSË$1BAKFuꋋ(f1,1-BABABACuȃBABABACu[^% $ > $ > : ; I I&I : ;  : ; I8  : ; I !I/ !I/ : ; I8 ' I' I.: ; ' I@: ; I.: ; ' @4: ; I4: ; I4: ; I 4: ; I?  4: ; I? < .|intL.tZl^10,i#j#k# _0h3#y5#9*# A | *Z  @a  =>,#g?,#@#A#  B#CA# DCTD# A ?H 4*N"#ZO8#|P,# uP,#$XQ,#(TH#,U,#0WH#4oX,#8X,#<ZS#@%[c# \y# o]y#8^3# Ya# Cra# Cba#d"#I 22 O H, NZ c@  y  ?   O  O ?  3,4+38V>=>psH?y1H]i3pZ@sHyH pi3Hj3f(_q^p`saHvy1aHib3jb365.u4s6Hy6Hp7i83j83Rz  ?sa jpeg../includeyuv420p.ctinyjpeg.htinyjpeg-internal.hstdint.hYg!g!ggggYguwEJg=8mg=8mg=8lOg=8mgg-8 -8lXg=8mgWw7gW7t< ȼOg=8mg gt<,Z7,Z7@| AA A$AA AAC @AA $AA AAC AA ttt tPSRVRQWQttt tt>t P:SWQ<QR>RVU V1;V@AtABtBt @TPTStRRRPtRJnQQQRwVyVVttt ttt PWVU@S@FVPPS_pRppSp}U}}R}}V}}SSRV@QFPUPPQppQppV}}Q}UQSuwSUNhNpd}dPRP_Rp}RRRtt.t P,SRRRQQQVVV-V'TINYJPEG_FMT_YUV420P.privQ_tableHTDCnbits_in_reservoirQ_tablesshort intdefault_huffman_table_initializedbytes_per_rowlookupHTACuint8_twidthfloatlong long inttinyjpeg_colorspace_tformat_yuv420ptinyjpeg_colorspacecomponentsdecode_MCU_fctprevious_DCjpeg/yuv420p.cstream_lengthinitializeunsigned charinitialize_yuv420pbytes_per_mcusigned charflagslong long unsigned intheightunsigned intcomponent_infosstreamshort unsigned intcharuint16_tbytes_per_blocklinesjdec_private/home/hpa/syslinux/release/syslinux-3.63/com32/libHfactorcomponentYCrCB_to_YUV420P_2x1YCrCB_to_YUV420P_2x2TINYJPEG_FMT_YUV420PVfactorreservoircode_sizestream_beginplanedecode_mcu_tableslowtableGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)AC_tableYCrCB_to_YUV420P_1x1YCrCB_to_YUV420P_1x2DC_tableconvert_colorspace_fctconvert_colorspacetinyjpeg_decode_mcu_3comp_tablehuffman_tableGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4. (%d+d0dAB> pR N | b ^ 8 n j P { M+ !   !0,m.   3@H] r   yuv420p.cinitialize_yuv420pYCrCB_to_YUV420P_2x2YCrCB_to_YUV420P_1x2YCrCB_to_YUV420P_2x1YCrCB_to_YUV420P_1x1format_yuv420pmallocmemcpyTINYJPEG_FMT_YUV420Ptinyjpeg_decode_mcu_3comp_table-E !&-;BIP[bmt{EM[iw-;IWes %/9@DHMWdq ,9GTakrvz n  8<`d|grey.o/ 1207848667 1026 1026 100664 7148 ` ELF4(WVSÉ։σ8u@ C$@{ukC CC1;[^_ÐUWVS $h1ډGu [^_]ÍvVS$p1ۋBACu[^ÐUWVS $h1ډGu [^_]ÍvVS$p1ۋBACu[^% $ > $ > : ; I I&I : ;  : ; I8  : ; I !I/ !I/ : ; I8 ' I' I.: ; ' I@: ; I.: ; ' @4: ; I4: ; I4: ; I 4: ; I 4: ; I?  4: ; I? < int^ZP!l 10Gi#j#Ek# Z03#5#9*# A  *Z  @a  c=[>,#m?,#@#A# 'B#CA# DCTD# A ? H *4*N"#O8#P,# P,#$Q,#(TH#,7U,#0WH#4uX,#80X,#<ZS#@U[c#\y# ]y#h^3# Ya# Cra# Cba#d"#0I 22 O H, NZ c@  y  ?   O  O ?  3,43C8~V~D}}yH pi,1$3DZIdWcyeHRpfQig,$h3PIH yJHpK2iL,E$M3X71k0y2HRp3Qi4,$53Cz  ^t^ jpeg../includegrey.ctinyjpeg.htinyjpeg-internal.hstdint.hYgvYbXzgg[VkW4gg[VkVJzgg[VkY4gg[VkD| CAA A$D9AA AAC +AA $9AA AAC +AA ttt CtP@SRAVACRQBWBCQDEtEFtFGt GHtHKtK}t DePWySQzV\{WZ|Uttt PSVttt ttt PSVWUttt PSV$TINYJPEG_FMT_GREYprivjpeg/grey.cQ_tableHTDCYCrCB_to_Grey_2x2nbits_in_reservoirTINYJPEG_FMT_GREYQ_tablesshort intdefault_huffman_table_initializedbytes_per_rowlookupHTACuint8_tbytes_per_mcuwidthfloatlong long inttinyjpeg_colorspace_ttinyjpeg_colorspacecomponentsdecode_MCU_fctprevious_DCoffset_to_next_rowstream_lengthinitializeunsigned chartinyjpeg_decode_mcu_1comp_tablebytes_per_blocklinessigned charflagslong long unsigned intheightunsigned intinitialize_greycomponent_infosstreamYCrCB_to_Grey_2x1short unsigned intcharuint16_tjdec_privateYCrCB_to_Grey_1x1YCrCB_to_Grey_1x2HfactorcomponentVfactorreservoircode_sizestream_beginplanedecode_mcu_tableformat_greyslowtableGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)/home/hpa/syslinux/release/syslinux-3.63/com32/libAC_tableDC_tableconvert_colorspace_fctconvert_colorspacehuffman_tableGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %H+H0HRB> hRN Db8 ^ L8 nT j P {  (   0( h.x CD9*+<9N+ `  lsz grey.cinitialize_greyYCrCB_to_Grey_2x2YCrCB_to_Grey_1x2YCrCB_to_Grey_2x1YCrCB_to_Grey_1x1format_greymallocmemcpyTINYJPEG_FMT_GREYtinyjpeg_decode_mcu_1comp_tablef !&-;BIP[bmt{EM[iw-;IWes %/9@DHMWdq~ "/<AKU\`dis k  8<`d|rgba32.o/ 1207848667 1026 1026 100664 10896 ` ELF4(y1=~UWVS($T$T$T$T$@ D$D$ $0 @$T$$D$BT$$D$ À@D$ iÜ0 ^iD$i)؍0 =GiD$0 #GGEmD$D$D$D$ |$ t2D$T$D D$T$$D$D$$T$T$ |$1!([^_]ÍvUWVS,$T$T$(T$ T$@@D$ D$ $HB$T$$BT$$iМT$iѠi)T$iD$D$ D$ FD$ FF_ D$ FD$ FD$ FFE#D$(D$D$ D$|$t.T$D$ T@T$|$(D$ $T$T$$t$1,[^_]ÐUWVS4$T$$PL$$щL$( $L$D$TT$D$ T$0HBT$0T$,BT$,iМT$iѠi)T$iD$ ] ED$ D$ zGD$  iGG] D$ JD$ :FD$  )FFD$|$D$D$D$ |$ t;$D$ D$$D$(L$L$,|$$t$(,$D$D$0D$4[^_]UWVS4$T$(PL$(щL$ L$$L$D$TT$D$T$0HBT$0T$,BT$,iМiѠi)T$iD$ $ D D$ GD$  GG$X $D GD$ GD$  GG$Z D |D$ lFD$  [FF $Y D >FD$ -FD$  FFD$|$D$D$D$|$t@D$$ D$@D$(D$ D$$$T$T$0L$L$,|$(t$ D$F4[^_]fWVSÉ։σ8u@ C${u C CC 1;[^_% $ > $ > : ; I I&I : ;  : ; I8  : ; I !I/ !I/ : ; I8 ' I' I.: ; ' I@ : ; I.: ; ' @: ; I4: ; I4: ; I 4: ; I  4: ; I4: ; I.: ;' @: ;I4: ;I4: ;I 4: ;I 4: ;I!4: ;I".: ;' I@#4: ;I?  $4: ; I? < \:intLZ?l'1(0Oi#j#k# 03#5#9*# A  *Z  @a  =>,#?,# @#&A# /B#VCA# DCTD# A ?GH 4*<N"#O8#P,# P,#$Q,#(TH#,uU,#0 WH#4X,#8X,#<ZS#@C[c#\y# ]y#V^3# Ya# Cra# Cba#d"#8I 22 O H, NZ c@  y  ?   O  O ?  3,+9Zti83HIE)HyYJHCbJHCrJHpKiL3PjL3 bM3T^y\3cb\3Xcr\31]3]3 ]3r^3g^3b^3a^3Z HDYHCbHCrHpi3Hj3&b3Lay39cb3Wcr3j3P3T 3Xr3g3b3a3.H}YHCbHCrH"pBp2ai3Dj3Hb3L y3cb3cr33P3T 3Xr3g3b3a3V HZ YH(CbHICrHjpp2i3Hj3Lb3Py!3cb!3cr!3 "3""3T "3X!r#3!g#3!b#3!a#3"1a3\5^m_`xm#yz  $bsD` jpeg../includergba32.ctinyjpeg.htinyjpeg-internal.hstdint.h9v=  t f/h"lt  = t fguLbt* 7 tɑ Juvvbt,DJ<7  tɟ JuLvLNt?X;YgYHH\|  $-AA AAC<$HsAA AAC@$AA AACH$HAA AACH\EAA APPPttt ttEt<JP3^`^ED=^H^EhG^L^Ed)^\^CW^DU^BVSHItIJtJKt KLtLOtOtHzPchWm`@wDdY\VUS!SQPttt ttHtP  GU  Hh @ Hd \ FW ` EV dSdSvQ$EPHItIJtJKt KLtLOtOZtHPp\ZzZh@ZdY`XWfDWVS-SuSVSQPYU\]t]^t^_t _t\mPmS\jRjVR\jQjWQ&TINYJPEG_FMT_RGBA32privadd_rQ_tableHTDCnbits_in_reservoirclampinitialize_rgba32Q_tablesshort intdefault_huffman_table_initializedformat_rgba32bytes_per_rowTINYJPEG_FMT_RGBA32add_glookupHTACuint8_tYCrCB_to_RGBA32_2x2bytes_per_mcuwidthfloatlong long intYCrCB_to_RGBA32_1x2tinyjpeg_colorspace_ttinyjpeg_colorspacecomponentsdecode_MCU_fctprevious_DCoffset_to_next_rowstream_lengthinitializeunsigned charbytes_per_blocklinessigned charflagslong long unsigned intheightunsigned intcomponent_infosjpeg/rgba32.cYCrCB_to_RGBA32_2x1streamshort unsigned intcharuint16_tYCrCB_to_RGBA32_1x1/home/hpa/syslinux/release/syslinux-3.63/com32/libHfactorcomponentVfactorreservoircode_sizejdec_privatestream_beginplanedecode_mcu_tableslowtableGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)add_bAC_tableDC_tableconvert_colorspace_fctconvert_colorspacetinyjpeg_decode_mcu_3comp_tablehuffman_tableGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %%+0B> %RHN )b ^ )8 n(j *` { * x*  *03." L$ -$Hs8LH`\E r   rgba32.cclampYCrCB_to_RGBA32_1x1YCrCB_to_RGBA32_2x1YCrCB_to_RGBA32_1x2YCrCB_to_RGBA32_2x2initialize_rgba32format_rgba32mallocTINYJPEG_FMT_RGBA32tinyjpeg_decode_mcu_3comp_tableu !&-;BIP[bmt{EM[iw-;IWes#',6CQ_l!%).8ESan '+/4>KYgt3;?CHSap [gkotm (,PTx|bgra32.o/ 1207848667 1026 1026 100664 10888 ` ELF4(y1=~UWVS($T$T$T$T$@ D$D$ $ @$T$$xBT$$T$ D$BT$ i ^iנiD$) =FiD$ #FFEmD$D$D$D$ |$ t2T$D$T T$D$$T$T$$D$D$ t$1!([^_]ÍvUWVS,$T$T$(T$ T$@@D$ D$$HB$T$$BT$$iМT$iѠi)T$iD$  D$ FD$ FF_ D$ FD$ FD$ FFE'D$(D$D$ D$|$t.T$D$ T@T$|$(D$ $T$T$$t$1,[^_]ÐUWVS4$T$$PL$$щL$( $L$D$TT$D$ T$0HBT$0T$,BT$,iМT$iѠi)T$iD$ ] E D$ GD$ qGG] D$  RD$ BFD$ 1FFD$|$D$D$D$ |$ t;$D$ D$$D$(L$L$,|$$t$(,$D$D$0D$4[^_]UWVS4$T$(PL$(щL$ L$$L$D$TT$D$T$0HBT$0T$,BT$,iМT$iѠi)T$ i $ D D$  GD$ GG$X $D GD$  GD$ GG$Z D D$  sFD$ bFF $Y D EFD$  4FD$ #FFD$|$D$D$D$|$t@D$$ D$@D$(D$ D$$$T$T$0L$L$,|$(t$ D$E4[^_]ÐWVSÉ։σ8u@ C${u C CC 1;[^_% $ > $ > : ; I I&I : ;  : ; I8  : ; I !I/ !I/ : ; I8 ' I' I.: ; ' I@ : ; I.: ; ' @: ; I4: ; I4: ; I 4: ; I  4: ; I4: ; I.: ;' @: ;I4: ;I4: ;I 4: ;I 4: ;I!4: ;I".: ;' I@#4: ;I?  $4: ; I? < VC(int:Z-l10Oi#j#k# 03#5#9*# A  *Z  @a  =v>,#?,# @#&A# /B#JCA# DCTD# A ?;H 64*0N"#zO8#P,# P,#$Q,#(TH#,wU,#0WH#4X,#8X,#<ZS#@1[c#\y# ]y#D^3# Ya# Cra# Cba#d"#8I 22 O H, NZ c@  y  ?   O  O ?  3,+9Zti83IE)HyYJHCbJHCrJHpKiL3PjL3 dM3T^y\3cb\31cr\3X]3]3 ]3r^3g^3b^3a^3ZfHDYHCbHCrHpi3Hj3&d3L]y39cb3Wcr3j3P3T 3Xr3g3b3a3.@}YHCbHCrH"pBp2ai3Dj3Hd3Ly3cb3cr33P3T 3Xr3g3b3a3V~@SYH(CbHICrHjpp2i3Hj3Ld3Py$3cb$3cr$3%3T%3X %3"!r&3!g&3!b&3!a&3"d3T5ambcp#|z  $bsD` jpeg../includebgra32.ctinyjpeg.htinyjpeg-internal.hstdint.h9v=  t f4h"lt! = t fuhLbt+ 7 tɑ Ju愼vvbt,DJ<7  tɟ JuLvLNt?X;YgYH@T|  $-AA AAC<$HoAA AAC@$AA AACH$@AA AACHTEAA APPPttt ttEt<JP3^`^ED=^H^EhG^L^Ed)^\^BV^DU^AS^CWHItIJtJKt KLtLOtOtHzPchWm`@wDdY\VUSSQPttt tt@tP?U@h@@d\>W`=V`S`SnQ AP@AtABtBCt CDtDGtGSt@wPh\SrSh{@SdQ`QW^DPVS&SnSOSQPRUTUtUVtVWt WtTePeSTbRbVRTbQbWQ&TINYJPEG_FMT_BGRA32privadd_rQ_tableHTDCnbits_in_reservoirclampQ_tablesshort intdefault_huffman_table_initializedYCrCB_to_BGRA32_2x1bytes_per_rowadd_glookupHTACformat_bgra32uint8_tYCrCB_to_BGRA32_1x1YCrCB_to_BGRA32_1x2widthTINYJPEG_FMT_BGRA32floatlong long inttinyjpeg_colorspace_ttinyjpeg_colorspacecomponentsdecode_MCU_fctprevious_DCjpeg/bgra32.coffset_to_next_rowstream_lengthinitializeunsigned charbytes_per_mcubytes_per_blocklinessigned charflagslong long unsigned intheightunsigned intcomponent_infosstreamshort unsigned intcharuint16_tjdec_private/home/hpa/syslinux/release/syslinux-3.63/com32/libHfactorYCrCB_to_BGRA32_2x2componentVfactorreservoircode_sizeinitialize_bgra32stream_beginplanedecode_mcu_tableslowtableGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)add_bAC_tableDC_tableconvert_colorspace_fctconvert_colorspacetinyjpeg_decode_mcu_3comp_tablehuffman_tableGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %%+0B> %RHN )b^ )8 n j *` {* p*   x*0+." D$ -$Ho8L@`TE r   bgra32.cclampYCrCB_to_BGRA32_1x1YCrCB_to_BGRA32_2x1YCrCB_to_BGRA32_1x2YCrCB_to_BGRA32_2x2initialize_bgra32format_bgra32mallocTINYJPEG_FMT_BGRA32tinyjpeg_decode_mcu_3comp_tablem !&-;BIP[bmt{EM[iw-;IWes#',6CQ_l!%).8ESan '+/4>KYgt3;?CHSap([gkotm (,PTx|x86_init_fpu.o/ 1207848667 1026 1026 100664 2880 ` ELF4(fD$ "|$f|$ufD$ |$ D$ %??u0% $ > $ > : ; I.: ; ' I 4: ; I.: ; ' : ; I .? : ; ' I@ 4: ; I 4: ; I 1X Y 1ID2intSeww< lv Z vZ #3I cr0$Z fsw%Hz fcw&H> + i@ sys../includex86_init_fpu.cstdint.h">w=j<f/Kw tK_| ICtIt 4PBEP+>x>@P@BxBEPEIx x86_init_fpuIuint64_tset_cr0unsigned charshort unsigned intshort intget_cr0/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlong long intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)x86_init_fpuuint16_tsys/x86_init_fpu.cuint32_tsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4I!',>@ : 8 NLmJ  ^(Z   kzd#v (    0 0.      Ix86_init_fpu.cx86_init_fpu   ! & - ; B I T [ f m x       Mpow.o/ 1207848667 1026 1026 100664 1200 ` ELF4( D$ D$B! mathpow.S KK//////////hmath/pow.S/home/hpa/syslinux/release/syslinux-3.63/com32/libGNU AS 2.17.50.0.18%.symtab.strtab.shstrtab.text.data.bss.rel.debug_line.rel.debug_info.debug_abbrev.rel.debug_aranges4!T'T0TF, x @l<  L^  Z  @m  p pow. strtod.o/ 1207848667 1026 1026 100664 4056 ` ELF 4(UWVSՉB u+t-t1 1B1P$ɃC 0 vڀ.t121P$ɃAD0 v؍T ߅u"t $ > .? : ; ' I : ; I.: ; ' I 4: ; I&I .? : ; ' I@ : ; I : ; I 4: ; I 4: ; I4: ; I4: ; I  I4: ; I? < I!b4intQ[,__cZ,w*,x)wInf+~w :~0wb str/:t /L 1w[ 2, u3,p4Rp105w\n6,6 7,u '8,Inf9~@ERE,ppg#eE math../includestrtod.cctype.herrno.h/jRi (4`Mhiw_gKL1! LKL0/v. fKw A| ,bAA AA~HkHttt tBtBJtJutu}t}bt P PRaUdfW`W%'V,.V0VVV_V]R]bRSP)W)IPI^W5S^ShQQbQstrtodbunsigned intnum_digitsnumberis_realnum_decimals/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned charnegativestrtoddoublemath/strtod.c__ctypesGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)isspaceexponenterrnocharendptrGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.cst4.rodata.cst8.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4b XH%+0B> R0N ^k|Dx     0.11 @ 8     bstrtod.cstrtod__ctypeserrno7j #C N !&9Vx        * FYqxR idle.o/ 1207848667 1026 1026 100664 3464 ` ELF4(<=t!L$"D$8Ѓ<% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8 &I .: ; ' .? : ; ' @4: ; I 1X Y 3 Pint:S!e)*%llwbZH<~ ,! gs"Z# fs#Z# es$Z# ds%Z# edi'# esi(# ebp)# D*# ebx+# edx,# ecx-# eax.#$ 30#(1  >(3-P-/8F),*` syslinux../include/sys../includeidle.ccpu.hcom32.hstdint.h' <0 z.| 3C@t3t syslinux_idle3com32sys_tsyslinux/idle.cunsigned charshort unsigned intreg32_t_unused_esp/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intuint8_tidle_resultsyslinux_idlelong long intcharcpu_relaxGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)sys_idleshort intuint16_tuint32_teflagssigned chardo_idleGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack43 %h+l0lBC> @ RHN X ^, j (f `  w4!U$ p y  x 0N. @  ;,    #31idle.cdo_idle.1524sys_idle.1525syslinux_idle__intcall ) !&4;BIT[fmx;  m reboot.o/ 1207848667 1026 1026 100664 3316 ` ELF4( t41fr j% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8 &I .? : ; ' @: ; I4: ; I I4: ; I? < 5tintBS?eM2%llwbZH`~ ,! gs"Z# fs#Z# es$Z# ds%Z# edi'# esi(# ebp)# h*# ebx+# edx,# ecx-# eax.#$ ;0#(1  /'5&,D&( ZXdJ syslinux../includereboot.cstdint.hcom32.h&?/| 5CVB O.Httt2t 25t PP"syslinux_reboot5syslinux/reboot.ccom32sys_t__com32_zero_regssyslinux_rebootunsigned charshort unsigned intreg32_t_unused_esp/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intuint8_tlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)warmshort intuint16_treboot_flaguint32_teflagssigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack45 %l+l0lBN> RAhN b4^  ob~B&z  h  0N.d   6    5,reboot.csyslinux_reboot__com32_zero_regs__farcall+   ! & 4 ; B I T [ f m x   ;          Wfeatures.o/ 1207848667 1026 1026 100664 3796 ` ELF4(W 1f$ʰ" УXZ_%  : ;  : ; I8 $ >  I&I$ > : ; I  : ; : ; I I !I/  : ;  : ; I8  .: ; ' I : ; I.? : ; ' @4: ; I 4: ; I?  9RzN:"len#N#ptr$U#[`,intR/`9SBN  l w b  f ,!gs"#fs##es$#ds%#edi'#esi(# ebp)#n*#ebx+#edx,#ecx-# eax.#$K0#(1^}|%|**Rreg+:'%n syslinux../include../include/syslinuxfeatures.ccom32.hstdint.hfeatures.h)Mػu| RACK AttOtOPt PRtJ=__syslinux_detect_features*__syslinux_feature_flagsRsyslinux/features.ccom32sys_t__seg__offsunsigned char__syslinux_feature_flagsshort unsigned intreg32_t_unused_esp/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intuint8_t__syslinux_detect_featureslong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tuint32_teflagssigned charMK_PTRGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.ctors.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4R D H%+, 0 B=> RN bx^  m|4i  zDN B  0be. @  S ,  R0:features.creg.1585__syslinux_detect_features__intcall__syslinux_feature_flags&-29CJ !*Oaov}o  %+8{ config.o/ 1207848667 1026 1026 100664 5564 ` ELF, 4( f$ʸ"У % $ > $ > : ; I : ; (  : ;  : ; I8  I &I  : ; : ; I8 & : ;  : ; I : ; I : ; I!I/  .: ; ' I : ; I.? : ; ' @4: ; I 4: ; I? < 4: ; I?  9j l"int LY^p9x'0@1U234/0S#1S#2~#F3#4#   2?@A# ahAA# C axDS# cxES# dxFS#GS#kH#,I# gJ#  %LMA# ahNA#OA# chPA#UQA# dhRA#SS#T#bU%# + e WXA# ahYA# cxZS#%[S#\S#]#^# `aA# ahbA#cA# chdA#UeA# dhfA#gS#h#bi%# ],>cBrK2Vpxe_0isojtuS#1vS#wS#p3# ptr#  lewbS9A ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)#B*# ebx+# edx,# ecx-# eax.#$E0#(N1}|S;|S9#9reg$(7mLz] |j syslinux../include../include/syslinuxconfig.ccom32.hstdint.hconfig.h"?u| 9Ct9tl__syslinux_get_config_file_nameF__syslinux_derivative_infoe__syslinux_config_file9SYSLINUX_FS_UNKNOWNversion__segshort intsyslinux_derivative_infoeflags__syslinux_serial_console_infoesbxsyslinux_ipappend_strings__syslinux_config_fileuint8_tspec_packetsyslinux_filesystemiobase__syslinux_get_config_file_nameflowctlsyslinux_versionlong long intmax_apiptab_ptr__syslinux_version__offs_unused_espcom32sys_tunsigned chargsdisigned charlong long unsigned intuint32_treg32_tSYSLINUX_FS_ISOLINUXdiskstackshort unsigned int_padcopyright_stringsector_shiftcharuint16_tpxenvptr/home/hpa/syslinux/release/syslinux-3.63/com32/libSYSLINUX_FS_SYSLINUXSYSLINUX_FS_PXELINUXsyslinux/config.c__syslinux_ipappend_stringsfilesystemcount__syslinux_derivative_infoMK_PTRSYSLINUX_FS_EXTLINUXsyslinux_serial_console_infoGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)apiverfssidivisorunsigned intversion_stringdrive_numberesdi_ptrGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.ctors.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack49 0%p+, 0UB> RZN b^  m(i  z 0p   0k+ .Y Y P do ,  93=Tconfig.creg.1540__syslinux_get_config_file_name__intcall__syslinux_config_file__syslinux_derivative_info  *1 !&-;BMT_fqxbp~ 9ao}"<bjx# 4:GTYfsxw serial.o/ 1207848667 1026 1026 100664 5576 ` ELF$ 4(W 1f$ ʰ"f ffXZ_% $ > $ > : ; I : ; (  : ;  : ; I8  I &I  : ; : ; I8 & : ;  : ; I : ; I : ; I!I/ .? : ; ' @4: ; I 4: ; I? < 4: ; I?  WObint LT^p(n'061K234/0S#1S#|2~#53#4#   2?|@A# ahAA# C axDS# cxES# dxFS#GS#H# I# eJ#  %L|MA# ahNA#OA# chPA#DQA# dhRA#SS#!T#QU%# + e W|XA# ahYA# cxZS#[S#\S#]#^# `|aA# ahbA#cA# chdA#DeA# dhfA#gS#h#Qi%# ]&>cBrK2Vpxe_0isojtuS#vS#wS#3# ptr#  lewbS(A ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)#=*# ebx+# edx,# ecx-# eax.#$?0#(I1j*Oreg+*7mF']`j syslinux../include../include/syslinuxserial.ccom32.hstdint.hconfig.h)Mح| OACH AttLtLMt MOtw[__syslinux_get_serial_console_info__syslinux_derivative_info.__syslinux_serial_console_infoOSYSLINUX_FS_UNKNOWNversionshort intsyslinux_derivative_infoeflags__syslinux_serial_console_infogsdi__syslinux_get_serial_console_infoesbxsyslinux_ipappend_strings__syslinux_config_fileuint8_tspec_packetsyslinux_filesystemiobaseflowctlsyslinux_versionlong long intmax_apiptab_ptr__syslinux_version_unused_espcom32sys_tunsigned charsigned charlong long unsigned intuint32_treg32_tSYSLINUX_FS_ISOLINUXdiskstackshort unsigned int_padcopyright_stringsector_shiftcharuint16_tpxenvptr/home/hpa/syslinux/release/syslinux-3.63/com32/libSYSLINUX_FS_SYSLINUXSYSLINUX_FS_PXELINUX__syslinux_ipappend_stringsfilesystemcount__syslinux_derivative_infoSYSLINUX_FS_EXTLINUXsyslinux_serial_console_infoGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)apiverfssidivisorsyslinux/serial.cunsigned intversion_stringdrive_numberesdi_ptrGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.ctors.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4O P%+, 0.B[> (hR)N b^  m4i  zD0{   0Z% .S S  P \z ,  O6@_serial.creg.1656__syslinux_get_serial_console_info__intcall__syslinux_serial_console_info__syslinux_derivative_info&+16<AG !&-;BMT_fqxbp~ 9ao}"<bjx */<ANw ipappend.o/ 1207848667 1026 1026 100664 6016 ` ELFl4(VSf$ʸ"(uC5 5@ 1Љ@C9|X[^% $ > $ > : ; I : ; (  : ;  : ; I8  I &I  : ; : ; I8 & : ;  : ; I : ; I : ; I!I/  .: ; ' I : ; I.? : ; ' @4: ; I1X Y 14: ; I 4: ; I 4: ; I? < 4: ; I?  o+"intLW^pY'0^1s234/0S#1S#2~#f3#4#   2?@A# ahAA# C axDS# cxES# dxFS#GS#H#LI# eJ#  %LMA# ahNA#OA# chPA#uQA# dhRA#SS#T#U%# + e WXA# ahYA# cxZS#E[S#\S#"]#^# `aA# ahbA#cA# chdA#ueA# dhfA#gS#h#i%# ]J>cBrK2Vpxe_0isojtuS#QvS#wS#3# ptr#  lewbSYA ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)#@*# ebx+# edx,# ecx-# eax.#$c0#(L1}|S9|Sdj*oi,3DRES6reg+t,'d@&7mjz]&l syslinux../include../include/syslinuxipappend.ccom32.hstdint.hconfig.h)\ɡf|  oAA Cg ttt ltlot QmSq__syslinux_get_ipappend_strings__syslinux_derivative_info__syslinux_ipappend_stringsoSYSLINUX_FS_UNKNOWNversion__segshort intsyslinux_ipappend_string_listsyslinux_derivative_infoeflags__syslinux_serial_console_infoesbxsyslinux_ipappend_strings__syslinux_config_fileuint8_tspec_packetsyslinux_filesystemiobaseflowctlsyslinux_versionlong long intmax_apiptab_ptr__syslinux_version__offs_unused_espcom32sys_tunsigned chargsdi__syslinux_get_ipappend_stringssigned charlong long unsigned intuint32_treg32_tSYSLINUX_FS_ISOLINUXdiskstackshort unsigned int_padcopyright_stringsector_shiftcharuint16_tpxenvptr/home/hpa/syslinux/release/syslinux-3.63/com32/libSYSLINUX_FS_SYSLINUXSYSLINUX_FS_PXELINUX__syslinux_ipappend_stringsfilesystemcount__syslinux_derivative_infoMK_PTRSYSLINUX_FS_EXTLINUXsyslinux/ipappend.csyslinux_serial_console_infoGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)apiverfssidivisorunsigned intversion_stringdrive_numberesdi_ptrGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.ctors.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4o HX%+ 0BK> RN Hb^ P m8i X zWK u h  p0 k .  T`  ,@  3oS]yipappend.creg.1541syslinux_ipappend_string_list__syslinux_get_ipappend_strings__intcall__syslinux_ipappend_strings__syslinux_derivative_info!+17;AH_ !&-;BMT_fqxbp~ 9ao}"<bjx# 0 =A_uy addlist.o/ 1207848667 1026 1026 100664 3044 ` ELF4(WVSljӉθ…upD$BB 1[^_% $ > $ > : ; I : ;  : ; I8  : ; I8  I .? : ; ' I@ : ; I : ; I : ; I 4: ; I+78K~int%%V dsto#srco#leno## z (!,7 (8 dst oV src ot len o ml"b syslinux../include/syslinux../includeaddlist.cmovebits.hstdint.h /=uZL| 7AA Attt 7tP6WR4SQ5V(/syslinux_add_movelist7nextsyslinux_movelistunsigned charshort unsigned intsyslinux/addlist.c/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlistlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint32_taddr_tsigned charsyslinux_add_movelistGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack47 %l+l0lB,/> R[N b4^  o~,z    0.>>   (    7!addlist.csyslinux_add_movelistmalloc   ! & 4 ; B I P W b i p         ofreelist.o/ 1207848667 1026 1026 100664 2868 ` ELFd4(S X ؅uXZ[% $ > $ > : ; I : ;  : ; I8  : ; I8  I .? : ; ' @ : ; I 4: ; I8cint%% V dsto#srco#leno## z L& %D m'|c syslinux../include/syslinux../includefreelist.cmovebits.hstdint.h%k=qO| ACQ Atttt tPSP)syslinux_free_movelistnextsyslinux_movelistunsigned charshort unsigned intsyslinux/freelist.csyslinux_free_movelist/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intlistlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint32_taddr_tsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 4 %L+L0LB> < RN  b`4^  om~-z   .  $ 0N n.  (    #freelist.csyslinux_free_movelistfree    ! & 4 ; B I P W b i p       pmemmap.o/ 1207848667 1026 1026 100664 6108 ` ELF 4(UWVS< D$D$8L$ T$0Bf=`w*  |D$Dj|d \PAMSX`D$fDD$fHD$L$ @D$4|$0PAMS|$,L$yE1yAQ wqw(1)9rZw9vT11ɻ)9r w9vӉ t" D$DUD$D$$X(|$fdL$ @D$4uGD$,ftx  \$DjuID$(ft: jfd D$Dj1ɺuD$8 D$81fdf|$0t뾃<[^_]% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I& : ; ( .: ; ' I : ; I5.: ; ' I .? : ; ' I@4: ; I 4: ; I4: ; I4: ; I : ;  !4: ; I? < rW xaintWZlI|,lswbaO  ,! gs"a# fs#a# es$a# ds%a# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ '0#(1 HF (Gs# SH# IH# ^JN# 9Ks# .Lf# M# %7O7B =  !fs7B P3ss  lus_~pE3  ' C(# k)# * #  I- C.~# len/~# k0s#fSEGea__pdf lqja__pifb4 W\67bC8~len8~,<8~93f: hk;d/ ?AkhD 5@5 !Nl syslinux../include../include/syslinuxmemmap.ccom32.hstdint.hmovebits.h3w/*M0$Yh\K ,g0" .ivȑ | hWAA AACP}\R`E.HP`.\E`B.HPC.X\L`G.HPP\G`IPN\F`OPN.ttt ttDtDVtVctc]t]btbltltttttttt%t%WtTVW=PRBVQS||PRVU&vsyslinux_memory_mapWcs_cfarcalliregnextuint64_t__com32eflagscs_farcallcs_bounce_sizecom32_sys_argsuint8_tsyslinux_memmap_typesaddr_tuint32_tshort intbaillong long intmemfoundSMT_RESERVED_unused_espcom32sys_tunsigned charsigned charlong long unsigned intSMT_ALLOCreg32_tunsigned intuint16_tcs_sysargsSMT_FREEmaxlenstartshort unsigned intoregcharmmaptypeSMT_END/home/hpa/syslinux/release/syslinux-3.63/com32/libsyslinux_memory_mape820bufziregsyslinux_memmapOFFSSMT_ZEROe820_entrycs_intcallSMT_ERRORsyslinux/memmap.cGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)SMT_UNDEFINEDcs_cmdlinecs_bouncedosmemGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4W %+l 0B@v> dHRN b| ^  o w~s *z    0 o,.ZZp ( ,@,   W3;PZnmemmap.czireg.1915ireg.1914syslinux_memory_map__com32syslinux_init_memmap__intcallsyslinux_add_memmapsyslinux_free_memmap&0\mwe4? !&-;BIP[bmtM ;w     "+/4@LQ]iy movebits.o/ 1207848668 1026 1026 100664 12612 ` ELF#4(WVS| X 9wI9rNu9s ؋pu1[^_ËQ fjft$t fWVSÉ։ϸupx@ [^_ÍvUWVS ljՉˋ1F9v%)ËN)ىV P ^F ^ ƋN9v)VrV P nF ؃ [^_]UWVSLD$T$ $D$HD$DD$D$HuD$8\$8T$J֋RX F D$|$uڋD$8D$D$%uf C)эD$TV[suӋ\$D KSD$TjY[ uE;EuD$DU T$ B;u Z uL$DL$EG9s)ƋG9s)v );wrwD$H |$t$>uEUT$ 9s()‰T$E9s4D$ )щL$(HD$ D$0v+D$ D$;Es t$ t$(ml$D$ D$(D$D$HT$ …t[@|$t L$(L$)+L$(t9;L$vt$|$tT$T$()D$H D$HT$(T$ *E;D$ M;D$ vl$$D$HUVt]}u}L$HL$1s+ 9r t9v؉ʉ{ut\$@t t$$~vq L$LD$HPD$(\$@|$t#+D$ $ > : ; I : ;  : ; I8 I!I/ : ; I8  I  : ; ( .: ; ' I@: ; I: ; I : ; I4: ; I&I.: ; ' @ 4: ; I.: ; ' @4: ; I  .: ; ' I : ; I4: ; I: ; I.: ; ' .? : ;' I@: ;I 4: ;I !4: ;I"4: ;I#4: ;I$ : ;% : ;&1X Y'1( U)41*1+41,1X Y-4: ; I Jintt^,| ,#D ,# ,#7 ,# 1 ,#S,#o]B dst# src# len#B#   ~    $  J '(#)H#*#  ""0"8RlenKi| (a0>taoB B@N len gPv1eie|lenffH \GBxdstFsrcFlenF6mlHB raTqlenqqamsB mlsB'lz:l,UWBsrcVBdstXB XamlXB"lenljE"s"= wfpalobF}#g3fBmvB a<Ya+83Mw5a6B 7 9h!mm:"!ep:" O;Bd!mv<B[!f=Bn!fp=a!o>B!op>a"?"#?H"b?"o?"l?"@r A`"A B#=C!rvD3 gE3$U%8 %:&$oW'() 1 ) )! &r,'S*H '=)^ +i+r)}# &>''''(+)W )u ) ) ) )  ), ,#$'0-jC syslinux../include/syslinux../include../include/klibcmovebits.cmovebits.hstdint.harchsetjmp.hAiYI"L^Nq.UJ/Y=uf=]fK/==wt4uLg=>]wg=@!&~//=ptYg;ٮu8 ?wBlJ( f=KuuOOu" <==}hgu0E'f.}J0j XKL_1jvft5=Y|t | 0AA A 0@CB @.IP&CD @.HN.x9AA A$hAA AAC xAA AAC`lLp@.K`QlLpK`U.lIpI.H`\.MlBpH.J`IlLpV`a.lFp@.O`[.ttt 0t,PQ"0Q/W Q0Q09P2>Q@CtCEtENt NNt@JP@JR@JQPStSWtW_t _vtP\PP\RP\QPccv|xytyztz{t {txPSxRVxQWttt ttt PWRURQSP PVSttt  t #t#tttttt t t&t&ttttttttttCPCHRHHQHSRPPR^hRrvRvP'PPPS%UxU'USUJWW W8:W>WW'D'5R7JRJ{WRWxUW'W::U:>WUW%@%OSSSP'S:@SSJHJSS@SSUUeViV'-V-4Q>VW WF\Wz W:>WSSS:@SS;AVAmQmrVV VW\VjV:V)1Q5\Q^dQrQQ'QQ QQt\tzQz\joSSSwXPXPXPX{SPW FW\zWWSP SzPSRQzzQz|RCPP%SRSQQKWR_zRRUWQixQQ@SSP,<syslinux_compute_movelisto}>vflen/home/hpa/syslinux/release/syslinux-3.63/com32/libbailbest_lenfreebasefragsdup_movelistcopysrcnew_movelist_bail__jmp_bufadd_freelistnomemfstartfree_arealistmove_chunkallocate_fromparentptrsyslinux_memmap_typesaddr_tuint32_tnew_movelistshort intifragslong long intSMT_RESERVED__edi__esiep_len__espsyslinux/movebits.cunsigned charcopylensigned charcbytelong long unsigned intSMT_ALLOCsyslinux_movelistSMT_FREEsplit_moveliststartshort unsigned intsyslinux_memmapcharmmaptypedstpSMT_ENDis_free_zoneneedlensyslinux_compute_movelistbestSMT_ZERO__eipfree_movelistreversecopydstmovesfreelenllastSMT_ERRORavailslenGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)SMT_UNDEFINED__ebpdelete_movelistlast__ebxneedbaseunsigned intmemmapjmp_bufnextGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack4 T*h%P+P0PfB> *RN 0bdD^ 0p o? ~0z ,1   41780o!".""T' T) 00)@7P&DVx9ch   rwmovebits.cis_free_zonedelete_movelistallocate_fromadd_freelistnew_movelist_bailnew_movelistsplit_movelistfreesyslinux_add_memmaplongjmpmallocsyslinux_compute_movelistsetjmpsyslinux_init_memmapsyslinux_memmap_largestsyslinux_free_memmapFXin?D[: !&-;BIPW^it|4MU[agmsy29=EO\lsw{  />Malpty1>T_s~(1BNRV[fkv{  +0;@KP[`kp -1BLPYl{ 8<HLdhshuffle.o/ 1207848668 1026 1026 100664 7548 ` ELF4(UWVS\D$T$D$T1 uERBuD$XD$D$T_\$@ KSt$`j8 Kj[ u L$\D$`T$XRD$TD$D$T,THЙk , ȋD$L9D$P)ȉD$ D$`jT$0L$TD$XT$iD$X1G@ u/,J؉љD$ 9{D$TD$T3k D$\$ )É\$$T$X-,ED$(9~k D$L$11<;|$(u\$$D AD$A F1BABA FGR u\$Fu>;|$(uT$$D AD$A F1AC)ЉA FG[CuT$ T$4L$L$8k D$ $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I& : ; ( .? : ; ' I@: ; I4: ; I 4: ; I4: ; I4: ; I : ;  .: ; ' @4: ; I 4: ; I? < ? EintXqS7e%dllwbZH~ ,! gs"Z# fs#Z# es$Z# ds%Z# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ "0#(,1 bF Gl# H # zI=# JC# SKl# )L[# M# ,H,7 2  [l,7 E{,l{l  al  dst# src# len# # y~{> L. ' (# )# *L#  4 6 dst7l# src7l# len7l#K,IJL cLhmpL-MLdmlMLwdpNNnpO,nbO,rvO,WP,GP,iQ`Q\QQ R,BR,`SDlrt~ RR$= reg>G:,, Nm syslinux../include/syslinux../includeshuffle.cmovebits.hstdint.hcom32.h YuɃh=y%Ʌ1wL  KggvjKghrXYggvjKuqXxK>Y[~?| \AA AACpK|LB.HpK|ELpR|MMpL.P|FD.HpT.=Cttt ttRtR^t^hthstsxtxtttt t tttPRMCSCRP#R79RQ`RS R ShQVVWWSSVVWWUUQQQQt t+Csyslinux_prepare_shuffle fraglistcs_cfarcallnext__com32eflagscs_farcallshuffle_descriptorneed_blockscs_bounce_sizecom32_sys_argsuint8_tsyslinux_memmap_typesaddr_tuint32_tshort intbailnmoveslong long intrxmapprimariesSMT_RESERVED__syslinux_get_desc_block_sizesyslinux_movelistnzerodescfree_unused_espcom32sys_tunsigned charsyslinux/shuffle.csigned charlong long unsigned intSMT_ALLOCreg32_tunsigned intuint16_tcs_sysargsSMT_FREEstartshort unsigned intchartypesyslinux_prepare_shuffleSMT_END/home/hpa/syslinux/release/syslinux-3.63/com32/libsyslinux_memmapSMT_ZEROdesc_block_sizedesc_blocksmovesdesczonedescmemcs_intcallSMT_ERRORdbufGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)SMT_UNDEFINEDcs_cmdlinecs_bouncedescoffsmemmapdescaddrGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.ctors.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4  %D+`0 0`BC> \R< N 4b, ^ < m0 i D  z / d  l0.  ,=:,  C\pshuffle.cdesc_block_size__syslinux_get_desc_block_sizereg.1900syslinux_prepare_shufflesyslinux_dup_memmapsyslinux_add_memmapsyslinux_memmap_largestsyslinux_free_memmapsyslinux_compute_movelistmalloc__com32memcpysyslinux_free_movelist__intcall9a}3Tq !&4;BIT[fmx; "0>W       - ; @J OZhv      %16z x |shuffle_pm.o/ 1207848668 1026 1026 100664 5208 ` ELF 4(UWVS<ƅxtk  $T$PD$D$ 1|$fD$4fl$, fT$D$t$0fD$\$T$"<[^_]% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I& : ; ( .: ; ' I : ; I5.: ; ' I .? : ; ' I@: ; I: ; I 4: ; I4: ; I 4: ; I 1X Y !1"4: ; I? < Vint!kSce%-llwbZVHN~ ,! gs"Z# fs#Z# es$Z# ds%Z# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ 10#(1 RF lGl# OH # I=# ZJC# CKl# 8L[# M# ,H,7 2  [l,7 E{,l{l  al  dst# src# len# $# s~AwDk L ' (# )# $*L#  $( eax)l# ecx*l# edx+l# ebx,l# esp-l# ebp.l# esi/l# edi0l# eip2l# SEGeZ__pd #jZ__pi-,)Qd*Lda+Zwt,nd.,/@0  OT=! R")N| syslinux../include../include/syslinuxshuffle_pm.ccom32.hstdint.hmovebits.hbootpm.h,uMZu*XWXuKu | $AA AACPttt tttPRQUV(P(VS+#syslinux_shuffle_boot_pmsyslinux_pm_regsfraglistOFFSiregnext__com32eflagscs_farcallcs_bounce_sizecom32_sys_argsbootflagsuint8_tsyslinux_memmap_typesaddr_tuint32_tshort intlong long intSMT_RESERVEDcs_cfarcallsyslinux_movelistsyslinux_shuffle_boot_pmregbuf_unused_espcom32sys_tunsigned charsigned charlong long unsigned intSMT_ALLOCreg32_tunsigned intuint16_tcs_sysargsSMT_FREEstartshort unsigned intchartypeSMT_END/home/hpa/syslinux/release/syslinux-3.63/com32/libsyslinux_memmapsyslinux/shuffle_pm.ccs_intcallSMT_ERRORGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)SMT_UNDEFINEDcs_cmdlinecs_bouncememmapSMT_ZEROregsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 (%+0Bw> RGN (b<^ 0 o0~ /z @ 0  H0P y .  T@ Y   '@HOshuffle_pm.csyslinux_shuffle_boot_pmsyslinux_prepare_shuffle__com32memcpy__intcall )P   ! & 4 ; B I T [ f m x   ;                        " 0 > W  ) 48< A K P Z _ i n      shuffle_rm.o/ 1207848668 1026 1026 100664 5320 ` ELF$ 4(UWVS<ƅxtk  0T$PD$D$ 1|$fD$4fl$, fT$D$t$0fD$\$T$"<[^_]% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I& : ; ( .: ; ' I : ; I5.: ; ' I .? : ; ' I@: ; I: ; I 4: ; I4: ; I 4: ; I 1X Y !1"4: ; I? < '$rint=wSe%IllwbZrHj~ ,! gs"Z# fs#Z# es$Z# ds%Z# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ =0#(1 ^F Gl# ZH # I=# eJC# OKl# DL[# M# ,H,7 2  [l,7 E{,l{l  al  dst# src# len# 0# ~L`v L ' (# )# 0*L#  8,0, es-Z# .Z# ds/Z# ss0Z# fs1Z# gs2Z# eax4# ecx5# edx6# ebx7# esp8# ebp9# esi:#$ edi;#( ip=Z#, cs>Z#.USEGeZ__pdU [`~ jZ__piU-,)Qo*Ldm+Zw,nd.,+/@0  8OT=!I R"5N| syslinux../include../include/syslinuxshuffle_rm.ccom32.hstdint.hmovebits.hbootrm.h,uMZu*XWXuKu | $AA AACPttt tttPRQUV(P(VS++~syslinux_shuffle_boot_rmsyslinux/shuffle_rm.cfraglistcs_cfarcalliregnext__com32eflagscs_farcallcs_bounce_sizecom32_sys_argsbootflagsuint8_tsyslinux_memmap_typesaddr_tuint32_tshort int_unused_cssyslinux_shuffle_boot_rmlong long intSMT_RESERVEDsyslinux_movelistregbuf_unused_espcom32sys_tunsigned charsyslinux_rm_regssigned charlong long unsigned intSMT_ALLOCreg32_tunsigned intuint16_tcs_sysargsSMT_FREEstartshort unsigned intchartypeSMT_END/home/hpa/syslinux/release/syslinux-3.63/com32/libsyslinux_memmapOFFScs_intcallSMT_ERRORGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)SMT_UNDEFINEDcs_cmdlinecs_bouncememmapSMT_ZEROregsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 X(%+0Bw+> RN bP<^  o~] /z    0 0 .^ ^ @ Y   '@HOshuffle_rm.csyslinux_shuffle_boot_rmsyslinux_prepare_shuffle__com32memcpy__intcall )P   ! & 4 ; B I T [ f m x   ;                        " 0 > W l f                zonelist.o/ 1207848668 1026 1026 100664 6816 ` ELFH4(WVSӍ| p9w I9s9s Pu[^_fUWVSÉT$ $11s;T$u )9v͉߉Su߅u$D$(1ZY[^_]fS X؅u[X[VSD$t$6 …u D$1!CBBr[uƋD$[^ÍvUWVS D$ׅL L$ƽ9Cs{u. ty8T$ PXp kD$ CsH9D$ws …t $ > : ; I : ; (  : ;  : ; I8  I .? : ; ' I@ : ; I : ; I 4: ; I: ; I .? : ; ' @4: ; I4: ; I 4: ; I: ; I 4: ; I.? : ; ' I@LCm intZXv%*hVN~9Al! 'f(o#)z#*#  Wz2 A8 foV lenot o o ,4 A+ zT fslen o o  o Aml jFC A{pnlpjml  %L, AIj fJo lenJoDKz MohmpNmmppNjmpiOP Qz-C2sp.vep.c syslinux../include/syslinux../includezonelist.cmovebits.hstdint.h[iYI"La Ȋkvd0 uk=qOPuڻKKgu/>t<JK~ІvwgM/u/=\=u9/Mu=/ <=gp[1MI2Kgu>guw| 2AA A,4VAA AACIAACQ AYAA C $AA AAC WACP Attt 2t P .V R /SQ2Q 1W Q2Q45t56t67t 78t8;t;ttt4JPJJVJS4JRJh4JQJdJOQ[QFUHWtttt tPSPttt t PSVttt ttt PdRWRQQQ$jSjySRRSSSRVSS$$U$NPw{PPtt@t@At ACtBSPsyslinux_memmap_typeWsyslinux_memmap_largestsyslinux_free_memmapsyslinux_dup_memmappsyslinux_add_memmapsyslinux_init_memmapCnextsyslinux_memmap_largestnewlistsyslinux_add_memmapSMT_ENDSMT_RESERVEDSMT_ERRORunsigned charstartSMT_ALLOCshort unsigned intllastbest_sizerangeSMT_UNDEFINEDsyslinux_free_memmapsyslinux_memmap_types/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intSMT_FREESMT_ZEROlong long unsigned intlistsyslinux_dup_memmaplong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)typeshort intsyslinux_init_memmapbestuint32_tsyslinux_memmap_typeaddr_tsyslinux_memmapoldtypesigned charsizelastsyslinux/zonelist.cGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4C H%x+x0x@BP> 0RN b^ (` o~e z    0.%S.p P    2!4V9NSYgnWzonelist.csyslinux_memmap_typesyslinux_memmap_largestsyslinux_free_memmapfreesyslinux_dup_memmapmallocsyslinux_add_memmapsyslinux_init_memmapO   ! & 4 ; B I P W b i p                  % 4 9 C H R ] hlp u                 '+/ 4 > C [ v                *.2 @ p8<hldump_mmap.o/ 1207848668 1026 1026 100664 3692 ` ELF4(VSƉhhh hP PC)PRhCV[ CuX[^% $ > $ > : ; I<  : ; (  : ; : ; I8  I .? : ; ' @ : ; I:Q94intIEfNlp,yn?~#2b ' \(# a)# *#  7'Q &7 +& :o syslinux../include../include/syslinuxdump_mmap.cstdio.hmovebits.hstdint.h&cTypeLengthStart%10s %10s %10s -------------------------------- 0x%08x 0x%08x %10d | LQAA CI E$E(E,A0@.GE(A,H0A4E8A<@. KIttt tt t$t(t,%t0%*t*+t(+3t,34t049t49:t8:Etsyslinux_dump_memmapQnext_IO_filesyslinux/dump_mmap.cSMT_ENDmemmapSMT_RESERVEDSMT_ERRORFILEunsigned charstartSMT_ALLOCshort unsigned intfileSMT_UNDEFINEDsyslinux_memmap_types/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intSMT_FREESMT_ZEROlong long unsigned intlong long intsyslinux_dump_memmapcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)typeshort intuint32_taddr_tsyslinux_memmapsigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4Q 8%+0B->>  8RkN <^2WqTdm D ~+ T  \0.   *    Q"dump_mmap.csyslinux_dump_memmapfprintf 5;   ! & - ; F L S Z a h o z                 # ( 2 | dump_movelist.o/1207848668 1026 1026 100664 3464 ` ELF04(VSƉhhh hP ss3hAV[ uX[^% $ > $ > : ; I<  : ;  : ; I8  : ; I8  I .? : ; ' @ : ; I : ; IIbint E<J,n dst#src#len##  %'I ]&  ml& :s syslinux../include../include/syslinuxdump_movelist.cstdio.hmovebits.hstdint.h&YdNLengthSrcDest%10s %10s %10s -------------------------------- 0x%08x 0x%08x 0x%08x | LIAA CI E$E(E,A0@.GC(C,C0B4E8A<@. KEttt tt t$t(t,%t0%(t(+t(+.t,.0t005t456t86At x R?N X ^2Wq,dm `  ~- p   x 03,.ZZ   0   I(dump_movelist.csyslinux_dump_movelistfprintf 17   ! & - ; F L S Z a h o z          run_default.o/ 1207848668 1026 1026 100664 3112 ` ELF4( f$1ɺ"% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8 .? : ; ' @ 4: ; I .q. intL ^JplewbSA]~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# e*# ebx+# edx,# ecx-# eax.#$ '0#(1  ! E"fO syslinux../includerun_default.ccom32.hstdint.h ?| Ctt'syslinux_run_defaultcom32sys_tsyslinux_run_defaultunsigned charsyslinux/run_default.ciregshort unsigned intreg32_t_unused_esp/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intuint8_tlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tuint32_teflagssigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %T+`, 0`B>  RjN bH(^  op ~+z      0:.CC   8,   .run_default.cireg.1472syslinux_run_default__intcall   ! & - ; B M T _ f q x   ;       \ run_command.o/ 1207848668 1026 1026 100664 4056 ` ELF4( ¡ f$ ff1ɺ"% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I&.: ; ' I : ; I5.: ; ' I .? : ; ' @: ; I1X Y 14: ; I 4: ; I? < 6E7&_int$Lji^}plewbSA~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ 0#(=1 F Ge# H # I=# rJC# HKe# _L[# M# 2,A,7 2  [e,7 E{3e{e  aSEGeS__pd jS__pi!"E|!! (x# 'WNrO syslinux../includerun_command.ccom32.hstdint.h!??BX| ECtEt P R':syslinux_run_commandEcs_sysargscs_cmdlineOFFScs_intcallsyslinux/run_command.ccom32sys_tcs_bounce_size__com32cs_farcallunsigned chariregshort unsigned intreg32_t_unused_esp/home/hpa/syslinux/release/syslinux-3.63/com32/libcs_cfarcallunsigned intlong long unsigned intuint8_tsyslinux_run_commandlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tcs_bouncecommanduint32_teflagssigned charcom32_sys_argsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4E @%|+, 0jB:> PXR$vN b(^  o>~+z  -  0M.** @  G,   E.6=run_command.cireg.1586syslinux_run_command__com32strcpy__intcall %.5?   ! & - ; B M T _ f q x   ;                  - \ cleanup.o/ 1207848668 1026 1026 100664 3144 ` ELF4(f$ f1ɺ"% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8 .? : ; ' @ : ; I4: ; I  0o2 intL"^H"plewbSA[~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# c*# ebx+# edx,# ecx-# eax.#$ +0#(1  ! t  SC"aK syslinux../includecleanup.cstdint.hcom32.h#h|  P)syslinux_final_cleanup com32sys_tsyslinux_final_cleanupunsigned charsyslinux/cleanup.ciregshort unsigned intreg32_t_unused_esp/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intuint8_tlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tflagsuint32_teflagssigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4   %T+`, 0`B!> ( ReN  b`$^  o~-z 0    8 0>".PP   6 ,    ,cleanup.cireg.1472syslinux_final_cleanup__intcall    ! & - ; B M T _ f q x   ;        X localboot.o/ 1207848668 1026 1026 100664 3140 ` ELF4(f$f1ɺ"% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8 .? : ; ' @ : ; I4: ; I   n1intL ^G!plewbSAZ~ ,! gs"S# fs#S# es$S# ds%S# edi'# esi(# ebp)# b*# ebx+# edx,# ecx-# eax.#$ *0#(1 .# t "SB$cM syslinux../includelocalboot.cstdint.hcom32.h%h|  P&syslinux_local_boot com32sys_tsyslinux/localboot.cunsigned charsyslinux_local_bootiregshort unsigned intreg32_t_unused_esp/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intuint8_tlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tflagsuint32_teflagssigned charGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4   %T+`, 0`B!> $ RgN  b`$^   o~*z ,    4 0=.LL   5 ,    +localboot.cireg.1472syslinux_local_boot__intcall    ! & - ; B M T _ f q x   ;        Z runimage.o/ 1207848668 1026 1026 100664 4596 ` ELF 4(UWVS ƉT$L$D$ $ 1Չ,+|$1щf$ff ff-L$ <$=1ɺ" [^_]% $ > $ > : ; I : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I&.: ; ' I : ; I5.: ; ' I .? : ; ' @: ; I: ; I 4: ; I4: ; I4: ; I 4: ; I? < y9 intj!Sbteu%llwbZH~ ,! gs"Z# fs#Z# es$Z# ds%Z# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ 0#(51 F Gl# H # *I=# }JC# @Kl# WL[# M# 4,H,7 2  [l,7 E{,l{l  aSEGeZ__pd %jZ__pid)a'dP'dn(l/(l+ + + ,,p* jONrL syslinux../includerunimage.ccom32.hstdint.h(yh>דs| $AA AAC ttt ttt PV R h$Q$d:S:U,}syslinux_run_kernel_imageipappend_flagscs_sysargscs_cmdlineOFFScs_intcallcom32sys_tcs_bounce_size__com32cs_farcallunsigned chariregshort unsigned intreg32_t_unused_espbbptr/home/hpa/syslinux/release/syslinux-3.63/com32/libcs_cfarcallunsigned intlong long unsigned intuint8_tsyslinux/runimage.clong long inttypecharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)filenameshort intuint16_tcs_bouncesyslinux_run_kernel_imageuint32_tbbcmdlineeflagssigned charbytescmdlinecom32_sys_argsbbfilenameGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 `%+, 0}B}}> ,RvN bp<^  o~v0z    0 .  @@ I ,   08?runimage.cireg.1708syslinux_run_kernel_image__com32memcpy__intcall3MTakv   ! & 4 ; B I T [ f m x   ;                      # . 9 C H S _p Y loadfile.o/ 1207848668 1026 1026 100664 4352 ` ELF 4(HfUWVS$ՉjPxnFubT$uND$\$?ljEt.T$;D$u)11p[^_]% $ > : ; I$ > <  : ;  : ; I8 .: ; ' I : ; I  I .: ; ' I@ : ; I : ; I&I.? : ; ' I  .? : ; ' I@: ; I4: ; I4: ; I 4: ; I : ; 1X Y 1Uq 7int.P B+3IN ><,,A-#!.#5%> __f$ E \:>t __f956 5> __m55 ;%^O, __pN __sN, __nN, __fNLh>"5 ptrL lenRfd>std)  f!?c",hBU@@[f8sh]R  , ../includesyslinux../include/bitsize../include/sysstdio.hloadfile.cstddef.hstat.htypes.h;axYxgJhiv|  4AA AAC8F (R~N b8\^   o{~z  .  0Nd.@ p @    "'-4;loadfile.cfclosecloseloadfileopenfstatmalloc_freadfree(3Nb   ! & - 8 F Q W ^ e l s z           F               #,0 ( ,load_linux.o/ 1207848668 1026 1026 100664 10276 ` ELF4(UWVSʼn։L$ $DŽ$DŽ$DŽ$1$эyD$$<f$"U$&HdrStfDŽ$*Ƅ$5f$uƄ$f$*w DŽ$P7$t$H;$Pv$P@$f$*w DŽ$\_$\9v$Df$*fv$5D$)\$d$$x $5D$D$ |$ t fw fvcƅ0f$*vD$f-f$f$*vD$D$(fE ?D$fE"Df$$$$t, $ٍ$j$ WT$ $ L$$jT$ $ L$$)T$$jj T$T$$S$$@ L=VT$$$ jT$$$|$ D$ x1G T! _u$1*:Hu"B%)9r )΁RBu΅ $jVD$ Xo,>Szt؋R J!Ń{t K$W C9v# )Ǎ$j[{u$` 1D$f$jf$hf$ff$df$` f$D$f$| $$Sb$x )D$)p8)D$D$gD$)\$d$$x 븋$$$Ĝ[^_]% : ; I$ > $ >  : ;  : ; I8  : ; I8  I &  : ; : ; I I !I/   : ; (  : ; !I/.: ; ' I : ; I4: ; I4: ; I.? : ; ' I@: ; I: ; I 4: ; I 4: ; I4: ; I  : ;1X Y1 !41"41#4: ;I$4: ;I%4: ;I& '1X Y( U)&IviR 0=int?^Wp0-).#t.#len/%#0%# 1#2%#  lw w b2 +e += BS +5Sw dst\#src\#len\#t# g~`+?  '(\#M)#t* # 0,es-e#.e#ds/e#ss0e#fs1e#gs2e# eax4B# ecx5B#edx6B#ebx7B#esp8B#ebp9B# esi:B#$edi;B#(ip=e#,cs>e#.g<3k4#5e# 6e#"y7#$8S#9e#R:w#;e#e#m?e# @w#0Ae#Bw#Ce#De#OES#CFS#Ge#Hw#.Iw#pJw#Kw#Le#fMe#JNw#MOw#Pw#QS#kR#Sw# S + S+ 'S +Y0`\_ipaZb\,t7'p:qr}s\ipuv\lenv\padv\ ~7vZ_%'q<M8erwhdr zY%^%\:{\i]\%%y&'h: d `LD='Iw8 Iw!CE"M m#\$ml %D &%$\'Ym3uj(!"!! )\U syslinux../include/syslinux../include../include/bitsizeload_linux.cmovebits.hstdint.hlinux.hstddef.hbootrm.hcom32.h>ɟvb <"#1uuvg X,&(*#~"=/gh~Ȓ@/1guo#// yf򻻼| vAA AAF8RG.HKAUKHSKUHKIVKESKBUIJtKJRNJpOHk.ttt t t BtBTtTctcntnotottttttttttt t t*t*,t,AtAtttt%t%/t/AtAOtOYtYtttvt@P@UfuUeRezVVV V#sV>Q>vzZZ S vd[Wm~W#W?tWzVmVV V#VDsVz#zDvzz#zDvz]QmzQDPQ SaPpsSmtSPS#<PPz#z+vz[WWfiWm~WDtWVRUDDVDsURDPRtSDrS~WDtW$P7:P&syslinux_boot_linuxvVm,>SMT_RESERVEDheaderrelocatable_kernelfraglistversionvideo_modeloadflagstypesize_twhdrprot_mode_sizejumpmemlimitprot_mode_basecmdline_offsetnext_addrvid_modeuint8_tsyslinux_memmap_typesaddr_tuint32_tkernel_versionshort intbailcode32_start_unused_csreal_mode_sizecmdline_sizemap_initramfsmmaplong long intinitrd_addr_maxirf_sizepad1pad2ramdisk_sizeaddrbootsect_kludgeinitramfssyslinux_movelistheap_end_ptrdata_lenroot_flagsunsigned charbest_addrsetup_move_sizesyslinux_rm_regssigned charlong long unsigned intSMT_ALLOCreg32_tunsigned intcmd_line_ptruint16_tSMT_FREEsyslinux/load_linux.cstartshort unsigned intamapcharrealmode_swtchSMT_END/home/hpa/syslinux/release/syslinux-3.63/com32/libdatastart_sysram_sizesyslinux_memmapkernel_bufkernel_alignmentinitramfs_sizeSMT_ZEROboot_flagsyssizesizekernel_sizeboot_sector_1boot_sector_2setup_sectsalignold_cmd_line_magicreal_mode_baseSMT_ERRORadj_startGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)SMT_UNDEFINEDcmdline_max_lenold_cmd_line_offsetprevramdisk_imagecmdlinealign_masktype_of_loaderroot_devlinux_headernextregssyslinux_boot_linuxGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack4v #%+0B> #hRYN 'b^ ' o;~*z ( !  (A 0a.!!  D"   v")=Qe{load_linux.csyslinux_boot_linuxmemcpysyslinux_memory_mapsyslinux_dup_memmapsyslinux_add_memmapsyslinux_add_movelistsyslinux_shuffle_boot_rmsyslinux_free_movelistsyslinux_free_memmapf\}:(RLXd   ! & 1 ? F M T _ f q x        , C T ] l              + @   ( 6 D R a p            $ 3 B Q ` o ~        , 9 N ^ k v             ' 1 6 S ^ h m w |               %)2 >BG R a f vz     initramfs.o/ 1207848668 1026 1026 100664 3612 ` ELF4(UWVS Ɖ׉͋\$$|$ t?t?Cu8w0…t D$ BzjZ rP1 [^_]f t@ % : ; I$ > $ >  : ;  : ; I8  : ; I8  I & .? : ; ' I@ : ; I : ; I 4: ; I.? : ; ' I@4: ; ImZo 0int .A-+.#.#len/%# 0%# 1#2%#h H 37f 1P 1n 2% len2% 2% in4K&hir' i syslinux../include/syslinux../include/bitsizeinitramfs.clinux.hstddef.h2x1Mu==>=K=h=Z?MZ| $fAA AAC hCttt ttft PcVRdWdfRQeUefQbSbfhktktP8qinitramfs_add_dataHinitramfs_initsize_tnextaligndata_lendataunsigned charshort unsigned intinitramfsinitramfs_initsyslinux/initramfs.c/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intiheadlong long intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intinitramfs_add_datasigned charprevGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %+0Bq> 0R N bP^  o~<z  N  0n0., 0 \ =    f 'h6initramfs.cinitramfs_add_datamallocinitramfs_initcalloc1v   ! & 1 ? F M T [ b m u             / 9 J UY] k v@D/40 1207848668 1026 1026 100664 7660 ` ELF84(UWVS Ɖ׉D$9tz/t)rD$B/…u;\$|$s9to}/ti)BPjCPjjjjjjjjjhARht$@|$Dǃ@ى߹)كA1|$/ŅwD$ [^_]ÍvUWVSD$T$L$D$0fD$1эi|$u111ҋD$Er4Å|$u‹D$<BQjEPt$Ht$Hjjt$PjjjjD$>PRhWǃ@T$)A|$41RRjVڋD$(t [^_]f jjjj1ɺ;ÐUWVS ƉՉϋ\$ T$$L$(D$,fuf jjSPuD$$\$ [^_] [^_]% : ; I$ > $ >  : ;  : ; I8  : ; I8  I & .: ; ' I@ : ; I 4: ; I 4: ; I 4: ; I&I .? : ; ' I@: ; I 4: ; I4: ; I: ; I${+A 0int&\3mlt0-.#.#len/%#0%#  1#*2%#  @% S>% f>C ?%l pA bpB! lenC7K D%hpadE7>>bvk7^ g Sg h7 ia8leni% jsX $jsl%m7padn7fo bpo7+ 7{ & Z *%len% S 7/ sZ :s syslinux../include/bitsize../include/syslinux../includeinitramfs_file.cstddef.hlinux.hstdint.h?Ȧ7sKA0vX 蒑A>==tX!sY 070701%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08xTRAILER!!!| `AA AAC j$B(D,B0B4B8BBRBRPRTUTTPXUPPURPTdTWWTSttt ttut0uwt4w{t8{t<tttttttttttttt0t4t8t<tt0Ph R "d"&R&d Q `^  "R1:R:AVZcRRPTVWfWWtttttt tPttt tt@t @Bt$BCt(CDt,DNt0N{t 1P1iVipPpxV)R)kUkpRpzU-Q-jWjpQpyW77hShppwSw{77KRK{77KQK{7 7;P;{ S(initramfs_mknodbinitramfs_add_trailerinitramfs_add_file{size_taligndatanameleninitramfsminordata_lenunsigned char/home/hpa/syslinux/release/syslinux-3.63/com32/libshort unsigned intinitramfs_add_filemajorinitramfs_add_trailersyslinux/initramfs_file.cnext_inounsigned intbuflenlong long unsigned intiheadmodelong long intdo_mkdircharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)filenameshort intbufferuint16_tinitramfs_mknoduint32_tbytessigned charnextprevinitramfs_mkdirsGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4{ D%+0$B(> RN ^2Fq(Tm @ ~| W X  0x4.bb  #  ,3;B RYlqginitramfs_file.cinitramfs_mkdirsnext_inostrchrsprintfmemcpyinitramfs_mknodmallocinitramfs_add_datafreeinitramfs_add_trailerinitramfs_add_file8dl=hp Gl !&1?FMT[bmt  ! &0 5? L Z i n        * /EO ] hsw{          # |   /58 1207848668 1026 1026 100664 3456 ` ELF 4(VSƉЉˍL$ T$tL$ T$t$$t$$SQ[^% : ; I$ > $ >  : ;  : ; I8  : ; I8  I & .? : ; ' I@ : ; I : ; I 4: ; I 4: ; I &I uCO 0intP0AmG0-\.#.#len/%# 0%# <1#32%#s d'7C %t &%d :&d &7 &a <(vplen)%ljo syslinux../include/syslinux../include/bitsize../includeinitramfs_loadfile.clinux.hstddef.hstdint.h&[| ,CAA C h$D(A,A0B.H ttt -t -1t$12t(23t,3=t0=Ct P BVRPQAS&yinitramfs_load_fileCsize_tnextaligninitramfs_load_filesrc_filenamedata_lendataunsigned charsyslinux/initramfs_loadfile.cshort unsigned intinitramfs/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intiheadmodelong long intdo_mkdircharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intdst_filenameuint32_tsigned charprevGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4C %x+x0xBMy> 0 RN P bpD^ X  o~*z h    p 0a-.[[   F   C*3initramfs_loadfile.cinitramfs_load_fileloadfileinitramfs_add_file6   ! & 1 ? F M T [ b m x             ' , : H p /80 1207848668 1026 1026 100664 3232 ` ELFh4(SÉЍL$T$tL$PPT$jQ[% : ; I$ > $ >  : ;  : ; I8  : ; I8  I & .? : ; ' I@ : ; I 4: ; I 4: ; I &I ?: h 0int* =K^-6.#.#len/%#)0%# 81#/2%#h .'7: &h &. 8(@t len)%p49q syslinux../include/syslinux../include/bitsizeinitramfs_archive.clinux.hstddef.h&[g| (:AC _$A(F,A0B.H tt#t #$t$$*t(*+t,+5t05:t P9SRP)Cinitramfs_load_archive:size_tnextsyslinux/initramfs_archive.caligndata_lendataunsigned charshort unsigned intinitramfs/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intiheadlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)filenameshort intinitramfs_load_archivesigned charprevGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4: h %p+p0pB6C> x RyN p b@^ x  oH~-z    09;t.   H   :,5initramfs_archive.cinitramfs_load_archiveloadfileinitramfs_add_data.   ! & 1 ? F M T [ b m u            : ~/101 1207848668 1026 1026 100664 4920 ` ELF 4(UWVSLD$ՉL$ D$ D$ 1҉ljfD$D fD$8qfT$$ڃfT$(s fD$fCfC fCfCfCL$ ʸ"D$Hu8fft.CDžtK}CT$1L[^_]% : ; I$ > $ >  : ;  : ; II!I/  : ; : ; I8 : ; I8  : ;  I' I&I ' I&.: ; ' I : ; I5.: ; ' I .? : ; ' I@: ; I: ; I4: ; I 4: ; I4: ; I4: ; I4: ; I? < O  0intC5%^p0lwwbeS ,! gs"e# fs#e# es$e# ds%e# edi'# esi(# ebp)# *# ebx+# edx,# ecx-# eax.#$ p0#(41 wF eGw# H# IH# JN# Kw# Lf# OM# 7S7B =  !fw7B P7ww  l0e < [=e# seg>e#? ! D -E# Fe# wJe# K# Le# MISEGee__pdI OTr`je__piI,7+7Qbuf+qlen+-@gci./N/N N % !N syslinux../include../include/bitsize../include/syslinuxpxe_get_cached.ccom32.hstdint.hstddef.hpxe.h+iYuu>YwZM==| $AA AAC`ttt tttP'R'U%Q%SRV&rpxe_get_cached_infosegoff16_tsize_t_unused_esplong long unsigned intlong long intsigned charGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)com32_sys_argsPacketTypecs_cmdlineuint16_tnbuf__com32cs_bounceunsigned intcs_bounce_sizecs_farcallt_PXENV_GET_CACHED_INFOlevelshort unsigned intreg32_t/home/hpa/syslinux/release/syslinux-3.63/com32/libcs_cfarcalloffsOFFScs_sysargseflagsBufferSizebbufpxe_get_cached_infosyslinux/pxe_get_cached.cunsigned charshort intuint32_ts_PXENV_GET_CACHED_INFOBufferLimitregscharBuffercs_intcallpxenv_status_tuint8_tStatuscom32sys_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4  % + 0 B> @RN bp<^  o~*z    (0? .8 8 @ F   &.8?pxe_get_cached.cpxe_get_cached_info__com32__intcallmallocmemcpy   ! & 1 ? F M T _ f q x    F                     " Z x            adv.o/ 1207848668 1026 1026 100664 3692 ` ELFH4( f$ʸ"У % : ; I$ > $ >  : ;  : ; II!I/  : ; : ; I8 : ; I8  .: ; ' I : ; I.? : ; ' @4: ; I 4: ; I?  "ET 0intZ#^-p-60lwwbeS@ ,! gs"e# fs#e# es$e# ds%e# edi'# esi(# ebp)# H*# ebx+# edx,# ecx-# eax.#$ S0#(1  f}|e|e*Ereg+&?'%f syslinux../include../include/bitsizeadv.ccom32.hstdint.hstddef.h)?u| ECtEtT&__syslinux_get_adv__syslinux_adv_ptr__syslinux_adv_sizeEsize_tcom32sys_t__seg__offsunsigned charshort unsigned intreg32_t_unused_esp/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned int__syslinux_adv_ptrlong long unsigned intuint8_tsyslinux/adv.c__syslinux_get_advlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intuint16_tuint32_t__syslinux_adv_sizeeflagssigned charMK_PTRGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.ctors.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4E @%|+, 0Bl&>  RN 4b^ < m(i D zD dX T  \0mI.ww0 P  T,  E#-@adv.creg.1473__syslinux_get_adv__intcall__syslinux_adv_ptr__syslinux_adv_size  *18= !&1?FMT_fqxF !s advwrite.o/ 1207848668 1026 1026 100664 3300 ` ELF4( f$ʸ"(؃ % : ; I$ > $ >  : ;  : ; II!I/  : ; : ; I8 : ; I8  .? : ; ' I@4: ; I 4: ; I? < +G 0zint?^p 0lwwbezS3 ,! gs"e# fs#e# es$e# ds%e# edi'# esi(# ebp)# ;*# ebx+# edx,# ecx-# eax.#$ 80#(1  '7+reg(K'$(% syslinux../include../include/syslinux../include/bitsizeadvwrite.ccom32.hstdint.hadv.hstddef.h&?| +Ct+t%syslinux_adv_write+size_tcom32sys_tunsigned charshort unsigned intreg32_t_unused_esp/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intuint8_tlong long intsyslinux/advwrite.ccharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)syslinux_adv_writeshort intuint16_tuint32_t__syslinux_adv_sizeeflagssigned char__syslinux_adv_ptrGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4+ %`+`, 0`B.> R&N b(^  o ~)z  =  0]^.H  h 2 ,   +(advwrite.creg.1471syslinux_adv_write__intcall    ! & 1 ? F M T _ f q x    F         getadv.o/ 1207848668 1026 1026 100664 3524 ` ELFX4(UWVSljՋ02Jt)ɍX9r9uM ʉ)ȃw1[^_]% : ; I$ > $ > .: ; ' I  .? : ; ' I@: ; I : ; I 4: ; I 4: ; I 4: ; I 1X Y   I&&I4: ; I? < XQ]o 0int4^J7!+0%)()Qtag'7D 2'0b p)6 *% len*% -E X0S 1%/%<S@' (%{ syslinux../include/syslinux../include/bitsize../includegetadv.cadv.hstddef.hstdint.h'ks=?c=AzJ <=M/oJt|  QAA AAttt tQtPOWRPU.R.ARLQRPS'=S?LPNVQ$QQ"\syslinux_getadvQsize_tplenleftsyslinux_getadvsyslinux_adv_ptrsizeshort unsigned intunsigned charptagsyslinux/getadv.c/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intuint8_tlong long intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)syslinux_adv_sizeshort int__syslinux_adv_sizesigned char__syslinux_adv_ptrGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4Q T %+0Bw\> d 0RN b8^  o~&z    0Sc.   A    Q-getadv.csyslinux_getadv__syslinux_adv_ptr__syslinux_adv_size    ! & 1 ? F M T _ f m t              # B O setadv.o/ 1207848668 1026 1026 100664 4080 ` ELF4(UWVSE։MH=v vE)č|$}M7 Ct4P;Eu;Us!M)э ;Uw )UӃ}wÅt0F9EsECUE)E1ߋM U1e[^_% : ; I$ > $ > .: ; ' I  .? : ; ' I@: ; I : ; I 4: ; I 4: ; I 1X Y  I&4: ; I? < m=z 0intF!^gT0%'+< 07tag/7, O/%K 8/< p1C ?1C 2% s?G> m uCS D%pBSR'+(%!7 syslinux../include/syslinux../include/bitsize../includesetadv.cadv.hstddef.hstdint.herrno.h/w !?/>Hk\[=k.fKYM| AB FttuPupR?V?_R_VVRQul-?SkSdiPR-?udGud-?QmrPrQPPQQQ-?RmRRRR"qsyslinux_setadvsize_tplensyslinux_setadvlefterrnosyslinux_adv_ptrdatasyslinux/setadv.csizeshort unsigned intunsigned charptag/home/hpa/syslinux/release/syslinux-3.63/com32/libunsigned intlong long unsigned intuint8_tlong long intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)syslinux_adv_sizeshort int__syslinux_adv_sizeadvtmpsigned char__syslinux_adv_ptrGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 P%<+<0<Bq> hXRN bT4^  o~7&z  ]  0}e.p P  V     4GNsetadv.csyslinux_setadverrno__syslinux_adv_size__syslinux_adv_ptrmemcpymemmove/@[e   ! & 1 ? F M T _ f m t                ' , 6 J W d syslinux-legacy-3.63+dfsg/com32/lib/sprintf.c0000664000175000017500000000036310777447272017537 0ustar evanevan/* * sprintf.c */ #include #include int sprintf(char *buffer, const char *format, ...) { va_list ap; int rv; va_start(ap, format); rv = vsnprintf(buffer, ~(size_t)0, format, ap); va_end(ap); return rv; } syslinux-legacy-3.63+dfsg/com32/lib/fprintf.c0000664000175000017500000000037410777447272017524 0ustar evanevan/* * fprintf.c */ #include #include #define BUFFER_SIZE 16384 int fprintf(FILE *file, const char *format, ...) { va_list ap; int rv; va_start(ap, format); rv = vfprintf(file, format, ap); va_end(ap); return rv; } syslinux-legacy-3.63+dfsg/com32/lib/memccpy.c0000664000175000017500000000050710777447272017507 0ustar evanevan/* * memccpy.c * * memccpy() */ #include #include void *memccpy(void *dst, const void *src, int c, size_t n) { char *q = dst; const char *p = src; char ch; while ( n-- ) { *q++ = ch = *p++; if ( ch == (char)c ) return q; } return NULL; /* No instance of "c" found */ } syslinux-legacy-3.63+dfsg/com32/lib/qsort.c0000664000175000017500000000141010777447272017214 0ustar evanevan/* * qsort.c * * This is actually combsort. It's an O(n log n) algorithm with * simplicity/small code size being its main virtue. */ #include #include static inline size_t newgap(size_t gap) { gap = (gap*10)/13; if ( gap == 9 || gap == 10 ) gap = 11; if ( gap < 1 ) gap = 1; return gap; } void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { size_t gap = nmemb; size_t i, j; char *p1, *p2; int swapped; do { gap = newgap(gap); swapped = 0; for ( i = 0, p1 = base ; i < nmemb-gap ; i++, p1 += size ) { j = i+gap; if ( compar(p1, p2 = (char *)base+j*size) > 0 ) { memswap(p1, p2, size); swapped = 1; } } } while ( gap > 1 || swapped ); } syslinux-legacy-3.63+dfsg/com32/lib/sys/0000775000175000017500000000000010777447344016522 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/lib/sys/isatty.c0000664000175000017500000000332610777447272020207 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * isatty.c * * Return if this is a tty or not */ #include #include #include #include #include #include #include "file.h" int isatty(int fd) { struct file_info *fp = &__file_info[fd]; if ( fd >= NFILES || !fp->iop ) { errno = EBADF; return -1; } /* __DEV_TTY == 1 */ return (fp->iop->flags & __DEV_TTY); } syslinux-legacy-3.63+dfsg/com32/lib/sys/times.c0000664000175000017500000000310410777447272020005 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * sys/times.c * * Returns something like a clock. */ #include #include #include clock_t times(struct tms *buf) { (void)buf; /* Ignored */ /* Should we get this via INT 1Ah? */ return *(uint16_t *)0x46c; } syslinux-legacy-3.63+dfsg/com32/lib/sys/farcall.c0000664000175000017500000000027110777447272020272 0ustar evanevan/* * farcall.c */ #include void __farcall(uint16_t cs, uint16_t ip, const com32sys_t *ireg, com32sys_t *oreg) { __com32.cs_farcall((cs << 16)+ip, ireg, oreg); } syslinux-legacy-3.63+dfsg/com32/lib/sys/ansi.h0000664000175000017500000000234710777447272017633 0ustar evanevan/* * ansi.h */ #ifndef COM32_LIB_SYS_ANSI_H #define COM32_LIB_SYS_ANSI_H #include #define ANSI_MAX_PARMS 16 enum ansi_state { st_init, st_esc, st_csi, st_tbl, st_tblc, }; struct curxy { uint8_t x, y; } __attribute__((packed)); struct term_state { struct curxy xy; int cindex; /* SOH color index */ int vtgraphics; /* VT graphics on/off */ int intensity; int underline; int blink; int reverse; int fg; int bg; int autocr; struct curxy saved_xy; int cursor; enum ansi_state state; int pvt; /* Private code? */ int nparms; /* Number of parameters seen */ int parms[ANSI_MAX_PARMS]; }; struct ansi_ops { void (*erase)(const struct term_state *st, int x0, int y0, int x1, int y1); void (*write_char)(int x, int y, uint8_t ch, const struct term_state *st); void (*showcursor)(const struct term_state *st); void (*scroll_up)(const struct term_state *st); void (*set_cursor)(int x, int y, int visible); }; struct term_info { int rows, cols; /* Screen size */ int disabled; struct term_state *ts; const struct ansi_ops *op; }; void __ansi_init(const struct term_info *ti); void __ansi_putchar(const struct term_info *ti, uint8_t ch); #endif /* COM32_LIB_SYS_ANSI_H */ syslinux-legacy-3.63+dfsg/com32/lib/sys/exit.S0000664000175000017500000000105310777447272017616 0ustar evanevan# # Implementation of _exit() for com32 based on c32entry.S # .text .globl _exit .type _exit, @function _exit: #ifdef REGPARM pushl %eax #endif # Run any destructors movl $__dtors_start, %esi 2: cmpl $__dtors_end, %esi jae 1f call *(%esi) addl $4,%esi jmp 2b 1: #ifdef REGPARM popl %eax #else movl 4(%esp),%eax # Exit code in %eax = return value #endif movl (__entry_esp),%esp # Return stack pointer to entry value ret # Return to termination address .size _exit, .-_exit .data __exit_handler: .globl __exit_handler .long _exit syslinux-legacy-3.63+dfsg/com32/lib/sys/write.c0000664000175000017500000000330410777447272020020 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * write.c * * Write to a file descriptor */ #include #include #include #include #include #include "file.h" ssize_t write(int fd, void *buf, size_t count) { struct file_info *fp = &__file_info[fd]; if ( fd >= NFILES || !fp->oop ) { errno = EBADF; return -1; } return fp->oop->write(fp, buf, count); } syslinux-legacy-3.63+dfsg/com32/lib/sys/null_write.c0000664000175000017500000000346710777447272021064 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * null_write.c * * Null writing device */ #include #include #include #include #include "file.h" static ssize_t __null_write(struct file_info *fp, const void *buf, size_t count) { (void)fp; (void)buf; (void)count; return count; } const struct output_dev dev_null_w = { .dev_magic = __DEV_MAGIC, .flags = __DEV_OUTPUT | __DEV_NULL, .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, .write = __null_write, .close = NULL, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/x86_init_fpu.c0000664000175000017500000000207410777447272021213 0ustar evanevan/* * x86_has_fpu.c * * Test for an x86 FPU, and do any necessary setup. */ #include #include static inline uint64_t get_cr0(void) { uint32_t v; asm("movl %%cr0,%0" : "=r" (v)); return v; } static inline void set_cr0(uint32_t v) { asm volatile("movl %0,%%cr0" : : "r" (v)); } #define CR0_PE 0x00000001 #define CR0_MP 0x00000002 #define CR0_EM 0x00000004 #define CR0_TS 0x00000008 #define CR0_ET 0x00000010 #define CR0_NE 0x00000020 #define CR0_WP 0x00010000 #define CR0_AM 0x00040000 #define CR0_NW 0x20000000 #define CR0_CD 0x40000000 #define CR0_PG 0x80000000 int x86_init_fpu(void) { uint32_t cr0; uint16_t fsw = 0xffff; uint16_t fcw = 0xffff; cr0 = get_cr0(); cr0 &= ~(CR0_EM|CR0_TS); cr0 |= CR0_MP; set_cr0(cr0); asm volatile("fninit"); asm volatile("fnstsw %0" : "+m" (fsw)); if (fsw != 0) return -1; asm volatile("fnstcw %0" : "+m" (fcw)); if ((fcw & 0x103f) != 0x3f) return -1; /* Techically, this could be a 386 with a 287. We could add a check for that here... */ return 0; } syslinux-legacy-3.63+dfsg/com32/lib/sys/serial_write.c0000664000175000017500000000425410777447272021364 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * serial_write.c * * Raw writing to the serial port; no \n -> \r\n translation */ #include #include #include #include #include #include "file.h" ssize_t __serial_write(struct file_info *fp, const void *buf, size_t count) { com32sys_t ireg; const char *bufp = buf; size_t n = 0; (void)fp; if (!syslinux_serial_console_info()->iobase) return count; /* Nothing to do */ memset(&ireg, 0, sizeof ireg); ireg.eax.b[1] = 0x04; while ( count-- ) { ireg.edx.b[0] = *bufp++; __intcall(0x21, &ireg, NULL); n++; } return n; } const struct output_dev dev_serial_w = { .dev_magic = __DEV_MAGIC, .flags = __DEV_TTY | __DEV_OUTPUT, .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, .write = __serial_write, .close = NULL, .open = NULL, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/rawcon_read.c0000664000175000017500000000447010777447272021157 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * rawcon_read.c * * Character-oriented reading from the console without echo; * this is a NONBLOCKING device. */ #include #include #include #include #include #include "file.h" /* Global, since it's used by stdcon_read */ ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count) { com32sys_t ireg, oreg; char *bufp = buf; size_t n = 0; clock_t start; (void)fp; memset(&ireg, 0, sizeof ireg); start = times(NULL); while ( n < count ) { /* Poll */ ireg.eax.b[1] = 0x0B; __intcall(0x21, &ireg, &oreg); if ( !oreg.eax.b[0] ) break; /* We have data, go get it */ ireg.eax.b[1] = 0x08; __intcall(0x21, &ireg, &oreg); *bufp++ = oreg.eax.b[0]; n++; } return n; } const struct input_dev dev_rawcon_r = { .dev_magic = __DEV_MAGIC, .flags = __DEV_TTY | __DEV_INPUT, .fileflags = O_RDONLY, .read = __rawcon_read, .close = NULL, .open = NULL, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/null_read.c0000664000175000017500000000341110777447272020632 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * null_read.c * * Reading null device */ #include #include #include #include #include "file.h" static ssize_t __null_read(struct file_info *fp, void *buf, size_t count) { (void)fp; (void)buf; (void)count; return 0; } const struct input_dev dev_null_r = { .dev_magic = __DEV_MAGIC, .flags = __DEV_INPUT | __DEV_NULL, .fileflags = O_RDONLY, .read = __null_read, .close = NULL, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/fstat.c0000664000175000017500000000342110777447272020007 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2005-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * fstat.c * * Very trivial fstat emulation */ #include #include #include "file.h" int fstat(int fd, struct stat *buf) { struct file_info *fp = &__file_info[fd]; if ( fd >= NFILES || !fp->iop ) { errno = EBADF; return -1; } if ( fp->iop->flags & __DEV_FILE ) { buf->st_mode = S_IFREG | 0444; buf->st_size = fp->i.length; } else { buf->st_mode = S_IFCHR | 0666; buf->st_size = 0; } return 0; } syslinux-legacy-3.63+dfsg/com32/lib/sys/ansiserial_write.c0000664000175000017500000000425510777447272022240 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * ansiserial_write.c * * Write to both to the ANSI console and the serial port */ #include #include #include #include #include "file.h" extern int __ansicon_open(struct file_info *); extern int __ansicon_close(struct file_info *); extern ssize_t __ansicon_write(struct file_info *, const void *, size_t); extern ssize_t __xserial_write(struct file_info *, const void *, size_t); static ssize_t __ansiserial_write(struct file_info *fp, const void *buf, size_t count) { __ansicon_write(fp, buf, count); return __xserial_write(fp, buf, count); } const struct output_dev dev_ansiserial_w = { .dev_magic = __DEV_MAGIC, .flags = __DEV_TTY | __DEV_OUTPUT, .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, .write = __ansiserial_write, .close = __ansicon_close, .open = __ansicon_open, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/stdcon_read.c0000664000175000017500000000437610777447272021165 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * stdcon_read.c * * Line-oriented reading from the standard console */ #include #include #include #include #include "file.h" extern ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count); static ssize_t __stdcon_read(struct file_info *fp, void *buf, size_t count) { char *bufp = buf; size_t n = 0; char ch; (void)fp; while ( n < count ) { if ( fp->i.nbytes ) { ch = *bufp++ = *fp->i.datap++; fp->i.nbytes--; n++; if ( ch == '\n' ) return n; } else { fp->i.nbytes = __line_input(fp, fp->i.buf, MAXBLOCK, __rawcon_read); fp->i.datap = fp->i.buf; if ( fp->i.nbytes == 0 ) return n; } } return n; } const struct input_dev dev_stdcon_r = { .dev_magic = __DEV_MAGIC, .flags = __DEV_TTY | __DEV_INPUT, .fileflags = O_RDONLY, .read = __stdcon_read, .close = NULL, .open = NULL, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/fileclose.c0000664000175000017500000000331110777447272020631 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * fileclose.c * * Close an ordinary file */ #include #include #include #include "file.h" int __file_close(struct file_info *fp) { com32sys_t regs; if ( fp->i.filedes ) { memset(®s, 0, sizeof regs); regs.eax.w[0] = 0x0008; /* Close file */ regs.esi.w[0] = fp->i.filedes; __com32.cs_intcall(0x22, ®s, NULL); } return 0; } syslinux-legacy-3.63+dfsg/com32/lib/sys/fileread.c0000664000175000017500000000502210777447272020440 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * read.c * * Reading from a file */ #include #include #include #include #include "file.h" ssize_t __file_read(struct file_info *fp, void *buf, size_t count) { com32sys_t ireg, oreg; char *bufp = buf; size_t n = 0; size_t ncopy; memset(&ireg, 0, sizeof ireg); ireg.eax.w[0] = 0x0007; /* Read file */ ireg.ebx.w[0] = OFFS(__com32.cs_bounce); ireg.es = SEG(__com32.cs_bounce); while ( count ) { if ( fp->i.nbytes == 0 ) { if ( fp->i.offset >= fp->i.length || !fp->i.filedes ) return n; /* As good as it gets... */ ireg.esi.w[0] = fp->i.filedes; ireg.ecx.w[0] = MAXBLOCK >> fp->i.blocklg2; __intcall(0x22, &ireg, &oreg); if ( oreg.eflags.l & EFLAGS_CF ) { errno = EIO; return -1; } fp->i.filedes = oreg.esi.w[0]; fp->i.nbytes = min(fp->i.length-fp->i.offset, (unsigned)MAXBLOCK); fp->i.datap = fp->i.buf; memcpy(fp->i.buf, __com32.cs_bounce, fp->i.nbytes); } ncopy = min(count, fp->i.nbytes); memcpy(bufp, fp->i.datap, ncopy); n += ncopy; bufp += ncopy; count -= ncopy; fp->i.datap += ncopy; fp->i.offset += ncopy; fp->i.nbytes -= ncopy; } return n; } syslinux-legacy-3.63+dfsg/com32/lib/sys/argv.c0000664000175000017500000000535510777447272017635 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * argv.c * * Parse a single C string into argc and argv (argc is return value.) * memptr points to available memory. */ #include #include #include #define ALIGN_UP(p,t) ((t *)(((uintptr_t)(p) + (sizeof(t)-1)) & ~(sizeof(t)-1))) extern char _end[]; /* Symbol created by linker */ void *__mem_end = &_end; /* Global variable for use by malloc() */ int __parse_argv(char ***argv, const char *str) { char argv0[] = ""; char *mem = __mem_end; const char *p = str; char *q = mem; char *r; char **arg; int wasspace = 1; int argc = 1; /* First copy the string, turning whitespace runs into nulls */ for ( p = str ; ; p++ ) { if ( *p <= ' ' ) { if ( !wasspace ) { wasspace = 1; *q++ = '\0'; } } else { if ( wasspace ) { argc++; wasspace = 0; } *q++ = *p; } /* This test is AFTER we have processed the null byte; we treat it as a whitespace character so it terminates the last argument */ if ( ! *p ) break; } /* Now create argv */ arg = ALIGN_UP(q,char *); *argv = arg; *arg++ = argv0; /* argv[0] */ q--; /* Point q to final null */ if ( mem < q ) *arg++ = mem; /* argv[1] */ for ( r = mem ; r < q ; r++ ) { if ( *r == '\0' ) { *arg++ = r+1; } } *arg++ = NULL; /* Null pointer at the end */ __mem_end = arg; /* End of memory we used */ return argc; } syslinux-legacy-3.63+dfsg/com32/lib/sys/xserial_write.c0000664000175000017500000000551510777447272021555 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * xserial_write.c * * Raw writing to the serial port; no \n -> \r\n translation, but * convert \1# sequences. */ #include #include #include #include #include #include #include "file.h" static void emit(char ch) { static com32sys_t ireg; /* Zeroed with the BSS */ ireg.eax.b[1] = 0x04; ireg.edx.b[0] = ch; __intcall(0x21, &ireg, NULL); } ssize_t __xserial_write(struct file_info *fp, const void *buf, size_t count) { const char *bufp = buf; size_t n = 0; static enum { st_init, st_tbl, st_tblc } state = st_init; static int ndigits; static int ncolor = 0; int num; const char *p; (void)fp; if (!syslinux_serial_console_info()->iobase) return count; /* Nothing to do */ while ( count-- ) { unsigned char ch = *bufp++; switch (state) { case st_init: if (ch >= 1 && ch <= 5) { state = st_tbl; ndigits = ch; } else { emit(ch); } break; case st_tbl: if (ch == '#') { state = st_tblc; ncolor = 0; } else { state = st_init; } break; case st_tblc: num = ch-'0'; if (num < 10) { ncolor = (ncolor*10)+num; if (--ndigits == 0) { if (ncolor < console_color_table_size) { emit('\033'); emit('['); emit('0'); emit(';'); for (p = console_color_table[ncolor].ansi; *p; p++) emit(*p); emit('m'); } state = st_init; } } else { state = st_init; } break; } n++; } return n; } syslinux-legacy-3.63+dfsg/com32/lib/sys/ansi.c0000664000175000017500000002121010777447272017614 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * ansi.c * * ANSI character code engine */ #include #include #include "ansi.h" static const struct term_state default_state = { .xy = { 0, 0 }, .cindex = 0, /* First color table entry */ .vtgraphics = 0, .intensity = 1, .underline = 0, .blink = 0, .reverse = 0, .fg = 7, .bg = 0, .autocr = 0, .saved_xy = { 0, 0 }, .cursor = 1, .state = st_init, .pvt = 0, .nparms = 0, }; /* DEC VT graphics to codepage 437 table (characters 0x60-0x7F only) */ static const char decvt_to_cp437[] = { 0004, 0261, 0007, 0007, 0007, 0007, 0370, 0361, 0007, 0007, 0331, 0277, 0332, 0300, 0305, 0304, 0304, 0304, 0137, 0137, 0303, 0264, 0301, 0302, 0263, 0363, 0362, 0343, 0330, 0234, 0007, 00 }; void __ansi_init(const struct term_info *ti) { memcpy(ti->ts, &default_state, sizeof default_state); } void __ansi_putchar(const struct term_info *ti, uint8_t ch) { const struct ansi_ops *op = ti->op; struct term_state *st = ti->ts; const int rows = ti->rows; const int cols = ti->cols; struct curxy xy = st->xy; switch ( st->state ) { case st_init: switch ( ch ) { case 1 ... 5: st->state = st_tbl; st->parms[0] = ch; break; case '\b': if ( xy.x > 0 ) xy.x--; break; case '\t': { int nsp = 8 - (xy.x & 7); while ( nsp-- ) __ansi_putchar(ti, ' '); } return; /* Cursor already updated */ case '\n': case '\v': case '\f': xy.y++; if ( st->autocr ) xy.x = 0; break; case '\r': xy.x = 0; break; case 127: /* Ignore delete */ break; case 14: st->vtgraphics = 1; break; case 15: st->vtgraphics = 0; break; case 27: st->state = st_esc; break; default: /* Print character */ if ( ch >= 32 ) { if ( st->vtgraphics && (ch & 0xe0) == 0x60 ) ch = decvt_to_cp437[ch - 0x60]; op->write_char(xy.x, xy.y, ch, st); xy.x++; } break; } break; case st_esc: switch ( ch ) { case '%': case '(': case ')': case '#': /* Ignore this plus the subsequent character, allows compatibility with Linux sequence to set charset */ break; case '[': st->state = st_csi; st->nparms = st->pvt = 0; memset(st->parms, 0, sizeof st->parms); break; case 'c': /* Reset terminal */ memcpy(&st, &default_state, sizeof st); op->erase(st, 0, 0, cols-1, rows-1); xy.x = xy.y = 0; st->state = st_init; break; default: /* Ignore sequence */ st->state = st_init; break; } break; case st_csi: { int p0 = st->parms[0] ? st->parms[0] : 1; if ( ch >= '0' && ch <= '9' ) { st->parms[st->nparms] = st->parms[st->nparms]*10 + (ch-'0'); } else if ( ch == ';' ) { st->nparms++; if ( st->nparms >= ANSI_MAX_PARMS ) st->nparms = ANSI_MAX_PARMS-1; break; } else if ( ch == '?' ) { st->pvt = 1; } else { switch ( ch ) { case 'A': { int y = xy.y - p0; xy.y = (y < 0) ? 0 : y; } break; case 'B': { int y = xy.y + p0; xy.y = (y >= rows) ? rows-1 : y; } break; case 'C': { int x = xy.x + p0; xy.x = (x >= cols) ? cols-1 : x; } break; case 'D': { int x = xy.x - p0; xy.x = (x < 0) ? 0 : x; } break; case 'E': { int y = xy.y + p0; xy.y = (y >= rows) ? rows-1 : y; xy.x = 0; } break; case 'F': { int y = xy.y - p0; xy.y = (y < 0) ? 0 : y; xy.x = 0; } break; case 'G': case '\'': { int x = st->parms[0] - 1; xy.x = (x >= cols) ? cols-1 : (x < 0) ? 0 : x; } break; case 'H': case 'f': { int y = st->parms[0] - 1; int x = st->parms[1] - 1; xy.x = (x >= cols) ? cols-1 : (x < 0) ? 0 : x; xy.y = (y >= rows) ? rows-1 : (y < 0) ? 0 : y; } break; case 'J': { switch ( st->parms[0] ) { case 0: op->erase(st, xy.x, xy.y, cols-1, xy.y); if ( xy.y < rows-1 ) op->erase(st, 0, xy.y+1, cols-1, rows-1); break; case 1: if ( xy.y > 0 ) op->erase(st, 0, 0, cols-1, xy.y-1); if ( xy.y > 0 ) op->erase(st, 0, xy.y, xy.x-1, xy.y); break; case 2: op->erase(st, 0, 0, cols-1, rows-1); break; default: /* Ignore */ break; } } break; case 'K': { switch ( st->parms[0] ) { case 0: op->erase(st, xy.x, xy.y, cols-1, xy.y); break; case 1: if ( xy.x > 0 ) op->erase(st, 0, xy.y, xy.x-1, xy.y); break; case 2: op->erase(st, 0, xy.y, cols-1, xy.y); break; default: /* Ignore */ break; } } break; case 'h': case 'l': { int set = (ch == 'h'); switch ( st->parms[0] ) { case 20: st->autocr = set; break; case 25: st->cursor = set; op->showcursor(st); break; default: /* Ignore */ break; } } break; case 'm': { static const int ansi2pc[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; int i; for ( i = 0 ; i <= st->nparms ; i++ ) { int a = st->parms[i]; switch ( a ) { case 0: st->fg = 7; st->bg = 0; st->intensity = 1; st->underline = 0; st->blink = 0; st->reverse = 0; break; case 1: st->intensity = 2; break; case 2: st->intensity = 0; break; case 4: st->underline = 1; break; case 5: st->blink = 1; break; case 7: st->reverse = 1; break; case 21: case 22: st->intensity = 1; break; case 24: st->underline = 0; break; case 25: st->blink = 0; break; case 27: st->reverse = 0; break; case 30 ... 37: st->fg = ansi2pc[a-30]; break; case 38: st->fg = 7; st->underline = 1; break; case 39: st->fg = 7; st->underline = 0; break; case 40 ... 47: st->bg = ansi2pc[a-40]; break; case 49: st->bg = 7; break; default: /* Do nothing */ break; } } } break; case 's': st->saved_xy = xy; break; case 'u': xy = st->saved_xy; break; default: /* Includes CAN and SUB */ break; /* Drop unknown sequence */ } st->state = st_init; } } break; case st_tbl: st->parms[1] = 0; if ( ch == '#' ) st->state = st_tblc; else st->state = st_init; break; case st_tblc: { unsigned int n = (unsigned char)ch - '0'; const char *p; if (n < 10) { st->parms[1] = st->parms[1]*10+n; if (! --st->parms[0]) { if (st->parms[1] < console_color_table_size) { /* Set the color table index */ st->cindex = st->parms[1]; /* See if there are any other attributes we care about */ p = console_color_table[st->parms[1]].ansi; if (p) { st->state = st_esc; __ansi_putchar(ti, '['); __ansi_putchar(ti, '0'); __ansi_putchar(ti, ';'); while (*p) __ansi_putchar(ti, *p++); __ansi_putchar(ti, 'm'); } } st->state = st_init; } } else { st->state = st_init; } } break; } /* If we fell off the end of the screen, adjust */ if ( xy.x >= cols ) { xy.x = 0; xy.y++; } while ( xy.y >= rows ) { xy.y--; op->scroll_up(st); } /* Update cursor position */ op->set_cursor(xy.x, xy.y, st->cursor); st->xy = xy; } syslinux-legacy-3.63+dfsg/com32/lib/sys/open.c0000664000175000017500000000505110777447272017630 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include #include #include #include "file.h" /* * open.c * * Open an ordinary file */ extern ssize_t __file_read(struct file_info *, void *, size_t); extern int __file_close(struct file_info *); static const struct input_dev file_dev = { .dev_magic = __DEV_MAGIC, .flags = __DEV_FILE | __DEV_INPUT, .fileflags = O_RDONLY, .read = __file_read, .close = __file_close, .open = NULL, }; int open(const char *pathname, int flags, ...) { com32sys_t regs; int fd; struct file_info *fp; fd = opendev(&file_dev, NULL, flags); if ( fd < 0 ) return -1; fp = &__file_info[fd]; strlcpy(__com32.cs_bounce, pathname, __com32.cs_bounce_size); regs.eax.w[0] = 0x0006; regs.esi.w[0] = OFFS(__com32.cs_bounce); regs.es = SEG(__com32.cs_bounce); __com32.cs_intcall(0x22, ®s, ®s); if ( (regs.eflags.l & EFLAGS_CF) || regs.esi.w[0] == 0 ) { errno = ENOENT; return -1; } { uint16_t blklg2; asm("bsrw %1,%0" : "=r" (blklg2) : "rm" (regs.ecx.w[0])); fp->i.blocklg2 = blklg2; } fp->i.length = regs.eax.l; fp->i.filedes = regs.esi.w[0]; fp->i.offset = 0; fp->i.nbytes = 0; return fd; } syslinux-legacy-3.63+dfsg/com32/lib/sys/openconsole.c0000664000175000017500000000335610777447272021221 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * openconsole.c * * Open the chosen console device */ #include #include #include int openconsole(const struct input_dev *idev, const struct output_dev *odev) { close(0); if ( opendev(idev, odev, O_RDONLY) != 0 ) return -1; close(1); if ( opendev(idev, odev, O_WRONLY) != 1 ) return -1; close(2); if ( opendev(idev, odev, O_WRONLY) != 2 ) return -1; return 0; } syslinux-legacy-3.63+dfsg/com32/lib/sys/file.h0000664000175000017500000000676410777447272017627 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * file.h * * Internal implementation of file I/O for COM32 */ #ifndef _COM32_SYS_FILE_H #define _COM32_SYS_FILE_H #include #include #include #include #include /* Device structure; contains the relevant operations */ struct file_info; #define __DEV_MAGIC 0xf4e7 #define __DEV_TTY 0x0001 /* TTY - must be bit 0 */ #define __DEV_FILE 0x0002 /* Ordinary file */ #define __DEV_OUTPUT 0x0004 /* This is an output device */ #define __DEV_INPUT 0 /* Dummy */ #define __DEV_ERROR 0x0008 /* This is the error device */ #define __DEV_NULL 0x0010 /* This is the null device */ struct input_dev { uint16_t dev_magic; /* Magic number */ uint16_t flags; /* Flags */ int fileflags; /* Permitted file flags */ ssize_t (*read)(struct file_info *, void *, size_t); int (*close)(struct file_info *); int (*open)(struct file_info *); }; struct output_dev { uint16_t dev_magic; /* Magic number */ uint16_t flags; /* Flags */ int fileflags; ssize_t (*write)(struct file_info *, const void *, size_t); int (*close)(struct file_info *); int (*open)(struct file_info *); const struct output_dev *fallback; /* Fallback option for certain consoles */ }; /* File structure */ #define NFILES 32 /* Number of files to support */ #define MAXBLOCK 16384 /* Defined by ABI */ struct file_info { const struct input_dev *iop; /* Input operations */ const struct output_dev *oop; /* Output operations */ /* Structure used for input blocking */ struct { int blocklg2; /* Blocksize log 2 */ size_t offset; /* Current file offset */ size_t length; /* Total file length */ uint16_t filedes; /* File descriptor */ uint16_t _filler; /* Unused */ size_t nbytes; /* Number of bytes available in buffer */ char *datap; /* Current data pointer */ char buf[MAXBLOCK]; } i; /* Output file data */ struct { int rows, cols; /* Rows and columns */ } o; }; extern struct file_info __file_info[NFILES]; /* Line input discipline */ ssize_t __line_input(struct file_info *fp, char *buf, size_t bufsize, ssize_t (*get_char)(struct file_info *, void *, size_t)); #endif /* _COM32_SYS_FILE_H */ syslinux-legacy-3.63+dfsg/com32/lib/sys/rawcon_write.c0000664000175000017500000000404510777447272021374 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * rawcon_write.c * * Raw writing to the console; no \n -> \r\n translation */ #include #include #include #include #include "file.h" static ssize_t __rawcon_write(struct file_info *fp, const void *buf, size_t count) { com32sys_t ireg; const char *bufp = buf; size_t n = 0; (void)fp; memset(&ireg, 0, sizeof ireg); ireg.eax.b[1] = 0x02; while ( count-- ) { ireg.edx.b[0] = *bufp++; __intcall(0x21, &ireg, NULL); n++; } return n; } const struct output_dev dev_rawcon_w = { .dev_magic = __DEV_MAGIC, .flags = __DEV_TTY | __DEV_OUTPUT, .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, .write = __rawcon_write, .close = NULL, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/fileinfo.c0000664000175000017500000000007110777447272020457 0ustar evanevan#include "file.h" struct file_info __file_info[NFILES]; syslinux-legacy-3.63+dfsg/com32/lib/sys/ansicon_write.c0000664000175000017500000001414210777447272021534 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * ansicon_write.c * * Write to the screen using ANSI control codes (about as capable as * DOS' ANSI.SYS.) */ #include #include #include #include #include #include #include "file.h" #include "ansi.h" static void ansicon_erase(const struct term_state *, int, int, int, int); static void ansicon_write_char(int, int, uint8_t, const struct term_state *); static void ansicon_showcursor(const struct term_state *); static void ansicon_scroll_up(const struct term_state *); static void ansicon_set_cursor(int, int, int); static struct term_state ts; struct ansi_ops __ansicon_ops = { .erase = ansicon_erase, .write_char = ansicon_write_char, .showcursor = ansicon_showcursor, .set_cursor = ansicon_set_cursor, .scroll_up = ansicon_scroll_up, }; static struct term_info ti = { .disabled = 0, .ts = &ts, .op = &__ansicon_ops }; #define BIOS_CURXY ((struct curxy *)0x450) /* Array for each page */ #define BIOS_ROWS (*(uint8_t *)0x484) /* Minus one; if zero use 24 (= 25 lines) */ #define BIOS_COLS (*(uint16_t *)0x44A) #define BIOS_PAGE (*(uint8_t *)0x462) /* Reference counter to the screen, to keep track of if we need reinitialization. */ static int ansicon_counter = 0; static uint16_t cursor_type; /* Saved cursor pattern */ /* Common setup */ int __ansicon_open(struct file_info *fp) { static com32sys_t ireg; /* Auto-initalized to all zero */ com32sys_t oreg; if (!ansicon_counter) { /* Are we disabled? */ ireg.eax.w[0] = 0x000b; __intcall(0x22, &ireg, &oreg); if ( (signed char)oreg.ebx.b[1] < 0 ) { ti.disabled = 1; } else { /* Force text mode */ ireg.eax.w[0] = 0x0005; __intcall(0x22, &ireg, NULL); /* Initial state */ ti.rows = BIOS_ROWS ? BIOS_ROWS+1 : 25; ti.cols = BIOS_COLS; __ansi_init(&ti); /* Get cursor shape and position */ ireg.eax.b[1] = 0x03; ireg.ebx.b[1] = BIOS_PAGE; __intcall(0x10, &ireg, &oreg); cursor_type = oreg.ecx.w[0]; ti.ts->xy.x = oreg.edx.b[0]; ti.ts->xy.y = oreg.edx.b[1]; } } fp->o.rows = ti.rows; fp->o.cols = ti.cols; ansicon_counter++; return 0; } int __ansicon_close(struct file_info *fp) { (void)fp; ansicon_counter--; return 0; } /* Turn ANSI attributes into VGA attributes */ static uint8_t ansicon_attribute(const struct term_state *st) { int bg = st->bg; int fg; if ( st->underline ) fg = 0x01; else if ( st->intensity == 0 ) fg = 0x08; else fg = st->fg; if ( st->reverse ) { bg = fg & 0x07; fg &= 0x08; fg |= st->bg; } if ( st->blink ) bg ^= 0x08; if ( st->intensity == 2 ) fg ^= 0x08; return (bg << 4) | fg; } /* Erase a region of the screen */ static void ansicon_erase(const struct term_state *st, int x0, int y0, int x1, int y1) { static com32sys_t ireg; ireg.eax.w[0] = 0x0600; /* Clear window */ ireg.ebx.b[1] = ansicon_attribute(st); ireg.ecx.b[0] = x0; ireg.ecx.b[1] = y0; ireg.edx.b[0] = x1; ireg.edx.b[1] = y1; __intcall(0x10, &ireg, NULL); } /* Show or hide the cursor */ static void ansicon_showcursor(const struct term_state *st) { static com32sys_t ireg; ireg.eax.b[1] = 0x01; ireg.ecx.w[0] = st->cursor ? cursor_type : 0x2020; __intcall(0x10, &ireg, NULL); } static void ansicon_set_cursor(int x, int y, int visible) { const int page = BIOS_PAGE; struct curxy xy = BIOS_CURXY[page]; static com32sys_t ireg; (void)visible; if (xy.x != x || xy.y != y) { ireg.eax.b[1] = 0x02; ireg.ebx.b[1] = page; ireg.edx.b[1] = y; ireg.edx.b[0] = x; __intcall(0x10, &ireg, NULL); } } static void ansicon_write_char(int x, int y, uint8_t ch, const struct term_state *st) { static com32sys_t ireg; ansicon_set_cursor(x, y, 0); ireg.eax.b[1] = 0x09; ireg.eax.b[0] = ch; ireg.ebx.b[1] = BIOS_PAGE; ireg.ebx.b[0] = ansicon_attribute(st); ireg.ecx.w[0] = 1; __intcall(0x10, &ireg, NULL); } static void ansicon_scroll_up(const struct term_state *st) { static com32sys_t ireg; ireg.eax.w[0] = 0x0601; ireg.ebx.b[1] = ansicon_attribute(st); ireg.ecx.w[0] = 0; ireg.edx.b[1] = ti.rows-1; ireg.edx.b[0] = ti.cols-1; __intcall(0x10, &ireg, NULL); /* Scroll */ } ssize_t __ansicon_write(struct file_info *fp, const void *buf, size_t count) { const unsigned char *bufp = buf; size_t n = 0; (void)fp; if ( ti.disabled ) return n; /* Nothing to do */ while ( count-- ) { __ansi_putchar(&ti, *bufp++); n++; } return n; } const struct output_dev dev_ansicon_w = { .dev_magic = __DEV_MAGIC, .flags = __DEV_TTY | __DEV_OUTPUT, .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, .write = __ansicon_write, .close = __ansicon_close, .open = __ansicon_open, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/vesa/0000775000175000017500000000000010777447344017460 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/lib/sys/vesa/initvesa.c0000664000175000017500000002177210777447272021457 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 1999-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * initvesa.c * * Query the VESA BIOS and select a 640x480x32 mode with local mapping * support, if one exists. */ #include #include #include #include #include #include "vesa.h" #include "video.h" #include "fill.h" #include "debug.h" struct vesa_info __vesa_info; struct vesa_char *__vesacon_text_display; int __vesacon_font_height, __vesacon_text_rows; enum vesa_pixel_format __vesacon_pixel_format = PXF_NONE; unsigned int __vesacon_bytes_per_pixel; uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT]; uint32_t __vesacon_background[VIDEO_Y_SIZE][VIDEO_X_SIZE]; static void unpack_font(uint8_t *dst, uint8_t *src, int height) { int i; for (i = 0; i < FONT_MAX_CHARS; i++) { memcpy(dst, src, height); memset(dst+height, 0, FONT_MAX_HEIGHT-height); dst += FONT_MAX_HEIGHT; src += height; } } static int __constfunc is_power_of_2(unsigned int x) { return x && !(x & (x-1)); } static int vesacon_paged_mode_ok(const struct vesa_mode_info *mi) { int i; if (!is_power_of_2(mi->win_size) || !is_power_of_2(mi->win_grain) || mi->win_grain > mi->win_size) return 0; /* Impossible... */ for (i = 0; i < 2; i++) { if ((mi->win_attr[i] & 0x05) == 0x05 && mi->win_seg[i]) return 1; /* Usable window */ } return 0; /* Nope... */ } static int vesacon_set_mode(void) { com32sys_t rm; uint8_t *rom_font; uint16_t mode, bestmode, *mode_ptr; struct vesa_general_info *gi; struct vesa_mode_info *mi; enum vesa_pixel_format pxf, bestpxf; /* Allocate space in the bounce buffer for these structures */ gi = &((struct vesa_info *)__com32.cs_bounce)->gi; mi = &((struct vesa_info *)__com32.cs_bounce)->mi; debug("Hello, World!\r\n"); memset(&rm, 0, sizeof rm); memset(gi, 0, sizeof *gi); gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */ rm.eax.w[0] = 0x4F00; /* Get SVGA general information */ rm.edi.w[0] = OFFS(gi); rm.es = SEG(gi); __intcall(0x10, &rm, &rm); if ( rm.eax.w[0] != 0x004F ) return 1; /* Function call failed */ if ( gi->signature != VESA_MAGIC ) return 2; /* No magic */ if ( gi->version < 0x0102 ) return 3; /* VESA 1.2+ required */ /* Copy general info */ memcpy(&__vesa_info.gi, gi, sizeof *gi); /* Search for a 640x480 mode with a suitable color and memory model... */ mode_ptr = GET_PTR(gi->video_mode_ptr); bestmode = 0; bestpxf = PXF_NONE; while ((mode = *mode_ptr++) != 0xFFFF) { mode &= 0x1FF; /* The rest are attributes of sorts */ debug("Found mode: 0x%04x\r\n", mode); memset(mi, 0, sizeof *mi); rm.eax.w[0] = 0x4F01; /* Get SVGA mode information */ rm.ecx.w[0] = mode; rm.edi.w[0] = OFFS(mi); rm.es = SEG(mi); __intcall(0x10, &rm, &rm); /* Must be a supported mode */ if ( rm.eax.w[0] != 0x004f ) continue; debug("mode_attr 0x%04x, h_res = %4d, v_res = %4d, bpp = %2d, layout = %d (%d,%d,%d)\r\n", mi->mode_attr, mi->h_res, mi->v_res, mi->bpp, mi->memory_layout, mi->rpos, mi->gpos, mi->bpos); /* Must be an LFB color graphics mode supported by the hardware. The bits tested are: 4 - graphics mode 3 - color mode 1 - mode information available (mandatory in VBE 1.2+) 0 - mode supported by hardware */ if ( (mi->mode_attr & 0x001b) != 0x001b ) continue; /* Must be 640x480 */ if ( mi->h_res != VIDEO_X_SIZE || mi->v_res != VIDEO_Y_SIZE ) continue; /* We don't support multibank (interlaced memory) modes */ /* * Note: The Bochs VESA BIOS (vbe.c 1.58 2006/08/19) violates the * specification which states that banks == 1 for unbanked modes; * fortunately it does report bank_size == 0 for those. */ if ( mi->banks > 1 && mi->bank_size ) { debug("bad: banks = %d, banksize = %d, pages = %d\r\n", mi->banks, mi->bank_size, mi->image_pages); continue; } /* Must be either a flat-framebuffer mode, or be an acceptable paged mode */ if ( !(mi->mode_attr & 0x0080) && !vesacon_paged_mode_ok(mi) ) { debug("bad: invalid paged mode\r\n"); continue; } /* Must either be a packed-pixel mode or a direct color mode (depending on VESA version ); must be a supported pixel format */ pxf = PXF_NONE; /* Not usable */ if (mi->bpp == 32 && (mi->memory_layout == 4 || (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 && mi->bpos == 0))) pxf = PXF_BGRA32; else if (mi->bpp == 24 && (mi->memory_layout == 4 || (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 && mi->bpos == 0))) pxf = PXF_BGR24; else if (mi->bpp == 16 && (mi->memory_layout == 4 || (mi->memory_layout == 6 && mi->rpos == 11 && mi->gpos == 5 && mi->bpos == 0))) pxf = PXF_LE_RGB16_565; else if (mi->bpp == 15 && (mi->memory_layout == 4 || (mi->memory_layout == 6 && mi->rpos == 10 && mi->gpos == 5 && mi->bpos == 0))) pxf = PXF_LE_RGB15_555; if (pxf < bestpxf) { debug("Best mode so far, pxf = %d\r\n", pxf); /* Best mode so far... */ bestmode = mode; bestpxf = pxf; /* Copy mode info */ memcpy(&__vesa_info.mi, mi, sizeof *mi); } } if (bestpxf == PXF_NONE) return 4; /* No mode found */ mi = &__vesa_info.mi; mode = bestmode; __vesacon_bytes_per_pixel = (mi->bpp+7) >> 3; __vesacon_format_pixels = __vesacon_format_pixels_list[bestpxf]; /* Download the SYSLINUX- or BIOS-provided font */ rm.eax.w[0] = 0x0018; /* Query custom font */ __intcall(0x22, &rm, &rm); if (!(rm.eflags.l & EFLAGS_CF) && rm.eax.b[0]) { __vesacon_font_height = rm.eax.b[0]; rom_font = MK_PTR(rm.es, rm.ebx.w[0]); } else { rm.eax.w[0] = 0x1130; /* Get Font Information */ rm.ebx.w[0] = 0x0600; /* Get 8x16 ROM font */ __intcall(0x10, &rm, &rm); rom_font = MK_PTR(rm.es, rm.ebp.w[0]); __vesacon_font_height = 16; } unpack_font((uint8_t *)__vesacon_graphics_font, rom_font, __vesacon_font_height); __vesacon_text_rows = (VIDEO_Y_SIZE-2*VIDEO_BORDER)/__vesacon_font_height; __vesacon_init_cursor(__vesacon_font_height); /* Now set video mode */ rm.eax.w[0] = 0x4F02; /* Set SVGA video mode */ if (mi->mode_attr & 0x0080) mode |= 0x4000; /* Request linear framebuffer if supported */ rm.ebx.w[0] = mode; __intcall(0x10, &rm, &rm); if ( rm.eax.w[0] != 0x004F ) return 9; /* Failed to set mode */ __vesacon_init_copy_to_screen(); /* Tell syslinux we changed video mode */ rm.eax.w[0] = 0x0017; /* Report video mode change */ /* In theory this should be: rm.ebx.w[0] = (mi->mode_attr & 4) ? 0x0007 : 0x000f; However, that would assume all systems that claim to handle text output in VESA modes actually do that... */ rm.ebx.w[0] = 0x000f; rm.ecx.w[0] = VIDEO_X_SIZE; rm.edx.w[0] = VIDEO_Y_SIZE; __intcall(0x22, &rm, NULL); __vesacon_pixel_format = bestpxf; return 0; } static int init_text_display(void) { size_t nchars; struct vesa_char *ptr; struct vesa_char def_char = { .ch = ' ', .attr = 0, }; nchars = (TEXT_PIXEL_ROWS/__vesacon_font_height+2)* (TEXT_PIXEL_COLS/FONT_WIDTH+2); __vesacon_text_display = ptr = malloc(nchars*sizeof(struct vesa_char)); if (!ptr) return -1; vesacon_fill(ptr, def_char, nchars); return 0; } int __vesacon_init(void) { int rv; /* We need the FPU for graphics, at least libpng et al will need it... */ if (x86_init_fpu()) return 10; rv = vesacon_set_mode(); if (rv) return rv; init_text_display(); debug("Mode set, now drawing at %#p\r\n", __vesa_info.mi.lfb_ptr); __vesacon_init_background(); debug("Ready!\r\n"); return 0; } syslinux-legacy-3.63+dfsg/com32/lib/sys/vesa/alphatbl.pl0000664000175000017500000000173010777447272021605 0ustar evanevan#!/usr/bin/perl # # Produce gamma-correction tables for alpha blending, assuming sRGB space. # sub srgb_to_linear($) { my($s) = @_; if ($s <= 10) { return $s/(255*12.92); } else { return (($s+14.025)/269.025)**2.4; } } sub linear_to_srgb($) { my($l) = @_; my $s; if ($l <= 0.00304) { $s = 12.92*$l; } else { $s = 1.055*$l**(1.0/2.4) - 0.055; } return int($s*255+0.5); } # Header print "#include \n\n"; # # Table 1: convert 8-bit sRGB values to 16-bit linear values # print "const uint16_t __vesacon_srgb_to_linear[256] = {\n"; for ($i = 0; $i <= 255; $i++) { printf "\t%5d,\n", int(srgb_to_linear($i)*65535+0.5); } print "};\n\n"; # # Table 2: convert linear values in the range [0, 65535*255], # shifted right by 12 bits, to sRGB # print "const uint8_t __vesacon_linear_to_srgb[4080] = {\n"; for ($i = 0; $i <= 4079; $i++) { printf "\t%3d,\n", linear_to_srgb(($i+0.5)/4079.937744); } print "};\n\n"; syslinux-legacy-3.63+dfsg/com32/lib/sys/vesa/background.c0000664000175000017500000002003110777447272021737 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include "vesa.h" #include "video.h" static size_t filesize(FILE *fp) { struct stat st; if (fstat(fileno(fp), &st)) return 0; else return st.st_size; } /*** FIX: This really should be alpha-blended with color index 0 ***/ /* For best performance, "start" should be a multiple of 4, to assure aligned dwords. */ static void draw_background_line(int line, int start, int npixels) { uint32_t *bgptr = &__vesacon_background[line][start]; unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel; size_t fbptr = line*__vesa_info.mi.logical_scan + start*bytes_per_pixel; __vesacon_copy_to_screen(fbptr, bgptr, npixels); } /* This draws the border, then redraws the text area */ static void draw_background(void) { int i; const int bottom_border = VIDEO_BORDER + (TEXT_PIXEL_ROWS % __vesacon_font_height); const int right_border = VIDEO_BORDER + (TEXT_PIXEL_COLS % FONT_WIDTH); for (i = 0; i < VIDEO_BORDER; i++) draw_background_line(i, 0, VIDEO_X_SIZE); for (i = VIDEO_BORDER; i < VIDEO_Y_SIZE-bottom_border; i++) { draw_background_line(i, 0, VIDEO_BORDER); draw_background_line(i, VIDEO_X_SIZE-right_border, right_border); } for (i = VIDEO_Y_SIZE-bottom_border; i < VIDEO_Y_SIZE; i++) draw_background_line(i, 0, VIDEO_X_SIZE); __vesacon_redraw_text(); } static int read_png_file(FILE *fp) { png_structp png_ptr = NULL; png_infop info_ptr = NULL; png_infop end_ptr = NULL; #if 0 png_color_16p image_background; static const png_color_16 my_background = {0,0,0,0,0}; #endif png_bytep row_pointers[VIDEO_Y_SIZE]; int passes; int i; int rv = -1; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); end_ptr = png_create_info_struct(png_ptr); if (!png_ptr || !info_ptr || !end_ptr || setjmp(png_jmpbuf(png_ptr))) goto err; png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_set_user_limits(png_ptr, VIDEO_X_SIZE, VIDEO_Y_SIZE); png_read_info(png_ptr, info_ptr); /* Set the appropriate set of transformations. We need to end up with 32-bit BGRA format, no more, no less. */ /* Expand to RGB first... */ if (info_ptr->color_type & PNG_COLOR_MASK_PALETTE) png_set_palette_to_rgb(png_ptr); else if (!(info_ptr->color_type & PNG_COLOR_MASK_COLOR)) png_set_gray_to_rgb(png_ptr); /* Add alpha channel, if need be */ if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA)) { if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); else png_set_add_alpha(png_ptr, ~0, PNG_FILLER_AFTER); } /* Adjust the byte order, if necessary */ png_set_bgr(png_ptr); /* Make sure we end up with 8-bit data */ if (info_ptr->bit_depth == 16) png_set_strip_16(png_ptr); else if (info_ptr->bit_depth < 8) png_set_packing(png_ptr); #if 0 if (png_get_bKGD(png_ptr, info_ptr, &image_background)) png_set_background(png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); else png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); #endif /* Whew! Now we should get the stuff we want... */ for (i = 0; i < (int)info_ptr->height; i++) row_pointers[i] = (void *)__vesacon_background[i]; passes = png_set_interlace_handling(png_ptr); for (i = 0; i < passes; i++) png_read_rows(png_ptr, row_pointers, NULL, info_ptr->height); rv = 0; err: if (png_ptr) png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return rv; } static int jpeg_sig_cmp(uint8_t *bytes, int len) { (void)len; return (bytes[0] == 0xff && bytes[1] == 0xd8) ? 0 : -1; } static int read_jpeg_file(FILE *fp, uint8_t *header, int len) { struct jdec_private *jdec = NULL; unsigned char *jpeg_file = NULL; size_t length_of_file = filesize(fp); unsigned int width, height; int rv = -1; unsigned char *components[1]; unsigned int bytes_per_row[1]; jpeg_file = malloc(length_of_file); if (!jpeg_file) goto err; memcpy(jpeg_file, header, len); if (fread(jpeg_file+len, 1, length_of_file-len, fp) != length_of_file-len) goto err; jdec = tinyjpeg_init(); if (!jdec) goto err; if (tinyjpeg_parse_header(jdec, jpeg_file, length_of_file) < 0) goto err; tinyjpeg_get_size(jdec, &width, &height); if (width > VIDEO_X_SIZE || height > VIDEO_Y_SIZE) goto err; components[0] = (void *)&__vesacon_background[0]; tinyjpeg_set_components(jdec, components, 1); bytes_per_row[0] = VIDEO_X_SIZE << 2; tinyjpeg_set_bytes_per_row(jdec, bytes_per_row, 1); tinyjpeg_decode(jdec, TINYJPEG_FMT_BGRA32); rv = 0; err: /* Don't use tinyjpeg_free() here, since we didn't allow tinyjpeg to allocate the frame buffer */ if (jdec) free(jdec); if (jpeg_file) free(jpeg_file); return rv; } /* Simple grey Gaussian hole, enough to look interesting */ int vesacon_default_background(void) { int x, y, dx, dy, dy2; uint8_t *bgptr = (uint8_t *)&__vesacon_background; uint8_t k; if (__vesacon_pixel_format == PXF_NONE) return 0; /* Not in graphics mode */ for (y = 0, dy = -VIDEO_Y_SIZE/2; y < VIDEO_Y_SIZE; y++, dy++) { dy2 = dy*dy; for (x = 0, dx = -VIDEO_X_SIZE/2; x < VIDEO_X_SIZE; x++, dx++) { k = __vesacon_linear_to_srgb[500+((dx*dx+dy2) >> 6)]; bgptr[0] = k; /* Blue */ bgptr[1] = k; /* Green */ bgptr[2] = k; /* Red */ bgptr += 4; /* Dummy alpha */ } } draw_background(); return 0; } /* Set the background to a single flat color */ int vesacon_set_background(unsigned int rgb) { void *bgptr = __vesacon_background; unsigned int count = VIDEO_X_SIZE*VIDEO_Y_SIZE; if (__vesacon_pixel_format == PXF_NONE) return 0; /* Not in graphics mode */ asm volatile("cld; rep; stosl" : "+D" (bgptr), "+c" (count) : "a" (rgb) : "memory"); draw_background(); return 0; } int vesacon_load_background(const char *filename) { FILE *fp = NULL; uint8_t header[8]; int rv = 1; if (__vesacon_pixel_format == PXF_NONE) return 0; /* Not in graphics mode */ fp = fopen(filename, "r"); if (!fp) goto err; if (fread(header, 1, 8, fp) != 8) goto err; if (!png_sig_cmp(header, 0, 8)) { rv = read_png_file(fp); } else if (!jpeg_sig_cmp(header, 8)) { rv = read_jpeg_file(fp, header, 8); } /* This actually displays the stuff */ draw_background(); err: if (fp) fclose(fp); return rv; } int __vesacon_init_background(void) { /* The BSS clearing has already cleared __vesacon_background */ /* The VESA BIOS has already cleared the screen */ return 0; } syslinux-legacy-3.63+dfsg/com32/lib/sys/vesa/drawtxt.c0000664000175000017500000002166210777447272021330 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include "vesa.h" #include "video.h" #include "fill.h" /* * Visible cursor information */ static uint8_t cursor_pattern[FONT_MAX_HEIGHT]; static struct vesa_char *cursor_pointer = NULL; static int cursor_x, cursor_y; static inline void *copy_dword(void *dst, void *src, size_t dword_count) { asm volatile("cld; rep; movsl" : "+D" (dst), "+S" (src), "+c" (dword_count)); return dst; /* Updated destination pointer */ } static inline __attribute__((always_inline)) uint8_t alpha_val(uint8_t fg, uint8_t bg, uint8_t alpha) { unsigned int tmp; tmp = __vesacon_srgb_to_linear[fg] * alpha; tmp += __vesacon_srgb_to_linear[bg] * (255-alpha); return __vesacon_linear_to_srgb[tmp >> 12]; } static uint32_t alpha_pixel(uint32_t fg, uint32_t bg) { uint8_t alpha = fg >> 24; uint8_t fg_r = fg >> 16; uint8_t fg_g = fg >> 8; uint8_t fg_b = fg; uint8_t bg_r = bg >> 16; uint8_t bg_g = bg >> 8; uint8_t bg_b = bg; return (alpha_val(fg_r, bg_r, alpha) << 16)| (alpha_val(fg_g, bg_g, alpha) << 8)| (alpha_val(fg_b, bg_b, alpha)); } static void vesacon_update_characters(int row, int col, int nrows, int ncols) { const int height = __vesacon_font_height; const int width = FONT_WIDTH; uint32_t *bgrowptr, *bgptr, bgval, fgval; uint32_t fgcolor = 0, bgcolor = 0, color; uint8_t chbits = 0, chxbits = 0, chsbits = 0; int i, j, jx, pixrow, pixsrow; struct vesa_char *rowptr, *rowsptr, *cptr, *csptr; unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel; unsigned long pixel_offset; uint32_t row_buffer[VIDEO_X_SIZE], *rowbufptr; size_t fbrowptr; uint8_t sha; bgrowptr = &__vesacon_background[row*height+VIDEO_BORDER][col*width+VIDEO_BORDER]; pixel_offset = ((row*height+VIDEO_BORDER)*VIDEO_X_SIZE)+ (col*width+VIDEO_BORDER); fbrowptr = (row*height+VIDEO_BORDER) * __vesa_info.mi.logical_scan + (col*width+VIDEO_BORDER) * bytes_per_pixel; /* Note that we keep a 1-character guard area around the real text area... */ rowptr = &__vesacon_text_display[(row+1)*(TEXT_PIXEL_COLS/FONT_WIDTH+2)+(col+1)]; rowsptr = rowptr - ((TEXT_PIXEL_COLS/FONT_WIDTH+2)+1); pixrow = 0; pixsrow = height-1; for (i = height*nrows; i >= 0; i--) { bgptr = bgrowptr; rowbufptr = row_buffer; cptr = rowptr; csptr = rowsptr; chsbits = __vesacon_graphics_font[csptr->ch][pixsrow]; if (__unlikely(csptr == cursor_pointer)) chsbits |= cursor_pattern[pixsrow]; sha = console_color_table[csptr->attr].shadow; chsbits &= (sha & 0x02) ? 0xff : 0x00; chsbits ^= (sha & 0x01) ? 0xff : 0x00; chsbits <<= (width-2); csptr++; /* Draw two pixels beyond the end of the line. One for the shadow, and one to make sure we have a whole dword of data for the copy operation at the end. Note that this code depends on the fact that all characters begin on dword boundaries in the frame buffer. */ for (jx = 1, j = width*ncols+1; j >= 0; j--) { chbits <<= 1; chsbits <<= 1; chxbits <<= 1; switch (jx) { case 1: chbits = __vesacon_graphics_font[cptr->ch][pixrow]; if (__unlikely(cptr == cursor_pointer)) chbits |= cursor_pattern[pixrow]; sha = console_color_table[cptr->attr].shadow; chxbits = chbits; chxbits &= (sha & 0x02) ? 0xff : 0x00; chxbits ^= (sha & 0x01) ? 0xff : 0x00; fgcolor = console_color_table[cptr->attr].argb_fg; bgcolor = console_color_table[cptr->attr].argb_bg; cptr++; jx--; break; case 0: chsbits = __vesacon_graphics_font[csptr->ch][pixsrow]; if (__unlikely(csptr == cursor_pointer)) chsbits |= cursor_pattern[pixsrow]; sha = console_color_table[csptr->attr].shadow; chsbits &= (sha & 0x02) ? 0xff : 0x00; chsbits ^= (sha & 0x01) ? 0xff : 0x00; csptr++; jx = width-1; break; default: jx--; break; } /* If this pixel is raised, use the offsetted value */ bgval = (chxbits & 0x80) ? bgptr[VIDEO_X_SIZE+1] : *bgptr; bgptr++; /* If this pixel is set, use the fg color, else the bg color */ fgval = (chbits & 0x80) ? fgcolor : bgcolor; /* Produce the combined color pixel value */ color = alpha_pixel(fgval, bgval); /* Apply the shadow (75% shadow) */ if ((chsbits & ~chxbits) & 0x80) { color >>= 2; color &= 0x3f3f3f; } *rowbufptr++ = color; } /* Copy to frame buffer */ __vesacon_copy_to_screen(fbrowptr, row_buffer, rowbufptr-row_buffer); bgrowptr += VIDEO_X_SIZE; fbrowptr += __vesa_info.mi.logical_scan; if (++pixrow == height) { rowptr += TEXT_PIXEL_COLS/FONT_WIDTH+2; pixrow = 0; } if (++pixsrow == height) { rowsptr += TEXT_PIXEL_COLS/FONT_WIDTH+2; pixsrow = 0; } } } /* Bounding box for changed text. The (x1, y1) coordinates are +1! */ static unsigned int upd_x0 = -1U, upd_x1, upd_y0 = -1U, upd_y1; /* Update the range already touched by various variables */ void __vesacon_doit(void) { if (upd_x1 > upd_x0 && upd_y1 > upd_y0) { vesacon_update_characters(upd_y0, upd_x0, upd_y1-upd_y0, upd_x1-upd_x0); upd_x0 = upd_y0 = -1U; upd_x1 = upd_y1 = 0; } } /* Mark a range for update; note argument sequence is the same as vesacon_update_characters() */ static inline void vesacon_touch(int row, int col, int rows, int cols) { unsigned int y0 = row; unsigned int x0 = col; unsigned int y1 = y0+rows; unsigned int x1 = x0+cols; if (y0 < upd_y0) upd_y0 = y0; if (y1 > upd_y1) upd_y1 = y1; if (x0 < upd_x0) upd_x0 = x0; if (x1 > upd_x1) upd_x1 = x1; } /* Erase a region of the screen */ void __vesacon_erase(int x0, int y0, int x1, int y1, attr_t attr) { int y; struct vesa_char *ptr = &__vesacon_text_display [(y0+1)*(TEXT_PIXEL_COLS/FONT_WIDTH+2)+(x0+1)]; struct vesa_char fill = { .ch = ' ', .attr = attr, }; int ncols = x1-x0+1; for (y = y0; y <= y1; y++) { vesacon_fill(ptr, fill, ncols); ptr += TEXT_PIXEL_COLS/FONT_WIDTH+2; } vesacon_touch(y0, x0, y1-y0+1, ncols); } /* Scroll the screen up */ void __vesacon_scroll_up(int nrows, attr_t attr) { struct vesa_char *fromptr = &__vesacon_text_display [(nrows+1)*(TEXT_PIXEL_COLS/FONT_WIDTH+2)]; struct vesa_char *toptr = &__vesacon_text_display [(TEXT_PIXEL_COLS/FONT_WIDTH+2)]; int dword_count = (__vesacon_text_rows-nrows)*(TEXT_PIXEL_COLS/FONT_WIDTH+2); struct vesa_char fill = { .ch = ' ', .attr = attr, }; toptr = copy_dword(toptr, fromptr, dword_count); dword_count = nrows*(TEXT_PIXEL_COLS/FONT_WIDTH+2); vesacon_fill(toptr, fill, dword_count); vesacon_touch(0, 0, __vesacon_text_rows, TEXT_PIXEL_COLS/FONT_WIDTH); } /* Draw one character text at a specific area of the screen */ void __vesacon_write_char(int x, int y, uint8_t ch, attr_t attr) { struct vesa_char *ptr = &__vesacon_text_display [(y+1)*(TEXT_PIXEL_COLS/FONT_WIDTH+2)+(x+1)]; ptr->ch = ch; ptr->attr = attr; vesacon_touch(y, x, 1, 1); } void __vesacon_set_cursor(int x, int y, int visible) { struct vesa_char *ptr = &__vesacon_text_display [(y+1)*(TEXT_PIXEL_COLS/FONT_WIDTH+2)+(x+1)]; if (cursor_pointer) vesacon_touch(cursor_y, cursor_x, 1, 1); if (!visible) { /* Invisible cursor */ cursor_pointer = NULL; } else { cursor_pointer = ptr; vesacon_touch(y, x, 1, 1); } cursor_x = x; cursor_y = y; } void __vesacon_init_cursor(int font_height) { int r0 = font_height - (font_height < 10 ? 2 : 3); if (r0 < 0) r0 = 0; /* cursor_pattern is assumed to be all zero */ cursor_pattern[r0] = 0xff; cursor_pattern[r0+1] = 0xff; } void __vesacon_redraw_text(void) { vesacon_update_characters(0, 0, __vesacon_text_rows, TEXT_PIXEL_COLS/FONT_WIDTH); } syslinux-legacy-3.63+dfsg/com32/lib/sys/vesa/fmtpixel.c0000664000175000017500000000561010777447272021456 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * fmtpixel.c * * Functions to format a single pixel */ #include #include "video.h" /* * Format a sequence of pixels. The first argument is the line buffer; * we can use it to write up to 4 bytes past the end of the last pixel. * Return the place we should be copying from, this is usually the * buffer address, but doesn't *have* to be. */ static const void * format_pxf_bgra32(void *ptr, const uint32_t *p, size_t n) { (void)ptr; (void)n; return p; /* No conversion needed! */ } static const void * format_pxf_bgr24(void *ptr, const uint32_t *p, size_t n) { char *q = ptr; while (n--) { *(uint32_t *)q = *p++; q += 3; } return ptr; } static const void * format_pxf_le_rgb16_565(void *ptr, const uint32_t *p, size_t n) { uint32_t bgra; uint16_t *q = ptr; while (n--) { bgra = *p++; *q++ = ((bgra >> 3) & 0x1f) + ((bgra >> (2+8-5)) & (0x3f << 5)) + ((bgra >> (3+16-11)) & (0x1f << 11)); } return ptr; } static const void * format_pxf_le_rgb15_555(void *ptr, const uint32_t *p, size_t n) { uint32_t bgra; uint16_t *q = ptr; while (n--) { bgra = *p++; *q++ = ((bgra >> 3) & 0x1f) + ((bgra >> (2+8-5)) & (0x1f << 5)) + ((bgra >> (3+16-10)) & (0x1f << 10)); } return ptr; } __vesacon_format_pixels_t __vesacon_format_pixels; const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE] = { [PXF_BGRA32] = format_pxf_bgra32, [PXF_BGR24] = format_pxf_bgr24, [PXF_LE_RGB16_565] = format_pxf_le_rgb16_565, [PXF_LE_RGB15_555] = format_pxf_le_rgb15_555, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/vesa/debug.h0000664000175000017500000000104210777447272020714 0ustar evanevan#ifndef LIB_SYS_VESA_DEBUG_H #define LIB_SYS_VESA_DEBUG_H #if 0 #include #include ssize_t __serial_write(void *fp, const void *buf, size_t count); static void debug(const char *str, ...) { va_list va; char buf[65536]; size_t len; va_start(va, str); len = vsnprintf(buf, sizeof buf, str, va); va_end(va); if (len >= sizeof buf) len = sizeof buf - 1; __serial_write(NULL, buf, len); } #else static inline void debug(const char *str, ...) { (void)str; } #endif #endif /* LIB_SYS_VESA_DEBUG_H */ syslinux-legacy-3.63+dfsg/com32/lib/sys/vesa/vesa.h0000664000175000017500000000625010777447272020572 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 1999-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #ifndef LIB_SYS_VESA_H #define LIB_SYS_VESA_H #include #include /* VESA General Information table */ struct vesa_general_info { uint32_t signature; /* Magic number = "VESA" */ uint16_t version; far_ptr_t vendor_string; uint8_t capabilities[4]; far_ptr_t video_mode_ptr; uint32_t total_memory; uint16_t oem_software_rev; far_ptr_t oem_vendor_name_ptr; far_ptr_t oem_product_name_ptr; far_ptr_t oem_product_rev_ptr; uint8_t reserved[222]; uint8_t oem_data[256]; } __attribute__((packed)); #define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24)) #define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24)) struct vesa_mode_info { uint16_t mode_attr; uint8_t win_attr[2]; uint16_t win_grain; uint16_t win_size; uint16_t win_seg[2]; far_ptr_t win_scheme; uint16_t logical_scan; uint16_t h_res; uint16_t v_res; uint8_t char_width; uint8_t char_height; uint8_t memory_planes; uint8_t bpp; uint8_t banks; uint8_t memory_layout; uint8_t bank_size; uint8_t image_pages; uint8_t page_function; uint8_t rmask; uint8_t rpos; uint8_t gmask; uint8_t gpos; uint8_t bmask; uint8_t bpos; uint8_t resv_mask; uint8_t resv_pos; uint8_t dcm_info; uint8_t *lfb_ptr; /* Linear frame buffer address */ uint8_t *offscreen_ptr; /* Offscreen memory address */ uint16_t offscreen_size; uint8_t reserved[206]; } __attribute__((packed)); struct vesa_info { struct vesa_general_info gi; struct vesa_mode_info mi; }; extern struct vesa_info __vesa_info; #if 0 static inline void vesa_debug(uint32_t color, int pos) { uint32_t *stp = (uint32_t *)__vesa_info.mi.lfb_ptr; stp[pos*3] = color; } #else static inline void vesa_debug(uint32_t color, int pos) { (void)color; (void)pos; } #endif #endif /* LIB_SYS_VESA_H */ syslinux-legacy-3.63+dfsg/com32/lib/sys/vesa/fill.h0000664000175000017500000000406310777447272020562 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #ifndef LIB_SYS_VESA_FILL_H #define LIB_SYS_VESA_FILL_H #include "video.h" /* Fill a number of characters. */ static inline struct vesa_char *vesacon_fill(struct vesa_char *ptr, struct vesa_char fill, unsigned int count) { switch (sizeof(struct vesa_char)) { case 1: asm volatile("cld; rep; stosb" : "+D" (ptr), "+c" (count) : "a" (fill) : "memory"); break; case 2: asm volatile("cld; rep; stosw" : "+D" (ptr), "+c" (count) : "a" (fill) : "memory"); break; case 4: asm volatile("cld; rep; stosl" : "+D" (ptr), "+c" (count) : "a" (fill) : "memory"); break; default: while (count--) *ptr++ = fill; break; } return ptr; } #endif /* LIB_SYS_VESA_FILL_H */ syslinux-legacy-3.63+dfsg/com32/lib/sys/vesa/screencpy.c0000664000175000017500000000665210777447272021630 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include #include #include #include "vesa.h" #include "video.h" static struct win_info { char *win_base; size_t win_pos; size_t win_size; int win_gshift; int win_num; } wi; static inline int __constfunc ilog2(unsigned int x) { asm("bsrl %1,%0" : "=r" (x) : "rm" (x)); return x; } void __vesacon_init_copy_to_screen(void) { struct vesa_mode_info * const mi = &__vesa_info.mi; int winn; if (mi->mode_attr & 0x0080) { /* Linear frame buffer */ wi.win_base = (char *)mi->lfb_ptr; wi.win_size = 1 << 31; /* 2 GB, i.e. one huge window */ wi.win_pos = 0; /* Already positioned (only one position...) */ wi.win_num = -1; /* Not a window */ } else { /* Paged frame buffer */ /* We have already tested that *one* of these is usable */ if ((mi->win_attr[0] & 0x05) == 0x05 && mi->win_seg[0]) winn = 0; else winn = 1; wi.win_num = winn; wi.win_base = (char *)(mi->win_seg[winn] << 4); wi.win_size = mi->win_size << 10; wi.win_gshift = ilog2(mi->win_grain) + 10; wi.win_pos = -1; /* Undefined position */ } } static void set_window_pos(size_t win_pos) { static com32sys_t ireg; wi.win_pos = win_pos; if (wi.win_num < 0) return; /* This should never happen... */ ireg.eax.w[0] = 0x4F05; ireg.ebx.b[0] = wi.win_num; ireg.edx.w[0] = win_pos >> wi.win_gshift; __intcall(0x10, &ireg, NULL); } void __vesacon_copy_to_screen(size_t dst, const uint32_t *src, size_t npixels) { size_t win_pos, win_off; size_t win_size = wi.win_size; size_t omask = win_size - 1; char *win_base = wi.win_base; size_t l; size_t bytes = npixels * __vesacon_bytes_per_pixel; char rowbuf[bytes+4] __aligned(4); const char *s; s = (const char *)__vesacon_format_pixels(rowbuf, src, npixels); while (bytes) { win_off = dst & omask; win_pos = dst & ~omask; if (__unlikely(win_pos != wi.win_pos)) set_window_pos(win_pos); l = min(bytes, win_size-win_off); memcpy(win_base+win_off, s, l); bytes -= l; s += l; dst += l; } } syslinux-legacy-3.63+dfsg/com32/lib/sys/vesa/video.h0000664000175000017500000000665410777447272020752 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #ifndef LIB_SYS_VESA_VIDEO_H #define LIB_SYS_VESA_VIDEO_H #include #define FONT_MAX_CHARS 256 #define FONT_MAX_HEIGHT 32 #define FONT_WIDTH 8 #define VIDEO_X_SIZE 640 #define VIDEO_Y_SIZE 480 #define VIDEO_BORDER 8 #define TEXT_PIXEL_ROWS (VIDEO_Y_SIZE-2*VIDEO_BORDER) #define TEXT_PIXEL_COLS (VIDEO_X_SIZE-2*VIDEO_BORDER) typedef uint16_t attr_t; struct vesa_char { uint8_t ch; /* Character */ uint8_t _filler; /* Currently unused */ attr_t attr; /* Color table index */ }; /* Pixel formats in order of decreasing preference; PXF_NONE should be last */ /* BGR24 is preferred over BGRA32 since the I/O overhead is smaller. */ enum vesa_pixel_format { PXF_BGR24, /* 24-bit BGR */ PXF_BGRA32, /* 32-bit BGRA */ PXF_LE_RGB16_565, /* 16-bit littleendian 5:6:5 RGB */ PXF_LE_RGB15_555, /* 15-bit littleendian 5:5:5 RGB */ PXF_NONE }; extern enum vesa_pixel_format __vesacon_pixel_format; extern unsigned int __vesacon_bytes_per_pixel; typedef const void * (*__vesacon_format_pixels_t)(void *, const uint32_t *, size_t); extern __vesacon_format_pixels_t __vesacon_format_pixels; extern const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE]; extern struct vesa_char *__vesacon_text_display; extern int __vesacon_font_height, __vesacon_text_rows; extern uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT]; extern uint32_t __vesacon_background[VIDEO_Y_SIZE][VIDEO_X_SIZE]; extern uint32_t __vesacon_shadowfb[VIDEO_Y_SIZE][VIDEO_X_SIZE]; extern const uint16_t __vesacon_srgb_to_linear[256]; extern const uint8_t __vesacon_linear_to_srgb[4080]; int __vesacon_init_background(void); int vesacon_load_background(const char *); int __vesacon_init(void); void __vesacon_init_cursor(int); void __vesacon_erase(int, int, int, int, attr_t); void __vesacon_scroll_up(int, attr_t); void __vesacon_write_char(int, int, uint8_t, attr_t); void __vesacon_redraw_text(void); void __vesacon_doit(void); void __vesacon_set_cursor(int, int, int); void __vesacon_copy_to_screen(size_t, const uint32_t *, size_t); void __vesacon_init_copy_to_screen(void); #endif /* LIB_SYS_VESA_VIDEO_H */ syslinux-legacy-3.63+dfsg/com32/lib/sys/opendev.c0000664000175000017500000000476610777447272020343 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include #include #include "file.h" /* * opendev.c * * Open a special device */ int opendev(const struct input_dev *idev, const struct output_dev *odev, int flags) { int fd; struct file_info *fp; int okflags; int e; okflags = (idev ? idev->fileflags : 0) | (odev ? odev->fileflags : 0); if ( !(flags & 3) || (flags & ~okflags) ) { errno = EINVAL; return -1; } for ( fd = 0, fp = __file_info ; fd < NFILES ; fd++, fp++ ) if ( !fp->iop && !fp->oop ) break; if ( fd >= NFILES ) { errno = EMFILE; return -1; } /* The file structure is already zeroed */ fp->iop = &dev_error_r; fp->oop = &dev_error_w; fp->i.datap = fp->i.buf; if (idev) { if (idev->open && (e = idev->open(fp))) { errno = e; goto puke; } fp->iop = idev; } while (odev) { if (odev->open && (e = odev->open(fp))) { if (e == EAGAIN) { if (odev->fallback) { odev = odev->fallback; continue; } else { e = EIO; } } errno = e; goto puke; } fp->oop = odev; break; } return fd; puke: close(fd); return -1; } syslinux-legacy-3.63+dfsg/com32/lib/sys/read.c0000664000175000017500000000330510777447272017602 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * read.c * * Reading from a file descriptor */ #include #include #include #include #include #include "file.h" ssize_t read(int fd, void *buf, size_t count) { struct file_info *fp = &__file_info[fd]; if ( fd >= NFILES || !fp->iop ) { errno = EBADF; return -1; } return fp->iop->read(fp, buf, count); } syslinux-legacy-3.63+dfsg/com32/lib/sys/vesacon_write.c0000664000175000017500000001067010777447272021542 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * vesacon_write.c * * Write to the screen using ANSI control codes (about as capable as * DOS' ANSI.SYS.) */ #include #include #include #include #include #include #include #include "ansi.h" #include "file.h" #include "vesa/video.h" static void vesacon_erase(const struct term_state *, int, int, int, int); static void vesacon_write_char(int, int, uint8_t, const struct term_state *); static void vesacon_showcursor(const struct term_state *); static void vesacon_scroll_up(const struct term_state *); static struct term_state ts; static struct ansi_ops op = { .erase = vesacon_erase, .write_char = vesacon_write_char, .showcursor = vesacon_showcursor, .set_cursor = __vesacon_set_cursor, /* in drawtxt.c */ .scroll_up = vesacon_scroll_up, }; static struct term_info ti = { .cols = TEXT_PIXEL_COLS/FONT_WIDTH, .disabled = 0, .ts = &ts, .op = &op }; /* Reference counter to the screen, to keep track of if we need reinitialization. */ static int vesacon_counter = 0; /* Common setup */ int __vesacon_open(struct file_info *fp) { static com32sys_t ireg; /* Auto-initalized to all zero */ com32sys_t oreg; (void)fp; if (!vesacon_counter) { /* Are we disabled? */ ireg.eax.w[0] = 0x000b; __intcall(0x22, &ireg, &oreg); if ( (signed char)oreg.ebx.b[1] < 0 ) { ti.disabled = 1; } else { /* Switch mode */ if (__vesacon_init()) { vesacon_counter = -1; return EAGAIN; } /* Initial state */ __ansi_init(&ti); ti.rows = __vesacon_text_rows; } } else if (vesacon_counter == -1) { return EAGAIN; } fp->o.rows = ti.rows; fp->o.cols = ti.cols; vesacon_counter++; return 0; } int __vesacon_close(struct file_info *fp) { (void)fp; vesacon_counter--; return 0; } /* Erase a region of the screen */ static void vesacon_erase(const struct term_state *st, int x0, int y0, int x1, int y1) { __vesacon_erase(x0, y0, x1, y1, st->cindex); } /* Draw text on the screen */ static void vesacon_write_char(int x, int y, uint8_t ch, const struct term_state *st) { __vesacon_write_char(x, y, ch, st->cindex); } /* Show or hide the cursor */ static void vesacon_showcursor(const struct term_state *st) { __vesacon_set_cursor(st->xy.x, st->xy.y, st->cursor); } static void vesacon_scroll_up(const struct term_state *st) { __vesacon_scroll_up(1, st->cindex); } ssize_t __vesacon_write(struct file_info *fp, const void *buf, size_t count) { const unsigned char *bufp = buf; size_t n = 0; (void)fp; if ( ti.disabled ) return n; /* Nothing to do */ /* This only updates the shadow text buffer... */ while ( count-- ) { __ansi_putchar(&ti, *bufp++); n++; } /* This actually draws it */ __vesacon_doit(); return n; } const struct output_dev dev_vesacon_w = { .dev_magic = __DEV_MAGIC, .flags = __DEV_TTY | __DEV_OUTPUT, .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, .write = __vesacon_write, .close = __vesacon_close, .open = __vesacon_open, .fallback = &dev_ansicon_w, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/close.c0000664000175000017500000000353410777447272020000 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * close.c */ #include #include #include #include "file.h" int close(int fd) { struct file_info *fp = &__file_info[fd]; int rv = 0; if ( fd >= NFILES || !fp->iop || !fp->oop ) { errno = EBADF; return -1; } if ( fp->iop->close ) { rv = fp->iop->close(fp); if ( rv ) return rv; } fp->iop = &dev_error_r; if ( fp->oop->close ) { rv = fp->oop->close(fp); if ( rv ) return rv; } memset(fp, 0, sizeof *fp); /* File structure unused */ return 0; } syslinux-legacy-3.63+dfsg/com32/lib/sys/cfarcall.c0000664000175000017500000000030710777447272020435 0ustar evanevan/* * cfarcall.c */ #include int __cfarcall(uint16_t cs, uint16_t ip, const void *stack, uint32_t stack_size) { return __com32.cs_cfarcall((cs << 16)+ip, stack, stack_size); } syslinux-legacy-3.63+dfsg/com32/lib/sys/err_read.c0000664000175000017500000000347410777447272020461 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * err_read.c * * Reading from a device which doesn't support reading */ #include #include #include #include #include "file.h" static ssize_t __err_read(struct file_info *fp, void *buf, size_t count) { (void)fp; (void)buf; (void)count; errno = -EINVAL; return -1; } const struct input_dev dev_error_r = { .dev_magic = __DEV_MAGIC, .flags = __DEV_INPUT | __DEV_ERROR, .fileflags = O_RDONLY, .read = __err_read, .close = NULL, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/entry.S0000664000175000017500000000525110777447272020012 0ustar evanevan# ----------------------------------------------------------------------- # # Copyright 2003-2008 H. Peter Anvin - All Rights Reserved # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom # the Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall # be included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ----------------------------------------------------------------------- # COM32 start up code - must be linked first in the binary /* Number of arguments in our version of the entry structure */ #define COM32_ARGS 6 .section ".init","ax" .globl _start .type _start, @function _start: # This first instruction acts as COM32 magic number movl $0x21cd4cff,%eax # Upwards string operations cld # Zero the .bss segment xorl %eax,%eax movl $__bss_start,%edi # Symbol provided by linker movl $_end+3,%ecx # Symbol provided by linker subl %edi,%ecx shrl $2,%ecx rep ; stosl # Copy COM32 invocation parameters leal 4(%esp),%esi # Argument list movl $__com32,%edi movl $COM32_ARGS,%ecx movl %esp,-4(%edi) # Save the initial stack ptr cmpl (%esi),%ecx jbe 1f movl (%esi),%ecx 1: inc %ecx # Copy the argument count, too rep ; movsl # Parse the command line (assumes REGPARM) movl __com32+4,%edx # Command line pushl %edx # Make space for argv movl %esp,%eax call __parse_argv pushl %eax # Save argc # Look for library initialization functions movl $__ctors_start, %esi 2: cmpl $__ctors_end, %esi jae 3f call *(%esi) addl $4,%esi jmp 2b # # Actually run main. This assumes REGPARM is used!!!! # 3: popl %eax # argc popl %edx # argv call main call *(__exit_handler) hlt .size _start, .-_start .bss .globl __entry_esp __entry_esp: .space 4 .globl __com32 __com32: .space 4*(COM32_ARGS+1) syslinux-legacy-3.63+dfsg/com32/lib/sys/vesaserial_write.c0000664000175000017500000000432710777447272022244 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * vesaserial_write.c * * Write to both to the VESA console and the serial port */ #include #include #include #include #include #include "file.h" extern int __vesacon_open(void); extern int __vesacon_close(struct file_info *); extern ssize_t __vesacon_write(struct file_info *, const void *, size_t); extern ssize_t __xserial_write(struct file_info *, const void *, size_t); static ssize_t __vesaserial_write(struct file_info *fp, const void *buf, size_t count) { __vesacon_write(fp, buf, count); return __xserial_write(fp, buf, count); } const struct output_dev dev_vesaserial_w = { .dev_magic = __DEV_MAGIC, .flags = __DEV_TTY | __DEV_OUTPUT, .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, .write = __vesaserial_write, .close = __vesacon_close, .open = __vesacon_open, .fallback = &dev_ansiserial_w, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/stdcon_write.c0000664000175000017500000000417510777447272021401 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * stdcon_write.c * * Writing to the console */ #include #include #include #include #include "file.h" static ssize_t __stdcon_write(struct file_info *fp, const void *buf, size_t count) { com32sys_t ireg; const char *bufp = buf; size_t n = 0; (void)fp; memset(&ireg, 0, sizeof ireg); ireg.eax.b[1] = 0x02; while ( count-- ) { if ( *bufp == '\n' ) { ireg.edx.b[0] = '\r'; __intcall(0x21, &ireg, NULL); } ireg.edx.b[0] = *bufp++; __intcall(0x21, &ireg, NULL); n++; } return n; } const struct output_dev dev_stdcon_w = { .dev_magic = __DEV_MAGIC, .flags = __DEV_TTY | __DEV_OUTPUT, .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, .write = __stdcon_write, .close = NULL, .open = NULL, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/zeroregs.c0000664000175000017500000000026210777447272020526 0ustar evanevan#include /* When we don't need to pass any registers, it's convenient to just be able to pass a prepared all-zero structure. */ const com32sys_t __com32_zero_regs; syslinux-legacy-3.63+dfsg/com32/lib/sys/ftell.c0000664000175000017500000000035510777447272017777 0ustar evanevan/* * sys/ftell.c * * We can't seek, but we can at least tell... */ #include #include "sys/file.h" long ftell(FILE *stream) { int fd = fileno(stream); struct file_info *fp = &__file_info[fd]; return fp->i.offset; } syslinux-legacy-3.63+dfsg/com32/lib/sys/colortable.c0000664000175000017500000000044410777447272021016 0ustar evanevan#include static struct color_table default_color_table[] = { {"default", "0", 0xffffffff, 0x00000000, SHADOW_NORMAL } }; struct color_table *console_color_table = &default_color_table; int console_color_table_size = (sizeof default_color_table/sizeof(struct color_table)); syslinux-legacy-3.63+dfsg/com32/lib/sys/err_write.c0000664000175000017500000000354410777447272020676 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * err_write.c * * Writing to a device which doesn't support writing */ #include #include #include #include #include "file.h" static ssize_t __err_write(struct file_info *fp, const void *buf, size_t count) { (void)fp; (void)buf; (void)count; errno = -EINVAL; return -1; } const struct output_dev dev_error_w = { .dev_magic = __DEV_MAGIC, .flags = __DEV_OUTPUT | __DEV_ERROR, .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, .write = __err_write, .close = NULL, }; syslinux-legacy-3.63+dfsg/com32/lib/sys/line_input.c0000664000175000017500000000443410777447272021041 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * line_input.c * * Line-oriented input discupline */ #include "file.h" #include #include ssize_t __line_input(struct file_info *fp, char *buf, size_t bufsize, ssize_t (*get_char)(struct file_info *, void *, size_t)) { size_t n = 0; char ch; int rv; ssize_t (* const Write)(struct file_info *, const void *, size_t) = fp->oop->write; for(;;) { rv = get_char(fp, &ch, 1); if ( rv != 1 ) { syslinux_idle(); continue; } switch ( ch ) { case '\n': /* Ignore incoming linefeed */ break; case '\r': *buf = '\n'; Write(fp, "\n", 1); return n+1; case '\b': if ( n > 0 ) { n--; buf--; Write(fp, "\b \b", 3); } break; case '\x15': /* Ctrl-U */ while ( n ) { n--; buf--; Write(fp, "\b \b", 3); } break; default: if ( n < bufsize-1 ) { *buf = ch; Write(fp, buf, 1); n++; buf++; } break; } } } syslinux-legacy-3.63+dfsg/com32/lib/sys/intcall.c0000664000175000017500000000024010777447272020310 0ustar evanevan/* * intcall.c */ #include void __intcall(uint8_t vector, const com32sys_t *ireg, com32sys_t *oreg) { __com32.cs_intcall(vector, ireg, oreg); } syslinux-legacy-3.63+dfsg/com32/lib/sys/screensize.c0000664000175000017500000000053610777447272021044 0ustar evanevan#include #include #include "file.h" int getscreensize(int fd, int *rows, int *cols) { struct file_info *fp = &__file_info[fd]; if ( fd >= NFILES || !fp->iop ) { errno = EBADF; return -1; } *rows = fp->o.rows; *cols = fp->o.cols; if (!rows || !cols) { errno = ENOTTY; return -1; } return 0; } syslinux-legacy-3.63+dfsg/com32/lib/creat.c0000664000175000017500000000027610777447272017153 0ustar evanevan/* * creat.c */ #include #include #include int creat(const char *pathname, mode_t mode) { return open(pathname, O_CREAT|O_WRONLY|O_TRUNC, mode); } syslinux-legacy-3.63+dfsg/com32/lib/com32.ld0000664000175000017500000000724710777447272017162 0ustar evanevan/* * Linker script for COM32 binaries using libcom32 */ /* Script for -z combreloc: combine and sort reloc sections */ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) EXTERN(_start) ENTRY(_start) SECTIONS { /* Read-only sections, merged into text segment: */ . = 0x101000; PROVIDE (__executable_start = .); .init : { KEEP (*(.init)) } =0x90909090 .text : { *(.text .stub .text.* .gnu.linkonce.t.*) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) } =0x90909090 .fini : { KEEP (*(.fini)) } =0x90909090 PROVIDE (__etext = .); PROVIDE (_etext = .); PROVIDE (etext = .); .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } /* Ensure the __preinit_array_start label is properly aligned. We could instead move the label definition inside the section, but the linker would then create the section even if it turns out to be empty, which isn't pretty. */ . = ALIGN(4); PROVIDE (__preinit_array_start = .); .preinit_array : { *(.preinit_array) } PROVIDE (__preinit_array_end = .); PROVIDE (__init_array_start = .); .init_array : { *(.init_array) } PROVIDE (__init_array_end = .); PROVIDE (__fini_array_start = .); .fini_array : { *(.fini_array) } PROVIDE (__fini_array_end = .); PROVIDE (__ctors_start = .); .ctors : { KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) } PROVIDE (__ctors_end = .); PROVIDE (__dtors_start = .); .dtors : { KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } PROVIDE (__dtors_end = .); /* Adjust the address for the data segment. Avoid mixing code and data within same 128-byte chunk. */ . = ALIGN(128); .data : { *(.data .data.* .gnu.linkonce.d.*) SORT(CONSTRUCTORS) } .data1 : { *(.data1) } _edata = .; PROVIDE (edata = .); __bss_start = .; .bss : { *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) /* Align here to ensure that the .bss section occupies space up to _end. Align after .bss to ensure correct alignment even if the .bss section disappears because there are no input sections. */ . = ALIGN(32 / 8); } . = ALIGN(32 / 8); _end = .; PROVIDE (end = .); /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions */ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2 */ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } /* DWARF 2 */ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions */ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } /DISCARD/ : { *(.note.GNU-stack) } } syslinux-legacy-3.63+dfsg/com32/lib/atol.c0000664000175000017500000000006610777447272017011 0ustar evanevan#define TYPE long #define NAME atol #include "atox.c" syslinux-legacy-3.63+dfsg/com32/lib/pci/0000775000175000017500000000000010777447344016457 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/lib/pci/writel.c0000664000175000017500000000013410777447272020127 0ustar evanevan#define TYPE uint32_t #define BWL(x) x ## l #define BIOSCALL 0xb10d #include "pci/writex.c" syslinux-legacy-3.63+dfsg/com32/lib/pci/pci.h0000664000175000017500000000047410777447272017410 0ustar evanevan/* * pci/pci.h * * Common internal header file */ #ifndef PCI_PCI_H #include #include extern enum pci_config_type __pci_cfg_type; extern uint32_t __pci_read_bios(uint32_t call, pciaddr_t a); extern void __pci_write_bios(uint32_t call, uint32_t v, pciaddr_t a); #endif /* PCI_PCI_H */ syslinux-legacy-3.63+dfsg/com32/lib/pci/readw.c0000664000175000017500000000013310777447272017722 0ustar evanevan#define TYPE uint16_t #define BWL(x) x ## w #define BIOSCALL 0xb109 #include "pci/readx.c" syslinux-legacy-3.63+dfsg/com32/lib/pci/writeb.c0000664000175000017500000000013310777447272020114 0ustar evanevan#define TYPE uint8_t #define BWL(x) x ## b #define BIOSCALL 0xb10b #include "pci/writex.c" syslinux-legacy-3.63+dfsg/com32/lib/pci/readb.c0000664000175000017500000000013210777447272017674 0ustar evanevan#define TYPE uint8_t #define BWL(x) x ## b #define BIOSCALL 0xb108 #include "pci/readx.c" syslinux-legacy-3.63+dfsg/com32/lib/pci/writebios.c0000664000175000017500000000051210777447272020630 0ustar evanevan#include #include #include "pci/pci.h" void __pci_write_bios(uint32_t call, uint32_t v, pciaddr_t a) { com32sys_t rs; memset(&rs, 0, sizeof rs); rs.eax.w[0] = call; rs.ebx.w[0] = a >> 8; /* bus:device:function */ rs.edi.b[0] = a; /* address:reg */ rs.ecx.l = v; __intcall(0x1a, &rs, NULL); } syslinux-legacy-3.63+dfsg/com32/lib/pci/readx.c0000664000175000017500000000164210777447272017731 0ustar evanevan#include "pci/pci.h" #include TYPE BWL(pci_read) (pciaddr_t a) { TYPE r; for (;;) { switch ( __pci_cfg_type ) { case PCI_CFG_AUTO: pci_set_config_type(PCI_CFG_AUTO); break; /* Try again */ case PCI_CFG_TYPE1: { uint32_t oldcf8; cli(); oldcf8 = inl(0xcf8); outl(a, 0xcf8); r = BWL(in) (0xcfc + (a & 3)); outl(oldcf8, 0xcf8); sti(); } return r; case PCI_CFG_TYPE2: { uint8_t oldcf8, oldcfa; if ( a & (0x10 << 11) ) return (TYPE)~0; /* Device 16-31 not supported */ cli(); oldcf8 = inb(0xcf8); oldcfa = inb(0xcfa); outb(0xf0 + ((a >> (8-1)) & 0x0e), 0xcf8); outb(a >> 16, 0xcfa); r = BWL(in) (0xc000 + ((a >> (11-8)) & 0xf00) + (a & 0xff)); outb(oldcf8, 0xcf8); outb(oldcfa, 0xcfa); sti(); } return r; case PCI_CFG_BIOS: return (TYPE) __pci_read_bios(BIOSCALL, a); default: return (TYPE)~0; } } } syslinux-legacy-3.63+dfsg/com32/lib/pci/cfgtype.c0000664000175000017500000000353110777447272020266 0ustar evanevan#include "pci/pci.h" #include #include enum pci_config_type __pci_cfg_type; static int type1_ok(void) { uint32_t oldcf8, newcf8; /* Test for Configuration Method #1 */ /* Note: XFree86 writes ~0 and expects to read back 0x80fffffc. Linux does this less severe test; go with Linux. */ cli(); outb(1, 0xcfb); /* For old Intel chipsets */ oldcf8 = inl(0xcf8); outl(0x80000000, 0xcf8); newcf8 = inl(0xcf8); outl(oldcf8, 0xcf8); sti(); return newcf8 == 0x80000000; } static int type2_ok(void) { uint8_t oldcf8, oldcfa; uint8_t cf8, cfa; /* Test for Configuration Method #2 */ /* CM#2 is hard to probe for, but let's do our best... */ cli(); outb(0, 0xcfb); /* For old Intel chipsets */ oldcf8 = inb(0xcf8); outb(0, 0xcf8); oldcfa = inb(0xcfa); outb(0, 0xcfa); cf8 = inb(0xcf8); cfa = inb(0xcfa); outb(oldcf8, 0xcf8); outb(oldcfa, 0xcfa); sti(); return cf8 == 0 && cfa == 0; } int pci_set_config_type(enum pci_config_type type) { static const com32sys_t ireg = { .eax.l = 0xb101, .edi.l = 0, .eflags.l = EFLAGS_CF, }; com32sys_t oreg; if ( type == PCI_CFG_AUTO ) { type = PCI_CFG_NONE; /* Try to detect PCI BIOS */ __intcall(0x1a, &ireg, &oreg); if ( !(oreg.eflags.l & EFLAGS_CF) && oreg.eax.b[1] == 0 && oreg.edx.l == 0x20494250 ) { /* PCI BIOS present. Use direct access if we know how to do it. */ if ( (oreg.eax.b[0] & 1) && type1_ok() ) type = PCI_CFG_TYPE1; else if ( (oreg.eax.b[0] & 2) && type2_ok() ) type = PCI_CFG_TYPE2; else type = PCI_CFG_BIOS; /* Use BIOS calls as fallback */ } else if ( type1_ok() ) { type = PCI_CFG_TYPE1; } else if ( type2_ok() ) { type = PCI_CFG_TYPE2; } else { type = PCI_CFG_NONE; /* Badness... */ } } return (__pci_cfg_type = type); } syslinux-legacy-3.63+dfsg/com32/lib/pci/writew.c0000664000175000017500000000013410777447272020142 0ustar evanevan#define TYPE uint16_t #define BWL(x) x ## w #define BIOSCALL 0xb10c #include "pci/writex.c" syslinux-legacy-3.63+dfsg/com32/lib/pci/readl.c0000664000175000017500000000013310777447272017707 0ustar evanevan#define TYPE uint32_t #define BWL(x) x ## l #define BIOSCALL 0xb10a #include "pci/readx.c" syslinux-legacy-3.63+dfsg/com32/lib/pci/readbios.c0000664000175000017500000000055710777447272020422 0ustar evanevan#include #include #include "pci/pci.h" uint32_t __pci_read_bios(uint32_t call, pciaddr_t a) { com32sys_t rs; memset(&rs, 0, sizeof rs); rs.eax.w[0] = call; rs.ebx.w[0] = a >> 8; /* bus:device:function */ rs.edi.b[0] = a; /* address:reg */ __intcall(0x1a, &rs, &rs); return (rs.eflags.l & EFLAGS_CF) ? ~(uint32_t)0 : rs.ecx.l; } syslinux-legacy-3.63+dfsg/com32/lib/pci/writex.c0000664000175000017500000000157410777447272020154 0ustar evanevan#include "pci/pci.h" void BWL(pci_write) (TYPE v, pciaddr_t a) { for (;;) { switch ( __pci_cfg_type ) { case PCI_CFG_AUTO: pci_set_config_type(PCI_CFG_AUTO); break; /* Try again */ case PCI_CFG_TYPE1: { uint32_t oldcf8; cli(); oldcf8 = inl(0xcf8); outl(a, 0xcf8); BWL(out) (v, 0xcfc + (a & 3)); outl(oldcf8, 0xcf8); sti(); } return; case PCI_CFG_TYPE2: { uint8_t oldcf8, oldcfa; if ( a & (0x10 << 11) ) return; /* Devices 16-31 not supported */ cli(); oldcf8 = inb(0xcf8); oldcfa = inb(0xcfa); outb(0xf0 + ((a >> (8-1)) & 0x0e), 0xcf8); outb(a >> 16, 0xcfa); BWL(out) (v, 0xc000 + ((a >> (11-8)) & 0xf00) + (a & 0xff)); outb(oldcf8, 0xcf8); outb(oldcfa, 0xcfa); sti(); } return; case PCI_CFG_BIOS: __pci_write_bios(BIOSCALL, v, a); return; default: return; } } } syslinux-legacy-3.63+dfsg/com32/lib/pci/scan.c0000664000175000017500000003054110777447272017552 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006-2007 Erwan Velu - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * pci.c * * A module to extract pci informations */ #include #include #include #include #include #include #include #include #ifdef DEBUG # define dprintf printf #else # define dprintf(...) ((void)0) #endif #define MAX_LINE 512 /* searching the next char that is not a space */ static char *skipspace(char *p) { while (*p && *p <= ' ') p++; return p; } /* removing any \n found in a string */ static void remove_eol(char *string) { int j = strlen(string); int i = 0; for(i = 0; i < j; i++) if(string[i] == '\n') string[i] = 0; } /* converting a hexa string into its numerical value*/ static int hex_to_int(char *hexa) { return strtoul(hexa, NULL, 16); } /* Try to match any pci device to the appropriate kernel module */ /* it uses the modules.pcimap from the boot device*/ void get_module_name_from_pci_ids(struct pci_device_list *pci_device_list) { char line[MAX_LINE]; char module_name[21]; // the module name field is 21 char long char delims[]=" "; // colums are separated by spaces char vendor_id[16]; char product_id[16]; char sub_vendor_id[16]; char sub_product_id[16]; FILE *f; int pci_dev; /* Intializing the linux_kernel_module for each pci device to "unknow" */ /* adding a pci_dev_info member if needed*/ for (pci_dev=0; pci_dev < pci_device_list->count; pci_dev++) { struct pci_device *pci_device = &(pci_device_list->pci_device[pci_dev]); /* initialize the pci_dev_info structure if it doesn't exist yet. */ if (! pci_device->pci_dev_info) { pci_device->pci_dev_info = calloc(1,sizeof *pci_device->pci_dev_info); if (!pci_device->pci_dev_info) { printf("Can't allocate memory\n"); return; } } strlcpy(pci_device->pci_dev_info->linux_kernel_module,"unknown",7); } /* Opening the modules.pcimap (ofa linux kernel) from the boot device*/ f=fopen("modules.pcimap","r"); if (!f) return; strcpy(vendor_id,"0000"); strcpy(product_id,"0000"); strcpy(sub_product_id,"0000"); strcpy(sub_vendor_id,"0000"); /* for each line we found in the modules.pcimap*/ while ( fgets(line, sizeof line, f) ) { /*skipping unecessary lines */ if ((line[0] == '#') || (line[0] == ' ') || (line[0] == 10)) continue; char *result = NULL; int field=0; /* looking for the next field */ result = strtok(line, delims); while( result != NULL ) { /* if the column is larger than 1 char */ /* multiple spaces generates some empty fields*/ if (strlen(result)>1) { switch (field) { case 0:strcpy(module_name,result); break; case 1:strcpy(vendor_id,result); break; case 2:strcpy(product_id,result); break; case 3:strcpy(sub_vendor_id,result); break; case 4:strcpy(sub_product_id,result); break; } field++; } /* Searching the next field*/ result = strtok( NULL, delims ); } /* if a pci_device match an entry, fill the linux_kernel_module with the appropriate kernel module */ for (pci_dev=0; pci_dev < pci_device_list->count; pci_dev++) { struct pci_device *pci_device = &pci_device_list->pci_device[pci_dev]; if (hex_to_int(vendor_id) == pci_device->vendor && hex_to_int(product_id) == pci_device->product && (hex_to_int(sub_product_id) & pci_device->sub_product) == pci_device->sub_product && (hex_to_int(sub_vendor_id) & pci_device->sub_vendor) == pci_device->sub_vendor) strcpy(pci_device->pci_dev_info->linux_kernel_module, module_name); } } fclose(f); } /* Try to match any pci device to the appropriate vendor and product name */ /* it uses the pci.ids from the boot device*/ void get_name_from_pci_ids(struct pci_device_list *pci_device_list) { char line[MAX_LINE]; char vendor[255]; char vendor_id[5]; char product[255]; char product_id[5]; char sub_product_id[5]; char sub_vendor_id[5]; FILE *f; int pci_dev; /* Intializing the vendor/product name for each pci device to "unknow" */ /* adding a pci_dev_info member if needed*/ for (pci_dev=0; pci_dev < pci_device_list->count; pci_dev++) { struct pci_device *pci_device = &pci_device_list->pci_device[pci_dev]; /* initialize the pci_dev_info structure if it doesn't exist yet. */ if (! pci_device->pci_dev_info) { pci_device->pci_dev_info = calloc(1,sizeof *pci_device->pci_dev_info); if (!pci_device->pci_dev_info) { printf("Can't allocate memory\n"); return; } } strlcpy(pci_device->pci_dev_info->vendor_name,"unknown",7); strlcpy(pci_device->pci_dev_info->product_name,"unknown",7); } /* Opening the pci.ids from the boot device*/ f=fopen("pci.ids","r"); if (!f) return; strcpy(vendor_id,"0000"); strcpy(product_id,"0000"); strcpy(sub_product_id,"0000"); strcpy(sub_vendor_id,"0000"); /* for each line we found in the pci.ids*/ while ( fgets(line, sizeof line, f) ) { /* Skipping uncessary lines */ if ((line[0] == '#') || (line[0] == ' ') || (line[0] == 'C') || (line[0] == 10)) continue; /* If the line doesn't start with a tab, it means that's a vendor id */ if (line[0] != '\t') { /* the 4th first chars are the vendor_id */ strlcpy(vendor_id,line,4); /* the vendor name is the next field*/ vendor_id[4]=0; strlcpy(vendor,skipspace(strstr(line," ")),255); remove_eol(vendor); /* init product_id, sub_product and sub_vendor */ strcpy(product_id,"0000"); strcpy(sub_product_id,"0000"); strcpy(sub_vendor_id,"0000"); /* ffff is an invalid vendor id */ if (strstr(vendor_id,"ffff")) break; /* assign the vendor_name to any matching pci device*/ for (pci_dev=0; pci_dev < pci_device_list->count; pci_dev++) { struct pci_device *pci_device = &pci_device_list->pci_device[pci_dev]; if (hex_to_int(vendor_id) == pci_device->vendor) strlcpy(pci_device->pci_dev_info->vendor_name,vendor,255); } /* if we have a tab + a char, it means this is a product id */ } else if ((line[0] == '\t') && (line[1] != '\t')) { /* the product name the second field */ strlcpy(product,skipspace(strstr(line," ")),255); remove_eol(product); /* the product id is first field */ strlcpy(product_id,&line[1],4); product_id[4]=0; /* init sub_product and sub_vendor */ strcpy(sub_product_id,"0000"); strcpy(sub_vendor_id,"0000"); /* assign the product_name to any matching pci device*/ for (pci_dev=0; pci_dev < pci_device_list->count; pci_dev++) { struct pci_device *pci_device = &pci_device_list->pci_device[pci_dev]; if (hex_to_int(vendor_id) == pci_device->vendor && hex_to_int(product_id) == pci_device->product) strlcpy(pci_device->pci_dev_info->product_name,product,255); } /* if we have two tabs, it means this is a sub product */ } else if ((line[0] == '\t') && (line[1] == '\t')) { /* the product name is last field */ strlcpy(product,skipspace(strstr(line," ")),255); strlcpy(product,skipspace(strstr(product," ")),255); remove_eol(product); /* the sub_vendor id is first field */ strlcpy(sub_vendor_id,&line[2],4); sub_vendor_id[4]=0; /* the sub_vendor id is second field */ strlcpy(sub_product_id,&line[7],4); sub_product_id[4]=0; /* assign the product_name to any matching pci device*/ for (pci_dev=0; pci_dev < pci_device_list->count; pci_dev++) { struct pci_device *pci_device = &pci_device_list->pci_device[pci_dev]; if (hex_to_int(vendor_id) == pci_device->vendor && hex_to_int(product_id) == pci_device->product && hex_to_int(sub_product_id) == pci_device->sub_product && hex_to_int(sub_vendor_id) == pci_device->sub_vendor) strlcpy(pci_device->pci_dev_info->product_name,product,255); } } } fclose(f); } /* searching if any pcidevice match our query */ struct match *find_pci_device(struct pci_device_list * pci_device_list, struct match *list) { int pci_dev; uint32_t did, sid; struct match *m; /* for all matches we have to search */ for (m = list; m; m = m->next) { /* for each pci device we know */ for (pci_dev = 0; pci_dev < pci_device_list->count; pci_dev++) { struct pci_device *pci_device = &pci_device_list->pci_device[pci_dev]; /* sid & did are the easiest way to compare devices */ /* they are made of vendor/product subvendor/subproduct ids */ sid = ((pci_device->sub_product) << 16 | (pci_device-> sub_vendor)); did = ((pci_device->product << 16) | (pci_device->vendor)); /*if the current device match */ if (((did ^ m->did) & m->did_mask) == 0 && ((sid ^ m->sid) & m->sid_mask) == 0 && pci_device->revision >= m->rid_min && pci_device->revision <= m->rid_max) { dprintf("PCI Match: Vendor=%04x Product=%04x Sub_vendor=%04x Sub_Product=%04x Release=%02x\n", pci_device->vendor, pci_device->product, pci_device->sub_vendor, pci_device->sub_product, pci_device->revision); /* returning the matched pci device */ return m; } } } return NULL; } /* scanning the pci bus to find pci devices */ int pci_scan(struct pci_bus_list * pci_bus_list, struct pci_device_list * pci_device_list) { unsigned int bus, dev, func, maxfunc; uint32_t did, sid; uint8_t hdrtype, rid; pciaddr_t a; int cfgtype; pci_device_list->count = 0; #ifdef DEBUG outl(~0, 0xcf8); printf("Poking at port CF8 = %#08x\n", inl(0xcf8)); outl(0, 0xcf8); #endif cfgtype = pci_set_config_type(PCI_CFG_AUTO); (void)cfgtype; dprintf("PCI configuration type %d\n", cfgtype); dprintf("Scanning PCI Buses\n"); /* We try to detect 255 buses */ for (bus = 0; bus <= MAX_PCI_BUSES; bus++) { dprintf("Probing bus 0x%02x... \n", bus); pci_bus_list->pci_bus[bus].id = bus; pci_bus_list->pci_bus[bus].pci_device_count = 0; pci_bus_list->count = 0;; for (dev = 0; dev <= 0x1f; dev++) { maxfunc = 0; for (func = 0; func <= maxfunc; func++) { a = pci_mkaddr(bus, dev, func, 0); did = pci_readl(a); if (did == 0xffffffff || did == 0xffff0000 || did == 0x0000ffff || did == 0x00000000) continue; hdrtype = pci_readb(a + 0x0e); if (hdrtype & 0x80) maxfunc = 7; /* Multifunction device */ rid = pci_readb(a + 0x08); sid = pci_readl(a + 0x2c); struct pci_device *pci_device = &pci_device_list-> pci_device[pci_device_list->count]; pci_device->product = did >> 16; pci_device->sub_product = sid >> 16; pci_device->vendor = (did << 16) >> 16; pci_device->sub_vendor = (sid << 16) >> 16; pci_device->revision = rid; pci_device_list->count++; dprintf ("Scanning: BUS %02x DID %08x (%04x:%04x) SID %08x RID %02x\n", bus, did, did >> 16, (did << 16) >> 16, sid, rid); /* Adding the detected pci device to the bus */ pci_bus_list->pci_bus[bus]. pci_device[pci_bus_list->pci_bus[bus]. pci_device_count] = pci_device; pci_bus_list->pci_bus[bus].pci_device_count++; } } } /* Detecting pci buses that have pci devices connected */ for (bus = 0; bus <= 0xff; bus++) { if (pci_bus_list->pci_bus[bus].pci_device_count > 0) { pci_bus_list->count++; } } return 0; } syslinux-legacy-3.63+dfsg/com32/lib/MCONFIG0000664000175000017500000000364210777447272016716 0ustar evanevan# -*- makefile -*- TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if gcc $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \ then echo $(1); else echo $(2); fi; rm -f $$tmpf) GCCOPT := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,) CC = gcc LD = ld INCLUDE = -I. AR = ar RANLIB = ranlib NM = nm PERL = perl STRIP = strip --strip-all -R .comment -R .note OBJCOPY = objcopy # zlib and libpng configuration flags LIBFLAGS = -DDYNAMIC_CRC_TABLE -DPNG_NO_CONSOLE_IO \ -DPNG_NO_WRITE_SUPPORTED \ -DPNG_NO_MNG_FEATURES \ -DPNG_NO_READ_tIME -DPNG_NO_WRITE_tIME # We need some features in libpng which apparently aren't available in the # fixed-point versions. It's OK, because we have to have a non-graphical # fallback anyway, just use that on old machines... # LIBFLAGS += -DPNG_NO_FLOATING_POINT_SUPPORTED REQFLAGS = $(GCCOPT) -g -mregparm=3 -DREGPARM=3 -D__COM32__ \ -nostdinc -iwithprefix include -I. -I./sys -I../include OPTFLAGS = -Os -march=i386 -falign-functions=0 -falign-jumps=0 \ -falign-labels=0 -ffast-math -fomit-frame-pointer WARNFLAGS = -W -Wall -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Winline CFLAGS = -Wp,-MT,$@,-MD,$(dir $@).$(notdir $@).d $(OPTFLAGS) \ $(REQFLAGS) $(WARNFLAGS) $(LIBFLAGS) LDFLAGS = -m elf32_i386 .SUFFIXES: .c .o .a .so .lo .i .S .s .ls .ss .lss % : %.c # Cancel default rule % : %.S .c.o: $(CC) $(CFLAGS) -c -o $@ $< .c.i: $(CC) $(CFLAGS) -E -o $@ $< .c.s: $(CC) $(CFLAGS) -S -o $@ $< .S.o: $(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $< .S.s: $(CC) $(CFLAGS) -D__ASSEMBLY__ -E -o $@ $< .S.lo: $(CC) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -c -o $@ $< .S.ls: $(CC) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -E -o $@ $< .s.o: $(CC) $(CFLAGS) -x assembler -c -o $@ $< .ls.lo: $(CC) $(CFLAGS) $(SOFLAGS) -x assembler -c -o $@ $< .c.lo: $(CC) $(CFLAGS) $(SOFLAGS) -c -o $@ $< .c.ls: $(CC) $(CFLAGS) $(SOFLAGS) -S -o $@ $< syslinux-legacy-3.63+dfsg/com32/lib/jpeg/0000775000175000017500000000000010777447344016631 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/lib/jpeg/rgba32.c0000664000175000017500000002213210777447272020055 0ustar evanevan/* * Small jpeg decoder library * * Copyright (c) 2006, Luc Saillard * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include "tinyjpeg.h" #include "tinyjpeg-internal.h" /******************************************************************************* * * Colorspace conversion routine * * * Note: * YCbCr is defined per CCIR 601-1, except that Cb and Cr are * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. * The conversion equations to be implemented are therefore * R = Y + 1.40200 * Cr * G = Y - 0.34414 * Cb - 0.71414 * Cr * B = Y + 1.77200 * Cb * ******************************************************************************/ static unsigned char clamp(int i) { if (i<0) return 0; else if (i>255) return 255; else return i; } /** * YCrCb -> RGBA32 (1x1) * .---. * | 1 | * `---' */ static void YCrCB_to_RGBA32_1x1(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = priv->bytes_per_row[0] - 8*4; for (i=0; i<8; i++) { for (j=0;j<8;j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b, a; y = (*Y++) << SCALEBITS; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); a = 255; *p++ = a; } p += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } /** * YCrCb -> RGBA32 (2x1) * .-------. * | 1 | 2 | * `-------' */ static void YCrCB_to_RGBA32_2x1(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = priv->bytes_per_row[0] - 16*4; for (i=0; i<8; i++) { for (j=0; j<8; j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b, a; y = (*Y++) << SCALEBITS; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); a = 255; *p++ = a; y = (*Y++) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); a = 255; *p++ = a; } p += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } /** * YCrCb -> RGBA32 (1x2) * .---. * | 1 | * |---| * | 2 | * `---' */ static void YCrCB_to_RGBA32_1x2(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p, *p2; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; p2 = priv->plane[0] + priv->bytes_per_row[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = 2*priv->bytes_per_row[0] - 8*4; for (i=0; i<8; i++) { for (j=0; j<8; j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b, a; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; y = (*Y++) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); a = 255; *p++ = a; y = (Y[8-1]) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); a = 255; *p2++ = a; } Y += 8; p += offset_to_next_row; p2 += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } /** * YCrCb -> RGBA32 (2x2) * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */ static void YCrCB_to_RGBA32_2x2(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p, *p2; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; p2 = priv->plane[0] + priv->bytes_per_row[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = 2*priv->bytes_per_row[0] - 16*4; for (i=0; i<8; i++) { for (j=0;j<8;j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b, a; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; y = (*Y++) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); a = 255; *p++ = a; y = (*Y++) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); a = 255; *p++ = a; y = (Y[16-2]) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); a = 255; *p2++ = a; y = (Y[16-1]) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); a = 255; *p2++ = a; } Y += 16; p += offset_to_next_row; p2 += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } static int initialize_rgba32(struct jdec_private *priv, unsigned int *bytes_per_blocklines, unsigned int *bytes_per_mcu) { if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 4); if (!priv->bytes_per_row[0]) priv->bytes_per_row[0] = priv->width * 4; bytes_per_blocklines[0] = priv->bytes_per_row[0]; bytes_per_mcu[0] = 4*8; return !priv->components[0]; } static const struct tinyjpeg_colorspace format_rgba32 = { { YCrCB_to_RGBA32_1x1, YCrCB_to_RGBA32_1x2, YCrCB_to_RGBA32_2x1, YCrCB_to_RGBA32_2x2, }, tinyjpeg_decode_mcu_3comp_table, initialize_rgba32 }; const tinyjpeg_colorspace_t TINYJPEG_FMT_RGBA32 = &format_rgba32; syslinux-legacy-3.63+dfsg/com32/lib/jpeg/tinyjpeg-internal.h0000664000175000017500000001317210777447272022451 0ustar evanevan/* * Small jpeg decoder library (Internal header) * * Copyright (c) 2006, Luc Saillard * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __TINYJPEG_INTERNAL_H_ #define __TINYJPEG_INTERNAL_H_ struct jdec_private; #define HUFFMAN_HASH_NBITS 9 #define HUFFMAN_HASH_SIZE (1UL<0) { if (value & (1UL<=0) { bitstr[j++] = (value & (1UL< * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include "tinyjpeg.h" #include "tinyjpeg-internal.h" /******************************************************************************* * * Colorspace conversion routine * * * Note: * YCbCr is defined per CCIR 601-1, except that Cb and Cr are * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. * The conversion equations to be implemented are therefore * R = Y + 1.40200 * Cr * G = Y - 0.34414 * Cb - 0.71414 * Cr * B = Y + 1.77200 * Cb * ******************************************************************************/ static unsigned char clamp(int i) { if (i<0) return 0; else if (i>255) return 255; else return i; } /** * YCrCb -> RGB24 (1x1) * .---. * | 1 | * `---' */ static void YCrCB_to_RGB24_1x1(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = priv->bytes_per_row[0] - 8*3; for (i=0; i<8; i++) { for (j=0;j<8;j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b; y = (*Y++) << SCALEBITS; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); } p += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } /** * YCrCb -> RGB24 (2x1) * .-------. * | 1 | 2 | * `-------' */ static void YCrCB_to_RGB24_2x1(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = priv->bytes_per_row[0] - 16*3; for (i=0; i<8; i++) { for (j=0; j<8; j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b; y = (*Y++) << SCALEBITS; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); y = (*Y++) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); } p += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } /** * YCrCb -> RGB24 (1x2) * .---. * | 1 | * |---| * | 2 | * `---' */ static void YCrCB_to_RGB24_1x2(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p, *p2; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; p2 = priv->plane[0] + priv->bytes_per_row[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = 2*priv->bytes_per_row[0] - 8*3; for (i=0; i<8; i++) { for (j=0; j<8; j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; y = (*Y++) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); y = (Y[8-1]) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); } Y += 8; p += offset_to_next_row; p2 += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } /** * YCrCb -> RGB24 (2x2) * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */ static void YCrCB_to_RGB24_2x2(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p, *p2; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; p2 = priv->plane[0] + priv->bytes_per_row[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = 2*priv->bytes_per_row[0] - 16*3; for (i=0; i<8; i++) { for (j=0;j<8;j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; y = (*Y++) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); y = (*Y++) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); y = (Y[16-2]) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); y = (Y[16-1]) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); } Y += 16; p += offset_to_next_row; p2 += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } static int initialize_rgb24(struct jdec_private *priv, unsigned int *bytes_per_blocklines, unsigned int *bytes_per_mcu) { if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3); if (!priv->bytes_per_row[0]) priv->bytes_per_row[0] = priv->width * 3; bytes_per_blocklines[0] = priv->bytes_per_row[0]; bytes_per_mcu[0] = 3*8; return !priv->components[0]; } static const struct tinyjpeg_colorspace format_rgb24 = { { YCrCB_to_RGB24_1x1, YCrCB_to_RGB24_1x2, YCrCB_to_RGB24_2x1, YCrCB_to_RGB24_2x2, }, tinyjpeg_decode_mcu_3comp_table, initialize_rgb24 }; const tinyjpeg_colorspace_t TINYJPEG_FMT_RGB24 = &format_rgb24; syslinux-legacy-3.63+dfsg/com32/lib/jpeg/decode3.c0000664000175000017500000001023010777447272020277 0ustar evanevan/* * Small jpeg decoder library * * Copyright (c) 2006, Luc Saillard * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include "tinyjpeg.h" #include "tinyjpeg-internal.h" /* * Decode all the 3 components for 1x1 */ static void decode_MCU_1x1_3planes(struct jdec_private *priv) { // Y tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 8); // Cb tinyjpeg_process_Huffman_data_unit(priv, cCb); IDCT(&priv->component_infos[cCb], priv->Cb, 8); // Cr tinyjpeg_process_Huffman_data_unit(priv, cCr); IDCT(&priv->component_infos[cCr], priv->Cr, 8); } /* * Decode a 2x1 * .-------. * | 1 | 2 | * `-------' */ static void decode_MCU_2x1_3planes(struct jdec_private *priv) { // Y tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 16); tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+8, 16); // Cb tinyjpeg_process_Huffman_data_unit(priv, cCb); IDCT(&priv->component_infos[cCb], priv->Cb, 8); // Cr tinyjpeg_process_Huffman_data_unit(priv, cCr); IDCT(&priv->component_infos[cCr], priv->Cr, 8); } /* * Decode a 2x2 * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */ static void decode_MCU_2x2_3planes(struct jdec_private *priv) { // Y tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 16); tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+8, 16); tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+64*2, 16); tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16); // Cb tinyjpeg_process_Huffman_data_unit(priv, cCb); IDCT(&priv->component_infos[cCb], priv->Cb, 8); // Cr tinyjpeg_process_Huffman_data_unit(priv, cCr); IDCT(&priv->component_infos[cCr], priv->Cr, 8); } /* * Decode a 1x2 mcu * .---. * | 1 | * |---| * | 2 | * `---' */ static void decode_MCU_1x2_3planes(struct jdec_private *priv) { // Y tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 8); tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+64, 8); // Cb tinyjpeg_process_Huffman_data_unit(priv, cCb); IDCT(&priv->component_infos[cCb], priv->Cb, 8); // Cr tinyjpeg_process_Huffman_data_unit(priv, cCr); IDCT(&priv->component_infos[cCr], priv->Cr, 8); } const decode_MCU_fct tinyjpeg_decode_mcu_3comp_table[4] = { decode_MCU_1x1_3planes, decode_MCU_1x2_3planes, decode_MCU_2x1_3planes, decode_MCU_2x2_3planes, }; syslinux-legacy-3.63+dfsg/com32/lib/jpeg/tinyjpeg.c0000664000175000017500000006455610777447272020646 0ustar evanevan/* * Small jpeg decoder library * * Copyright (c) 2006, Luc Saillard * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include "tinyjpeg.h" #include "tinyjpeg-internal.h" /* Global variable to return the last error found while deconding */ static char error_string[256]; static const unsigned char zigzag[64] = { 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63 }; /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ /* IMPORTANT: these are only valid for 8-bit data precision! */ static const unsigned char bits_dc_luminance[17] = { 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; static const unsigned char val_dc_luminance[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static const unsigned char bits_dc_chrominance[17] = { 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; static const unsigned char val_dc_chrominance[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static const unsigned char bits_ac_luminance[17] = { 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; static const unsigned char val_ac_luminance[] = { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa }; static const unsigned char bits_ac_chrominance[17] = { 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; static const unsigned char val_ac_chrominance[] = { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa }; /* * 4 functions to manage the stream * * fill_nbits: put at least nbits in the reservoir of bits. * But convert any 0xff,0x00 into 0xff * get_nbits: read nbits from the stream, and put it in result, * bits is removed from the stream and the reservoir is filled * automaticaly. The result is signed according to the number of * bits. * look_nbits: read nbits from the stream without marking as read. * skip_nbits: read nbits from the stream but do not return the result. * * stream: current pointer in the jpeg data (read bytes per bytes) * nbits_in_reservoir: number of bits filled into the reservoir * reservoir: register that contains bits information. Only nbits_in_reservoir * is valid. * nbits_in_reservoir * <-- 17 bits --> * Ex: 0000 0000 1010 0000 1111 0000 <== reservoir * ^ * bit 1 * To get two bits from this example * result = (reservoir >> 15) & 3 * */ #define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \ while (nbits_in_reservoir>(nbits_in_reservoir-(nbits_wanted))); \ nbits_in_reservoir -= (nbits_wanted); \ reservoir &= ((1U<>(nbits_in_reservoir-(nbits_wanted))); \ } while(0); #define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \ fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \ nbits_in_reservoir -= (nbits_wanted); \ reservoir &= ((1U<reservoir, priv->nbits_in_reservoir, priv->stream, HUFFMAN_HASH_NBITS, hcode); value = huffman_table->lookup[hcode]; if (value>=0) { int code_size = huffman_table->code_size[value]; skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, code_size); return value; } /* Decode more bits each time ... */ for (extra_nbits=0; extra_nbits<16-HUFFMAN_HASH_NBITS; extra_nbits++) { nbits = HUFFMAN_HASH_NBITS + 1 + extra_nbits; look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits, hcode); slowtable = huffman_table->slowtable[extra_nbits]; /* Search if the code is in this array */ while (slowtable[0]) { if (slowtable[0] == hcode) { skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits); return slowtable[1]; } slowtable+=2; } } return 0; } /** * * Decode a single block that contains the DCT coefficients. * The table coefficients is already dezigzaged at the end of the operation. * */ void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component) { unsigned char j; int huff_code; unsigned char size_val, count_0; struct component *c = &priv->component_infos[component]; short int DCT[64]; /* Initialize the DCT coef table */ memset(DCT, 0, sizeof(DCT)); /* DC coefficient decoding */ huff_code = get_next_huffman_code(priv, c->DC_table); if (huff_code) { get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, huff_code, DCT[0]); DCT[0] += c->previous_DC; c->previous_DC = DCT[0]; } else { DCT[0] = c->previous_DC; } /* AC coefficient decoding */ j = 1; while (j<64) { huff_code = get_next_huffman_code(priv, c->AC_table); size_val = huff_code & 0xF; count_0 = huff_code >> 4; if (size_val == 0) { /* RLE */ if (count_0 == 0) break; /* EOB found, go out */ else if (count_0 == 0xF) j += 16; /* skip 16 zeros */ } else { j += count_0; /* skip count_0 zeroes */ get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, size_val, DCT[j]); j++; } } for (j = 0; j < 64; j++) c->DCT[j] = DCT[zigzag[j]]; } /* * Takes two array of bits, and build the huffman table for size, and code * * lookup will return the symbol if the code is less or equal than HUFFMAN_HASH_NBITS. * code_size will be used to known how many bits this symbol is encoded. * slowtable will be used when the first lookup didn't give the result. */ static void build_huffman_table(const unsigned char *bits, const unsigned char *vals, struct huffman_table *table) { unsigned int i, j, code, code_size, val, nbits; unsigned char huffsize[257], *hz; unsigned int huffcode[257], *hc; int next_free_entry; /* * Build a temp array * huffsize[X] => numbers of bits to write vals[X] */ hz = huffsize; for (i=1; i<=16; i++) { for (j=1; j<=bits[i]; j++) *hz++ = i; } *hz = 0; memset(table->lookup, 0xff, sizeof(table->lookup)); for (i=0; i<(16-HUFFMAN_HASH_NBITS); i++) table->slowtable[i][0] = 0; /* Build a temp array * huffcode[X] => code used to write vals[X] */ code = 0; hc = huffcode; hz = huffsize; nbits = *hz; while (*hz) { while (*hz == nbits) { *hc++ = code++; hz++; } code <<= 1; nbits++; } /* * Build the lookup table, and the slowtable if needed. */ next_free_entry = -1; for (i=0; huffsize[i]; i++) { val = vals[i]; code = huffcode[i]; code_size = huffsize[i]; trace("val=%2.2x code=%8.8x codesize=%2.2d\n", i, code, code_size); table->code_size[val] = code_size; if (code_size <= HUFFMAN_HASH_NBITS) { /* * Good: val can be put in the lookup table, so fill all value of this * column with value val */ int repeat = 1UL<<(HUFFMAN_HASH_NBITS - code_size); code <<= HUFFMAN_HASH_NBITS - code_size; while ( repeat-- ) table->lookup[code++] = val; } else { /* Perhaps sorting the array will be an optimization */ uint16_t *slowtable = table->slowtable[code_size-HUFFMAN_HASH_NBITS-1]; while(slowtable[0]) slowtable+=2; slowtable[0] = code; slowtable[1] = val; slowtable[2] = 0; /* TODO: NEED TO CHECK FOR AN OVERFLOW OF THE TABLE */ } } } static void build_default_huffman_tables(struct jdec_private *priv) { if ( (priv->flags & TINYJPEG_FLAGS_MJPEG_TABLE) && priv->default_huffman_table_initialized) return; build_huffman_table(bits_dc_luminance, val_dc_luminance, &priv->HTDC[0]); build_huffman_table(bits_ac_luminance, val_ac_luminance, &priv->HTAC[0]); build_huffman_table(bits_dc_chrominance, val_dc_chrominance, &priv->HTDC[1]); build_huffman_table(bits_ac_chrominance, val_ac_chrominance, &priv->HTAC[1]); priv->default_huffman_table_initialized = 1; } /******************************************************************************* * * Colorspace conversion routine * * * Note: * YCbCr is defined per CCIR 601-1, except that Cb and Cr are * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. * The conversion equations to be implemented are therefore * R = Y + 1.40200 * Cr * G = Y - 0.34414 * Cb - 0.71414 * Cr * B = Y + 1.77200 * Cb * ******************************************************************************/ static void print_SOF(const unsigned char *stream) { int width, height, nr_components, precision; #if DEBUG const char *nr_components_to_string[] = { "????", "Grayscale", "????", "YCbCr", "CYMK" }; #endif precision = stream[2]; height = be16_to_cpu(stream+3); width = be16_to_cpu(stream+5); nr_components = stream[7]; trace("> SOF marker\n"); trace("Size:%dx%d nr_components:%d (%s) precision:%d\n", width, height, nr_components, nr_components_to_string[nr_components], precision); } /******************************************************************************* * * JPEG/JFIF Parsing functions * * Note: only a small subset of the jpeg file format is supported. No markers, * nor progressive stream is supported. * ******************************************************************************/ static void build_quantization_table(float *qtable, const unsigned char *ref_table) { /* Taken from libjpeg. Copyright Independent JPEG Group's LLM idct. * For float AA&N IDCT method, divisors are equal to quantization * coefficients scaled by scalefactor[row]*scalefactor[col], where * scalefactor[0] = 1 * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 * We apply a further scale factor of 8. * What's actually stored is 1/divisor so that the inner loop can * use a multiplication rather than a division. */ int i, j; static const double aanscalefactor[8] = { 1.0, 1.387039845, 1.306562965, 1.175875602, 1.0, 0.785694958, 0.541196100, 0.275899379 }; const unsigned char *zz = zigzag; for (i=0; i<8; i++) { for (j=0; j<8; j++) { *qtable++ = ref_table[*zz++] * aanscalefactor[i] * aanscalefactor[j]; } } } static int parse_DQT(struct jdec_private *priv, const unsigned char *stream) { int length, qi; float *table; trace("> DQT marker\n"); length = be16_to_cpu(stream) - 2; stream += 2; /* Skip length */ while (length>0) { qi = *stream++; #if SANITY_CHECK if (qi>>4) error("16 bits quantization table is not supported\n"); if (qi>4) error("No more 4 quantization table is supported (got %d)\n", qi); #endif table = priv->Q_tables[qi]; build_quantization_table(table, stream); stream += 64; length -= 65; } return 0; } static int parse_SOF(struct jdec_private *priv, const unsigned char *stream) { int i, width, height, nr_components, cid, sampling_factor; int Q_table; struct component *c; print_SOF(stream); height = be16_to_cpu(stream+3); width = be16_to_cpu(stream+5); nr_components = stream[7]; #if SANITY_CHECK if (stream[2] != 8) error("Precision other than 8 is not supported\n"); if (width>2048 || height>2048) error("Width and Height (%dx%d) seems suspicious\n", width, height); if (nr_components != 3) error("We only support YUV images\n"); if (height%16) error("Height need to be a multiple of 16 (current height is %d)\n", height); if (width%16) error("Width need to be a multiple of 16 (current Width is %d)\n", width); #endif stream += 8; for (i=0; icomponent_infos[cid]; c->Vfactor = sampling_factor&0xf; c->Hfactor = sampling_factor>>4; c->Q_table = priv->Q_tables[Q_table]; trace("Component:%d factor:%dx%d Quantization table:%d\n", cid, c->Hfactor, c->Hfactor, Q_table ); } priv->width = width; priv->height = height; return 0; } static int parse_SOS(struct jdec_private *priv, const unsigned char *stream) { unsigned int i, cid, table; unsigned int nr_components = stream[2]; trace("> SOS marker\n"); #if SANITY_CHECK if (nr_components != 3) error("We only support YCbCr image\n"); #endif stream += 3; for (i=0;i=4) error("We do not support more than 2 AC Huffman table\n"); if ((table>>4)>=4) error("We do not support more than 2 DC Huffman table\n"); trace("ComponentId:%d tableAC:%d tableDC:%d\n", cid, table&0xf, table>>4); #endif priv->component_infos[cid].AC_table = &priv->HTAC[table&0xf]; priv->component_infos[cid].DC_table = &priv->HTDC[table>>4]; } priv->stream = stream+3; return 0; } static int parse_DHT(struct jdec_private *priv, const unsigned char *stream) { unsigned int count, i; unsigned char huff_bits[17]; int length, index; length = be16_to_cpu(stream) - 2; stream += 2; /* Skip length */ trace("> DHT marker (length=%d)\n", length); while (length>0) { index = *stream++; /* We need to calculate the number of bytes 'vals' will takes */ huff_bits[0] = 0; count = 0; for (i=1; i<17; i++) { huff_bits[i] = *stream++; count += huff_bits[i]; } #if SANITY_CHECK if (count > 1024) error("No more than 1024 bytes is allowed to describe a huffman table"); if ( (index &0xf) >= HUFFMAN_TABLES) error("No mode than %d Huffman tables is supported\n", HUFFMAN_TABLES); trace("Huffman table %s n%d\n", (index&0xf0)?"AC":"DC", index&0xf); trace("Length of the table: %d\n", count); #endif if (index & 0xf0 ) build_huffman_table(huff_bits, stream, &priv->HTAC[index&0xf]); else build_huffman_table(huff_bits, stream, &priv->HTDC[index&0xf]); length -= 1; length -= 16; length -= count; } trace("< DHT marker\n"); return 0; } static void resync(struct jdec_private *priv) { int i; /* Init DC coefficients */ for (i=0; icomponent_infos[i].previous_DC = 0; priv->reservoir = 0; priv->nbits_in_reservoir = 0; } static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream) { int chuck_len; int marker; int sos_marker_found = 0; int dht_marker_found = 0; const unsigned char *next_chunck; /* Parse marker */ while (!sos_marker_found) { if (*stream++ != 0xff) goto bogus_jpeg_format; /* Skip any padding ff byte (this is normal) */ while (*stream == 0xff) stream++; marker = *stream++; chuck_len = be16_to_cpu(stream); next_chunck = stream + chuck_len; switch (marker) { case SOF: if (parse_SOF(priv, stream) < 0) return -1; break; case DQT: if (parse_DQT(priv, stream) < 0) return -1; break; case SOS: if (parse_SOS(priv, stream) < 0) return -1; sos_marker_found = 1; break; case DHT: if (parse_DHT(priv, stream) < 0) return -1; dht_marker_found = 1; break; default: trace("> Unknown marker %2.2x\n", marker); break; } stream = next_chunck; } if (!dht_marker_found) { trace("No Huffman table loaded, using the default one\n"); build_default_huffman_tables(priv); } #ifdef SANITY_CHECK if ( (priv->component_infos[cY].Hfactor < priv->component_infos[cCb].Hfactor) || (priv->component_infos[cY].Hfactor < priv->component_infos[cCr].Hfactor)) error("Horizontal sampling factor for Y should be greater than horitontal sampling factor for Cb or Cr\n"); if ( (priv->component_infos[cY].Vfactor < priv->component_infos[cCb].Vfactor) || (priv->component_infos[cY].Vfactor < priv->component_infos[cCr].Vfactor)) error("Vertical sampling factor for Y should be greater than vertical sampling factor for Cb or Cr\n"); if ( (priv->component_infos[cCb].Hfactor!=1) || (priv->component_infos[cCr].Hfactor!=1) || (priv->component_infos[cCb].Vfactor!=1) || (priv->component_infos[cCr].Vfactor!=1)) error("Sampling other than 1x1 for Cr and Cb is not supported"); #endif return 0; bogus_jpeg_format: trace("Bogus jpeg format\n"); return -1; } /******************************************************************************* * * Functions exported of the library. * * Note: Some applications can access directly to internal pointer of the * structure. It's is not recommended, but if you have many images to * uncompress with the same parameters, some functions can be called to speedup * the decoding. * ******************************************************************************/ /** * Allocate a new tinyjpeg decoder object. * * Before calling any other functions, an object need to be called. */ struct jdec_private *tinyjpeg_init(void) { struct jdec_private *priv; priv = (struct jdec_private *)calloc(1, sizeof(struct jdec_private)); if (priv == NULL) return NULL; return priv; } /** * Free a tinyjpeg object. * * No others function can be called after this one. */ void tinyjpeg_free(struct jdec_private *priv) { int i; for (i=0; icomponents[i]) free(priv->components[i]); priv->components[i] = NULL; } free(priv); } /** * Initialize the tinyjpeg object and prepare the decoding of the stream. * * Check if the jpeg can be decoded with this jpeg decoder. * Fill some table used for preprocessing. */ int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size) { int ret; /* Identify the file */ if ((buf[0] != 0xFF) || (buf[1] != SOI)) error("Not a JPG file ?\n"); priv->stream_begin = buf+2; priv->stream_length = size-2; ret = parse_JFIF(priv, priv->stream_begin); return ret; } /** * Decode and convert the jpeg image into @pixfmt@ image * * Note: components will be automaticaly allocated if no memory is attached. */ int tinyjpeg_decode(struct jdec_private *priv, const struct tinyjpeg_colorspace *pixfmt) { unsigned int x, y, xstride_by_mcu, ystride_by_mcu; unsigned int bytes_per_blocklines[3], bytes_per_mcu[3]; decode_MCU_fct decode_MCU; const decode_MCU_fct *decode_mcu_table; convert_colorspace_fct convert_to_pixfmt; decode_mcu_table = pixfmt->decode_mcu_table; /* Fix: check return value */ pixfmt->initialize(priv, bytes_per_blocklines, bytes_per_mcu); xstride_by_mcu = ystride_by_mcu = 8; if ((priv->component_infos[cY].Hfactor | priv->component_infos[cY].Vfactor) == 1) { decode_MCU = decode_mcu_table[0]; convert_to_pixfmt = pixfmt->convert_colorspace[0]; trace("Use decode 1x1 sampling\n"); } else if (priv->component_infos[cY].Hfactor == 1) { decode_MCU = decode_mcu_table[1]; convert_to_pixfmt = pixfmt->convert_colorspace[1]; ystride_by_mcu = 16; trace("Use decode 1x2 sampling (not supported)\n"); } else if (priv->component_infos[cY].Vfactor == 2) { decode_MCU = decode_mcu_table[3]; convert_to_pixfmt = pixfmt->convert_colorspace[3]; xstride_by_mcu = 16; ystride_by_mcu = 16; trace("Use decode 2x2 sampling\n"); } else { decode_MCU = decode_mcu_table[2]; convert_to_pixfmt = pixfmt->convert_colorspace[2]; xstride_by_mcu = 16; trace("Use decode 2x1 sampling\n"); } resync(priv); /* Don't forget to that block can be either 8 or 16 lines */ bytes_per_blocklines[0] *= ystride_by_mcu; bytes_per_blocklines[1] *= ystride_by_mcu; bytes_per_blocklines[2] *= ystride_by_mcu; bytes_per_mcu[0] *= xstride_by_mcu/8; bytes_per_mcu[1] *= xstride_by_mcu/8; bytes_per_mcu[2] *= xstride_by_mcu/8; /* Just the decode the image by macroblock (size is 8x8, 8x16, or 16x16) */ for (y=0; y < priv->height/ystride_by_mcu; y++) { //trace("Decoding row %d\n", y); priv->plane[0] = priv->components[0] + (y * bytes_per_blocklines[0]); priv->plane[1] = priv->components[1] + (y * bytes_per_blocklines[1]); priv->plane[2] = priv->components[2] + (y * bytes_per_blocklines[2]); for (x=0; x < priv->width; x+=xstride_by_mcu) { decode_MCU(priv); convert_to_pixfmt(priv); priv->plane[0] += bytes_per_mcu[0]; priv->plane[1] += bytes_per_mcu[1]; priv->plane[2] += bytes_per_mcu[2]; } } return 0; } const char *tinyjpeg_get_errorstring(struct jdec_private *priv) { return error_string; } void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height) { *width = priv->width; *height = priv->height; } int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components, unsigned int ncomponents) { int i; if (ncomponents > COMPONENTS) ncomponents = COMPONENTS; for (i=0; icomponents[i]; return 0; } int tinyjpeg_set_components(struct jdec_private *priv, unsigned char * const *components, unsigned int ncomponents) { int i; if (ncomponents > COMPONENTS) ncomponents = COMPONENTS; for (i=0; icomponents[i] = components[i]; return 0; } int tinyjpeg_get_bytes_per_row(struct jdec_private *priv, unsigned int *bytes, unsigned int ncomponents) { int i; if (ncomponents > COMPONENTS) ncomponents = COMPONENTS; for (i=0; ibytes_per_row[i]; return 0; } int tinyjpeg_set_bytes_per_row(struct jdec_private *priv, const unsigned int *bytes, unsigned int ncomponents) { int i; if (ncomponents > COMPONENTS) ncomponents = COMPONENTS; for (i=0; ibytes_per_row[i] = bytes[i]; return 0; } int tinyjpeg_set_flags(struct jdec_private *priv, int flags) { int oldflags = priv->flags; priv->flags = flags; return oldflags; } syslinux-legacy-3.63+dfsg/com32/lib/jpeg/jidctflt.c0000664000175000017500000002364110777447272020606 0ustar evanevan/* * jidctflt.c * * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * * The authors make NO WARRANTY or representation, either express or implied, * with respect to this software, its quality, accuracy, merchantability, or * fitness for a particular purpose. This software is provided "AS IS", and you, * its user, assume the entire risk as to its quality and accuracy. * * This software is copyright (C) 1991-1998, Thomas G. Lane. * All Rights Reserved except as specified below. * * Permission is hereby granted to use, copy, modify, and distribute this * software (or portions thereof) for any purpose, without fee, subject to these * conditions: * (1) If any part of the source code for this software is distributed, then this * README file must be included, with this copyright and no-warranty notice * unaltered; and any additions, deletions, or changes to the original files * must be clearly indicated in accompanying documentation. * (2) If only executable code is distributed, then the accompanying * documentation must state that "this software is based in part on the work of * the Independent JPEG Group". * (3) Permission for use of this software is granted only if the user accepts * full responsibility for any undesirable consequences; the authors accept * NO LIABILITY for damages of any kind. * * These conditions apply to any software derived from or based on the IJG code, * not just to the unmodified library. If you use our work, you ought to * acknowledge us. * * Permission is NOT granted for the use of any IJG author's name or company name * in advertising or publicity relating to this software or products derived from * it. This software may be referred to only as "the Independent JPEG Group's * software". * * We specifically permit and encourage the use of this software as the basis of * commercial products, provided that all warranty or liability claims are * assumed by the product vendor. * * * This file contains a floating-point implementation of the * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine * must also perform dequantization of the input coefficients. * * This implementation should be more accurate than either of the integer * IDCT implementations. However, it may not give the same results on all * machines because of differences in roundoff behavior. Speed will depend * on the hardware's floating point capacity. * * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT * on each row (or vice versa, but it's more convenient to emit a row at * a time). Direct algorithms are also available, but they are much more * complex and seem not to be any faster when reduced to code. * * This implementation is based on Arai, Agui, and Nakajima's algorithm for * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in * Japanese, but the algorithm is described in the Pennebaker & Mitchell * JPEG textbook (see REFERENCES section in file README). The following code * is based directly on figure 4-8 in P&M. * While an 8-point DCT cannot be done in less than 11 multiplies, it is * possible to arrange the computation so that many of the multiplies are * simple scalings of the final outputs. These multiplies can then be * folded into the multiplications or divisions by the JPEG quantization * table entries. The AA&N method leaves only 5 multiplies and 29 adds * to be done in the DCT itself. * The primary disadvantage of this method is that with a fixed-point * implementation, accuracy is lost due to imprecise representation of the * scaled quantization values. However, that problem does not arise if * we use floating point arithmetic. */ #include #include "tinyjpeg-internal.h" #define FAST_FLOAT float #define DCTSIZE 8 #define DCTSIZE2 (DCTSIZE*DCTSIZE) #define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval)) #if defined(__GNUC__) && defined(__i686__) || defined(__x86_64__) static inline unsigned char descale_and_clamp(int x, int shift) { __asm__ ( "add %3,%1\n" "\tsar %2,%1\n" "\tsub $-128,%1\n" "\tcmovl %5,%1\n" /* Use the sub to compare to 0 */ "\tcmpl %4,%1\n" "\tcmovg %4,%1\n" : "=r"(x) : "0"(x), "i"(shift), "i"(1UL<<(shift-1)), "r" (0xff), "r" (0) ); return x; } #else static inline unsigned char descale_and_clamp(int x, int shift) { x += (1UL<<(shift-1)); if (x<0) x = (x >> shift) | ((~(0UL)) << (32-(shift))); else x >>= shift; x += 128; if (x>255) return 255; else if (x<0) return 0; else return x; } #endif /* * Perform dequantization and inverse DCT on one block of coefficients. */ void jpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride) { FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; FAST_FLOAT tmp10, tmp11, tmp12, tmp13; FAST_FLOAT z5, z10, z11, z12, z13; int16_t *inptr; FAST_FLOAT *quantptr; FAST_FLOAT *wsptr; uint8_t *outptr; int ctr; FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */ /* Pass 1: process columns from input, store into work array. */ inptr = compptr->DCT; quantptr = compptr->Q_table; wsptr = workspace; for (ctr = DCTSIZE; ctr > 0; ctr--) { /* Due to quantization, we will usually find that many of the input * coefficients are zero, especially the AC terms. We can exploit this * by short-circuiting the IDCT calculation for any column in which all * the AC terms are zero. In that case each output is equal to the * DC coefficient (with scale factor as needed). * With typical images and quantization tables, half or more of the * column DCT calculations can be simplified this way. */ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) { /* AC terms all zero */ FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); wsptr[DCTSIZE*0] = dcval; wsptr[DCTSIZE*1] = dcval; wsptr[DCTSIZE*2] = dcval; wsptr[DCTSIZE*3] = dcval; wsptr[DCTSIZE*4] = dcval; wsptr[DCTSIZE*5] = dcval; wsptr[DCTSIZE*6] = dcval; wsptr[DCTSIZE*7] = dcval; inptr++; /* advance pointers to next column */ quantptr++; wsptr++; continue; } /* Even part */ tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); tmp10 = tmp0 + tmp2; /* phase 3 */ tmp11 = tmp0 - tmp2; tmp13 = tmp1 + tmp3; /* phases 5-3 */ tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */ tmp0 = tmp10 + tmp13; /* phase 2 */ tmp3 = tmp10 - tmp13; tmp1 = tmp11 + tmp12; tmp2 = tmp11 - tmp12; /* Odd part */ tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); z13 = tmp6 + tmp5; /* phase 6 */ z10 = tmp6 - tmp5; z11 = tmp4 + tmp7; z12 = tmp4 - tmp7; tmp7 = z11 + z13; /* phase 5 */ tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */ z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ tmp6 = tmp12 - tmp7; /* phase 2 */ tmp5 = tmp11 - tmp6; tmp4 = tmp10 + tmp5; wsptr[DCTSIZE*0] = tmp0 + tmp7; wsptr[DCTSIZE*7] = tmp0 - tmp7; wsptr[DCTSIZE*1] = tmp1 + tmp6; wsptr[DCTSIZE*6] = tmp1 - tmp6; wsptr[DCTSIZE*2] = tmp2 + tmp5; wsptr[DCTSIZE*5] = tmp2 - tmp5; wsptr[DCTSIZE*4] = tmp3 + tmp4; wsptr[DCTSIZE*3] = tmp3 - tmp4; inptr++; /* advance pointers to next column */ quantptr++; wsptr++; } /* Pass 2: process rows from work array, store into output array. */ /* Note that we must descale the results by a factor of 8 == 2**3. */ wsptr = workspace; outptr = output_buf; for (ctr = 0; ctr < DCTSIZE; ctr++) { /* Rows of zeroes can be exploited in the same way as we did with columns. * However, the column calculation has created many nonzero AC terms, so * the simplification applies less often (typically 5% to 10% of the time). * And testing floats for zero is relatively expensive, so we don't bother. */ /* Even part */ tmp10 = wsptr[0] + wsptr[4]; tmp11 = wsptr[0] - wsptr[4]; tmp13 = wsptr[2] + wsptr[6]; tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13; tmp0 = tmp10 + tmp13; tmp3 = tmp10 - tmp13; tmp1 = tmp11 + tmp12; tmp2 = tmp11 - tmp12; /* Odd part */ z13 = wsptr[5] + wsptr[3]; z10 = wsptr[5] - wsptr[3]; z11 = wsptr[1] + wsptr[7]; z12 = wsptr[1] - wsptr[7]; tmp7 = z11 + z13; tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ tmp6 = tmp12 - tmp7; tmp5 = tmp11 - tmp6; tmp4 = tmp10 + tmp5; /* Final output stage: scale down by a factor of 8 and range-limit */ outptr[0] = descale_and_clamp(tmp0 + tmp7, 3); outptr[7] = descale_and_clamp(tmp0 - tmp7, 3); outptr[1] = descale_and_clamp(tmp1 + tmp6, 3); outptr[6] = descale_and_clamp(tmp1 - tmp6, 3); outptr[2] = descale_and_clamp(tmp2 + tmp5, 3); outptr[5] = descale_and_clamp(tmp2 - tmp5, 3); outptr[4] = descale_and_clamp(tmp3 + tmp4, 3); outptr[3] = descale_and_clamp(tmp3 - tmp4, 3); wsptr += DCTSIZE; /* advance pointer to next row */ outptr += stride; } } syslinux-legacy-3.63+dfsg/com32/lib/jpeg/yuv420p.c0000664000175000017500000001341610777447272020233 0ustar evanevan/* * Small jpeg decoder library * * Copyright (c) 2006, Luc Saillard * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ /* * yuv420p.c */ #include #include #include #include #include "tinyjpeg.h" #include "tinyjpeg-internal.h" /** * YCrCb -> YUV420P (1x1) * .---. * | 1 | * `---' */ static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv) { const unsigned char *s, *y; unsigned char *p; int i,j; p = priv->plane[0]; y = priv->Y; for (i=0; i<8; i++) { memcpy(p, y, 8); p += priv->bytes_per_row[0]; y += 8; } p = priv->plane[1]; s = priv->Cb; for (i=0; i<8; i+=2) { for (j=0; j<8; j+=2, s+=2) *p++ = *s; s += 8; /* Skip one line */ p += priv->bytes_per_row[1] - 4; } p = priv->plane[2]; s = priv->Cr; for (i=0; i<8; i+=2) { for (j=0; j<8; j+=2, s+=2) *p++ = *s; s += 8; /* Skip one line */ p += priv->bytes_per_row[2] - 4; } } /** * YCrCb -> YUV420P (2x1) * .-------. * | 1 | 2 | * `-------' */ static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv) { unsigned char *p; const unsigned char *s, *y1; int i,j; p = priv->plane[0]; y1 = priv->Y; for (i=0; i<8; i++) { memcpy(p, y1, 16); p += priv->bytes_per_row[0]; y1 += 16; } p = priv->plane[1]; s = priv->Cb; for (i=0; i<8; i+=2) { for (j=0; j<8; j+=1, s+=1) *p++ = *s; s += 8; /* Skip one line */ p += priv->bytes_per_row[1] - 8; } p = priv->plane[2]; s = priv->Cr; for (i=0; i<8; i+=2) { for (j=0; j<8; j+=1, s+=1) *p++ = *s; s += 8; /* Skip one line */ p += priv->bytes_per_row[2] - 8; } } /** * YCrCb -> YUV420P (1x2) * .---. * | 1 | * |---| * | 2 | * `---' */ static void YCrCB_to_YUV420P_1x2(struct jdec_private *priv) { const unsigned char *s, *y; unsigned char *p; int i,j; p = priv->plane[0]; y = priv->Y; for (i=0; i<16; i++) { memcpy(p, y, 8); p+=priv->bytes_per_row[0]; y+=8; } p = priv->plane[1]; s = priv->Cb; for (i=0; i<8; i++) { for (j=0; j<8; j+=2, s+=2) *p++ = *s; p += priv->bytes_per_row[1] - 4; } p = priv->plane[2]; s = priv->Cr; for (i=0; i<8; i++) { for (j=0; j<8; j+=2, s+=2) *p++ = *s; p += priv->bytes_per_row[2] - 4; } } /** * YCrCb -> YUV420P (2x2) * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */ static void YCrCB_to_YUV420P_2x2(struct jdec_private *priv) { unsigned char *p; const unsigned char *s, *y1; int i; p = priv->plane[0]; y1 = priv->Y; for (i=0; i<16; i++) { memcpy(p, y1, 16); p += priv->bytes_per_row[0]; y1 += 16; } p = priv->plane[1]; s = priv->Cb; for (i=0; i<8; i++) { memcpy(p, s, 8); s += 8; p += priv->bytes_per_row[1]; } p = priv->plane[2]; s = priv->Cr; for (i=0; i<8; i++) { memcpy(p, s, 8); s += 8; p += priv->bytes_per_row[2]; } } static int initialize_yuv420p(struct jdec_private *priv, unsigned int *bytes_per_blocklines, unsigned int *bytes_per_mcu) { if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height); if (priv->components[1] == NULL) priv->components[1] = (uint8_t *)malloc(priv->width * priv->height/4); if (priv->components[2] == NULL) priv->components[2] = (uint8_t *)malloc(priv->width * priv->height/4); if (!priv->bytes_per_row[0]) priv->bytes_per_row[0] = priv->width; if (!priv->bytes_per_row[1]) priv->bytes_per_row[1] = priv->width/2; if (!priv->bytes_per_row[2]) priv->bytes_per_row[2] = priv->width/2; bytes_per_blocklines[0] = priv->bytes_per_row[0]; bytes_per_blocklines[1] = priv->bytes_per_row[1]/2; bytes_per_blocklines[2] = priv->bytes_per_row[2]/2; bytes_per_mcu[0] = 8; bytes_per_mcu[1] = 4; bytes_per_mcu[2] = 4; /* Return nonzero on failure */ return !priv->components[0] || !priv->components[1] || !priv->components[2]; } static const struct tinyjpeg_colorspace format_yuv420p = { { YCrCB_to_YUV420P_1x1, YCrCB_to_YUV420P_1x2, YCrCB_to_YUV420P_2x1, YCrCB_to_YUV420P_2x2, }, tinyjpeg_decode_mcu_3comp_table, initialize_yuv420p }; const tinyjpeg_colorspace_t TINYJPEG_FMT_YUV420P = &format_yuv420p; syslinux-legacy-3.63+dfsg/com32/lib/jpeg/bgr24.c0000664000175000017500000002141710777447272017722 0ustar evanevan/* * Small jpeg decoder library * * Copyright (c) 2006, Luc Saillard * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include "tinyjpeg.h" #include "tinyjpeg-internal.h" /******************************************************************************* * * Colorspace conversion routine * * * Note: * YCbCr is defined per CCIR 601-1, except that Cb and Cr are * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. * The conversion equations to be implemented are therefore * R = Y + 1.40200 * Cr * G = Y - 0.34414 * Cb - 0.71414 * Cr * B = Y + 1.77200 * Cb * ******************************************************************************/ static unsigned char clamp(int i) { if (i<0) return 0; else if (i>255) return 255; else return i; } /** * YCrCb -> BGR24 (1x1) * .---. * | 1 | * `---' */ static void YCrCB_to_BGR24_1x1(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = priv->bytes_per_row[0] - 8*3; for (i=0; i<8; i++) { for (j=0;j<8;j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b; y = (*Y++) << SCALEBITS; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); } p += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } /* * YCrCb -> BGR24 (2x1) * .-------. * | 1 | 2 | * `-------' */ static void YCrCB_to_BGR24_2x1(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = priv->bytes_per_row[0] - 16*3; for (i=0; i<8; i++) { for (j=0; j<8; j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; y = (*Y++) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); y = (*Y++) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); } p += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } /* * YCrCb -> BGR24 (1x2) * .---. * | 1 | * |---| * | 2 | * `---' */ static void YCrCB_to_BGR24_1x2(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p, *p2; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; p2 = priv->plane[0] + priv->bytes_per_row[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = 2*priv->bytes_per_row[0] - 8*3; for (i=0; i<8; i++) { for (j=0; j<8; j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; y = (*Y++) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); y = (Y[8-1]) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); } Y += 8; p += offset_to_next_row; p2 += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } /* * YCrCb -> BGR24 (2x2) * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */ static void YCrCB_to_BGR24_2x2(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p, *p2; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; p2 = priv->plane[0] + priv->bytes_per_row[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = 2*priv->bytes_per_row[0] - 16*3; for (i=0; i<8; i++) { for (j=0;j<8;j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; y = (*Y++) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); y = (*Y++) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); y = (Y[16-2]) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); y = (Y[16-1]) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); } Y += 16; p += offset_to_next_row; p2 += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } static int initialize_bgr24(struct jdec_private *priv, unsigned int *bytes_per_blocklines, unsigned int *bytes_per_mcu) { if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3); if (!priv->bytes_per_row[0]) priv->bytes_per_row[0] = priv->width * 3; bytes_per_blocklines[0] = priv->bytes_per_row[0]; bytes_per_mcu[0] = 3*8; return !priv->components[0]; } static const struct tinyjpeg_colorspace format_bgr24 = { { YCrCB_to_BGR24_1x1, YCrCB_to_BGR24_1x2, YCrCB_to_BGR24_2x1, YCrCB_to_BGR24_2x2, }, tinyjpeg_decode_mcu_3comp_table, initialize_bgr24 }; const tinyjpeg_colorspace_t TINYJPEG_FMT_BGR24 = &format_bgr24; syslinux-legacy-3.63+dfsg/com32/lib/jpeg/bgra32.c0000664000175000017500000002213210777447272020055 0ustar evanevan/* * Small jpeg decoder library * * Copyright (c) 2006, Luc Saillard * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include "tinyjpeg.h" #include "tinyjpeg-internal.h" /******************************************************************************* * * Colorspace conversion routine * * * Note: * YCbCr is defined per CCIR 601-1, except that Cb and Cr are * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. * The conversion equations to be implemented are therefore * R = Y + 1.40200 * Cr * G = Y - 0.34414 * Cb - 0.71414 * Cr * B = Y + 1.77200 * Cb * ******************************************************************************/ static unsigned char clamp(int i) { if (i<0) return 0; else if (i>255) return 255; else return i; } /** * YCrCb -> BGRA32 (1x1) * .---. * | 1 | * `---' */ static void YCrCB_to_BGRA32_1x1(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = priv->bytes_per_row[0] - 8*4; for (i=0; i<8; i++) { for (j=0;j<8;j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b, a; y = (*Y++) << SCALEBITS; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); a = 255; *p++ = a; } p += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } /* * YCrCb -> BGRA32 (2x1) * .-------. * | 1 | 2 | * `-------' */ static void YCrCB_to_BGRA32_2x1(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = priv->bytes_per_row[0] - 16*4; for (i=0; i<8; i++) { for (j=0; j<8; j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b, a; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; y = (*Y++) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); a = 255; *p++ = a; y = (*Y++) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); a = 255; *p++ = a; } p += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } /* * YCrCb -> BGRA32 (1x2) * .---. * | 1 | * |---| * | 2 | * `---' */ static void YCrCB_to_BGRA32_1x2(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p, *p2; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; p2 = priv->plane[0] + priv->bytes_per_row[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = 2*priv->bytes_per_row[0] - 8*4; for (i=0; i<8; i++) { for (j=0; j<8; j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b, a; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; y = (*Y++) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); a = 255; *p++ = a; y = (Y[8-1]) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); a = 255; *p2++ = a; } Y += 8; p += offset_to_next_row; p2 += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } /* * YCrCb -> BGRA32 (2x2) * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */ static void YCrCB_to_BGRA32_2x2(struct jdec_private *priv) { const unsigned char *Y, *Cb, *Cr; unsigned char *p, *p2; int i,j; int offset_to_next_row; #define SCALEBITS 10 #define ONE_HALF (1UL << (SCALEBITS-1)) #define FIX(x) ((int)((x) * (1UL<plane[0]; p2 = priv->plane[0] + priv->bytes_per_row[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = 2*priv->bytes_per_row[0] - 16*4; for (i=0; i<8; i++) { for (j=0;j<8;j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b, a; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; y = (*Y++) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); a = 255; *p++ = a; y = (*Y++) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); a = 255; *p++ = a; y = (Y[16-2]) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); a = 255; *p2++ = a; y = (Y[16-1]) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); a = 255; *p2++ = a; } Y += 16; p += offset_to_next_row; p2 += offset_to_next_row; } #undef SCALEBITS #undef ONE_HALF #undef FIX } static int initialize_bgra32(struct jdec_private *priv, unsigned int *bytes_per_blocklines, unsigned int *bytes_per_mcu) { if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 4); if (!priv->bytes_per_row[0]) priv->bytes_per_row[0] = priv->width * 4; bytes_per_blocklines[0] = priv->bytes_per_row[0]; bytes_per_mcu[0] = 4*8; return !priv->components[0]; } static const struct tinyjpeg_colorspace format_bgra32 = { { YCrCB_to_BGRA32_1x1, YCrCB_to_BGRA32_1x2, YCrCB_to_BGRA32_2x1, YCrCB_to_BGRA32_2x2, }, tinyjpeg_decode_mcu_3comp_table, initialize_bgra32 }; const tinyjpeg_colorspace_t TINYJPEG_FMT_BGRA32 = &format_bgra32; syslinux-legacy-3.63+dfsg/com32/lib/jpeg/README0000664000175000017500000000311410777447272017510 0ustar evanevan/* * Small jpeg decoder library * * Copyright (c) 2006, Luc Saillard * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ syslinux-legacy-3.63+dfsg/com32/lib/jpeg/decode1.c0000664000175000017500000000760310777447272020307 0ustar evanevan/* * Small jpeg decoder library * * Copyright (c) 2006, Luc Saillard * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include "tinyjpeg.h" #include "tinyjpeg-internal.h" /* * Decode a 1x1 directly in 1 color */ static void decode_MCU_1x1_1plane(struct jdec_private *priv) { // Y tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 8); // Cb tinyjpeg_process_Huffman_data_unit(priv, cCb); IDCT(&priv->component_infos[cCb], priv->Cb, 8); // Cr tinyjpeg_process_Huffman_data_unit(priv, cCr); IDCT(&priv->component_infos[cCr], priv->Cr, 8); } /* * Decode a 2x1 * .-------. * | 1 | 2 | * `-------' */ static void decode_MCU_2x1_1plane(struct jdec_private *priv) { // Y tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 16); tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+8, 16); // Cb tinyjpeg_process_Huffman_data_unit(priv, cCb); // Cr tinyjpeg_process_Huffman_data_unit(priv, cCr); } /* * Decode a 2x2 directly in GREY format (8bits) * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */ static void decode_MCU_2x2_1plane(struct jdec_private *priv) { // Y tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 16); tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+8, 16); tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+64*2, 16); tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16); // Cb tinyjpeg_process_Huffman_data_unit(priv, cCb); // Cr tinyjpeg_process_Huffman_data_unit(priv, cCr); } /* * Decode a 1x2 mcu * .---. * | 1 | * |---| * | 2 | * `---' */ static void decode_MCU_1x2_1plane(struct jdec_private *priv) { // Y tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 8); tinyjpeg_process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+64, 8); // Cb tinyjpeg_process_Huffman_data_unit(priv, cCb); // Cr tinyjpeg_process_Huffman_data_unit(priv, cCr); } const decode_MCU_fct tinyjpeg_decode_mcu_1comp_table[4] = { decode_MCU_1x1_1plane, decode_MCU_1x2_1plane, decode_MCU_2x1_1plane, decode_MCU_2x2_1plane, }; syslinux-legacy-3.63+dfsg/com32/lib/jpeg/grey.c0000664000175000017500000001004010777447272017736 0ustar evanevan/* * Small jpeg decoder library * * Copyright (c) 2006, Luc Saillard * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include "tinyjpeg.h" #include "tinyjpeg-internal.h" /** * YCrCb -> Grey (1x1) * .---. * | 1 | * `---' */ static void YCrCB_to_Grey_1x1(struct jdec_private *priv) { const unsigned char *y; unsigned char *p; unsigned int i; int offset_to_next_row; p = priv->plane[0]; y = priv->Y; offset_to_next_row = priv->bytes_per_row[0]; for (i=0; i<8; i++) { memcpy(p, y, 8); y+=8; p += offset_to_next_row; } } /** * YCrCb -> Grey (2x1) * .-------. * | 1 | 2 | * `-------' */ static void YCrCB_to_Grey_2x1(struct jdec_private *priv) { const unsigned char *y; unsigned char *p; unsigned int i; int offset_to_next_row; p = priv->plane[0]; y = priv->Y; offset_to_next_row = priv->bytes_per_row[0]; for (i=0; i<8; i++) { memcpy(p, y, 16); y += 16; p += offset_to_next_row; } } /** * YCrCb -> Grey (1x2) * .---. * | 1 | * |---| * | 2 | * `---' */ static void YCrCB_to_Grey_1x2(struct jdec_private *priv) { const unsigned char *y; unsigned char *p; unsigned int i; int offset_to_next_row; p = priv->plane[0]; y = priv->Y; offset_to_next_row = priv->bytes_per_row[0]; for (i=0; i<16; i++) { memcpy(p, y, 8); y += 8; p += offset_to_next_row; } } /** * YCrCb -> Grey (2x2) * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */ static void YCrCB_to_Grey_2x2(struct jdec_private *priv) { const unsigned char *y; unsigned char *p; unsigned int i; int offset_to_next_row; p = priv->plane[0]; y = priv->Y; offset_to_next_row = priv->bytes_per_row[0]; for (i=0; i<16; i++) { memcpy(p, y, 16); y += 16; p += offset_to_next_row; } } static int initialize_grey(struct jdec_private *priv, unsigned int *bytes_per_blocklines, unsigned int *bytes_per_mcu) { if (priv->components[0] == NULL) priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3); if (!priv->bytes_per_row[0]) priv->bytes_per_row[0] = priv->width * 3; bytes_per_blocklines[0] = priv->bytes_per_row[0]; bytes_per_mcu[0] = 3*8; return !priv->components[0]; } static const struct tinyjpeg_colorspace format_grey = { { YCrCB_to_Grey_1x1, YCrCB_to_Grey_1x2, YCrCB_to_Grey_2x1, YCrCB_to_Grey_2x2, }, tinyjpeg_decode_mcu_1comp_table, initialize_grey }; const tinyjpeg_colorspace_t TINYJPEG_FMT_GREY = &format_grey; syslinux-legacy-3.63+dfsg/com32/lib/strdup.c0000664000175000017500000000027110777447272017371 0ustar evanevan/* * strdup.c */ #include #include char *strdup(const char *s) { int l = strlen(s)+1; char *d = malloc(l); if ( d ) memcpy(d, s, l); return d; } syslinux-legacy-3.63+dfsg/com32/lib/strtoull.c0000664000175000017500000000011210777447272017732 0ustar evanevan#define TYPE unsigned long long #define NAME strtoull #include "strtox.c" syslinux-legacy-3.63+dfsg/com32/lib/calloc.c0000664000175000017500000000041710777447272017307 0ustar evanevan/* * calloc.c */ #include #include /* FIXME: This should look for multiplication overflow */ void *calloc(size_t nmemb, size_t size) { void *ptr; size *= nmemb; ptr = malloc(size); if ( ptr ) memset(ptr, 0, size); return ptr; } syslinux-legacy-3.63+dfsg/com32/lib/stack.c0000664000175000017500000000012210777447272017150 0ustar evanevan#include /* Default stack size 8 MB */ size_t __stack_size = 8 << 20; syslinux-legacy-3.63+dfsg/com32/lib/fwrite.c0000664000175000017500000000072410777447272017353 0ustar evanevan/* * fwrite.c */ #include #include #include size_t _fwrite(const void *buf, size_t count, FILE *f) { size_t bytes = 0; ssize_t rv; const char *p = buf; while ( count ) { rv = write(fileno(f), p, count); if ( rv == -1 ) { if ( errno == EINTR || errno == EAGAIN ) continue; else break; } else if ( rv == 0 ) { break; } p += rv; bytes += rv; count -= rv; } return bytes; } syslinux-legacy-3.63+dfsg/com32/lib/fgets.c0000664000175000017500000000072410777447272017163 0ustar evanevan/* * fgets.c * * This will be very slow due to the implementation of getc(), * but we can't afford to drain characters we don't need from * the input. */ #include char *fgets(char *s, int n, FILE *f) { int ch; char *p = s; while ( n > 1 ) { ch = getc(f); if ( ch == EOF ) { *p = '\0'; return (p == s) ? NULL : s; } *p++ = ch; if ( ch == '\n' ) break; n--; } if ( n ) *p = '\0'; return s; } syslinux-legacy-3.63+dfsg/com32/lib/strcpy.c0000664000175000017500000000032710777447272017376 0ustar evanevan/* * strcpy.c * * strcpy() */ #include char *strcpy(char *dst, const char *src) { char *q = dst; const char *p = src; char ch; do { *q++ = ch = *p++; } while ( ch ); return dst; } syslinux-legacy-3.63+dfsg/com32/lib/snprintf.c0000664000175000017500000000034110777447272017711 0ustar evanevan/* * snprintf.c */ #include int snprintf(char *buffer, size_t n, const char *format, ...) { va_list ap; int rv; va_start(ap, format); rv = vsnprintf(buffer, n, format, ap); va_end(ap); return rv; } syslinux-legacy-3.63+dfsg/com32/lib/atoi.c0000664000175000017500000000006510777447272017005 0ustar evanevan#define TYPE int #define NAME atoi #include "atox.c" syslinux-legacy-3.63+dfsg/com32/lib/fread.c0000664000175000017500000000070510777447272017133 0ustar evanevan/* * fread.c */ #include #include #include size_t _fread(void *buf, size_t count, FILE *f) { size_t bytes = 0; ssize_t rv; char *p = buf; while ( count ) { rv = read(fileno(f), p, count); if ( rv == -1 ) { if ( errno == EINTR || errno == EAGAIN ) continue; else break; } else if ( rv == 0 ) { break; } p += rv; bytes += rv; count -= rv; } return bytes; } syslinux-legacy-3.63+dfsg/com32/lib/strcmp.c0000664000175000017500000000041610777447272017361 0ustar evanevan/* * strcmp.c */ #include int strcmp(const char *s1, const char *s2) { const unsigned char *c1 = s1, *c2 = s2; unsigned char ch; int d = 0; while ( 1 ) { d = (int)(ch = *c1++) - (int)*c2++; if ( d || !ch ) break; } return d; } syslinux-legacy-3.63+dfsg/com32/lib/strcat.c0000664000175000017500000000020610777447272017346 0ustar evanevan/* * strcat.c */ #include char *strcat(char *dst, const char *src) { strcpy(strchr(dst, '\0'), src); return dst; } syslinux-legacy-3.63+dfsg/com32/lib/Makefile0000664000175000017500000001053310777447272017346 0ustar evanevan# Include configuration rules include MCONFIG LIBOBJS = \ abort.o atexit.o atoi.o atol.o atoll.o calloc.o creat.o \ ctypes.o errno.o fgetc.o fgets.o fopen.o fprintf.o fputc.o \ putchar.o setjmp.o \ fputs.o fread2.o fread.o free.o fwrite2.o fwrite.o getopt.o \ lrand48.o malloc.o stack.o memccpy.o memchr.o memcmp.o \ memcpy.o mempcpy.o memmem.o memmove.o memset.o memswap.o \ exit.o onexit.o \ perror.o printf.o puts.o qsort.o realloc.o seed48.o snprintf.o \ sprintf.o srand48.o sscanf.o stack.o strcasecmp.o strcat.o \ strchr.o strcmp.o strcpy.o strdup.o strerror.o strlen.o \ strnlen.o \ strncasecmp.o strncat.o strncmp.o strncpy.o stpncpy.o strndup.o \ strntoimax.o strntoumax.o strrchr.o strsep.o strspn.o strstr.o \ strtoimax.o strtok.o strtol.o strtoll.o strtoul.o strtoull.o \ strtoumax.o vfprintf.o vprintf.o vsnprintf.o vsprintf.o \ asprintf.o vasprintf.o strlcpy.o strlcat.o \ vsscanf.o \ \ libgcc/__ashldi3.o libgcc/__udivdi3.o \ libgcc/__negdi2.o libgcc/__ashrdi3.o libgcc/__lshrdi3.o \ libgcc/__muldi3.o libgcc/__udivmoddi4.o libgcc/__umoddi3.o \ libgcc/__divdi3.o libgcc/__moddi3.o \ \ sys/intcall.o sys/farcall.o sys/cfarcall.o sys/zeroregs.o \ sys/entry.o sys/exit.o sys/argv.o sys/times.o \ sys/fileinfo.o sys/opendev.o sys/read.o sys/write.o sys/ftell.o \ sys/close.o sys/open.o sys/fileread.o sys/fileclose.o \ sys/isatty.o sys/fstat.o sys/openconsole.o sys/line_input.o \ sys/colortable.o sys/screensize.o \ \ sys/stdcon_read.o sys/stdcon_write.o sys/rawcon_read.o \ sys/rawcon_write.o sys/err_read.o sys/err_write.o \ sys/null_read.o sys/null_write.o sys/serial_write.o \ \ sys/xserial_write.o \ \ sys/ansi.o \ \ sys/ansicon_write.o sys/ansiserial_write.o \ \ sys/vesacon_write.o sys/vesaserial_write.o \ sys/vesa/initvesa.o sys/vesa/drawtxt.o sys/vesa/background.o \ sys/vesa/alphatbl.o sys/vesa/screencpy.o sys/vesa/fmtpixel.o \ \ pci/cfgtype.o pci/scan.o \ pci/readb.o pci/readw.o pci/readl.o pci/readbios.o \ pci/writeb.o pci/writew.o pci/writel.o pci/writebios.o \ \ zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/gzio.o \ zlib/uncompr.o zlib/deflate.o zlib/trees.o zlib/zutil.o \ zlib/inflate.o zlib/infback.o zlib/inftrees.o zlib/inffast.o \ \ libpng/png.o libpng/pngset.o libpng/pngget.o libpng/pngrutil.o \ libpng/pngtrans.o libpng/pngwutil.o libpng/pngread.o \ libpng/pngrio.o libpng/pngwio.o libpng/pngwrite.o \ libpng/pngrtran.o libpng/pngwtran.o libpng/pngmem.o \ libpng/pngerror.o libpng/pngpread.o \ \ jpeg/tinyjpeg.o jpeg/jidctflt.o jpeg/decode1.o jpeg/decode3.o \ jpeg/rgb24.o jpeg/bgr24.o jpeg/yuv420p.o jpeg/grey.o \ jpeg/rgba32.o jpeg/bgra32.o \ \ sys/x86_init_fpu.o math/pow.o math/strtod.o \ \ syslinux/idle.o syslinux/reboot.o \ syslinux/features.o syslinux/config.o syslinux/serial.o \ syslinux/ipappend.o \ \ syslinux/addlist.o syslinux/freelist.o syslinux/memmap.o \ syslinux/movebits.o syslinux/shuffle.o syslinux/shuffle_pm.o \ syslinux/shuffle_rm.o syslinux/zonelist.o \ syslinux/dump_mmap.o syslinux/dump_movelist.o \ \ syslinux/run_default.o syslinux/run_command.o \ syslinux/cleanup.o syslinux/localboot.o syslinux/runimage.o \ \ syslinux/loadfile.o \ syslinux/load_linux.o syslinux/initramfs.o \ syslinux/initramfs_file.o syslinux/initramfs_loadfile.o \ syslinux/initramfs_archive.o \ \ syslinux/pxe_get_cached.o \ \ syslinux/adv.o syslinux/advwrite.o syslinux/getadv.o \ syslinux/setadv.o BINDIR = /usr/bin LIBDIR = /usr/lib AUXDIR = $(LIBDIR)/syslinux INCDIR = /usr/include COM32DIR = $(AUXDIR)/com32 all: libcom32.a libcom32.a : $(LIBOBJS) rm -f $@ $(AR) cq $@ $^ $(RANLIB) $@ tidy: rm -f sys/vesa/alphatbl.c find . -name \*.o -print | xargs -r rm -f find . -name .\*.d -print | xargs -r rm -f clean: tidy rm -f *.a spotless: clean rm -f *~ \#* */*~ */\#* install: all mkdir -m 755 -p $(INSTALLROOT)$(COM32DIR) install -m 644 libcom32.a com32.ld $(INSTALLROOT)$(COM32DIR) -rm -rf $(INSTALLROOT)$(COM32DIR)/include cp -r ../include $(INSTALLROOT)$(COM32DIR) # These files are performance critical, and doesn't compile well with -Os sys/vesa/drawtxt.o: sys/vesa/drawtxt.c $(CC) $(CFLAGS) -O3 -c -o $@ $< sys/vesa/alphatbl.c: sys/vesa/alphatbl.pl $(PERL) $< > $@ jpeg/jidctflt.o: jpeg/jidctflt.c $(CC) $(CFLAGS) -O3 -c -o $@ $< -include .*.d */.*.d */*/.*.d syslinux-legacy-3.63+dfsg/com32/lib/errno.c0000664000175000017500000000006410777447272017175 0ustar evanevan/* * errno.c * */ #include int errno; syslinux-legacy-3.63+dfsg/com32/lib/atoll.c0000664000175000017500000000007410777447272017164 0ustar evanevan#define TYPE long long #define NAME atoll #include "atox.c" syslinux-legacy-3.63+dfsg/com32/lib/strncmp.c0000664000175000017500000000043410777447272017537 0ustar evanevan/* * strncmp.c */ #include int strncmp(const char *s1, const char *s2, size_t n) { const unsigned char *c1 = s1, *c2 = s2; unsigned char ch; int d = 0; while ( n-- ) { d = (int)(ch = *c1++) - (int)*c2++; if ( d || !ch ) break; } return d; } syslinux-legacy-3.63+dfsg/com32/lib/libpng/0000775000175000017500000000000010777447344017157 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/lib/libpng/pngrtran.c0000664000175000017500000042653610777447272021176 0ustar evanevan /* pngrtran.c - transforms the data in a row for PNG readers * * libpng version 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * * This file contains functions optionally called by an application * in order to tell libpng how to handle data when reading a PNG. * Transformations that are used in both reading and writing are * in pngtrans.c. */ #define PNG_INTERNAL #include "png.h" /* Set the action on getting a CRC error for an ancillary or critical chunk. */ void PNGAPI png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) { png_debug(1, "in png_set_crc_action\n"); /* Tell libpng how we react to CRC errors in critical chunks */ switch (crit_action) { case PNG_CRC_NO_CHANGE: /* leave setting as is */ break; case PNG_CRC_WARN_USE: /* warn/use data */ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; break; case PNG_CRC_QUIET_USE: /* quiet/use data */ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | PNG_FLAG_CRC_CRITICAL_IGNORE; break; case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */ png_warning(png_ptr, "Can't discard critical data on CRC error."); case PNG_CRC_ERROR_QUIT: /* error/quit */ case PNG_CRC_DEFAULT: default: png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; break; } switch (ancil_action) { case PNG_CRC_NO_CHANGE: /* leave setting as is */ break; case PNG_CRC_WARN_USE: /* warn/use data */ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE; break; case PNG_CRC_QUIET_USE: /* quiet/use data */ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN; break; case PNG_CRC_ERROR_QUIT: /* error/quit */ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; break; case PNG_CRC_WARN_DISCARD: /* warn/discard data */ case PNG_CRC_DEFAULT: default: png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; break; } } #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ defined(PNG_FLOATING_POINT_SUPPORTED) /* handle alpha and tRNS via a background color */ void PNGAPI png_set_background(png_structp png_ptr, png_color_16p background_color, int background_gamma_code, int need_expand, double background_gamma) { png_debug(1, "in png_set_background\n"); if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) { png_warning(png_ptr, "Application must supply a known background gamma"); return; } png_ptr->transformations |= PNG_BACKGROUND; png_memcpy(&(png_ptr->background), background_color, png_sizeof(png_color_16)); png_ptr->background_gamma = (float)background_gamma; png_ptr->background_gamma_type = (png_byte)(background_gamma_code); png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0); /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA * (in which case need_expand is superfluous anyway), the background color * might actually be gray yet not be flagged as such. This is not a problem * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to * decide when to do the png_do_gray_to_rgb() transformation. */ if ((need_expand && !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) || (!need_expand && background_color->red == background_color->green && background_color->red == background_color->blue)) png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; } #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) /* strip 16 bit depth files to 8 bit depth */ void PNGAPI png_set_strip_16(png_structp png_ptr) { png_debug(1, "in png_set_strip_16\n"); png_ptr->transformations |= PNG_16_TO_8; } #endif #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) void PNGAPI png_set_strip_alpha(png_structp png_ptr) { png_debug(1, "in png_set_strip_alpha\n"); png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; } #endif #if defined(PNG_READ_DITHER_SUPPORTED) /* Dither file to 8 bit. Supply a palette, the current number * of elements in the palette, the maximum number of elements * allowed, and a histogram if possible. If the current number * of colors is greater then the maximum number, the palette will be * modified to fit in the maximum number. "full_dither" indicates * whether we need a dithering cube set up for RGB images, or if we * simply are reducing the number of colors in a paletted image. */ typedef struct png_dsort_struct { struct png_dsort_struct FAR * next; png_byte left; png_byte right; } png_dsort; typedef png_dsort FAR * png_dsortp; typedef png_dsort FAR * FAR * png_dsortpp; void PNGAPI png_set_dither(png_structp png_ptr, png_colorp palette, int num_palette, int maximum_colors, png_uint_16p histogram, int full_dither) { png_debug(1, "in png_set_dither\n"); png_ptr->transformations |= PNG_DITHER; if (!full_dither) { int i; png_ptr->dither_index = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_palette * png_sizeof (png_byte))); for (i = 0; i < num_palette; i++) png_ptr->dither_index[i] = (png_byte)i; } if (num_palette > maximum_colors) { if (histogram != NULL) { /* This is easy enough, just throw out the least used colors. Perhaps not the best solution, but good enough. */ int i; /* initialize an array to sort colors */ png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_palette * png_sizeof (png_byte))); /* initialize the dither_sort array */ for (i = 0; i < num_palette; i++) png_ptr->dither_sort[i] = (png_byte)i; /* Find the least used palette entries by starting a bubble sort, and running it until we have sorted out enough colors. Note that we don't care about sorting all the colors, just finding which are least used. */ for (i = num_palette - 1; i >= maximum_colors; i--) { int done; /* to stop early if the list is pre-sorted */ int j; done = 1; for (j = 0; j < i; j++) { if (histogram[png_ptr->dither_sort[j]] < histogram[png_ptr->dither_sort[j + 1]]) { png_byte t; t = png_ptr->dither_sort[j]; png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1]; png_ptr->dither_sort[j + 1] = t; done = 0; } } if (done) break; } /* swap the palette around, and set up a table, if necessary */ if (full_dither) { int j = num_palette; /* put all the useful colors within the max, but don't move the others */ for (i = 0; i < maximum_colors; i++) { if ((int)png_ptr->dither_sort[i] >= maximum_colors) { do j--; while ((int)png_ptr->dither_sort[j] >= maximum_colors); palette[i] = palette[j]; } } } else { int j = num_palette; /* move all the used colors inside the max limit, and develop a translation table */ for (i = 0; i < maximum_colors; i++) { /* only move the colors we need to */ if ((int)png_ptr->dither_sort[i] >= maximum_colors) { png_color tmp_color; do j--; while ((int)png_ptr->dither_sort[j] >= maximum_colors); tmp_color = palette[j]; palette[j] = palette[i]; palette[i] = tmp_color; /* indicate where the color went */ png_ptr->dither_index[j] = (png_byte)i; png_ptr->dither_index[i] = (png_byte)j; } } /* find closest color for those colors we are not using */ for (i = 0; i < num_palette; i++) { if ((int)png_ptr->dither_index[i] >= maximum_colors) { int min_d, k, min_k, d_index; /* find the closest color to one we threw out */ d_index = png_ptr->dither_index[i]; min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); for (k = 1, min_k = 0; k < maximum_colors; k++) { int d; d = PNG_COLOR_DIST(palette[d_index], palette[k]); if (d < min_d) { min_d = d; min_k = k; } } /* point to closest color */ png_ptr->dither_index[i] = (png_byte)min_k; } } } png_free(png_ptr, png_ptr->dither_sort); png_ptr->dither_sort=NULL; } else { /* This is much harder to do simply (and quickly). Perhaps we need to go through a median cut routine, but those don't always behave themselves with only a few colors as input. So we will just find the closest two colors, and throw out one of them (chosen somewhat randomly). [We don't understand this at all, so if someone wants to work on improving it, be our guest - AED, GRP] */ int i; int max_d; int num_new_palette; png_dsortp t; png_dsortpp hash; t=NULL; /* initialize palette index arrays */ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_palette * png_sizeof (png_byte))); png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_palette * png_sizeof (png_byte))); /* initialize the sort array */ for (i = 0; i < num_palette; i++) { png_ptr->index_to_palette[i] = (png_byte)i; png_ptr->palette_to_index[i] = (png_byte)i; } hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 * png_sizeof (png_dsortp))); for (i = 0; i < 769; i++) hash[i] = NULL; /* png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */ num_new_palette = num_palette; /* initial wild guess at how far apart the farthest pixel pair we will be eliminating will be. Larger numbers mean more areas will be allocated, Smaller numbers run the risk of not saving enough data, and having to do this all over again. I have not done extensive checking on this number. */ max_d = 96; while (num_new_palette > maximum_colors) { for (i = 0; i < num_new_palette - 1; i++) { int j; for (j = i + 1; j < num_new_palette; j++) { int d; d = PNG_COLOR_DIST(palette[i], palette[j]); if (d <= max_d) { t = (png_dsortp)png_malloc_warn(png_ptr, (png_uint_32)(png_sizeof(png_dsort))); if (t == NULL) break; t->next = hash[d]; t->left = (png_byte)i; t->right = (png_byte)j; hash[d] = t; } } if (t == NULL) break; } if (t != NULL) for (i = 0; i <= max_d; i++) { if (hash[i] != NULL) { png_dsortp p; for (p = hash[i]; p; p = p->next) { if ((int)png_ptr->index_to_palette[p->left] < num_new_palette && (int)png_ptr->index_to_palette[p->right] < num_new_palette) { int j, next_j; if (num_new_palette & 0x01) { j = p->left; next_j = p->right; } else { j = p->right; next_j = p->left; } num_new_palette--; palette[png_ptr->index_to_palette[j]] = palette[num_new_palette]; if (!full_dither) { int k; for (k = 0; k < num_palette; k++) { if (png_ptr->dither_index[k] == png_ptr->index_to_palette[j]) png_ptr->dither_index[k] = png_ptr->index_to_palette[next_j]; if ((int)png_ptr->dither_index[k] == num_new_palette) png_ptr->dither_index[k] = png_ptr->index_to_palette[j]; } } png_ptr->index_to_palette[png_ptr->palette_to_index [num_new_palette]] = png_ptr->index_to_palette[j]; png_ptr->palette_to_index[png_ptr->index_to_palette[j]] = png_ptr->palette_to_index[num_new_palette]; png_ptr->index_to_palette[j] = (png_byte)num_new_palette; png_ptr->palette_to_index[num_new_palette] = (png_byte)j; } if (num_new_palette <= maximum_colors) break; } if (num_new_palette <= maximum_colors) break; } } for (i = 0; i < 769; i++) { if (hash[i] != NULL) { png_dsortp p = hash[i]; while (p) { t = p->next; png_free(png_ptr, p); p = t; } } hash[i] = 0; } max_d += 96; } png_free(png_ptr, hash); png_free(png_ptr, png_ptr->palette_to_index); png_free(png_ptr, png_ptr->index_to_palette); png_ptr->palette_to_index=NULL; png_ptr->index_to_palette=NULL; } num_palette = maximum_colors; } if (png_ptr->palette == NULL) { png_ptr->palette = palette; } png_ptr->num_palette = (png_uint_16)num_palette; if (full_dither) { int i; png_bytep distance; int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS; int num_red = (1 << PNG_DITHER_RED_BITS); int num_green = (1 << PNG_DITHER_GREEN_BITS); int num_blue = (1 << PNG_DITHER_BLUE_BITS); png_size_t num_entries = ((png_size_t)1 << total_bits); png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr, (png_uint_32)(num_entries * png_sizeof (png_byte))); png_memset(png_ptr->palette_lookup, 0, num_entries * png_sizeof (png_byte)); distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * png_sizeof(png_byte))); png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); for (i = 0; i < num_palette; i++) { int ir, ig, ib; int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS)); int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS)); int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS)); for (ir = 0; ir < num_red; ir++) { /* int dr = abs(ir - r); */ int dr = ((ir > r) ? ir - r : r - ir); int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS)); for (ig = 0; ig < num_green; ig++) { /* int dg = abs(ig - g); */ int dg = ((ig > g) ? ig - g : g - ig); int dt = dr + dg; int dm = ((dr > dg) ? dr : dg); int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS); for (ib = 0; ib < num_blue; ib++) { int d_index = index_g | ib; /* int db = abs(ib - b); */ int db = ((ib > b) ? ib - b : b - ib); int dmax = ((dm > db) ? dm : db); int d = dmax + dt + db; if (d < (int)distance[d_index]) { distance[d_index] = (png_byte)d; png_ptr->palette_lookup[d_index] = (png_byte)i; } } } } } png_free(png_ptr, distance); } } #endif #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) /* Transform the image from the file_gamma to the screen_gamma. We * only do transformations on images where the file_gamma and screen_gamma * are not close reciprocals, otherwise it slows things down slightly, and * also needlessly introduces small errors. * * We will turn off gamma transformation later if no semitransparent entries * are present in the tRNS array for palette images. We can't do it here * because we don't necessarily have the tRNS chunk yet. */ void PNGAPI png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) { png_debug(1, "in png_set_gamma\n"); if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) || (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) png_ptr->transformations |= PNG_GAMMA; png_ptr->gamma = (float)file_gamma; png_ptr->screen_gamma = (float)scrn_gamma; } #endif #if defined(PNG_READ_EXPAND_SUPPORTED) /* Expand paletted images to RGB, expand grayscale images of * less than 8-bit depth to 8-bit depth, and expand tRNS chunks * to alpha channels. */ void PNGAPI png_set_expand(png_structp png_ptr) { png_debug(1, "in png_set_expand\n"); png_ptr->transformations |= PNG_EXPAND; } /* GRR 19990627: the following three functions currently are identical * to png_set_expand(). However, it is entirely reasonable that someone * might wish to expand an indexed image to RGB but *not* expand a single, * fully transparent palette entry to a full alpha channel--perhaps instead * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace * the transparent color with a particular RGB value, or drop tRNS entirely. * IOW, a future version of the library may make the transformations flag * a bit more fine-grained, with separate bits for each of these three * functions. * * More to the point, these functions make it obvious what libpng will be * doing, whereas "expand" can (and does) mean any number of things. */ /* Expand paletted images to RGB. */ void PNGAPI png_set_palette_to_rgb(png_structp png_ptr) { png_debug(1, "in png_set_expand\n"); png_ptr->transformations |= PNG_EXPAND; } /* Expand grayscale images of less than 8-bit depth to 8 bits. */ void PNGAPI png_set_gray_1_2_4_to_8(png_structp png_ptr) { png_debug(1, "in png_set_expand\n"); png_ptr->transformations |= PNG_EXPAND; } /* Expand tRNS chunks to alpha channels. */ void PNGAPI png_set_tRNS_to_alpha(png_structp png_ptr) { png_debug(1, "in png_set_expand\n"); png_ptr->transformations |= PNG_EXPAND; } #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) void PNGAPI png_set_gray_to_rgb(png_structp png_ptr) { png_debug(1, "in png_set_gray_to_rgb\n"); png_ptr->transformations |= PNG_GRAY_TO_RGB; } #endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) #if defined(PNG_FLOATING_POINT_SUPPORTED) /* Convert a RGB image to a grayscale of the same width. This allows us, * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. */ void PNGAPI png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, double green) { int red_fixed = (int)((float)red*100000.0 + 0.5); int green_fixed = (int)((float)green*100000.0 + 0.5); png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed); } #endif void PNGAPI png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, png_fixed_point red, png_fixed_point green) { png_debug(1, "in png_set_rgb_to_gray\n"); switch(error_action) { case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY; break; case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; break; case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; } if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) #if defined(PNG_READ_EXPAND_SUPPORTED) png_ptr->transformations |= PNG_EXPAND; #else { png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED."); png_ptr->transformations &= ~PNG_RGB_TO_GRAY; } #endif { png_uint_16 red_int, green_int; if(red < 0 || green < 0) { red_int = 6968; /* .212671 * 32768 + .5 */ green_int = 23434; /* .715160 * 32768 + .5 */ } else if(red + green < 100000L) { red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L); green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L); } else { png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients"); red_int = 6968; green_int = 23434; } png_ptr->rgb_to_gray_red_coeff = red_int; png_ptr->rgb_to_gray_green_coeff = green_int; png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(32768-red_int-green_int); } } #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_LEGACY_SUPPORTED) void PNGAPI png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr read_user_transform_fn) { png_debug(1, "in png_set_read_user_transform_fn\n"); #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) png_ptr->transformations |= PNG_USER_TRANSFORM; png_ptr->read_user_transform_fn = read_user_transform_fn; #endif #ifdef PNG_LEGACY_SUPPORTED if(read_user_transform_fn) png_warning(png_ptr, "This version of libpng does not support user transforms"); #endif } #endif /* Initialize everything needed for the read. This includes modifying * the palette. */ void /* PRIVATE */ png_init_read_transformations(png_structp png_ptr) { png_debug(1, "in png_init_read_transformations\n"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if(png_ptr != NULL) #endif { #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \ || defined(PNG_READ_GAMMA_SUPPORTED) int color_type = png_ptr->color_type; #endif #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && (png_ptr->transformations & PNG_EXPAND)) { if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */ { /* expand background chunk. */ switch (png_ptr->bit_depth) { case 1: png_ptr->background.gray *= (png_uint_16)0xff; png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = png_ptr->background.gray; break; case 2: png_ptr->background.gray *= (png_uint_16)0x55; png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = png_ptr->background.gray; break; case 4: png_ptr->background.gray *= (png_uint_16)0x11; png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = png_ptr->background.gray; break; case 8: case 16: png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = png_ptr->background.gray; break; } } else if (color_type == PNG_COLOR_TYPE_PALETTE) { png_ptr->background.red = png_ptr->palette[png_ptr->background.index].red; png_ptr->background.green = png_ptr->palette[png_ptr->background.index].green; png_ptr->background.blue = png_ptr->palette[png_ptr->background.index].blue; #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) if (png_ptr->transformations & PNG_INVERT_ALPHA) { #if defined(PNG_READ_EXPAND_SUPPORTED) if (!(png_ptr->transformations & PNG_EXPAND)) #endif { /* invert the alpha channel (in tRNS) unless the pixels are going to be expanded, in which case leave it for later */ int i,istop; istop=(int)png_ptr->num_trans; for (i=0; itrans[i] = (png_byte)(255 - png_ptr->trans[i]); } } #endif } } #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) png_ptr->background_1 = png_ptr->background; #endif #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0) && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0) < PNG_GAMMA_THRESHOLD)) { int i,k; k=0; for (i=0; inum_trans; i++) { if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff) k=1; /* partial transparency is present */ } if (k == 0) png_ptr->transformations &= (~PNG_GAMMA); } if (png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) { png_build_gamma_table(png_ptr); #if defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->transformations & PNG_BACKGROUND) { if (color_type == PNG_COLOR_TYPE_PALETTE) { /* could skip if no transparency and */ png_color back, back_1; png_colorp palette = png_ptr->palette; int num_palette = png_ptr->num_palette; int i; if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) { back.red = png_ptr->gamma_table[png_ptr->background.red]; back.green = png_ptr->gamma_table[png_ptr->background.green]; back.blue = png_ptr->gamma_table[png_ptr->background.blue]; back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; } else { double g, gs; switch (png_ptr->background_gamma_type) { case PNG_BACKGROUND_GAMMA_SCREEN: g = (png_ptr->screen_gamma); gs = 1.0; break; case PNG_BACKGROUND_GAMMA_FILE: g = 1.0 / (png_ptr->gamma); gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); break; case PNG_BACKGROUND_GAMMA_UNIQUE: g = 1.0 / (png_ptr->background_gamma); gs = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma); break; default: g = 1.0; /* back_1 */ gs = 1.0; /* back */ } if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD) { back.red = (png_byte)png_ptr->background.red; back.green = (png_byte)png_ptr->background.green; back.blue = (png_byte)png_ptr->background.blue; } else { back.red = (png_byte)(pow( (double)png_ptr->background.red/255, gs) * 255.0 + .5); back.green = (png_byte)(pow( (double)png_ptr->background.green/255, gs) * 255.0 + .5); back.blue = (png_byte)(pow( (double)png_ptr->background.blue/255, gs) * 255.0 + .5); } back_1.red = (png_byte)(pow( (double)png_ptr->background.red/255, g) * 255.0 + .5); back_1.green = (png_byte)(pow( (double)png_ptr->background.green/255, g) * 255.0 + .5); back_1.blue = (png_byte)(pow( (double)png_ptr->background.blue/255, g) * 255.0 + .5); } for (i = 0; i < num_palette; i++) { if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff) { if (png_ptr->trans[i] == 0) { palette[i] = back; } else /* if (png_ptr->trans[i] != 0xff) */ { png_byte v, w; v = png_ptr->gamma_to_1[palette[i].red]; png_composite(w, v, png_ptr->trans[i], back_1.red); palette[i].red = png_ptr->gamma_from_1[w]; v = png_ptr->gamma_to_1[palette[i].green]; png_composite(w, v, png_ptr->trans[i], back_1.green); palette[i].green = png_ptr->gamma_from_1[w]; v = png_ptr->gamma_to_1[palette[i].blue]; png_composite(w, v, png_ptr->trans[i], back_1.blue); palette[i].blue = png_ptr->gamma_from_1[w]; } } else { palette[i].red = png_ptr->gamma_table[palette[i].red]; palette[i].green = png_ptr->gamma_table[palette[i].green]; palette[i].blue = png_ptr->gamma_table[palette[i].blue]; } } } /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ else /* color_type != PNG_COLOR_TYPE_PALETTE */ { double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1); double g = 1.0; double gs = 1.0; switch (png_ptr->background_gamma_type) { case PNG_BACKGROUND_GAMMA_SCREEN: g = (png_ptr->screen_gamma); gs = 1.0; break; case PNG_BACKGROUND_GAMMA_FILE: g = 1.0 / (png_ptr->gamma); gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); break; case PNG_BACKGROUND_GAMMA_UNIQUE: g = 1.0 / (png_ptr->background_gamma); gs = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma); break; } png_ptr->background_1.gray = (png_uint_16)(pow( (double)png_ptr->background.gray / m, g) * m + .5); png_ptr->background.gray = (png_uint_16)(pow( (double)png_ptr->background.gray / m, gs) * m + .5); if ((png_ptr->background.red != png_ptr->background.green) || (png_ptr->background.red != png_ptr->background.blue) || (png_ptr->background.red != png_ptr->background.gray)) { /* RGB or RGBA with color background */ png_ptr->background_1.red = (png_uint_16)(pow( (double)png_ptr->background.red / m, g) * m + .5); png_ptr->background_1.green = (png_uint_16)(pow( (double)png_ptr->background.green / m, g) * m + .5); png_ptr->background_1.blue = (png_uint_16)(pow( (double)png_ptr->background.blue / m, g) * m + .5); png_ptr->background.red = (png_uint_16)(pow( (double)png_ptr->background.red / m, gs) * m + .5); png_ptr->background.green = (png_uint_16)(pow( (double)png_ptr->background.green / m, gs) * m + .5); png_ptr->background.blue = (png_uint_16)(pow( (double)png_ptr->background.blue / m, gs) * m + .5); } else { /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ png_ptr->background_1.red = png_ptr->background_1.green = png_ptr->background_1.blue = png_ptr->background_1.gray; png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = png_ptr->background.gray; } } } else /* transformation does not include PNG_BACKGROUND */ #endif /* PNG_READ_BACKGROUND_SUPPORTED */ if (color_type == PNG_COLOR_TYPE_PALETTE) { png_colorp palette = png_ptr->palette; int num_palette = png_ptr->num_palette; int i; for (i = 0; i < num_palette; i++) { palette[i].red = png_ptr->gamma_table[palette[i].red]; palette[i].green = png_ptr->gamma_table[palette[i].green]; palette[i].blue = png_ptr->gamma_table[palette[i].blue]; } } } #if defined(PNG_READ_BACKGROUND_SUPPORTED) else #endif #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */ #if defined(PNG_READ_BACKGROUND_SUPPORTED) /* No GAMMA transformation */ if ((png_ptr->transformations & PNG_BACKGROUND) && (color_type == PNG_COLOR_TYPE_PALETTE)) { int i; int istop = (int)png_ptr->num_trans; png_color back; png_colorp palette = png_ptr->palette; back.red = (png_byte)png_ptr->background.red; back.green = (png_byte)png_ptr->background.green; back.blue = (png_byte)png_ptr->background.blue; for (i = 0; i < istop; i++) { if (png_ptr->trans[i] == 0) { palette[i] = back; } else if (png_ptr->trans[i] != 0xff) { /* The png_composite() macro is defined in png.h */ png_composite(palette[i].red, palette[i].red, png_ptr->trans[i], back.red); png_composite(palette[i].green, palette[i].green, png_ptr->trans[i], back.green); png_composite(palette[i].blue, palette[i].blue, png_ptr->trans[i], back.blue); } } } #endif /* PNG_READ_BACKGROUND_SUPPORTED */ #if defined(PNG_READ_SHIFT_SUPPORTED) if ((png_ptr->transformations & PNG_SHIFT) && (color_type == PNG_COLOR_TYPE_PALETTE)) { png_uint_16 i; png_uint_16 istop = png_ptr->num_palette; int sr = 8 - png_ptr->sig_bit.red; int sg = 8 - png_ptr->sig_bit.green; int sb = 8 - png_ptr->sig_bit.blue; if (sr < 0 || sr > 8) sr = 0; if (sg < 0 || sg > 8) sg = 0; if (sb < 0 || sb > 8) sb = 0; for (i = 0; i < istop; i++) { png_ptr->palette[i].red >>= sr; png_ptr->palette[i].green >>= sg; png_ptr->palette[i].blue >>= sb; } } #endif /* PNG_READ_SHIFT_SUPPORTED */ } #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \ && !defined(PNG_READ_BACKGROUND_SUPPORTED) if(png_ptr) return; #endif } /* Modify the info structure to reflect the transformations. The * info should be updated so a PNG file could be written with it, * assuming the transformations result in valid PNG data. */ void /* PRIVATE */ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) { png_debug(1, "in png_read_transform_info\n"); #if defined(PNG_READ_EXPAND_SUPPORTED) if (png_ptr->transformations & PNG_EXPAND) { if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (png_ptr->num_trans) info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; else info_ptr->color_type = PNG_COLOR_TYPE_RGB; info_ptr->bit_depth = 8; info_ptr->num_trans = 0; } else { if (png_ptr->num_trans) info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; if (info_ptr->bit_depth < 8) info_ptr->bit_depth = 8; info_ptr->num_trans = 0; } } #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->transformations & PNG_BACKGROUND) { info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; info_ptr->num_trans = 0; info_ptr->background = png_ptr->background; } #endif #if defined(PNG_READ_GAMMA_SUPPORTED) if (png_ptr->transformations & PNG_GAMMA) { #ifdef PNG_FLOATING_POINT_SUPPORTED info_ptr->gamma = png_ptr->gamma; #endif #ifdef PNG_FIXED_POINT_SUPPORTED info_ptr->int_gamma = png_ptr->int_gamma; #endif } #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16)) info_ptr->bit_depth = 8; #endif #if defined(PNG_READ_DITHER_SUPPORTED) if (png_ptr->transformations & PNG_DITHER) { if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && png_ptr->palette_lookup && info_ptr->bit_depth == 8) { info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; } } #endif #if defined(PNG_READ_PACK_SUPPORTED) if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) info_ptr->bit_depth = 8; #endif #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) if (png_ptr->transformations & PNG_GRAY_TO_RGB) info_ptr->color_type |= PNG_COLOR_MASK_COLOR; #endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) if (png_ptr->transformations & PNG_RGB_TO_GRAY) info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; #endif if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) info_ptr->channels = 1; else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) info_ptr->channels = 3; else info_ptr->channels = 1; #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; #endif if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) info_ptr->channels++; #if defined(PNG_READ_FILLER_SUPPORTED) /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ if ((png_ptr->transformations & PNG_FILLER) && ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) { info_ptr->channels++; /* if adding a true alpha channel not just filler */ #if !defined(PNG_1_0_X) if (png_ptr->transformations & PNG_ADD_ALPHA) info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; #endif } #endif #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ defined(PNG_READ_USER_TRANSFORM_SUPPORTED) if(png_ptr->transformations & PNG_USER_TRANSFORM) { if(info_ptr->bit_depth < png_ptr->user_transform_depth) info_ptr->bit_depth = png_ptr->user_transform_depth; if(info_ptr->channels < png_ptr->user_transform_channels) info_ptr->channels = png_ptr->user_transform_channels; } #endif info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width); #if !defined(PNG_READ_EXPAND_SUPPORTED) if(png_ptr) return; #endif } /* Transform the row. The order of transformations is significant, * and is very touchy. If you add a transformation, take care to * decide how it fits in with the other transformations here. */ void /* PRIVATE */ png_do_read_transformations(png_structp png_ptr) { png_debug(1, "in png_do_read_transformations\n"); #if !defined(PNG_USELESS_TESTS_SUPPORTED) if (png_ptr->row_buf == NULL) { #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) char msg[50]; sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number, png_ptr->pass); png_error(png_ptr, msg); #else png_error(png_ptr, "NULL row buffer"); #endif } #endif #if defined(PNG_READ_EXPAND_SUPPORTED) if (png_ptr->transformations & PNG_EXPAND) { if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) { png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->palette, png_ptr->trans, png_ptr->num_trans); } else { if (png_ptr->num_trans) png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, &(png_ptr->trans_values)); else png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, NULL); } } #endif #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)); #endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) if (png_ptr->transformations & PNG_RGB_TO_GRAY) { int rgb_error = png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1); if(rgb_error) { png_ptr->rgb_to_gray_status=1; if(png_ptr->transformations == PNG_RGB_TO_GRAY_WARN) png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); if(png_ptr->transformations == PNG_RGB_TO_GRAY_ERR) png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); } } #endif /* From Andreas Dilger e-mail to png-implement, 26 March 1998: In most cases, the "simple transparency" should be done prior to doing gray-to-RGB, or you will have to test 3x as many bytes to check if a pixel is transparent. You would also need to make sure that the transparency information is upgraded to RGB. To summarize, the current flow is: - Gray + simple transparency -> compare 1 or 2 gray bytes and composite with background "in place" if transparent, convert to RGB if necessary - Gray + alpha -> composite with gray background and remove alpha bytes, convert to RGB if necessary To support RGB backgrounds for gray images we need: - Gray + simple transparency -> convert to RGB + simple transparency, compare 3 or 6 bytes and composite with background "in place" if transparent (3x compare/pixel compared to doing composite with gray bkgrnd) - Gray + alpha -> convert to RGB + alpha, composite with background and remove alpha bytes (3x float operations/pixel compared with composite on gray background) Greg's change will do this. The reason it wasn't done before is for performance, as this increases the per-pixel operations. If we would check in advance if the background was gray or RGB, and position the gray-to-RGB transform appropriately, then it would save a lot of work/time. */ #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) /* if gray -> RGB, do so now only if background is non-gray; else do later * for performance reasons */ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) if ((png_ptr->transformations & PNG_BACKGROUND) && ((png_ptr->num_trans != 0 ) || (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1, &(png_ptr->trans_values), &(png_ptr->background) #if defined(PNG_READ_GAMMA_SUPPORTED) , &(png_ptr->background_1), png_ptr->gamma_table, png_ptr->gamma_from_1, png_ptr->gamma_to_1, png_ptr->gamma_16_table, png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1, png_ptr->gamma_shift #endif ); #endif #if defined(PNG_READ_GAMMA_SUPPORTED) if ((png_ptr->transformations & PNG_GAMMA) && #if defined(PNG_READ_BACKGROUND_SUPPORTED) !((png_ptr->transformations & PNG_BACKGROUND) && ((png_ptr->num_trans != 0) || (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && #endif (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->gamma_table, png_ptr->gamma_16_table, png_ptr->gamma_shift); #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) if (png_ptr->transformations & PNG_16_TO_8) png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_READ_DITHER_SUPPORTED) if (png_ptr->transformations & PNG_DITHER) { png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->palette_lookup, png_ptr->dither_index); if(png_ptr->row_info.rowbytes == (png_uint_32)0) png_error(png_ptr, "png_do_dither returned rowbytes=0"); } #endif #if defined(PNG_READ_INVERT_SUPPORTED) if (png_ptr->transformations & PNG_INVERT_MONO) png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_READ_SHIFT_SUPPORTED) if (png_ptr->transformations & PNG_SHIFT) png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, &(png_ptr->shift)); #endif #if defined(PNG_READ_PACK_SUPPORTED) if (png_ptr->transformations & PNG_PACK) png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_READ_BGR_SUPPORTED) if (png_ptr->transformations & PNG_BGR) png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) /* if gray -> RGB, do so now only if we did not do so above */ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_READ_FILLER_SUPPORTED) if (png_ptr->transformations & PNG_FILLER) png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, (png_uint_32)png_ptr->filler, png_ptr->flags); #endif #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) if (png_ptr->transformations & PNG_INVERT_ALPHA) png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) if (png_ptr->transformations & PNG_SWAP_ALPHA) png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_READ_SWAP_SUPPORTED) if (png_ptr->transformations & PNG_SWAP_BYTES) png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) if (png_ptr->transformations & PNG_USER_TRANSFORM) { if(png_ptr->read_user_transform_fn != NULL) (*(png_ptr->read_user_transform_fn)) /* user read transform function */ (png_ptr, /* png_ptr */ &(png_ptr->row_info), /* row_info: */ /* png_uint_32 width; width of row */ /* png_uint_32 rowbytes; number of bytes in row */ /* png_byte color_type; color type of pixels */ /* png_byte bit_depth; bit depth of samples */ /* png_byte channels; number of channels (1-4) */ /* png_byte pixel_depth; bits per pixel (depth*channels) */ png_ptr->row_buf + 1); /* start of pixel data for row */ #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) if(png_ptr->user_transform_depth) png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; if(png_ptr->user_transform_channels) png_ptr->row_info.channels = png_ptr->user_transform_channels; #endif png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * png_ptr->row_info.channels); png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->row_info.width); } #endif } #if defined(PNG_READ_PACK_SUPPORTED) /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, * without changing the actual values. Thus, if you had a row with * a bit depth of 1, you would end up with bytes that only contained * the numbers 0 or 1. If you would rather they contain 0 and 255, use * png_do_shift() after this. */ void /* PRIVATE */ png_do_unpack(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_unpack\n"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL && row_info->bit_depth < 8) #else if (row_info->bit_depth < 8) #endif { png_uint_32 i; png_uint_32 row_width=row_info->width; switch (row_info->bit_depth) { case 1: { png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); png_bytep dp = row + (png_size_t)row_width - 1; png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); for (i = 0; i < row_width; i++) { *dp = (png_byte)((*sp >> shift) & 0x01); if (shift == 7) { shift = 0; sp--; } else shift++; dp--; } break; } case 2: { png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); png_bytep dp = row + (png_size_t)row_width - 1; png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); for (i = 0; i < row_width; i++) { *dp = (png_byte)((*sp >> shift) & 0x03); if (shift == 6) { shift = 0; sp--; } else shift += 2; dp--; } break; } case 4: { png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); png_bytep dp = row + (png_size_t)row_width - 1; png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); for (i = 0; i < row_width; i++) { *dp = (png_byte)((*sp >> shift) & 0x0f); if (shift == 4) { shift = 0; sp--; } else shift = 4; dp--; } break; } } row_info->bit_depth = 8; row_info->pixel_depth = (png_byte)(8 * row_info->channels); row_info->rowbytes = row_width * row_info->channels; } } #endif #if defined(PNG_READ_SHIFT_SUPPORTED) /* Reverse the effects of png_do_shift. This routine merely shifts the * pixels back to their significant bits values. Thus, if you have * a row of bit depth 8, but only 5 are significant, this will shift * the values back to 0 through 31. */ void /* PRIVATE */ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) { png_debug(1, "in png_do_unshift\n"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && sig_bits != NULL && #endif row_info->color_type != PNG_COLOR_TYPE_PALETTE) { int shift[4]; int channels = 0; int c; png_uint_16 value = 0; png_uint_32 row_width = row_info->width; if (row_info->color_type & PNG_COLOR_MASK_COLOR) { shift[channels++] = row_info->bit_depth - sig_bits->red; shift[channels++] = row_info->bit_depth - sig_bits->green; shift[channels++] = row_info->bit_depth - sig_bits->blue; } else { shift[channels++] = row_info->bit_depth - sig_bits->gray; } if (row_info->color_type & PNG_COLOR_MASK_ALPHA) { shift[channels++] = row_info->bit_depth - sig_bits->alpha; } for (c = 0; c < channels; c++) { if (shift[c] <= 0) shift[c] = 0; else value = 1; } if (!value) return; switch (row_info->bit_depth) { case 2: { png_bytep bp; png_uint_32 i; png_uint_32 istop = row_info->rowbytes; for (bp = row, i = 0; i < istop; i++) { *bp >>= 1; *bp++ &= 0x55; } break; } case 4: { png_bytep bp = row; png_uint_32 i; png_uint_32 istop = row_info->rowbytes; png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) | (png_byte)((int)0xf >> shift[0])); for (i = 0; i < istop; i++) { *bp >>= shift[0]; *bp++ &= mask; } break; } case 8: { png_bytep bp = row; png_uint_32 i; png_uint_32 istop = row_width * channels; for (i = 0; i < istop; i++) { *bp++ >>= shift[i%channels]; } break; } case 16: { png_bytep bp = row; png_uint_32 i; png_uint_32 istop = channels * row_width; for (i = 0; i < istop; i++) { value = (png_uint_16)((*bp << 8) + *(bp + 1)); value >>= shift[i%channels]; *bp++ = (png_byte)(value >> 8); *bp++ = (png_byte)(value & 0xff); } break; } } } } #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) /* chop rows of bit depth 16 down to 8 */ void /* PRIVATE */ png_do_chop(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_chop\n"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL && row_info->bit_depth == 16) #else if (row_info->bit_depth == 16) #endif { png_bytep sp = row; png_bytep dp = row; png_uint_32 i; png_uint_32 istop = row_info->width * row_info->channels; for (i = 0; i> 8)) >> 8; * * Approximate calculation with shift/add instead of multiply/divide: * *dp = ((((png_uint_32)(*sp) << 8) | * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8; * * What we actually do to avoid extra shifting and conversion: */ *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0); #else /* Simply discard the low order byte */ *dp = *sp; #endif } row_info->bit_depth = 8; row_info->pixel_depth = (png_byte)(8 * row_info->channels); row_info->rowbytes = row_info->width * row_info->channels; } } #endif #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) void /* PRIVATE */ png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_read_swap_alpha\n"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif { png_uint_32 row_width = row_info->width; if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { /* This converts from RGBA to ARGB */ if (row_info->bit_depth == 8) { png_bytep sp = row + row_info->rowbytes; png_bytep dp = sp; png_byte save; png_uint_32 i; for (i = 0; i < row_width; i++) { save = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = save; } } /* This converts from RRGGBBAA to AARRGGBB */ else { png_bytep sp = row + row_info->rowbytes; png_bytep dp = sp; png_byte save[2]; png_uint_32 i; for (i = 0; i < row_width; i++) { save[0] = *(--sp); save[1] = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = save[0]; *(--dp) = save[1]; } } } else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { /* This converts from GA to AG */ if (row_info->bit_depth == 8) { png_bytep sp = row + row_info->rowbytes; png_bytep dp = sp; png_byte save; png_uint_32 i; for (i = 0; i < row_width; i++) { save = *(--sp); *(--dp) = *(--sp); *(--dp) = save; } } /* This converts from GGAA to AAGG */ else { png_bytep sp = row + row_info->rowbytes; png_bytep dp = sp; png_byte save[2]; png_uint_32 i; for (i = 0; i < row_width; i++) { save[0] = *(--sp); save[1] = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = save[0]; *(--dp) = save[1]; } } } } } #endif #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) void /* PRIVATE */ png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_read_invert_alpha\n"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif { png_uint_32 row_width = row_info->width; if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { /* This inverts the alpha channel in RGBA */ if (row_info->bit_depth == 8) { png_bytep sp = row + row_info->rowbytes; png_bytep dp = sp; png_uint_32 i; for (i = 0; i < row_width; i++) { *(--dp) = (png_byte)(255 - *(--sp)); /* This does nothing: *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); We can replace it with: */ sp-=3; dp=sp; } } /* This inverts the alpha channel in RRGGBBAA */ else { png_bytep sp = row + row_info->rowbytes; png_bytep dp = sp; png_uint_32 i; for (i = 0; i < row_width; i++) { *(--dp) = (png_byte)(255 - *(--sp)); *(--dp) = (png_byte)(255 - *(--sp)); /* This does nothing: *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); We can replace it with: */ sp-=6; dp=sp; } } } else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { /* This inverts the alpha channel in GA */ if (row_info->bit_depth == 8) { png_bytep sp = row + row_info->rowbytes; png_bytep dp = sp; png_uint_32 i; for (i = 0; i < row_width; i++) { *(--dp) = (png_byte)(255 - *(--sp)); *(--dp) = *(--sp); } } /* This inverts the alpha channel in GGAA */ else { png_bytep sp = row + row_info->rowbytes; png_bytep dp = sp; png_uint_32 i; for (i = 0; i < row_width; i++) { *(--dp) = (png_byte)(255 - *(--sp)); *(--dp) = (png_byte)(255 - *(--sp)); /* *(--dp) = *(--sp); *(--dp) = *(--sp); */ sp-=2; dp=sp; } } } } } #endif #if defined(PNG_READ_FILLER_SUPPORTED) /* Add filler channel if we have RGB color */ void /* PRIVATE */ png_do_read_filler(png_row_infop row_info, png_bytep row, png_uint_32 filler, png_uint_32 flags) { png_uint_32 i; png_uint_32 row_width = row_info->width; png_byte hi_filler = (png_byte)((filler>>8) & 0xff); png_byte lo_filler = (png_byte)(filler & 0xff); png_debug(1, "in png_do_read_filler\n"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif row_info->color_type == PNG_COLOR_TYPE_GRAY) { if(row_info->bit_depth == 8) { /* This changes the data from G to GX */ if (flags & PNG_FLAG_FILLER_AFTER) { png_bytep sp = row + (png_size_t)row_width; png_bytep dp = sp + (png_size_t)row_width; for (i = 1; i < row_width; i++) { *(--dp) = lo_filler; *(--dp) = *(--sp); } *(--dp) = lo_filler; row_info->channels = 2; row_info->pixel_depth = 16; row_info->rowbytes = row_width * 2; } /* This changes the data from G to XG */ else { png_bytep sp = row + (png_size_t)row_width; png_bytep dp = sp + (png_size_t)row_width; for (i = 0; i < row_width; i++) { *(--dp) = *(--sp); *(--dp) = lo_filler; } row_info->channels = 2; row_info->pixel_depth = 16; row_info->rowbytes = row_width * 2; } } else if(row_info->bit_depth == 16) { /* This changes the data from GG to GGXX */ if (flags & PNG_FLAG_FILLER_AFTER) { png_bytep sp = row + (png_size_t)row_width * 2; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 1; i < row_width; i++) { *(--dp) = hi_filler; *(--dp) = lo_filler; *(--dp) = *(--sp); *(--dp) = *(--sp); } *(--dp) = hi_filler; *(--dp) = lo_filler; row_info->channels = 2; row_info->pixel_depth = 32; row_info->rowbytes = row_width * 4; } /* This changes the data from GG to XXGG */ else { png_bytep sp = row + (png_size_t)row_width * 2; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 0; i < row_width; i++) { *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = hi_filler; *(--dp) = lo_filler; } row_info->channels = 2; row_info->pixel_depth = 32; row_info->rowbytes = row_width * 4; } } } /* COLOR_TYPE == GRAY */ else if (row_info->color_type == PNG_COLOR_TYPE_RGB) { if(row_info->bit_depth == 8) { /* This changes the data from RGB to RGBX */ if (flags & PNG_FLAG_FILLER_AFTER) { png_bytep sp = row + (png_size_t)row_width * 3; png_bytep dp = sp + (png_size_t)row_width; for (i = 1; i < row_width; i++) { *(--dp) = lo_filler; *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); } *(--dp) = lo_filler; row_info->channels = 4; row_info->pixel_depth = 32; row_info->rowbytes = row_width * 4; } /* This changes the data from RGB to XRGB */ else { png_bytep sp = row + (png_size_t)row_width * 3; png_bytep dp = sp + (png_size_t)row_width; for (i = 0; i < row_width; i++) { *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = lo_filler; } row_info->channels = 4; row_info->pixel_depth = 32; row_info->rowbytes = row_width * 4; } } else if(row_info->bit_depth == 16) { /* This changes the data from RRGGBB to RRGGBBXX */ if (flags & PNG_FLAG_FILLER_AFTER) { png_bytep sp = row + (png_size_t)row_width * 6; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 1; i < row_width; i++) { *(--dp) = hi_filler; *(--dp) = lo_filler; *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); } *(--dp) = hi_filler; *(--dp) = lo_filler; row_info->channels = 4; row_info->pixel_depth = 64; row_info->rowbytes = row_width * 8; } /* This changes the data from RRGGBB to XXRRGGBB */ else { png_bytep sp = row + (png_size_t)row_width * 6; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 0; i < row_width; i++) { *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = hi_filler; *(--dp) = lo_filler; } row_info->channels = 4; row_info->pixel_depth = 64; row_info->rowbytes = row_width * 8; } } } /* COLOR_TYPE == RGB */ } #endif #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) /* expand grayscale files to RGB, with or without alpha */ void /* PRIVATE */ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) { png_uint_32 i; png_uint_32 row_width = row_info->width; png_debug(1, "in png_do_gray_to_rgb\n"); if (row_info->bit_depth >= 8 && #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif !(row_info->color_type & PNG_COLOR_MASK_COLOR)) { if (row_info->color_type == PNG_COLOR_TYPE_GRAY) { if (row_info->bit_depth == 8) { png_bytep sp = row + (png_size_t)row_width - 1; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 0; i < row_width; i++) { *(dp--) = *sp; *(dp--) = *sp; *(dp--) = *(sp--); } } else { png_bytep sp = row + (png_size_t)row_width * 2 - 1; png_bytep dp = sp + (png_size_t)row_width * 4; for (i = 0; i < row_width; i++) { *(dp--) = *sp; *(dp--) = *(sp - 1); *(dp--) = *sp; *(dp--) = *(sp - 1); *(dp--) = *(sp--); *(dp--) = *(sp--); } } } else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { if (row_info->bit_depth == 8) { png_bytep sp = row + (png_size_t)row_width * 2 - 1; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 0; i < row_width; i++) { *(dp--) = *(sp--); *(dp--) = *sp; *(dp--) = *sp; *(dp--) = *(sp--); } } else { png_bytep sp = row + (png_size_t)row_width * 4 - 1; png_bytep dp = sp + (png_size_t)row_width * 4; for (i = 0; i < row_width; i++) { *(dp--) = *(sp--); *(dp--) = *(sp--); *(dp--) = *sp; *(dp--) = *(sp - 1); *(dp--) = *sp; *(dp--) = *(sp - 1); *(dp--) = *(sp--); *(dp--) = *(sp--); } } } row_info->channels += (png_byte)2; row_info->color_type |= PNG_COLOR_MASK_COLOR; row_info->pixel_depth = (png_byte)(row_info->channels * row_info->bit_depth); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); } } #endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) /* reduce RGB files to grayscale, with or without alpha * using the equation given in Poynton's ColorFAQ at * * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net * * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B * * We approximate this with * * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B * * which can be expressed with integers as * * Y = (6969 * R + 23434 * G + 2365 * B)/32768 * * The calculation is to be done in a linear colorspace. * * Other integer coefficents can be used via png_set_rgb_to_gray(). */ int /* PRIVATE */ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) { png_uint_32 i; png_uint_32 row_width = row_info->width; int rgb_error = 0; png_debug(1, "in png_do_rgb_to_gray\n"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif (row_info->color_type & PNG_COLOR_MASK_COLOR)) { png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff; if (row_info->color_type == PNG_COLOR_TYPE_RGB) { if (row_info->bit_depth == 8) { #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) { png_bytep sp = row; png_bytep dp = row; for (i = 0; i < row_width; i++) { png_byte red = png_ptr->gamma_to_1[*(sp++)]; png_byte green = png_ptr->gamma_to_1[*(sp++)]; png_byte blue = png_ptr->gamma_to_1[*(sp++)]; if(red != green || red != blue) { rgb_error |= 1; *(dp++) = png_ptr->gamma_from_1[ (rc*red+gc*green+bc*blue)>>15]; } else *(dp++) = *(sp-1); } } else #endif { png_bytep sp = row; png_bytep dp = row; for (i = 0; i < row_width; i++) { png_byte red = *(sp++); png_byte green = *(sp++); png_byte blue = *(sp++); if(red != green || red != blue) { rgb_error |= 1; *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15); } else *(dp++) = *(sp-1); } } } else /* RGB bit_depth == 16 */ { #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) { png_bytep sp = row; png_bytep dp = row; for (i = 0; i < row_width; i++) { png_uint_16 red, green, blue, w; red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; if(red == green && red == blue) w = red; else { png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> png_ptr->gamma_shift][red>>8]; png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >> png_ptr->gamma_shift][green>>8]; png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> png_ptr->gamma_shift][blue>>8]; png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 + bc*blue_1)>>15); w = png_ptr->gamma_16_from_1[(gray16&0xff) >> png_ptr->gamma_shift][gray16 >> 8]; rgb_error |= 1; } *(dp++) = (png_byte)((w>>8) & 0xff); *(dp++) = (png_byte)(w & 0xff); } } else #endif { png_bytep sp = row; png_bytep dp = row; for (i = 0; i < row_width; i++) { png_uint_16 red, green, blue, gray16; red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; if(red != green || red != blue) rgb_error |= 1; gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); *(dp++) = (png_byte)((gray16>>8) & 0xff); *(dp++) = (png_byte)(gray16 & 0xff); } } } } if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { if (row_info->bit_depth == 8) { #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) { png_bytep sp = row; png_bytep dp = row; for (i = 0; i < row_width; i++) { png_byte red = png_ptr->gamma_to_1[*(sp++)]; png_byte green = png_ptr->gamma_to_1[*(sp++)]; png_byte blue = png_ptr->gamma_to_1[*(sp++)]; if(red != green || red != blue) rgb_error |= 1; *(dp++) = png_ptr->gamma_from_1 [(rc*red + gc*green + bc*blue)>>15]; *(dp++) = *(sp++); /* alpha */ } } else #endif { png_bytep sp = row; png_bytep dp = row; for (i = 0; i < row_width; i++) { png_byte red = *(sp++); png_byte green = *(sp++); png_byte blue = *(sp++); if(red != green || red != blue) rgb_error |= 1; *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); *(dp++) = *(sp++); /* alpha */ } } } else /* RGBA bit_depth == 16 */ { #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) { png_bytep sp = row; png_bytep dp = row; for (i = 0; i < row_width; i++) { png_uint_16 red, green, blue, w; red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; if(red == green && red == blue) w = red; else { png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> png_ptr->gamma_shift][red>>8]; png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >> png_ptr->gamma_shift][green>>8]; png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> png_ptr->gamma_shift][blue>>8]; png_uint_16 gray16 = (png_uint_16)((rc * red_1 + gc * green_1 + bc * blue_1)>>15); w = png_ptr->gamma_16_from_1[(gray16&0xff) >> png_ptr->gamma_shift][gray16 >> 8]; rgb_error |= 1; } *(dp++) = (png_byte)((w>>8) & 0xff); *(dp++) = (png_byte)(w & 0xff); *(dp++) = *(sp++); /* alpha */ *(dp++) = *(sp++); } } else #endif { png_bytep sp = row; png_bytep dp = row; for (i = 0; i < row_width; i++) { png_uint_16 red, green, blue, gray16; red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; if(red != green || red != blue) rgb_error |= 1; gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); *(dp++) = (png_byte)((gray16>>8) & 0xff); *(dp++) = (png_byte)(gray16 & 0xff); *(dp++) = *(sp++); /* alpha */ *(dp++) = *(sp++); } } } } row_info->channels -= (png_byte)2; row_info->color_type &= ~PNG_COLOR_MASK_COLOR; row_info->pixel_depth = (png_byte)(row_info->channels * row_info->bit_depth); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); } return rgb_error; } #endif /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth * large of png_color. This lets grayscale images be treated as * paletted. Most useful for gamma correction and simplification * of code. */ void PNGAPI png_build_grayscale_palette(int bit_depth, png_colorp palette) { int num_palette; int color_inc; int i; int v; png_debug(1, "in png_do_build_grayscale_palette\n"); if (palette == NULL) return; switch (bit_depth) { case 1: num_palette = 2; color_inc = 0xff; break; case 2: num_palette = 4; color_inc = 0x55; break; case 4: num_palette = 16; color_inc = 0x11; break; case 8: num_palette = 256; color_inc = 1; break; default: num_palette = 0; color_inc = 0; break; } for (i = 0, v = 0; i < num_palette; i++, v += color_inc) { palette[i].red = (png_byte)v; palette[i].green = (png_byte)v; palette[i].blue = (png_byte)v; } } /* This function is currently unused. Do we really need it? */ #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED) void /* PRIVATE */ png_correct_palette(png_structp png_ptr, png_colorp palette, int num_palette) { png_debug(1, "in png_correct_palette\n"); #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND)) { png_color back, back_1; if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) { back.red = png_ptr->gamma_table[png_ptr->background.red]; back.green = png_ptr->gamma_table[png_ptr->background.green]; back.blue = png_ptr->gamma_table[png_ptr->background.blue]; back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; } else { double g; g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma); if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN || fabs(g - 1.0) < PNG_GAMMA_THRESHOLD) { back.red = png_ptr->background.red; back.green = png_ptr->background.green; back.blue = png_ptr->background.blue; } else { back.red = (png_byte)(pow((double)png_ptr->background.red/255, g) * 255.0 + 0.5); back.green = (png_byte)(pow((double)png_ptr->background.green/255, g) * 255.0 + 0.5); back.blue = (png_byte)(pow((double)png_ptr->background.blue/255, g) * 255.0 + 0.5); } g = 1.0 / png_ptr->background_gamma; back_1.red = (png_byte)(pow((double)png_ptr->background.red/255, g) * 255.0 + 0.5); back_1.green = (png_byte)(pow((double)png_ptr->background.green/255, g) * 255.0 + 0.5); back_1.blue = (png_byte)(pow((double)png_ptr->background.blue/255, g) * 255.0 + 0.5); } if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { png_uint_32 i; for (i = 0; i < (png_uint_32)num_palette; i++) { if (i < png_ptr->num_trans && png_ptr->trans[i] == 0) { palette[i] = back; } else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff) { png_byte v, w; v = png_ptr->gamma_to_1[png_ptr->palette[i].red]; png_composite(w, v, png_ptr->trans[i], back_1.red); palette[i].red = png_ptr->gamma_from_1[w]; v = png_ptr->gamma_to_1[png_ptr->palette[i].green]; png_composite(w, v, png_ptr->trans[i], back_1.green); palette[i].green = png_ptr->gamma_from_1[w]; v = png_ptr->gamma_to_1[png_ptr->palette[i].blue]; png_composite(w, v, png_ptr->trans[i], back_1.blue); palette[i].blue = png_ptr->gamma_from_1[w]; } else { palette[i].red = png_ptr->gamma_table[palette[i].red]; palette[i].green = png_ptr->gamma_table[palette[i].green]; palette[i].blue = png_ptr->gamma_table[palette[i].blue]; } } } else { int i; for (i = 0; i < num_palette; i++) { if (palette[i].red == (png_byte)png_ptr->trans_values.gray) { palette[i] = back; } else { palette[i].red = png_ptr->gamma_table[palette[i].red]; palette[i].green = png_ptr->gamma_table[palette[i].green]; palette[i].blue = png_ptr->gamma_table[palette[i].blue]; } } } } else #endif #if defined(PNG_READ_GAMMA_SUPPORTED) if (png_ptr->transformations & PNG_GAMMA) { int i; for (i = 0; i < num_palette; i++) { palette[i].red = png_ptr->gamma_table[palette[i].red]; palette[i].green = png_ptr->gamma_table[palette[i].green]; palette[i].blue = png_ptr->gamma_table[palette[i].blue]; } } #if defined(PNG_READ_BACKGROUND_SUPPORTED) else #endif #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->transformations & PNG_BACKGROUND) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { png_color back; back.red = (png_byte)png_ptr->background.red; back.green = (png_byte)png_ptr->background.green; back.blue = (png_byte)png_ptr->background.blue; for (i = 0; i < (int)png_ptr->num_trans; i++) { if (png_ptr->trans[i] == 0) { palette[i].red = back.red; palette[i].green = back.green; palette[i].blue = back.blue; } else if (png_ptr->trans[i] != 0xff) { png_composite(palette[i].red, png_ptr->palette[i].red, png_ptr->trans[i], back.red); png_composite(palette[i].green, png_ptr->palette[i].green, png_ptr->trans[i], back.green); png_composite(palette[i].blue, png_ptr->palette[i].blue, png_ptr->trans[i], back.blue); } } } else /* assume grayscale palette (what else could it be?) */ { int i; for (i = 0; i < num_palette; i++) { if (i == (png_byte)png_ptr->trans_values.gray) { palette[i].red = (png_byte)png_ptr->background.red; palette[i].green = (png_byte)png_ptr->background.green; palette[i].blue = (png_byte)png_ptr->background.blue; } } } } #endif } #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) /* Replace any alpha or transparency with the supplied background color. * "background" is already in the screen gamma, while "background_1" is * at a gamma of 1.0. Paletted files have already been taken care of. */ void /* PRIVATE */ png_do_background(png_row_infop row_info, png_bytep row, png_color_16p trans_values, png_color_16p background #if defined(PNG_READ_GAMMA_SUPPORTED) , png_color_16p background_1, png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, png_uint_16pp gamma_16_to_1, int gamma_shift #endif ) { png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width=row_info->width; int shift; png_debug(1, "in png_do_background\n"); if (background != NULL && #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) || (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values))) { switch (row_info->color_type) { case PNG_COLOR_TYPE_GRAY: { switch (row_info->bit_depth) { case 1: { sp = row; shift = 7; for (i = 0; i < row_width; i++) { if ((png_uint_16)((*sp >> shift) & 0x01) == trans_values->gray) { *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); *sp |= (png_byte)(background->gray << shift); } if (!shift) { shift = 7; sp++; } else shift--; } break; } case 2: { #if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_table != NULL) { sp = row; shift = 6; for (i = 0; i < row_width; i++) { if ((png_uint_16)((*sp >> shift) & 0x03) == trans_values->gray) { *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); *sp |= (png_byte)(background->gray << shift); } else { png_byte p = (png_byte)((*sp >> shift) & 0x03); png_byte g = (png_byte)((gamma_table [p | (p << 2) | (p << 4) | (p << 6)] >> 6) & 0x03); *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); *sp |= (png_byte)(g << shift); } if (!shift) { shift = 6; sp++; } else shift -= 2; } } else #endif { sp = row; shift = 6; for (i = 0; i < row_width; i++) { if ((png_uint_16)((*sp >> shift) & 0x03) == trans_values->gray) { *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); *sp |= (png_byte)(background->gray << shift); } if (!shift) { shift = 6; sp++; } else shift -= 2; } } break; } case 4: { #if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_table != NULL) { sp = row; shift = 4; for (i = 0; i < row_width; i++) { if ((png_uint_16)((*sp >> shift) & 0x0f) == trans_values->gray) { *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); *sp |= (png_byte)(background->gray << shift); } else { png_byte p = (png_byte)((*sp >> shift) & 0x0f); png_byte g = (png_byte)((gamma_table[p | (p << 4)] >> 4) & 0x0f); *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); *sp |= (png_byte)(g << shift); } if (!shift) { shift = 4; sp++; } else shift -= 4; } } else #endif { sp = row; shift = 4; for (i = 0; i < row_width; i++) { if ((png_uint_16)((*sp >> shift) & 0x0f) == trans_values->gray) { *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); *sp |= (png_byte)(background->gray << shift); } if (!shift) { shift = 4; sp++; } else shift -= 4; } } break; } case 8: { #if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_table != NULL) { sp = row; for (i = 0; i < row_width; i++, sp++) { if (*sp == trans_values->gray) { *sp = (png_byte)background->gray; } else { *sp = gamma_table[*sp]; } } } else #endif { sp = row; for (i = 0; i < row_width; i++, sp++) { if (*sp == trans_values->gray) { *sp = (png_byte)background->gray; } } } break; } case 16: { #if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_16 != NULL) { sp = row; for (i = 0; i < row_width; i++, sp += 2) { png_uint_16 v; v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); if (v == trans_values->gray) { /* background is already in screen gamma */ *sp = (png_byte)((background->gray >> 8) & 0xff); *(sp + 1) = (png_byte)(background->gray & 0xff); } else { v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); } } } else #endif { sp = row; for (i = 0; i < row_width; i++, sp += 2) { png_uint_16 v; v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); if (v == trans_values->gray) { *sp = (png_byte)((background->gray >> 8) & 0xff); *(sp + 1) = (png_byte)(background->gray & 0xff); } } } break; } } break; } case PNG_COLOR_TYPE_RGB: { if (row_info->bit_depth == 8) { #if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_table != NULL) { sp = row; for (i = 0; i < row_width; i++, sp += 3) { if (*sp == trans_values->red && *(sp + 1) == trans_values->green && *(sp + 2) == trans_values->blue) { *sp = (png_byte)background->red; *(sp + 1) = (png_byte)background->green; *(sp + 2) = (png_byte)background->blue; } else { *sp = gamma_table[*sp]; *(sp + 1) = gamma_table[*(sp + 1)]; *(sp + 2) = gamma_table[*(sp + 2)]; } } } else #endif { sp = row; for (i = 0; i < row_width; i++, sp += 3) { if (*sp == trans_values->red && *(sp + 1) == trans_values->green && *(sp + 2) == trans_values->blue) { *sp = (png_byte)background->red; *(sp + 1) = (png_byte)background->green; *(sp + 2) = (png_byte)background->blue; } } } } else /* if (row_info->bit_depth == 16) */ { #if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_16 != NULL) { sp = row; for (i = 0; i < row_width; i++, sp += 6) { png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); if (r == trans_values->red && g == trans_values->green && b == trans_values->blue) { /* background is already in screen gamma */ *sp = (png_byte)((background->red >> 8) & 0xff); *(sp + 1) = (png_byte)(background->red & 0xff); *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); *(sp + 3) = (png_byte)(background->green & 0xff); *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff); *(sp + 5) = (png_byte)(background->blue & 0xff); } else { png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; *(sp + 2) = (png_byte)((v >> 8) & 0xff); *(sp + 3) = (png_byte)(v & 0xff); v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; *(sp + 4) = (png_byte)((v >> 8) & 0xff); *(sp + 5) = (png_byte)(v & 0xff); } } } else #endif { sp = row; for (i = 0; i < row_width; i++, sp += 6) { png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1)); png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); if (r == trans_values->red && g == trans_values->green && b == trans_values->blue) { *sp = (png_byte)((background->red >> 8) & 0xff); *(sp + 1) = (png_byte)(background->red & 0xff); *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); *(sp + 3) = (png_byte)(background->green & 0xff); *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff); *(sp + 5) = (png_byte)(background->blue & 0xff); } } } } break; } case PNG_COLOR_TYPE_GRAY_ALPHA: { if (row_info->bit_depth == 8) { #if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_to_1 != NULL && gamma_from_1 != NULL && gamma_table != NULL) { sp = row; dp = row; for (i = 0; i < row_width; i++, sp += 2, dp++) { png_uint_16 a = *(sp + 1); if (a == 0xff) { *dp = gamma_table[*sp]; } else if (a == 0) { /* background is already in screen gamma */ *dp = (png_byte)background->gray; } else { png_byte v, w; v = gamma_to_1[*sp]; png_composite(w, v, a, background_1->gray); *dp = gamma_from_1[w]; } } } else #endif { sp = row; dp = row; for (i = 0; i < row_width; i++, sp += 2, dp++) { png_byte a = *(sp + 1); if (a == 0xff) { *dp = *sp; } #if defined(PNG_READ_GAMMA_SUPPORTED) else if (a == 0) { *dp = (png_byte)background->gray; } else { png_composite(*dp, *sp, a, background_1->gray); } #else *dp = (png_byte)background->gray; #endif } } } else /* if (png_ptr->bit_depth == 16) */ { #if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_16 != NULL && gamma_16_from_1 != NULL && gamma_16_to_1 != NULL) { sp = row; dp = row; for (i = 0; i < row_width; i++, sp += 4, dp += 2) { png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); if (a == (png_uint_16)0xffff) { png_uint_16 v; v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; *dp = (png_byte)((v >> 8) & 0xff); *(dp + 1) = (png_byte)(v & 0xff); } #if defined(PNG_READ_GAMMA_SUPPORTED) else if (a == 0) #else else #endif { /* background is already in screen gamma */ *dp = (png_byte)((background->gray >> 8) & 0xff); *(dp + 1) = (png_byte)(background->gray & 0xff); } #if defined(PNG_READ_GAMMA_SUPPORTED) else { png_uint_16 g, v, w; g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; png_composite_16(v, g, a, background_1->gray); w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; *dp = (png_byte)((w >> 8) & 0xff); *(dp + 1) = (png_byte)(w & 0xff); } #endif } } else #endif { sp = row; dp = row; for (i = 0; i < row_width; i++, sp += 4, dp += 2) { png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); if (a == (png_uint_16)0xffff) { png_memcpy(dp, sp, 2); } #if defined(PNG_READ_GAMMA_SUPPORTED) else if (a == 0) #else else #endif { *dp = (png_byte)((background->gray >> 8) & 0xff); *(dp + 1) = (png_byte)(background->gray & 0xff); } #if defined(PNG_READ_GAMMA_SUPPORTED) else { png_uint_16 g, v; g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); png_composite_16(v, g, a, background_1->gray); *dp = (png_byte)((v >> 8) & 0xff); *(dp + 1) = (png_byte)(v & 0xff); } #endif } } } break; } case PNG_COLOR_TYPE_RGB_ALPHA: { if (row_info->bit_depth == 8) { #if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_to_1 != NULL && gamma_from_1 != NULL && gamma_table != NULL) { sp = row; dp = row; for (i = 0; i < row_width; i++, sp += 4, dp += 3) { png_byte a = *(sp + 3); if (a == 0xff) { *dp = gamma_table[*sp]; *(dp + 1) = gamma_table[*(sp + 1)]; *(dp + 2) = gamma_table[*(sp + 2)]; } else if (a == 0) { /* background is already in screen gamma */ *dp = (png_byte)background->red; *(dp + 1) = (png_byte)background->green; *(dp + 2) = (png_byte)background->blue; } else { png_byte v, w; v = gamma_to_1[*sp]; png_composite(w, v, a, background_1->red); *dp = gamma_from_1[w]; v = gamma_to_1[*(sp + 1)]; png_composite(w, v, a, background_1->green); *(dp + 1) = gamma_from_1[w]; v = gamma_to_1[*(sp + 2)]; png_composite(w, v, a, background_1->blue); *(dp + 2) = gamma_from_1[w]; } } } else #endif { sp = row; dp = row; for (i = 0; i < row_width; i++, sp += 4, dp += 3) { png_byte a = *(sp + 3); if (a == 0xff) { *dp = *sp; *(dp + 1) = *(sp + 1); *(dp + 2) = *(sp + 2); } else if (a == 0) { *dp = (png_byte)background->red; *(dp + 1) = (png_byte)background->green; *(dp + 2) = (png_byte)background->blue; } else { png_composite(*dp, *sp, a, background->red); png_composite(*(dp + 1), *(sp + 1), a, background->green); png_composite(*(dp + 2), *(sp + 2), a, background->blue); } } } } else /* if (row_info->bit_depth == 16) */ { #if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_16 != NULL && gamma_16_from_1 != NULL && gamma_16_to_1 != NULL) { sp = row; dp = row; for (i = 0; i < row_width; i++, sp += 8, dp += 6) { png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) + (png_uint_16)(*(sp + 7))); if (a == (png_uint_16)0xffff) { png_uint_16 v; v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; *dp = (png_byte)((v >> 8) & 0xff); *(dp + 1) = (png_byte)(v & 0xff); v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; *(dp + 2) = (png_byte)((v >> 8) & 0xff); *(dp + 3) = (png_byte)(v & 0xff); v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; *(dp + 4) = (png_byte)((v >> 8) & 0xff); *(dp + 5) = (png_byte)(v & 0xff); } else if (a == 0) { /* background is already in screen gamma */ *dp = (png_byte)((background->red >> 8) & 0xff); *(dp + 1) = (png_byte)(background->red & 0xff); *(dp + 2) = (png_byte)((background->green >> 8) & 0xff); *(dp + 3) = (png_byte)(background->green & 0xff); *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff); *(dp + 5) = (png_byte)(background->blue & 0xff); } else { png_uint_16 v, w, x; v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; png_composite_16(w, v, a, background_1->red); x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; *dp = (png_byte)((x >> 8) & 0xff); *(dp + 1) = (png_byte)(x & 0xff); v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; png_composite_16(w, v, a, background_1->green); x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; *(dp + 2) = (png_byte)((x >> 8) & 0xff); *(dp + 3) = (png_byte)(x & 0xff); v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; png_composite_16(w, v, a, background_1->blue); x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8]; *(dp + 4) = (png_byte)((x >> 8) & 0xff); *(dp + 5) = (png_byte)(x & 0xff); } } } else #endif { sp = row; dp = row; for (i = 0; i < row_width; i++, sp += 8, dp += 6) { png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) + (png_uint_16)(*(sp + 7))); if (a == (png_uint_16)0xffff) { png_memcpy(dp, sp, 6); } else if (a == 0) { *dp = (png_byte)((background->red >> 8) & 0xff); *(dp + 1) = (png_byte)(background->red & 0xff); *(dp + 2) = (png_byte)((background->green >> 8) & 0xff); *(dp + 3) = (png_byte)(background->green & 0xff); *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff); *(dp + 5) = (png_byte)(background->blue & 0xff); } else { png_uint_16 v; png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + *(sp + 3)); png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + *(sp + 5)); png_composite_16(v, r, a, background->red); *dp = (png_byte)((v >> 8) & 0xff); *(dp + 1) = (png_byte)(v & 0xff); png_composite_16(v, g, a, background->green); *(dp + 2) = (png_byte)((v >> 8) & 0xff); *(dp + 3) = (png_byte)(v & 0xff); png_composite_16(v, b, a, background->blue); *(dp + 4) = (png_byte)((v >> 8) & 0xff); *(dp + 5) = (png_byte)(v & 0xff); } } } } break; } } if (row_info->color_type & PNG_COLOR_MASK_ALPHA) { row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; row_info->channels--; row_info->pixel_depth = (png_byte)(row_info->channels * row_info->bit_depth); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); } } } #endif #if defined(PNG_READ_GAMMA_SUPPORTED) /* Gamma correct the image, avoiding the alpha channel. Make sure * you do this after you deal with the transparency issue on grayscale * or RGB images. If your bit depth is 8, use gamma_table, if it * is 16, use gamma_16_table and gamma_shift. Build these with * build_gamma_table(). */ void /* PRIVATE */ png_do_gamma(png_row_infop row_info, png_bytep row, png_bytep gamma_table, png_uint_16pp gamma_16_table, int gamma_shift) { png_bytep sp; png_uint_32 i; png_uint_32 row_width=row_info->width; png_debug(1, "in png_do_gamma\n"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif ((row_info->bit_depth <= 8 && gamma_table != NULL) || (row_info->bit_depth == 16 && gamma_16_table != NULL))) { switch (row_info->color_type) { case PNG_COLOR_TYPE_RGB: { if (row_info->bit_depth == 8) { sp = row; for (i = 0; i < row_width; i++) { *sp = gamma_table[*sp]; sp++; *sp = gamma_table[*sp]; sp++; *sp = gamma_table[*sp]; sp++; } } else /* if (row_info->bit_depth == 16) */ { sp = row; for (i = 0; i < row_width; i++) { png_uint_16 v; v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; } } break; } case PNG_COLOR_TYPE_RGB_ALPHA: { if (row_info->bit_depth == 8) { sp = row; for (i = 0; i < row_width; i++) { *sp = gamma_table[*sp]; sp++; *sp = gamma_table[*sp]; sp++; *sp = gamma_table[*sp]; sp++; sp++; } } else /* if (row_info->bit_depth == 16) */ { sp = row; for (i = 0; i < row_width; i++) { png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 4; } } break; } case PNG_COLOR_TYPE_GRAY_ALPHA: { if (row_info->bit_depth == 8) { sp = row; for (i = 0; i < row_width; i++) { *sp = gamma_table[*sp]; sp += 2; } } else /* if (row_info->bit_depth == 16) */ { sp = row; for (i = 0; i < row_width; i++) { png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 4; } } break; } case PNG_COLOR_TYPE_GRAY: { if (row_info->bit_depth == 2) { sp = row; for (i = 0; i < row_width; i += 4) { int a = *sp & 0xc0; int b = *sp & 0x30; int c = *sp & 0x0c; int d = *sp & 0x03; *sp = (png_byte)( ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); sp++; } } if (row_info->bit_depth == 4) { sp = row; for (i = 0; i < row_width; i += 2) { int msb = *sp & 0xf0; int lsb = *sp & 0x0f; *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); sp++; } } else if (row_info->bit_depth == 8) { sp = row; for (i = 0; i < row_width; i++) { *sp = gamma_table[*sp]; sp++; } } else if (row_info->bit_depth == 16) { sp = row; for (i = 0; i < row_width; i++) { png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; } } break; } } } } #endif #if defined(PNG_READ_EXPAND_SUPPORTED) /* Expands a palette row to an RGB or RGBA row depending * upon whether you supply trans and num_trans. */ void /* PRIVATE */ png_do_expand_palette(png_row_infop row_info, png_bytep row, png_colorp palette, png_bytep trans, int num_trans) { int shift, value; png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width=row_info->width; png_debug(1, "in png_do_expand_palette\n"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif row_info->color_type == PNG_COLOR_TYPE_PALETTE) { if (row_info->bit_depth < 8) { switch (row_info->bit_depth) { case 1: { sp = row + (png_size_t)((row_width - 1) >> 3); dp = row + (png_size_t)row_width - 1; shift = 7 - (int)((row_width + 7) & 0x07); for (i = 0; i < row_width; i++) { if ((*sp >> shift) & 0x01) *dp = 1; else *dp = 0; if (shift == 7) { shift = 0; sp--; } else shift++; dp--; } break; } case 2: { sp = row + (png_size_t)((row_width - 1) >> 2); dp = row + (png_size_t)row_width - 1; shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); for (i = 0; i < row_width; i++) { value = (*sp >> shift) & 0x03; *dp = (png_byte)value; if (shift == 6) { shift = 0; sp--; } else shift += 2; dp--; } break; } case 4: { sp = row + (png_size_t)((row_width - 1) >> 1); dp = row + (png_size_t)row_width - 1; shift = (int)((row_width & 0x01) << 2); for (i = 0; i < row_width; i++) { value = (*sp >> shift) & 0x0f; *dp = (png_byte)value; if (shift == 4) { shift = 0; sp--; } else shift += 4; dp--; } break; } } row_info->bit_depth = 8; row_info->pixel_depth = 8; row_info->rowbytes = row_width; } switch (row_info->bit_depth) { case 8: { if (trans != NULL) { sp = row + (png_size_t)row_width - 1; dp = row + (png_size_t)(row_width << 2) - 1; for (i = 0; i < row_width; i++) { if ((int)(*sp) >= num_trans) *dp-- = 0xff; else *dp-- = trans[*sp]; *dp-- = palette[*sp].blue; *dp-- = palette[*sp].green; *dp-- = palette[*sp].red; sp--; } row_info->bit_depth = 8; row_info->pixel_depth = 32; row_info->rowbytes = row_width * 4; row_info->color_type = 6; row_info->channels = 4; } else { sp = row + (png_size_t)row_width - 1; dp = row + (png_size_t)(row_width * 3) - 1; for (i = 0; i < row_width; i++) { *dp-- = palette[*sp].blue; *dp-- = palette[*sp].green; *dp-- = palette[*sp].red; sp--; } row_info->bit_depth = 8; row_info->pixel_depth = 24; row_info->rowbytes = row_width * 3; row_info->color_type = 2; row_info->channels = 3; } break; } } } } /* If the bit depth < 8, it is expanded to 8. Also, if the * transparency value is supplied, an alpha channel is built. */ void /* PRIVATE */ png_do_expand(png_row_infop row_info, png_bytep row, png_color_16p trans_value) { int shift, value; png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width=row_info->width; png_debug(1, "in png_do_expand\n"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif { if (row_info->color_type == PNG_COLOR_TYPE_GRAY) { png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0); if (row_info->bit_depth < 8) { switch (row_info->bit_depth) { case 1: { gray = (png_uint_16)(gray*0xff); sp = row + (png_size_t)((row_width - 1) >> 3); dp = row + (png_size_t)row_width - 1; shift = 7 - (int)((row_width + 7) & 0x07); for (i = 0; i < row_width; i++) { if ((*sp >> shift) & 0x01) *dp = 0xff; else *dp = 0; if (shift == 7) { shift = 0; sp--; } else shift++; dp--; } break; } case 2: { gray = (png_uint_16)(gray*0x55); sp = row + (png_size_t)((row_width - 1) >> 2); dp = row + (png_size_t)row_width - 1; shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); for (i = 0; i < row_width; i++) { value = (*sp >> shift) & 0x03; *dp = (png_byte)(value | (value << 2) | (value << 4) | (value << 6)); if (shift == 6) { shift = 0; sp--; } else shift += 2; dp--; } break; } case 4: { gray = (png_uint_16)(gray*0x11); sp = row + (png_size_t)((row_width - 1) >> 1); dp = row + (png_size_t)row_width - 1; shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); for (i = 0; i < row_width; i++) { value = (*sp >> shift) & 0x0f; *dp = (png_byte)(value | (value << 4)); if (shift == 4) { shift = 0; sp--; } else shift = 4; dp--; } break; } } row_info->bit_depth = 8; row_info->pixel_depth = 8; row_info->rowbytes = row_width; } if (trans_value != NULL) { if (row_info->bit_depth == 8) { sp = row + (png_size_t)row_width - 1; dp = row + (png_size_t)(row_width << 1) - 1; for (i = 0; i < row_width; i++) { if (*sp == gray) *dp-- = 0; else *dp-- = 0xff; *dp-- = *sp--; } } else if (row_info->bit_depth == 16) { sp = row + row_info->rowbytes - 1; dp = row + (row_info->rowbytes << 1) - 1; for (i = 0; i < row_width; i++) { if (((png_uint_16)*(sp) | ((png_uint_16)*(sp - 1) << 8)) == gray) { *dp-- = 0; *dp-- = 0; } else { *dp-- = 0xff; *dp-- = 0xff; } *dp-- = *sp--; *dp-- = *sp--; } } row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; row_info->channels = 2; row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); } } else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value) { if (row_info->bit_depth == 8) { sp = row + (png_size_t)row_info->rowbytes - 1; dp = row + (png_size_t)(row_width << 2) - 1; for (i = 0; i < row_width; i++) { if (*(sp - 2) == trans_value->red && *(sp - 1) == trans_value->green && *(sp - 0) == trans_value->blue) *dp-- = 0; else *dp-- = 0xff; *dp-- = *sp--; *dp-- = *sp--; *dp-- = *sp--; } } else if (row_info->bit_depth == 16) { sp = row + row_info->rowbytes - 1; dp = row + (png_size_t)(row_width << 3) - 1; for (i = 0; i < row_width; i++) { if ((((png_uint_16)*(sp - 4) | ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) && (((png_uint_16)*(sp - 2) | ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) && (((png_uint_16)*(sp - 0) | ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue)) { *dp-- = 0; *dp-- = 0; } else { *dp-- = 0xff; *dp-- = 0xff; } *dp-- = *sp--; *dp-- = *sp--; *dp-- = *sp--; *dp-- = *sp--; *dp-- = *sp--; *dp-- = *sp--; } } row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; row_info->channels = 4; row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); } } } #endif #if defined(PNG_READ_DITHER_SUPPORTED) void /* PRIVATE */ png_do_dither(png_row_infop row_info, png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup) { png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width=row_info->width; png_debug(1, "in png_do_dither\n"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif { if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup && row_info->bit_depth == 8) { int r, g, b, p; sp = row; dp = row; for (i = 0; i < row_width; i++) { r = *sp++; g = *sp++; b = *sp++; /* this looks real messy, but the compiler will reduce it down to a reasonable formula. For example, with 5 bits per color, we get: p = (((r >> 3) & 0x1f) << 10) | (((g >> 3) & 0x1f) << 5) | ((b >> 3) & 0x1f); */ p = (((r >> (8 - PNG_DITHER_RED_BITS)) & ((1 << PNG_DITHER_RED_BITS) - 1)) << (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) | (((g >> (8 - PNG_DITHER_GREEN_BITS)) & ((1 << PNG_DITHER_GREEN_BITS) - 1)) << (PNG_DITHER_BLUE_BITS)) | ((b >> (8 - PNG_DITHER_BLUE_BITS)) & ((1 << PNG_DITHER_BLUE_BITS) - 1)); *dp++ = palette_lookup[p]; } row_info->color_type = PNG_COLOR_TYPE_PALETTE; row_info->channels = 1; row_info->pixel_depth = row_info->bit_depth; row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); } else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && palette_lookup != NULL && row_info->bit_depth == 8) { int r, g, b, p; sp = row; dp = row; for (i = 0; i < row_width; i++) { r = *sp++; g = *sp++; b = *sp++; sp++; p = (((r >> (8 - PNG_DITHER_RED_BITS)) & ((1 << PNG_DITHER_RED_BITS) - 1)) << (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) | (((g >> (8 - PNG_DITHER_GREEN_BITS)) & ((1 << PNG_DITHER_GREEN_BITS) - 1)) << (PNG_DITHER_BLUE_BITS)) | ((b >> (8 - PNG_DITHER_BLUE_BITS)) & ((1 << PNG_DITHER_BLUE_BITS) - 1)); *dp++ = palette_lookup[p]; } row_info->color_type = PNG_COLOR_TYPE_PALETTE; row_info->channels = 1; row_info->pixel_depth = row_info->bit_depth; row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); } else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && dither_lookup && row_info->bit_depth == 8) { sp = row; for (i = 0; i < row_width; i++, sp++) { *sp = dither_lookup[*sp]; } } } } #endif #ifdef PNG_FLOATING_POINT_SUPPORTED #if defined(PNG_READ_GAMMA_SUPPORTED) static int png_gamma_shift[] = {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0}; /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit * tables, we don't make a full table if we are reducing to 8-bit in * the future. Note also how the gamma_16 tables are segmented so that * we don't need to allocate > 64K chunks for a full 16-bit table. */ void /* PRIVATE */ png_build_gamma_table(png_structp png_ptr) { png_debug(1, "in png_build_gamma_table\n"); if(png_ptr->gamma != 0.0) { if (png_ptr->bit_depth <= 8) { int i; double g; if (png_ptr->screen_gamma > .000001) g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); else g = 1.0; png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr, (png_uint_32)256); for (i = 0; i < 256; i++) { png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0, g) * 255.0 + .5); } #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY)) { g = 1.0 / (png_ptr->gamma); png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr, (png_uint_32)256); for (i = 0; i < 256; i++) { png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0, g) * 255.0 + .5); } png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr, (png_uint_32)256); if(png_ptr->screen_gamma > 0.000001) g = 1.0 / png_ptr->screen_gamma; else g = png_ptr->gamma; /* probably doing rgb_to_gray */ for (i = 0; i < 256; i++) { png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0, g) * 255.0 + .5); } } #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ } else { double g; int i, j, shift, num; int sig_bit; png_uint_32 ig; if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) { sig_bit = (int)png_ptr->sig_bit.red; if ((int)png_ptr->sig_bit.green > sig_bit) sig_bit = png_ptr->sig_bit.green; if ((int)png_ptr->sig_bit.blue > sig_bit) sig_bit = png_ptr->sig_bit.blue; } else { sig_bit = (int)png_ptr->sig_bit.gray; } if (sig_bit > 0) shift = 16 - sig_bit; else shift = 0; if (png_ptr->transformations & PNG_16_TO_8) { if (shift < (16 - PNG_MAX_GAMMA_8)) shift = (16 - PNG_MAX_GAMMA_8); } if (shift > 8) shift = 8; if (shift < 0) shift = 0; png_ptr->gamma_shift = (png_byte)shift; num = (1 << (8 - shift)); if (png_ptr->screen_gamma > .000001) g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); else g = 1.0; png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr, (png_uint_32)(num * png_sizeof (png_uint_16p))); if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) { double fin, fout; png_uint_32 last, max; for (i = 0; i < num; i++) { png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, (png_uint_32)(256 * png_sizeof (png_uint_16))); } g = 1.0 / g; last = 0; for (i = 0; i < 256; i++) { fout = ((double)i + 0.5) / 256.0; fin = pow(fout, g); max = (png_uint_32)(fin * (double)((png_uint_32)num << 8)); while (last <= max) { png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] [(int)(last >> (8 - shift))] = (png_uint_16)( (png_uint_16)i | ((png_uint_16)i << 8)); last++; } } while (last < ((png_uint_32)num << 8)) { png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] [(int)(last >> (8 - shift))] = (png_uint_16)65535L; last++; } } else { for (i = 0; i < num; i++) { png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, (png_uint_32)(256 * png_sizeof (png_uint_16))); ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4); for (j = 0; j < 256; j++) { png_ptr->gamma_16_table[i][j] = (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / 65535.0, g) * 65535.0 + .5); } } } #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) { g = 1.0 / (png_ptr->gamma); png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr, (png_uint_32)(num * png_sizeof (png_uint_16p ))); for (i = 0; i < num; i++) { png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr, (png_uint_32)(256 * png_sizeof (png_uint_16))); ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4); for (j = 0; j < 256; j++) { png_ptr->gamma_16_to_1[i][j] = (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / 65535.0, g) * 65535.0 + .5); } } if(png_ptr->screen_gamma > 0.000001) g = 1.0 / png_ptr->screen_gamma; else g = png_ptr->gamma; /* probably doing rgb_to_gray */ png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr, (png_uint_32)(num * png_sizeof (png_uint_16p))); for (i = 0; i < num; i++) { png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr, (png_uint_32)(256 * png_sizeof (png_uint_16))); ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4); for (j = 0; j < 256; j++) { png_ptr->gamma_16_from_1[i][j] = (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / 65535.0, g) * 65535.0 + .5); } } } #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ } } } #endif /* To do: install integer version of png_build_gamma_table here */ #endif #if defined(PNG_MNG_FEATURES_SUPPORTED) /* undoes intrapixel differencing */ void /* PRIVATE */ png_do_read_intrapixel(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_read_intrapixel\n"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif (row_info->color_type & PNG_COLOR_MASK_COLOR)) { int bytes_per_pixel; png_uint_32 row_width = row_info->width; if (row_info->bit_depth == 8) { png_bytep rp; png_uint_32 i; if (row_info->color_type == PNG_COLOR_TYPE_RGB) bytes_per_pixel = 3; else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) bytes_per_pixel = 4; else return; for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) { *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff); *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff); } } else if (row_info->bit_depth == 16) { png_bytep rp; png_uint_32 i; if (row_info->color_type == PNG_COLOR_TYPE_RGB) bytes_per_pixel = 6; else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) bytes_per_pixel = 8; else return; for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) { png_uint_32 s0 = (*(rp ) << 8) | *(rp+1); png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3); png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5); png_uint_32 red = (png_uint_32)((s0+s1+65536L) & 0xffffL); png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL); *(rp ) = (png_byte)((red >> 8) & 0xff); *(rp+1) = (png_byte)(red & 0xff); *(rp+4) = (png_byte)((blue >> 8) & 0xff); *(rp+5) = (png_byte)(blue & 0xff); } } } } #endif /* PNG_MNG_FEATURES_SUPPORTED */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngset.c0000664000175000017500000011337510777447272020635 0ustar evanevan /* pngset.c - storage of image information into info struct * * libpng 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * * The functions here are used during reads to store data from the file * into the info struct, and during writes to store application data * into the info struct for writing into the file. This abstracts the * info struct and allows us to change the structure in the future. */ #define PNG_INTERNAL #include "png.h" #if defined(PNG_bKGD_SUPPORTED) void PNGAPI png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background) { png_debug1(1, "in %s storage function\n", "bKGD"); if (png_ptr == NULL || info_ptr == NULL) return; png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16)); info_ptr->valid |= PNG_INFO_bKGD; } #endif #if defined(PNG_cHRM_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI png_set_cHRM(png_structp png_ptr, png_infop info_ptr, double white_x, double white_y, double red_x, double red_y, double green_x, double green_y, double blue_x, double blue_y) { png_debug1(1, "in %s storage function\n", "cHRM"); if (png_ptr == NULL || info_ptr == NULL) return; if (white_x < 0.0 || white_y < 0.0 || red_x < 0.0 || red_y < 0.0 || green_x < 0.0 || green_y < 0.0 || blue_x < 0.0 || blue_y < 0.0) { png_warning(png_ptr, "Ignoring attempt to set negative chromaticity value"); return; } if (white_x > 21474.83 || white_y > 21474.83 || red_x > 21474.83 || red_y > 21474.83 || green_x > 21474.83 || green_y > 21474.83 || blue_x > 21474.83 || blue_y > 21474.83) { png_warning(png_ptr, "Ignoring attempt to set chromaticity value exceeding 21474.83"); return; } info_ptr->x_white = (float)white_x; info_ptr->y_white = (float)white_y; info_ptr->x_red = (float)red_x; info_ptr->y_red = (float)red_y; info_ptr->x_green = (float)green_x; info_ptr->y_green = (float)green_y; info_ptr->x_blue = (float)blue_x; info_ptr->y_blue = (float)blue_y; #ifdef PNG_FIXED_POINT_SUPPORTED info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5); info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5); info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5); info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5); info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5); info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5); info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5); info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5); #endif info_ptr->valid |= PNG_INFO_cHRM; } #endif #ifdef PNG_FIXED_POINT_SUPPORTED void PNGAPI png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, png_fixed_point blue_y) { png_debug1(1, "in %s storage function\n", "cHRM"); if (png_ptr == NULL || info_ptr == NULL) return; if (white_x < 0 || white_y < 0 || red_x < 0 || red_y < 0 || green_x < 0 || green_y < 0 || blue_x < 0 || blue_y < 0) { png_warning(png_ptr, "Ignoring attempt to set negative chromaticity value"); return; } if (white_x > (double) PNG_UINT_31_MAX || white_y > (double) PNG_UINT_31_MAX || red_x > (double) PNG_UINT_31_MAX || red_y > (double) PNG_UINT_31_MAX || green_x > (double) PNG_UINT_31_MAX || green_y > (double) PNG_UINT_31_MAX || blue_x > (double) PNG_UINT_31_MAX || blue_y > (double) PNG_UINT_31_MAX) { png_warning(png_ptr, "Ignoring attempt to set chromaticity value exceeding 21474.83"); return; } info_ptr->int_x_white = white_x; info_ptr->int_y_white = white_y; info_ptr->int_x_red = red_x; info_ptr->int_y_red = red_y; info_ptr->int_x_green = green_x; info_ptr->int_y_green = green_y; info_ptr->int_x_blue = blue_x; info_ptr->int_y_blue = blue_y; #ifdef PNG_FLOATING_POINT_SUPPORTED info_ptr->x_white = (float)(white_x/100000.); info_ptr->y_white = (float)(white_y/100000.); info_ptr->x_red = (float)( red_x/100000.); info_ptr->y_red = (float)( red_y/100000.); info_ptr->x_green = (float)(green_x/100000.); info_ptr->y_green = (float)(green_y/100000.); info_ptr->x_blue = (float)( blue_x/100000.); info_ptr->y_blue = (float)( blue_y/100000.); #endif info_ptr->valid |= PNG_INFO_cHRM; } #endif #endif #if defined(PNG_gAMA_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) { double gamma; png_debug1(1, "in %s storage function\n", "gAMA"); if (png_ptr == NULL || info_ptr == NULL) return; /* Check for overflow */ if (file_gamma > 21474.83) { png_warning(png_ptr, "Limiting gamma to 21474.83"); gamma=21474.83; } else gamma=file_gamma; info_ptr->gamma = (float)gamma; #ifdef PNG_FIXED_POINT_SUPPORTED info_ptr->int_gamma = (int)(gamma*100000.+.5); #endif info_ptr->valid |= PNG_INFO_gAMA; if(gamma == 0.0) png_warning(png_ptr, "Setting gamma=0"); } #endif void PNGAPI png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point int_gamma) { png_fixed_point gamma; png_debug1(1, "in %s storage function\n", "gAMA"); if (png_ptr == NULL || info_ptr == NULL) return; if (int_gamma > (png_fixed_point) PNG_UINT_31_MAX) { png_warning(png_ptr, "Limiting gamma to 21474.83"); gamma=PNG_UINT_31_MAX; } else { if (int_gamma < 0) { png_warning(png_ptr, "Setting negative gamma to zero"); gamma=0; } else gamma=int_gamma; } #ifdef PNG_FLOATING_POINT_SUPPORTED info_ptr->gamma = (float)(gamma/100000.); #endif #ifdef PNG_FIXED_POINT_SUPPORTED info_ptr->int_gamma = gamma; #endif info_ptr->valid |= PNG_INFO_gAMA; if(gamma == 0) png_warning(png_ptr, "Setting gamma=0"); } #endif #if defined(PNG_hIST_SUPPORTED) void PNGAPI png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist) { int i; png_debug1(1, "in %s storage function\n", "hIST"); if (png_ptr == NULL || info_ptr == NULL) return; if (info_ptr->num_palette == 0) { png_warning(png_ptr, "Palette size 0, hIST allocation skipped."); return; } #ifdef PNG_FREE_ME_SUPPORTED png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); #endif /* Changed from info->num_palette to 256 in version 1.2.1 */ png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, (png_uint_32)(256 * png_sizeof (png_uint_16))); if (png_ptr->hist == NULL) { png_warning(png_ptr, "Insufficient memory for hIST chunk data."); return; } for (i = 0; i < info_ptr->num_palette; i++) png_ptr->hist[i] = hist[i]; info_ptr->hist = png_ptr->hist; info_ptr->valid |= PNG_INFO_hIST; #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_HIST; #else png_ptr->flags |= PNG_FLAG_FREE_HIST; #endif } #endif void PNGAPI png_set_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, int interlace_type, int compression_type, int filter_type) { png_debug1(1, "in %s storage function\n", "IHDR"); if (png_ptr == NULL || info_ptr == NULL) return; /* check for width and height valid values */ if (width == 0 || height == 0) png_error(png_ptr, "Image width or height is zero in IHDR"); #ifdef PNG_SET_USER_LIMITS_SUPPORTED if (width > png_ptr->user_width_max || height > png_ptr->user_height_max) png_error(png_ptr, "image size exceeds user limits in IHDR"); #else if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX) png_error(png_ptr, "image size exceeds user limits in IHDR"); #endif if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX) png_error(png_ptr, "Invalid image size in IHDR"); if ( width > (PNG_UINT_32_MAX >> 3) /* 8-byte RGBA pixels */ - 64 /* bigrowbuf hack */ - 1 /* filter byte */ - 7*8 /* rounding of width to multiple of 8 pixels */ - 8) /* extra max_pixel_depth pad */ png_warning(png_ptr, "Width is too large for libpng to process pixels"); /* check other values */ if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && bit_depth != 8 && bit_depth != 16) png_error(png_ptr, "Invalid bit depth in IHDR"); if (color_type < 0 || color_type == 1 || color_type == 5 || color_type > 6) png_error(png_ptr, "Invalid color type in IHDR"); if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || ((color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY_ALPHA || color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) png_error(png_ptr, "Invalid color type/bit depth combination in IHDR"); if (interlace_type >= PNG_INTERLACE_LAST) png_error(png_ptr, "Unknown interlace method in IHDR"); if (compression_type != PNG_COMPRESSION_TYPE_BASE) png_error(png_ptr, "Unknown compression method in IHDR"); #if defined(PNG_MNG_FEATURES_SUPPORTED) /* Accept filter_method 64 (intrapixel differencing) only if * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and * 2. Libpng did not read a PNG signature (this filter_method is only * used in PNG datastreams that are embedded in MNG datastreams) and * 3. The application called png_permit_mng_features with a mask that * included PNG_FLAG_MNG_FILTER_64 and * 4. The filter_method is 64 and * 5. The color_type is RGB or RGBA */ if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted) png_warning(png_ptr,"MNG features are not allowed in a PNG datastream\n"); if(filter_type != PNG_FILTER_TYPE_BASE) { if(!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA))) png_error(png_ptr, "Unknown filter method in IHDR"); if(png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) png_warning(png_ptr, "Invalid filter method in IHDR"); } #else if(filter_type != PNG_FILTER_TYPE_BASE) png_error(png_ptr, "Unknown filter method in IHDR"); #endif info_ptr->width = width; info_ptr->height = height; info_ptr->bit_depth = (png_byte)bit_depth; info_ptr->color_type =(png_byte) color_type; info_ptr->compression_type = (png_byte)compression_type; info_ptr->filter_type = (png_byte)filter_type; info_ptr->interlace_type = (png_byte)interlace_type; if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) info_ptr->channels = 1; else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) info_ptr->channels = 3; else info_ptr->channels = 1; if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) info_ptr->channels++; info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); /* check for potential overflow */ if ( width > (PNG_UINT_32_MAX >> 3) /* 8-byte RGBA pixels */ - 64 /* bigrowbuf hack */ - 1 /* filter byte */ - 7*8 /* rounding of width to multiple of 8 pixels */ - 8) /* extra max_pixel_depth pad */ info_ptr->rowbytes = (png_size_t)0; else info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,width); } #if defined(PNG_oFFs_SUPPORTED) void PNGAPI png_set_oFFs(png_structp png_ptr, png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y, int unit_type) { png_debug1(1, "in %s storage function\n", "oFFs"); if (png_ptr == NULL || info_ptr == NULL) return; info_ptr->x_offset = offset_x; info_ptr->y_offset = offset_y; info_ptr->offset_unit_type = (png_byte)unit_type; info_ptr->valid |= PNG_INFO_oFFs; } #endif #if defined(PNG_pCAL_SUPPORTED) void PNGAPI png_set_pCAL(png_structp png_ptr, png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, png_charp units, png_charpp params) { png_uint_32 length; int i; png_debug1(1, "in %s storage function\n", "pCAL"); if (png_ptr == NULL || info_ptr == NULL) return; length = png_strlen(purpose) + 1; png_debug1(3, "allocating purpose for info (%lu bytes)\n", length); info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); if (info_ptr->pcal_purpose == NULL) { png_warning(png_ptr, "Insufficient memory for pCAL purpose."); return; } png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length); png_debug(3, "storing X0, X1, type, and nparams in info\n"); info_ptr->pcal_X0 = X0; info_ptr->pcal_X1 = X1; info_ptr->pcal_type = (png_byte)type; info_ptr->pcal_nparams = (png_byte)nparams; length = png_strlen(units) + 1; png_debug1(3, "allocating units for info (%lu bytes)\n", length); info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); if (info_ptr->pcal_units == NULL) { png_warning(png_ptr, "Insufficient memory for pCAL units."); return; } png_memcpy(info_ptr->pcal_units, units, (png_size_t)length); info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)((nparams + 1) * png_sizeof(png_charp))); if (info_ptr->pcal_params == NULL) { png_warning(png_ptr, "Insufficient memory for pCAL params."); return; } info_ptr->pcal_params[nparams] = NULL; for (i = 0; i < nparams; i++) { length = png_strlen(params[i]) + 1; png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length); info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); if (info_ptr->pcal_params[i] == NULL) { png_warning(png_ptr, "Insufficient memory for pCAL parameter."); return; } png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length); } info_ptr->valid |= PNG_INFO_pCAL; #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_PCAL; #endif } #endif #if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width, double height) { png_debug1(1, "in %s storage function\n", "sCAL"); if (png_ptr == NULL || info_ptr == NULL) return; info_ptr->scal_unit = (png_byte)unit; info_ptr->scal_pixel_width = width; info_ptr->scal_pixel_height = height; info_ptr->valid |= PNG_INFO_sCAL; } #else #ifdef PNG_FIXED_POINT_SUPPORTED void PNGAPI png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, int unit, png_charp swidth, png_charp sheight) { png_uint_32 length; png_debug1(1, "in %s storage function\n", "sCAL"); if (png_ptr == NULL || info_ptr == NULL) return; info_ptr->scal_unit = (png_byte)unit; length = png_strlen(swidth) + 1; png_debug1(3, "allocating unit for info (%d bytes)\n", length); info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length); if (info_ptr->scal_s_width == NULL) { png_warning(png_ptr, "Memory allocation failed while processing sCAL."); } png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length); length = png_strlen(sheight) + 1; png_debug1(3, "allocating unit for info (%d bytes)\n", length); info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length); if (info_ptr->scal_s_height == NULL) { png_free (png_ptr, info_ptr->scal_s_width); png_warning(png_ptr, "Memory allocation failed while processing sCAL."); } png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length); info_ptr->valid |= PNG_INFO_sCAL; #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_SCAL; #endif } #endif #endif #endif #if defined(PNG_pHYs_SUPPORTED) void PNGAPI png_set_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type) { png_debug1(1, "in %s storage function\n", "pHYs"); if (png_ptr == NULL || info_ptr == NULL) return; info_ptr->x_pixels_per_unit = res_x; info_ptr->y_pixels_per_unit = res_y; info_ptr->phys_unit_type = (png_byte)unit_type; info_ptr->valid |= PNG_INFO_pHYs; } #endif void PNGAPI png_set_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp palette, int num_palette) { png_debug1(1, "in %s storage function\n", "PLTE"); if (png_ptr == NULL || info_ptr == NULL) return; /* * It may not actually be necessary to set png_ptr->palette here; * we do it for backward compatibility with the way the png_handle_tRNS * function used to do the allocation. */ #ifdef PNG_FREE_ME_SUPPORTED png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); #endif /* Changed in libpng-1.2.1 to allocate 256 instead of num_palette entries, in case of an invalid PNG file that has too-large sample values. */ png_ptr->palette = (png_colorp)png_malloc(png_ptr, 256 * png_sizeof(png_color)); png_memset(png_ptr->palette, 0, 256 * png_sizeof(png_color)); png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof (png_color)); info_ptr->palette = png_ptr->palette; info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_PLTE; #else png_ptr->flags |= PNG_FLAG_FREE_PLTE; #endif info_ptr->valid |= PNG_INFO_PLTE; } #if defined(PNG_sBIT_SUPPORTED) void PNGAPI png_set_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p sig_bit) { png_debug1(1, "in %s storage function\n", "sBIT"); if (png_ptr == NULL || info_ptr == NULL) return; png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof (png_color_8)); info_ptr->valid |= PNG_INFO_sBIT; } #endif #if defined(PNG_sRGB_SUPPORTED) void PNGAPI png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent) { png_debug1(1, "in %s storage function\n", "sRGB"); if (png_ptr == NULL || info_ptr == NULL) return; info_ptr->srgb_intent = (png_byte)intent; info_ptr->valid |= PNG_INFO_sRGB; } void PNGAPI png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, int intent) { #if defined(PNG_gAMA_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED float file_gamma; #endif #ifdef PNG_FIXED_POINT_SUPPORTED png_fixed_point int_file_gamma; #endif #endif #if defined(PNG_cHRM_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; #endif #ifdef PNG_FIXED_POINT_SUPPORTED png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y, int_blue_x, int_blue_y; #endif #endif png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM"); if (png_ptr == NULL || info_ptr == NULL) return; png_set_sRGB(png_ptr, info_ptr, intent); #if defined(PNG_gAMA_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED file_gamma = (float).45455; png_set_gAMA(png_ptr, info_ptr, file_gamma); #endif #ifdef PNG_FIXED_POINT_SUPPORTED int_file_gamma = 45455L; png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma); #endif #endif #if defined(PNG_cHRM_SUPPORTED) #ifdef PNG_FIXED_POINT_SUPPORTED int_white_x = 31270L; int_white_y = 32900L; int_red_x = 64000L; int_red_y = 33000L; int_green_x = 30000L; int_green_y = 60000L; int_blue_x = 15000L; int_blue_y = 6000L; png_set_cHRM_fixed(png_ptr, info_ptr, int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y, int_blue_x, int_blue_y); #endif #ifdef PNG_FLOATING_POINT_SUPPORTED white_x = (float).3127; white_y = (float).3290; red_x = (float).64; red_y = (float).33; green_x = (float).30; green_y = (float).60; blue_x = (float).15; blue_y = (float).06; png_set_cHRM(png_ptr, info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); #endif #endif } #endif #if defined(PNG_iCCP_SUPPORTED) void PNGAPI png_set_iCCP(png_structp png_ptr, png_infop info_ptr, png_charp name, int compression_type, png_charp profile, png_uint_32 proflen) { png_charp new_iccp_name; png_charp new_iccp_profile; png_debug1(1, "in %s storage function\n", "iCCP"); if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) return; new_iccp_name = (png_charp)png_malloc_warn(png_ptr, png_strlen(name)+1); if (new_iccp_name == NULL) { png_warning(png_ptr, "Insufficient memory to process iCCP chunk."); return; } png_strcpy(new_iccp_name, name); new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen); if (new_iccp_profile == NULL) { png_free (png_ptr, new_iccp_name); png_warning(png_ptr, "Insufficient memory to process iCCP profile."); return; } png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); info_ptr->iccp_proflen = proflen; info_ptr->iccp_name = new_iccp_name; info_ptr->iccp_profile = new_iccp_profile; /* Compression is always zero but is here so the API and info structure * does not have to change if we introduce multiple compression types */ info_ptr->iccp_compression = (png_byte)compression_type; #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_ICCP; #endif info_ptr->valid |= PNG_INFO_iCCP; } #endif #if defined(PNG_TEXT_SUPPORTED) void PNGAPI png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, int num_text) { int ret; ret=png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); if (ret) png_error(png_ptr, "Insufficient memory to store text"); } int /* PRIVATE */ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, int num_text) { int i; png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ? "text" : (png_const_charp)png_ptr->chunk_name)); if (png_ptr == NULL || info_ptr == NULL || num_text == 0) return(0); /* Make sure we have enough space in the "text" array in info_struct * to hold all of the incoming text_ptr objects. */ if (info_ptr->num_text + num_text > info_ptr->max_text) { if (info_ptr->text != NULL) { png_textp old_text; int old_max; old_max = info_ptr->max_text; info_ptr->max_text = info_ptr->num_text + num_text + 8; old_text = info_ptr->text; info_ptr->text = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)(info_ptr->max_text * png_sizeof (png_text))); if (info_ptr->text == NULL) { png_free(png_ptr, old_text); return(1); } png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * png_sizeof(png_text))); png_free(png_ptr, old_text); } else { info_ptr->max_text = num_text + 8; info_ptr->num_text = 0; info_ptr->text = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)(info_ptr->max_text * png_sizeof (png_text))); if (info_ptr->text == NULL) return(1); #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_TEXT; #endif } png_debug1(3, "allocated %d entries for info_ptr->text\n", info_ptr->max_text); } for (i = 0; i < num_text; i++) { png_size_t text_length,key_len; png_size_t lang_len,lang_key_len; png_textp textp = &(info_ptr->text[info_ptr->num_text]); if (text_ptr[i].key == NULL) continue; key_len = png_strlen(text_ptr[i].key); if(text_ptr[i].compression <= 0) { lang_len = 0; lang_key_len = 0; } else #ifdef PNG_iTXt_SUPPORTED { /* set iTXt data */ if (text_ptr[i].lang != NULL) lang_len = png_strlen(text_ptr[i].lang); else lang_len = 0; if (text_ptr[i].lang_key != NULL) lang_key_len = png_strlen(text_ptr[i].lang_key); else lang_key_len = 0; } #else { png_warning(png_ptr, "iTXt chunk not supported."); continue; } #endif if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') { text_length = 0; #ifdef PNG_iTXt_SUPPORTED if(text_ptr[i].compression > 0) textp->compression = PNG_ITXT_COMPRESSION_NONE; else #endif textp->compression = PNG_TEXT_COMPRESSION_NONE; } else { text_length = png_strlen(text_ptr[i].text); textp->compression = text_ptr[i].compression; } textp->key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4)); if (textp->key == NULL) return(1); png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n", (png_uint_32)(key_len + lang_len + lang_key_len + text_length + 4), (int)textp->key); png_memcpy(textp->key, text_ptr[i].key, (png_size_t)(key_len)); *(textp->key+key_len) = '\0'; #ifdef PNG_iTXt_SUPPORTED if (text_ptr[i].compression > 0) { textp->lang=textp->key + key_len + 1; png_memcpy(textp->lang, text_ptr[i].lang, lang_len); *(textp->lang+lang_len) = '\0'; textp->lang_key=textp->lang + lang_len + 1; png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); *(textp->lang_key+lang_key_len) = '\0'; textp->text=textp->lang_key + lang_key_len + 1; } else #endif { #ifdef PNG_iTXt_SUPPORTED textp->lang=NULL; textp->lang_key=NULL; #endif textp->text=textp->key + key_len + 1; } if(text_length) png_memcpy(textp->text, text_ptr[i].text, (png_size_t)(text_length)); *(textp->text+text_length) = '\0'; #ifdef PNG_iTXt_SUPPORTED if(textp->compression > 0) { textp->text_length = 0; textp->itxt_length = text_length; } else #endif { textp->text_length = text_length; #ifdef PNG_iTXt_SUPPORTED textp->itxt_length = 0; #endif } info_ptr->text[info_ptr->num_text]= *textp; info_ptr->num_text++; png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text); } return(0); } #endif #if defined(PNG_tIME_SUPPORTED) void PNGAPI png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time) { png_debug1(1, "in %s storage function\n", "tIME"); if (png_ptr == NULL || info_ptr == NULL || (png_ptr->mode & PNG_WROTE_tIME)) return; png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof (png_time)); info_ptr->valid |= PNG_INFO_tIME; } #endif #if defined(PNG_tRNS_SUPPORTED) void PNGAPI png_set_tRNS(png_structp png_ptr, png_infop info_ptr, png_bytep trans, int num_trans, png_color_16p trans_values) { png_debug1(1, "in %s storage function\n", "tRNS"); if (png_ptr == NULL || info_ptr == NULL) return; if (trans != NULL) { /* * It may not actually be necessary to set png_ptr->trans here; * we do it for backward compatibility with the way the png_handle_tRNS * function used to do the allocation. */ #ifdef PNG_FREE_ME_SUPPORTED png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); #endif /* Changed from num_trans to 256 in version 1.2.1 */ png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr, (png_uint_32)256); png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans); #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_TRNS; #else png_ptr->flags |= PNG_FLAG_FREE_TRNS; #endif } if (trans_values != NULL) { png_memcpy(&(info_ptr->trans_values), trans_values, png_sizeof(png_color_16)); if (num_trans == 0) num_trans = 1; } info_ptr->num_trans = (png_uint_16)num_trans; info_ptr->valid |= PNG_INFO_tRNS; } #endif #if defined(PNG_sPLT_SUPPORTED) void PNGAPI png_set_sPLT(png_structp png_ptr, png_infop info_ptr, png_sPLT_tp entries, int nentries) { png_sPLT_tp np; int i; np = (png_sPLT_tp)png_malloc_warn(png_ptr, (info_ptr->splt_palettes_num + nentries) * png_sizeof(png_sPLT_t)); if (np == NULL) { png_warning(png_ptr, "No memory for sPLT palettes."); return; } png_memcpy(np, info_ptr->splt_palettes, info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t)); png_free(png_ptr, info_ptr->splt_palettes); info_ptr->splt_palettes=NULL; for (i = 0; i < nentries; i++) { png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; png_sPLT_tp from = entries + i; to->name = (png_charp)png_malloc(png_ptr, png_strlen(from->name) + 1); /* TODO: use png_malloc_warn */ png_strcpy(to->name, from->name); to->entries = (png_sPLT_entryp)png_malloc(png_ptr, from->nentries * png_sizeof(png_sPLT_t)); /* TODO: use png_malloc_warn */ png_memcpy(to->entries, from->entries, from->nentries * png_sizeof(png_sPLT_t)); to->nentries = from->nentries; to->depth = from->depth; } info_ptr->splt_palettes = np; info_ptr->splt_palettes_num += nentries; info_ptr->valid |= PNG_INFO_sPLT; #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_SPLT; #endif } #endif /* PNG_sPLT_SUPPORTED */ #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) void PNGAPI png_set_unknown_chunks(png_structp png_ptr, png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns) { png_unknown_chunkp np; int i; if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) return; np = (png_unknown_chunkp)png_malloc_warn(png_ptr, (info_ptr->unknown_chunks_num + num_unknowns) * png_sizeof(png_unknown_chunk)); if (np == NULL) { png_warning(png_ptr, "Out of memory while processing unknown chunk."); return; } png_memcpy(np, info_ptr->unknown_chunks, info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk)); png_free(png_ptr, info_ptr->unknown_chunks); info_ptr->unknown_chunks=NULL; for (i = 0; i < num_unknowns; i++) { png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; png_unknown_chunkp from = unknowns + i; png_strncpy((png_charp)to->name, (png_charp)from->name, 5); to->data = (png_bytep)png_malloc_warn(png_ptr, from->size); if (to->data == NULL) { png_warning(png_ptr, "Out of memory processing unknown chunk."); } else { png_memcpy(to->data, from->data, from->size); to->size = from->size; /* note our location in the read or write sequence */ to->location = (png_byte)(png_ptr->mode & 0xff); } } info_ptr->unknown_chunks = np; info_ptr->unknown_chunks_num += num_unknowns; #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_UNKN; #endif } void PNGAPI png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, int chunk, int location) { if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < (int)info_ptr->unknown_chunks_num) info_ptr->unknown_chunks[chunk].location = (png_byte)location; } #endif #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) void PNGAPI png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted) { /* This function is deprecated in favor of png_permit_mng_features() and will be removed from libpng-2.0.0 */ png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n"); if (png_ptr == NULL) return; png_ptr->mng_features_permitted = (png_byte) ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) | ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE))); } #endif #if defined(PNG_MNG_FEATURES_SUPPORTED) png_uint_32 PNGAPI png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) { png_debug(1, "in png_permit_mng_features\n"); if (png_ptr == NULL) return (png_uint_32)0; png_ptr->mng_features_permitted = (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); return (png_uint_32)png_ptr->mng_features_permitted; } #endif #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) void PNGAPI png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep chunk_list, int num_chunks) { png_bytep new_list, p; int i, old_num_chunks; if (num_chunks == 0) { if(keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; else png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; if(keep == PNG_HANDLE_CHUNK_ALWAYS) png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; else png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; return; } if (chunk_list == NULL) return; old_num_chunks=png_ptr->num_chunk_list; new_list=(png_bytep)png_malloc(png_ptr, (png_uint_32)(5*(num_chunks+old_num_chunks))); if(png_ptr->chunk_list != NULL) { png_memcpy(new_list, png_ptr->chunk_list, (png_size_t)(5*old_num_chunks)); png_free(png_ptr, png_ptr->chunk_list); png_ptr->chunk_list=NULL; } png_memcpy(new_list+5*old_num_chunks, chunk_list, (png_size_t)(5*num_chunks)); for (p=new_list+5*old_num_chunks+4, i=0; inum_chunk_list=old_num_chunks+num_chunks; png_ptr->chunk_list=new_list; #ifdef PNG_FREE_ME_SUPPORTED png_ptr->free_me |= PNG_FREE_LIST; #endif } #endif #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) void PNGAPI png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn) { png_debug(1, "in png_set_read_user_chunk_fn\n"); png_ptr->read_user_chunk_fn = read_user_chunk_fn; png_ptr->user_chunk_ptr = user_chunk_ptr; } #endif #if defined(PNG_INFO_IMAGE_SUPPORTED) void PNGAPI png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) { png_debug1(1, "in %s storage function\n", "rows"); if (png_ptr == NULL || info_ptr == NULL) return; if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers)) png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); info_ptr->row_pointers = row_pointers; if(row_pointers) info_ptr->valid |= PNG_INFO_IDAT; } #endif #ifdef PNG_WRITE_SUPPORTED void PNGAPI png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size) { if(png_ptr->zbuf) png_free(png_ptr, png_ptr->zbuf); png_ptr->zbuf_size = (png_size_t)size; png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; } #endif void PNGAPI png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) { if (png_ptr && info_ptr) info_ptr->valid &= ~(mask); } #ifndef PNG_1_0_X #ifdef PNG_ASSEMBLER_CODE_SUPPORTED /* this function was added to libpng 1.2.0 and should always exist by default */ void PNGAPI png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags) { png_uint_32 settable_asm_flags; png_uint_32 settable_mmx_flags; settable_mmx_flags = #ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | #endif #ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE PNG_ASM_FLAG_MMX_READ_INTERLACE | #endif #ifdef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW PNG_ASM_FLAG_MMX_READ_FILTER_SUB | PNG_ASM_FLAG_MMX_READ_FILTER_UP | PNG_ASM_FLAG_MMX_READ_FILTER_AVG | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH | #endif 0; /* could be some non-MMX ones in the future, but not currently: */ settable_asm_flags = settable_mmx_flags; if (!(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_COMPILED) || !(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU)) { /* clear all MMX flags if MMX isn't supported */ settable_asm_flags &= ~settable_mmx_flags; png_ptr->asm_flags &= ~settable_mmx_flags; } /* we're replacing the settable bits with those passed in by the user, * so first zero them out of the master copy, then logical-OR in the * allowed subset that was requested */ png_ptr->asm_flags &= ~settable_asm_flags; /* zero them */ png_ptr->asm_flags |= (asm_flags & settable_asm_flags); /* set them */ } #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ #ifdef PNG_ASSEMBLER_CODE_SUPPORTED /* this function was added to libpng 1.2.0 */ void PNGAPI png_set_mmx_thresholds (png_structp png_ptr, png_byte mmx_bitdepth_threshold, png_uint_32 mmx_rowbytes_threshold) { png_ptr->mmx_bitdepth_threshold = mmx_bitdepth_threshold; png_ptr->mmx_rowbytes_threshold = mmx_rowbytes_threshold; } #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED /* this function was added to libpng 1.2.6 */ void PNGAPI png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max) { /* Images with dimensions larger than these limits will be * rejected by png_set_IHDR(). To accept any PNG datastream * regardless of dimensions, set both limits to 0x7ffffffL. */ png_ptr->user_width_max = user_width_max; png_ptr->user_height_max = user_height_max; } #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ #endif /* ?PNG_1_0_X */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/pnggccrd.c0000664000175000017500000071310210777447272021116 0ustar evanevan/* pnggccrd.c - mixed C/assembler version of utilities to read a PNG file * * For Intel x86 CPU (Pentium-MMX or later) and GNU C compiler. * * See http://www.intel.com/drg/pentiumII/appnotes/916/916.htm * and http://www.intel.com/drg/pentiumII/appnotes/923/923.htm * for Intel's performance analysis of the MMX vs. non-MMX code. * * libpng version 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * Copyright (c) 1998, Intel Corporation * * Based on MSVC code contributed by Nirav Chhatrapati, Intel Corp., 1998. * Interface to libpng contributed by Gilles Vollant, 1999. * GNU C port by Greg Roelofs, 1999-2001. * * Lines 2350-4300 converted in place with intel2gas 1.3.1: * * intel2gas -mdI pnggccrd.c.partially-msvc -o pnggccrd.c * * and then cleaned up by hand. See http://hermes.terminal.at/intel2gas/ . * * NOTE: A sufficiently recent version of GNU as (or as.exe under DOS/Windows) * is required to assemble the newer MMX instructions such as movq. * For djgpp, see * * ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bnu281b.zip * * (or a later version in the same directory). For Linux, check your * distribution's web site(s) or try these links: * * http://rufus.w3.org/linux/RPM/binutils.html * http://www.debian.org/Packages/stable/devel/binutils.html * ftp://ftp.slackware.com/pub/linux/slackware/slackware/slakware/d1/ * binutils.tgz * * For other platforms, see the main GNU site: * * ftp://ftp.gnu.org/pub/gnu/binutils/ * * Version 2.5.2l.15 is definitely too old... */ /* * TEMPORARY PORTING NOTES AND CHANGELOG (mostly by Greg Roelofs) * ===================================== * * 19991006: * - fixed sign error in post-MMX cleanup code (16- & 32-bit cases) * * 19991007: * - additional optimizations (possible or definite): * x [DONE] write MMX code for 64-bit case (pixel_bytes == 8) [not tested] * - write MMX code for 48-bit case (pixel_bytes == 6) * - figure out what's up with 24-bit case (pixel_bytes == 3): * why subtract 8 from width_mmx in the pass 4/5 case? * (only width_mmx case) (near line 1606) * x [DONE] replace pixel_bytes within each block with the true * constant value (or are compilers smart enough to do that?) * - rewrite all MMX interlacing code so it's aligned with * the *beginning* of the row buffer, not the end. This * would not only allow one to eliminate half of the memory * writes for odd passes (that is, pass == odd), it may also * eliminate some unaligned-data-access exceptions (assuming * there's a penalty for not aligning 64-bit accesses on * 64-bit boundaries). The only catch is that the "leftover" * pixel(s) at the end of the row would have to be saved, * but there are enough unused MMX registers in every case, * so this is not a problem. A further benefit is that the * post-MMX cleanup code (C code) in at least some of the * cases could be done within the assembler block. * x [DONE] the "v3 v2 v1 v0 v7 v6 v5 v4" comments are confusing, * inconsistent, and don't match the MMX Programmer's Reference * Manual conventions anyway. They should be changed to * "b7 b6 b5 b4 b3 b2 b1 b0," where b0 indicates the byte that * was lowest in memory (e.g., corresponding to a left pixel) * and b7 is the byte that was highest (e.g., a right pixel). * * 19991016: * - Brennan's Guide notwithstanding, gcc under Linux does *not* * want globals prefixed by underscores when referencing them-- * i.e., if the variable is const4, then refer to it as const4, * not _const4. This seems to be a djgpp-specific requirement. * Also, such variables apparently *must* be declared outside * of functions; neither static nor automatic variables work if * defined within the scope of a single function, but both * static and truly global (multi-module) variables work fine. * * 19991023: * - fixed png_combine_row() non-MMX replication bug (odd passes only?) * - switched from string-concatenation-with-macros to cleaner method of * renaming global variables for djgpp--i.e., always use prefixes in * inlined assembler code (== strings) and conditionally rename the * variables, not the other way around. Hence _const4, _mask8_0, etc. * * 19991024: * - fixed mmxsupport()/png_do_read_interlace() first-row bug * This one was severely weird: even though mmxsupport() doesn't touch * ebx (where "row" pointer was stored), it nevertheless managed to zero * the register (even in static/non-fPIC code--see below), which in turn * caused png_do_read_interlace() to return prematurely on the first row of * interlaced images (i.e., without expanding the interlaced pixels). * Inspection of the generated assembly code didn't turn up any clues, * although it did point at a minor optimization (i.e., get rid of * mmx_supported_local variable and just use eax). Possibly the CPUID * instruction is more destructive than it looks? (Not yet checked.) * - "info gcc" was next to useless, so compared fPIC and non-fPIC assembly * listings... Apparently register spillage has to do with ebx, since * it's used to index the global offset table. Commenting it out of the * input-reg lists in png_combine_row() eliminated compiler barfage, so * ifdef'd with __PIC__ macro: if defined, use a global for unmask * * 19991107: * - verified CPUID clobberage: 12-char string constant ("GenuineIntel", * "AuthenticAMD", etc.) placed in ebx:ecx:edx. Still need to polish. * * 19991120: * - made "diff" variable (now "_dif") global to simplify conversion of * filtering routines (running out of regs, sigh). "diff" is still used * in interlacing routines, however. * - fixed up both versions of mmxsupport() (ORIG_THAT_USED_TO_CLOBBER_EBX * macro determines which is used); original not yet tested. * * 20000213: * - when compiling with gcc, be sure to use -fomit-frame-pointer * * 20000319: * - fixed a register-name typo in png_do_read_interlace(), default (MMX) case, * pass == 4 or 5, that caused visible corruption of interlaced images * * 20000623: * - Various problems were reported with gcc 2.95.2 in the Cygwin environment, * many of the form "forbidden register 0 (ax) was spilled for class AREG." * This is explained at http://gcc.gnu.org/fom_serv/cache/23.html, and * Chuck Wilson supplied a patch involving dummy output registers. See * http://sourceforge.net/bugs/?func=detailbug&bug_id=108741&group_id=5624 * for the original (anonymous) SourceForge bug report. * * 20000706: * - Chuck Wilson passed along these remaining gcc 2.95.2 errors: * pnggccrd.c: In function `png_combine_row': * pnggccrd.c:525: more than 10 operands in `asm' * pnggccrd.c:669: more than 10 operands in `asm' * pnggccrd.c:828: more than 10 operands in `asm' * pnggccrd.c:994: more than 10 operands in `asm' * pnggccrd.c:1177: more than 10 operands in `asm' * They are all the same problem and can be worked around by using the * global _unmask variable unconditionally, not just in the -fPIC case. * Reportedly earlier versions of gcc also have the problem with more than * 10 operands; they just don't report it. Much strangeness ensues, etc. * * 20000729: * - enabled png_read_filter_row_mmx_up() (shortest remaining unconverted * MMX routine); began converting png_read_filter_row_mmx_sub() * - to finish remaining sections: * - clean up indentation and comments * - preload local variables * - add output and input regs (order of former determines numerical * mapping of latter) * - avoid all usage of ebx (including bx, bh, bl) register [20000823] * - remove "$" from addressing of Shift and Mask variables [20000823] * * 20000731: * - global union vars causing segfaults in png_read_filter_row_mmx_sub()? * * 20000822: * - ARGH, stupid png_read_filter_row_mmx_sub() segfault only happens with * shared-library (-fPIC) version! Code works just fine as part of static * library. Damn damn damn damn damn, should have tested that sooner. * ebx is getting clobbered again (explicitly this time); need to save it * on stack or rewrite asm code to avoid using it altogether. Blargh! * * 20000823: * - first section was trickiest; all remaining sections have ebx -> edx now. * (-fPIC works again.) Also added missing underscores to various Shift* * and *Mask* globals and got rid of leading "$" signs. * * 20000826: * - added visual separators to help navigate microscopic printed copies * (http://pobox.com/~newt/code/gpr-latest.zip, mode 10); started working * on png_read_filter_row_mmx_avg() * * 20000828: * - finished png_read_filter_row_mmx_avg(): only Paeth left! (930 lines...) * What the hell, did png_read_filter_row_mmx_paeth(), too. Comments not * cleaned up/shortened in either routine, but functionality is complete * and seems to be working fine. * * 20000829: * - ahhh, figured out last(?) bit of gcc/gas asm-fu: if register is listed * as an input reg (with dummy output variables, etc.), then it *cannot* * also appear in the clobber list or gcc 2.95.2 will barf. The solution * is simple enough... * * 20000914: * - bug in png_read_filter_row_mmx_avg(): 16-bit grayscale not handled * correctly (but 48-bit RGB just fine) * * 20000916: * - fixed bug in png_read_filter_row_mmx_avg(), bpp == 2 case; three errors: * - "_ShiftBpp.use = 24;" should have been "_ShiftBpp.use = 16;" * - "_ShiftRem.use = 40;" should have been "_ShiftRem.use = 48;" * - "psllq _ShiftRem, %%mm2" should have been "psrlq _ShiftRem, %%mm2" * * 20010101: * - added new png_init_mmx_flags() function (here only because it needs to * call mmxsupport(), which should probably become global png_mmxsupport()); * modified other MMX routines to run conditionally (png_ptr->asm_flags) * * 20010103: * - renamed mmxsupport() to png_mmx_support(), with auto-set of mmx_supported, * and made it public; moved png_init_mmx_flags() to png.c as internal func * * 20010104: * - removed dependency on png_read_filter_row_c() (C code already duplicated * within MMX version of png_read_filter_row()) so no longer necessary to * compile it into pngrutil.o * * 20010310: * - fixed buffer-overrun bug in png_combine_row() C code (non-MMX) * * 20020304: * - eliminated incorrect use of width_mmx in pixel_bytes == 8 case * * 20040724: * - more tinkering with clobber list at lines 4529 and 5033, to get * it to compile on gcc-3.4. * * STILL TO DO: * - test png_do_read_interlace() 64-bit case (pixel_bytes == 8) * - write MMX code for 48-bit case (pixel_bytes == 6) * - figure out what's up with 24-bit case (pixel_bytes == 3): * why subtract 8 from width_mmx in the pass 4/5 case? * (only width_mmx case) (near line 1606) * - rewrite all MMX interlacing code so it's aligned with beginning * of the row buffer, not the end (see 19991007 for details) * x pick one version of mmxsupport() and get rid of the other * - add error messages to any remaining bogus default cases * - enable pixel_depth == 8 cases in png_read_filter_row()? (test speed) * x add support for runtime enable/disable/query of various MMX routines */ #define PNG_INTERNAL #include "png.h" #if defined(PNG_USE_PNGGCCRD) int PNGAPI png_mmx_support(void); #ifdef PNG_USE_LOCAL_ARRAYS static const int FARDATA png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; static const int FARDATA png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; static const int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1}; #endif #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) /* djgpp, Win32, and Cygwin add their own underscores to global variables, * so define them without: */ #if defined(__DJGPP__) || defined(WIN32) || defined(__CYGWIN__) # define _mmx_supported mmx_supported # define _const4 const4 # define _const6 const6 # define _mask8_0 mask8_0 # define _mask16_1 mask16_1 # define _mask16_0 mask16_0 # define _mask24_2 mask24_2 # define _mask24_1 mask24_1 # define _mask24_0 mask24_0 # define _mask32_3 mask32_3 # define _mask32_2 mask32_2 # define _mask32_1 mask32_1 # define _mask32_0 mask32_0 # define _mask48_5 mask48_5 # define _mask48_4 mask48_4 # define _mask48_3 mask48_3 # define _mask48_2 mask48_2 # define _mask48_1 mask48_1 # define _mask48_0 mask48_0 # define _LBCarryMask LBCarryMask # define _HBClearMask HBClearMask # define _ActiveMask ActiveMask # define _ActiveMask2 ActiveMask2 # define _ActiveMaskEnd ActiveMaskEnd # define _ShiftBpp ShiftBpp # define _ShiftRem ShiftRem #ifdef PNG_THREAD_UNSAFE_OK # define _unmask unmask # define _FullLength FullLength # define _MMXLength MMXLength # define _dif dif # define _patemp patemp # define _pbtemp pbtemp # define _pctemp pctemp #endif #endif /* These constants are used in the inlined MMX assembly code. Ignore gcc's "At top level: defined but not used" warnings. */ /* GRR 20000706: originally _unmask was needed only when compiling with -fPIC, * since that case uses the %ebx register for indexing the Global Offset Table * and there were no other registers available. But gcc 2.95 and later emit * "more than 10 operands in `asm'" errors when %ebx is used to preload unmask * in the non-PIC case, so we'll just use the global unconditionally now. */ #ifdef PNG_THREAD_UNSAFE_OK static int _unmask; #endif static unsigned long long _mask8_0 = 0x0102040810204080LL; static unsigned long long _mask16_1 = 0x0101020204040808LL; static unsigned long long _mask16_0 = 0x1010202040408080LL; static unsigned long long _mask24_2 = 0x0101010202020404LL; static unsigned long long _mask24_1 = 0x0408080810101020LL; static unsigned long long _mask24_0 = 0x2020404040808080LL; static unsigned long long _mask32_3 = 0x0101010102020202LL; static unsigned long long _mask32_2 = 0x0404040408080808LL; static unsigned long long _mask32_1 = 0x1010101020202020LL; static unsigned long long _mask32_0 = 0x4040404080808080LL; static unsigned long long _mask48_5 = 0x0101010101010202LL; static unsigned long long _mask48_4 = 0x0202020204040404LL; static unsigned long long _mask48_3 = 0x0404080808080808LL; static unsigned long long _mask48_2 = 0x1010101010102020LL; static unsigned long long _mask48_1 = 0x2020202040404040LL; static unsigned long long _mask48_0 = 0x4040808080808080LL; static unsigned long long _const4 = 0x0000000000FFFFFFLL; //static unsigned long long _const5 = 0x000000FFFFFF0000LL; // NOT USED static unsigned long long _const6 = 0x00000000000000FFLL; // These are used in the row-filter routines and should/would be local // variables if not for gcc addressing limitations. // WARNING: Their presence probably defeats the thread safety of libpng. #ifdef PNG_THREAD_UNSAFE_OK static png_uint_32 _FullLength; static png_uint_32 _MMXLength; static int _dif; static int _patemp; // temp variables for Paeth routine static int _pbtemp; static int _pctemp; #endif void /* PRIVATE */ png_squelch_warnings(void) { #ifdef PNG_THREAD_UNSAFE_OK _dif = _dif; _patemp = _patemp; _pbtemp = _pbtemp; _pctemp = _pctemp; _MMXLength = _MMXLength; #endif _const4 = _const4; _const6 = _const6; _mask8_0 = _mask8_0; _mask16_1 = _mask16_1; _mask16_0 = _mask16_0; _mask24_2 = _mask24_2; _mask24_1 = _mask24_1; _mask24_0 = _mask24_0; _mask32_3 = _mask32_3; _mask32_2 = _mask32_2; _mask32_1 = _mask32_1; _mask32_0 = _mask32_0; _mask48_5 = _mask48_5; _mask48_4 = _mask48_4; _mask48_3 = _mask48_3; _mask48_2 = _mask48_2; _mask48_1 = _mask48_1; _mask48_0 = _mask48_0; } #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ static int _mmx_supported = 2; /*===========================================================================*/ /* */ /* P N G _ C O M B I N E _ R O W */ /* */ /*===========================================================================*/ #if defined(PNG_HAVE_ASSEMBLER_COMBINE_ROW) #define BPP2 2 #define BPP3 3 /* bytes per pixel (a.k.a. pixel_bytes) */ #define BPP4 4 #define BPP6 6 /* (defined only to help avoid cut-and-paste errors) */ #define BPP8 8 /* Combines the row recently read in with the previous row. This routine takes care of alpha and transparency if requested. This routine also handles the two methods of progressive display of interlaced images, depending on the mask value. The mask value describes which pixels are to be combined with the row. The pattern always repeats every 8 pixels, so just 8 bits are needed. A one indicates the pixel is to be combined; a zero indicates the pixel is to be skipped. This is in addition to any alpha or transparency value associated with the pixel. If you want all pixels to be combined, pass 0xff (255) in mask. */ /* Use this routine for the x86 platform - it uses a faster MMX routine if the machine supports MMX. */ void /* PRIVATE */ png_combine_row(png_structp png_ptr, png_bytep row, int mask) { png_debug(1, "in png_combine_row (pnggccrd.c)\n"); #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) if (_mmx_supported == 2) { #if !defined(PNG_1_0_X) /* this should have happened in png_init_mmx_flags() already */ png_warning(png_ptr, "asm_flags may not have been initialized"); #endif png_mmx_support(); } #endif if (mask == 0xff) { png_debug(2,"mask == 0xff: doing single png_memcpy()\n"); png_memcpy(row, png_ptr->row_buf + 1, (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth,png_ptr->width)); } else /* (png_combine_row() is never called with mask == 0) */ { switch (png_ptr->row_info.pixel_depth) { case 1: /* png_ptr->row_info.pixel_depth */ { png_bytep sp; png_bytep dp; int s_inc, s_start, s_end; int m; int shift; png_uint_32 i; sp = png_ptr->row_buf + 1; dp = row; m = 0x80; #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; s_end = 7; s_inc = 1; } else #endif { s_start = 7; s_end = 0; s_inc = -1; } shift = s_start; for (i = 0; i < png_ptr->width; i++) { if (m & mask) { int value; value = (*sp >> shift) & 0x1; *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); *dp |= (png_byte)(value << shift); } if (shift == s_end) { shift = s_start; sp++; dp++; } else shift += s_inc; if (m == 1) m = 0x80; else m >>= 1; } break; } case 2: /* png_ptr->row_info.pixel_depth */ { png_bytep sp; png_bytep dp; int s_start, s_end, s_inc; int m; int shift; png_uint_32 i; int value; sp = png_ptr->row_buf + 1; dp = row; m = 0x80; #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; s_end = 6; s_inc = 2; } else #endif { s_start = 6; s_end = 0; s_inc = -2; } shift = s_start; for (i = 0; i < png_ptr->width; i++) { if (m & mask) { value = (*sp >> shift) & 0x3; *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); *dp |= (png_byte)(value << shift); } if (shift == s_end) { shift = s_start; sp++; dp++; } else shift += s_inc; if (m == 1) m = 0x80; else m >>= 1; } break; } case 4: /* png_ptr->row_info.pixel_depth */ { png_bytep sp; png_bytep dp; int s_start, s_end, s_inc; int m; int shift; png_uint_32 i; int value; sp = png_ptr->row_buf + 1; dp = row; m = 0x80; #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; s_end = 4; s_inc = 4; } else #endif { s_start = 4; s_end = 0; s_inc = -4; } shift = s_start; for (i = 0; i < png_ptr->width; i++) { if (m & mask) { value = (*sp >> shift) & 0xf; *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); *dp |= (png_byte)(value << shift); } if (shift == s_end) { shift = s_start; sp++; dp++; } else shift += s_inc; if (m == 1) m = 0x80; else m >>= 1; } break; } case 8: /* png_ptr->row_info.pixel_depth */ { png_bytep srcptr; png_bytep dstptr; #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && _mmx_supported */ ) #else if (_mmx_supported) #endif { png_uint_32 len; int diff; int dummy_value_a; // fix 'forbidden register spilled' error int dummy_value_d; int dummy_value_c; int dummy_value_S; int dummy_value_D; _unmask = ~mask; // global variable for -fPIC version srcptr = png_ptr->row_buf + 1; dstptr = row; len = png_ptr->width &~7; // reduce to multiple of 8 diff = (int) (png_ptr->width & 7); // amount lost __asm__ __volatile__ ( "movd _unmask, %%mm7 \n\t" // load bit pattern "psubb %%mm6, %%mm6 \n\t" // zero mm6 "punpcklbw %%mm7, %%mm7 \n\t" "punpcklwd %%mm7, %%mm7 \n\t" "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks "movq _mask8_0, %%mm0 \n\t" "pand %%mm7, %%mm0 \n\t" // nonzero if keep byte "pcmpeqb %%mm6, %%mm0 \n\t" // zeros->1s, v versa // preload "movl len, %%ecx \n\t" // load length of line // preload "movl srcptr, %%esi \n\t" // load source // preload "movl dstptr, %%edi \n\t" // load dest "cmpl $0, %%ecx \n\t" // len == 0 ? "je mainloop8end \n\t" "mainloop8: \n\t" "movq (%%esi), %%mm4 \n\t" // *srcptr "pand %%mm0, %%mm4 \n\t" "movq %%mm0, %%mm6 \n\t" "pandn (%%edi), %%mm6 \n\t" // *dstptr "por %%mm6, %%mm4 \n\t" "movq %%mm4, (%%edi) \n\t" "addl $8, %%esi \n\t" // inc by 8 bytes processed "addl $8, %%edi \n\t" "subl $8, %%ecx \n\t" // dec by 8 pixels processed "ja mainloop8 \n\t" "mainloop8end: \n\t" // preload "movl diff, %%ecx \n\t" // (diff is in eax) "movl %%eax, %%ecx \n\t" "cmpl $0, %%ecx \n\t" "jz end8 \n\t" // preload "movl mask, %%edx \n\t" "sall $24, %%edx \n\t" // make low byte, high byte "secondloop8: \n\t" "sall %%edx \n\t" // move high bit to CF "jnc skip8 \n\t" // if CF = 0 "movb (%%esi), %%al \n\t" "movb %%al, (%%edi) \n\t" "skip8: \n\t" "incl %%esi \n\t" "incl %%edi \n\t" "decl %%ecx \n\t" "jnz secondloop8 \n\t" "end8: \n\t" "EMMS \n\t" // DONE : "=a" (dummy_value_a), // output regs (dummy) "=d" (dummy_value_d), "=c" (dummy_value_c), "=S" (dummy_value_S), "=D" (dummy_value_D) : "3" (srcptr), // esi // input regs "4" (dstptr), // edi "0" (diff), // eax // was (unmask) "b" RESERVED // ebx // Global Offset Table idx "2" (len), // ecx "1" (mask) // edx #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm4", "%mm6", "%mm7" // clobber list #endif ); } else /* mmx _not supported - Use modified C routine */ #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ { register png_uint_32 i; png_uint_32 initial_val = png_pass_start[png_ptr->pass]; /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ register int stride = png_pass_inc[png_ptr->pass]; /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ register int rep_bytes = png_pass_width[png_ptr->pass]; /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ int diff = (int) (png_ptr->width & 7); /* amount lost */ register png_uint_32 final_val = len; /* GRR bugfix */ srcptr = png_ptr->row_buf + 1 + initial_val; dstptr = row + initial_val; for (i = initial_val; i < final_val; i += stride) { png_memcpy(dstptr, srcptr, rep_bytes); srcptr += stride; dstptr += stride; } if (diff) /* number of leftover pixels: 3 for pngtest */ { final_val+=diff /* *BPP1 */ ; for (; i < final_val; i += stride) { if (rep_bytes > (int)(final_val-i)) rep_bytes = (int)(final_val-i); png_memcpy(dstptr, srcptr, rep_bytes); srcptr += stride; dstptr += stride; } } } /* end of else (_mmx_supported) */ break; } /* end 8 bpp */ case 16: /* png_ptr->row_info.pixel_depth */ { png_bytep srcptr; png_bytep dstptr; #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && _mmx_supported */ ) #else if (_mmx_supported) #endif { png_uint_32 len; int diff; int dummy_value_a; // fix 'forbidden register spilled' error int dummy_value_d; int dummy_value_c; int dummy_value_S; int dummy_value_D; _unmask = ~mask; // global variable for -fPIC version srcptr = png_ptr->row_buf + 1; dstptr = row; len = png_ptr->width &~7; // reduce to multiple of 8 diff = (int) (png_ptr->width & 7); // amount lost // __asm__ __volatile__ ( "movd _unmask, %%mm7 \n\t" // load bit pattern "psubb %%mm6, %%mm6 \n\t" // zero mm6 "punpcklbw %%mm7, %%mm7 \n\t" "punpcklwd %%mm7, %%mm7 \n\t" "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks "movq _mask16_0, %%mm0 \n\t" "movq _mask16_1, %%mm1 \n\t" "pand %%mm7, %%mm0 \n\t" "pand %%mm7, %%mm1 \n\t" "pcmpeqb %%mm6, %%mm0 \n\t" "pcmpeqb %%mm6, %%mm1 \n\t" // preload "movl len, %%ecx \n\t" // load length of line // preload "movl srcptr, %%esi \n\t" // load source // preload "movl dstptr, %%edi \n\t" // load dest "cmpl $0, %%ecx \n\t" "jz mainloop16end \n\t" "mainloop16: \n\t" "movq (%%esi), %%mm4 \n\t" "pand %%mm0, %%mm4 \n\t" "movq %%mm0, %%mm6 \n\t" "movq (%%edi), %%mm7 \n\t" "pandn %%mm7, %%mm6 \n\t" "por %%mm6, %%mm4 \n\t" "movq %%mm4, (%%edi) \n\t" "movq 8(%%esi), %%mm5 \n\t" "pand %%mm1, %%mm5 \n\t" "movq %%mm1, %%mm7 \n\t" "movq 8(%%edi), %%mm6 \n\t" "pandn %%mm6, %%mm7 \n\t" "por %%mm7, %%mm5 \n\t" "movq %%mm5, 8(%%edi) \n\t" "addl $16, %%esi \n\t" // inc by 16 bytes processed "addl $16, %%edi \n\t" "subl $8, %%ecx \n\t" // dec by 8 pixels processed "ja mainloop16 \n\t" "mainloop16end: \n\t" // preload "movl diff, %%ecx \n\t" // (diff is in eax) "movl %%eax, %%ecx \n\t" "cmpl $0, %%ecx \n\t" "jz end16 \n\t" // preload "movl mask, %%edx \n\t" "sall $24, %%edx \n\t" // make low byte, high byte "secondloop16: \n\t" "sall %%edx \n\t" // move high bit to CF "jnc skip16 \n\t" // if CF = 0 "movw (%%esi), %%ax \n\t" "movw %%ax, (%%edi) \n\t" "skip16: \n\t" "addl $2, %%esi \n\t" "addl $2, %%edi \n\t" "decl %%ecx \n\t" "jnz secondloop16 \n\t" "end16: \n\t" "EMMS \n\t" // DONE : "=a" (dummy_value_a), // output regs (dummy) "=c" (dummy_value_c), "=d" (dummy_value_d), "=S" (dummy_value_S), "=D" (dummy_value_D) : "0" (diff), // eax // input regs // was (unmask) " " RESERVED // ebx // Global Offset Table idx "1" (len), // ecx "2" (mask), // edx "3" (srcptr), // esi "4" (dstptr) // edi #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1", "%mm4" // clobber list , "%mm5", "%mm6", "%mm7" #endif ); } else /* mmx _not supported - Use modified C routine */ #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ { register png_uint_32 i; png_uint_32 initial_val = BPP2 * png_pass_start[png_ptr->pass]; /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ register int stride = BPP2 * png_pass_inc[png_ptr->pass]; /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ register int rep_bytes = BPP2 * png_pass_width[png_ptr->pass]; /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ int diff = (int) (png_ptr->width & 7); /* amount lost */ register png_uint_32 final_val = BPP2 * len; /* GRR bugfix */ srcptr = png_ptr->row_buf + 1 + initial_val; dstptr = row + initial_val; for (i = initial_val; i < final_val; i += stride) { png_memcpy(dstptr, srcptr, rep_bytes); srcptr += stride; dstptr += stride; } if (diff) /* number of leftover pixels: 3 for pngtest */ { final_val+=diff*BPP2; for (; i < final_val; i += stride) { if (rep_bytes > (int)(final_val-i)) rep_bytes = (int)(final_val-i); png_memcpy(dstptr, srcptr, rep_bytes); srcptr += stride; dstptr += stride; } } } /* end of else (_mmx_supported) */ break; } /* end 16 bpp */ case 24: /* png_ptr->row_info.pixel_depth */ { png_bytep srcptr; png_bytep dstptr; #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && _mmx_supported */ ) #else if (_mmx_supported) #endif { png_uint_32 len; int diff; int dummy_value_a; // fix 'forbidden register spilled' error int dummy_value_d; int dummy_value_c; int dummy_value_S; int dummy_value_D; _unmask = ~mask; // global variable for -fPIC version srcptr = png_ptr->row_buf + 1; dstptr = row; len = png_ptr->width &~7; // reduce to multiple of 8 diff = (int) (png_ptr->width & 7); // amount lost // __asm__ __volatile__ ( "movd _unmask, %%mm7 \n\t" // load bit pattern "psubb %%mm6, %%mm6 \n\t" // zero mm6 "punpcklbw %%mm7, %%mm7 \n\t" "punpcklwd %%mm7, %%mm7 \n\t" "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks "movq _mask24_0, %%mm0 \n\t" "movq _mask24_1, %%mm1 \n\t" "movq _mask24_2, %%mm2 \n\t" "pand %%mm7, %%mm0 \n\t" "pand %%mm7, %%mm1 \n\t" "pand %%mm7, %%mm2 \n\t" "pcmpeqb %%mm6, %%mm0 \n\t" "pcmpeqb %%mm6, %%mm1 \n\t" "pcmpeqb %%mm6, %%mm2 \n\t" // preload "movl len, %%ecx \n\t" // load length of line // preload "movl srcptr, %%esi \n\t" // load source // preload "movl dstptr, %%edi \n\t" // load dest "cmpl $0, %%ecx \n\t" "jz mainloop24end \n\t" "mainloop24: \n\t" "movq (%%esi), %%mm4 \n\t" "pand %%mm0, %%mm4 \n\t" "movq %%mm0, %%mm6 \n\t" "movq (%%edi), %%mm7 \n\t" "pandn %%mm7, %%mm6 \n\t" "por %%mm6, %%mm4 \n\t" "movq %%mm4, (%%edi) \n\t" "movq 8(%%esi), %%mm5 \n\t" "pand %%mm1, %%mm5 \n\t" "movq %%mm1, %%mm7 \n\t" "movq 8(%%edi), %%mm6 \n\t" "pandn %%mm6, %%mm7 \n\t" "por %%mm7, %%mm5 \n\t" "movq %%mm5, 8(%%edi) \n\t" "movq 16(%%esi), %%mm6 \n\t" "pand %%mm2, %%mm6 \n\t" "movq %%mm2, %%mm4 \n\t" "movq 16(%%edi), %%mm7 \n\t" "pandn %%mm7, %%mm4 \n\t" "por %%mm4, %%mm6 \n\t" "movq %%mm6, 16(%%edi) \n\t" "addl $24, %%esi \n\t" // inc by 24 bytes processed "addl $24, %%edi \n\t" "subl $8, %%ecx \n\t" // dec by 8 pixels processed "ja mainloop24 \n\t" "mainloop24end: \n\t" // preload "movl diff, %%ecx \n\t" // (diff is in eax) "movl %%eax, %%ecx \n\t" "cmpl $0, %%ecx \n\t" "jz end24 \n\t" // preload "movl mask, %%edx \n\t" "sall $24, %%edx \n\t" // make low byte, high byte "secondloop24: \n\t" "sall %%edx \n\t" // move high bit to CF "jnc skip24 \n\t" // if CF = 0 "movw (%%esi), %%ax \n\t" "movw %%ax, (%%edi) \n\t" "xorl %%eax, %%eax \n\t" "movb 2(%%esi), %%al \n\t" "movb %%al, 2(%%edi) \n\t" "skip24: \n\t" "addl $3, %%esi \n\t" "addl $3, %%edi \n\t" "decl %%ecx \n\t" "jnz secondloop24 \n\t" "end24: \n\t" "EMMS \n\t" // DONE : "=a" (dummy_value_a), // output regs (dummy) "=d" (dummy_value_d), "=c" (dummy_value_c), "=S" (dummy_value_S), "=D" (dummy_value_D) : "3" (srcptr), // esi // input regs "4" (dstptr), // edi "0" (diff), // eax // was (unmask) "b" RESERVED // ebx // Global Offset Table idx "2" (len), // ecx "1" (mask) // edx #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1", "%mm2" // clobber list , "%mm4", "%mm5", "%mm6", "%mm7" #endif ); } else /* mmx _not supported - Use modified C routine */ #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ { register png_uint_32 i; png_uint_32 initial_val = BPP3 * png_pass_start[png_ptr->pass]; /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ register int stride = BPP3 * png_pass_inc[png_ptr->pass]; /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ register int rep_bytes = BPP3 * png_pass_width[png_ptr->pass]; /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ int diff = (int) (png_ptr->width & 7); /* amount lost */ register png_uint_32 final_val = BPP3 * len; /* GRR bugfix */ srcptr = png_ptr->row_buf + 1 + initial_val; dstptr = row + initial_val; for (i = initial_val; i < final_val; i += stride) { png_memcpy(dstptr, srcptr, rep_bytes); srcptr += stride; dstptr += stride; } if (diff) /* number of leftover pixels: 3 for pngtest */ { final_val+=diff*BPP3; for (; i < final_val; i += stride) { if (rep_bytes > (int)(final_val-i)) rep_bytes = (int)(final_val-i); png_memcpy(dstptr, srcptr, rep_bytes); srcptr += stride; dstptr += stride; } } } /* end of else (_mmx_supported) */ break; } /* end 24 bpp */ case 32: /* png_ptr->row_info.pixel_depth */ { png_bytep srcptr; png_bytep dstptr; #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && _mmx_supported */ ) #else if (_mmx_supported) #endif { png_uint_32 len; int diff; int dummy_value_a; // fix 'forbidden register spilled' error int dummy_value_d; int dummy_value_c; int dummy_value_S; int dummy_value_D; _unmask = ~mask; // global variable for -fPIC version srcptr = png_ptr->row_buf + 1; dstptr = row; len = png_ptr->width &~7; // reduce to multiple of 8 diff = (int) (png_ptr->width & 7); // amount lost // __asm__ __volatile__ ( "movd _unmask, %%mm7 \n\t" // load bit pattern "psubb %%mm6, %%mm6 \n\t" // zero mm6 "punpcklbw %%mm7, %%mm7 \n\t" "punpcklwd %%mm7, %%mm7 \n\t" "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks "movq _mask32_0, %%mm0 \n\t" "movq _mask32_1, %%mm1 \n\t" "movq _mask32_2, %%mm2 \n\t" "movq _mask32_3, %%mm3 \n\t" "pand %%mm7, %%mm0 \n\t" "pand %%mm7, %%mm1 \n\t" "pand %%mm7, %%mm2 \n\t" "pand %%mm7, %%mm3 \n\t" "pcmpeqb %%mm6, %%mm0 \n\t" "pcmpeqb %%mm6, %%mm1 \n\t" "pcmpeqb %%mm6, %%mm2 \n\t" "pcmpeqb %%mm6, %%mm3 \n\t" // preload "movl len, %%ecx \n\t" // load length of line // preload "movl srcptr, %%esi \n\t" // load source // preload "movl dstptr, %%edi \n\t" // load dest "cmpl $0, %%ecx \n\t" // lcr "jz mainloop32end \n\t" "mainloop32: \n\t" "movq (%%esi), %%mm4 \n\t" "pand %%mm0, %%mm4 \n\t" "movq %%mm0, %%mm6 \n\t" "movq (%%edi), %%mm7 \n\t" "pandn %%mm7, %%mm6 \n\t" "por %%mm6, %%mm4 \n\t" "movq %%mm4, (%%edi) \n\t" "movq 8(%%esi), %%mm5 \n\t" "pand %%mm1, %%mm5 \n\t" "movq %%mm1, %%mm7 \n\t" "movq 8(%%edi), %%mm6 \n\t" "pandn %%mm6, %%mm7 \n\t" "por %%mm7, %%mm5 \n\t" "movq %%mm5, 8(%%edi) \n\t" "movq 16(%%esi), %%mm6 \n\t" "pand %%mm2, %%mm6 \n\t" "movq %%mm2, %%mm4 \n\t" "movq 16(%%edi), %%mm7 \n\t" "pandn %%mm7, %%mm4 \n\t" "por %%mm4, %%mm6 \n\t" "movq %%mm6, 16(%%edi) \n\t" "movq 24(%%esi), %%mm7 \n\t" "pand %%mm3, %%mm7 \n\t" "movq %%mm3, %%mm5 \n\t" "movq 24(%%edi), %%mm4 \n\t" "pandn %%mm4, %%mm5 \n\t" "por %%mm5, %%mm7 \n\t" "movq %%mm7, 24(%%edi) \n\t" "addl $32, %%esi \n\t" // inc by 32 bytes processed "addl $32, %%edi \n\t" "subl $8, %%ecx \n\t" // dec by 8 pixels processed "ja mainloop32 \n\t" "mainloop32end: \n\t" // preload "movl diff, %%ecx \n\t" // (diff is in eax) "movl %%eax, %%ecx \n\t" "cmpl $0, %%ecx \n\t" "jz end32 \n\t" // preload "movl mask, %%edx \n\t" "sall $24, %%edx \n\t" // low byte => high byte "secondloop32: \n\t" "sall %%edx \n\t" // move high bit to CF "jnc skip32 \n\t" // if CF = 0 "movl (%%esi), %%eax \n\t" "movl %%eax, (%%edi) \n\t" "skip32: \n\t" "addl $4, %%esi \n\t" "addl $4, %%edi \n\t" "decl %%ecx \n\t" "jnz secondloop32 \n\t" "end32: \n\t" "EMMS \n\t" // DONE : "=a" (dummy_value_a), // output regs (dummy) "=d" (dummy_value_d), "=c" (dummy_value_c), "=S" (dummy_value_S), "=D" (dummy_value_D) : "3" (srcptr), // esi // input regs "4" (dstptr), // edi "0" (diff), // eax // was (unmask) "b" RESERVED // ebx // Global Offset Table idx "2" (len), // ecx "1" (mask) // edx #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list , "%mm4", "%mm5", "%mm6", "%mm7" #endif ); } else /* mmx _not supported - Use modified C routine */ #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ { register png_uint_32 i; png_uint_32 initial_val = BPP4 * png_pass_start[png_ptr->pass]; /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ register int stride = BPP4 * png_pass_inc[png_ptr->pass]; /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ register int rep_bytes = BPP4 * png_pass_width[png_ptr->pass]; /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ int diff = (int) (png_ptr->width & 7); /* amount lost */ register png_uint_32 final_val = BPP4 * len; /* GRR bugfix */ srcptr = png_ptr->row_buf + 1 + initial_val; dstptr = row + initial_val; for (i = initial_val; i < final_val; i += stride) { png_memcpy(dstptr, srcptr, rep_bytes); srcptr += stride; dstptr += stride; } if (diff) /* number of leftover pixels: 3 for pngtest */ { final_val+=diff*BPP4; for (; i < final_val; i += stride) { if (rep_bytes > (int)(final_val-i)) rep_bytes = (int)(final_val-i); png_memcpy(dstptr, srcptr, rep_bytes); srcptr += stride; dstptr += stride; } } } /* end of else (_mmx_supported) */ break; } /* end 32 bpp */ case 48: /* png_ptr->row_info.pixel_depth */ { png_bytep srcptr; png_bytep dstptr; #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && _mmx_supported */ ) #else if (_mmx_supported) #endif { png_uint_32 len; int diff; int dummy_value_a; // fix 'forbidden register spilled' error int dummy_value_d; int dummy_value_c; int dummy_value_S; int dummy_value_D; _unmask = ~mask; // global variable for -fPIC version srcptr = png_ptr->row_buf + 1; dstptr = row; len = png_ptr->width &~7; // reduce to multiple of 8 diff = (int) (png_ptr->width & 7); // amount lost // __asm__ __volatile__ ( "movd _unmask, %%mm7 \n\t" // load bit pattern "psubb %%mm6, %%mm6 \n\t" // zero mm6 "punpcklbw %%mm7, %%mm7 \n\t" "punpcklwd %%mm7, %%mm7 \n\t" "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks "movq _mask48_0, %%mm0 \n\t" "movq _mask48_1, %%mm1 \n\t" "movq _mask48_2, %%mm2 \n\t" "movq _mask48_3, %%mm3 \n\t" "movq _mask48_4, %%mm4 \n\t" "movq _mask48_5, %%mm5 \n\t" "pand %%mm7, %%mm0 \n\t" "pand %%mm7, %%mm1 \n\t" "pand %%mm7, %%mm2 \n\t" "pand %%mm7, %%mm3 \n\t" "pand %%mm7, %%mm4 \n\t" "pand %%mm7, %%mm5 \n\t" "pcmpeqb %%mm6, %%mm0 \n\t" "pcmpeqb %%mm6, %%mm1 \n\t" "pcmpeqb %%mm6, %%mm2 \n\t" "pcmpeqb %%mm6, %%mm3 \n\t" "pcmpeqb %%mm6, %%mm4 \n\t" "pcmpeqb %%mm6, %%mm5 \n\t" // preload "movl len, %%ecx \n\t" // load length of line // preload "movl srcptr, %%esi \n\t" // load source // preload "movl dstptr, %%edi \n\t" // load dest "cmpl $0, %%ecx \n\t" "jz mainloop48end \n\t" "mainloop48: \n\t" "movq (%%esi), %%mm7 \n\t" "pand %%mm0, %%mm7 \n\t" "movq %%mm0, %%mm6 \n\t" "pandn (%%edi), %%mm6 \n\t" "por %%mm6, %%mm7 \n\t" "movq %%mm7, (%%edi) \n\t" "movq 8(%%esi), %%mm6 \n\t" "pand %%mm1, %%mm6 \n\t" "movq %%mm1, %%mm7 \n\t" "pandn 8(%%edi), %%mm7 \n\t" "por %%mm7, %%mm6 \n\t" "movq %%mm6, 8(%%edi) \n\t" "movq 16(%%esi), %%mm6 \n\t" "pand %%mm2, %%mm6 \n\t" "movq %%mm2, %%mm7 \n\t" "pandn 16(%%edi), %%mm7 \n\t" "por %%mm7, %%mm6 \n\t" "movq %%mm6, 16(%%edi) \n\t" "movq 24(%%esi), %%mm7 \n\t" "pand %%mm3, %%mm7 \n\t" "movq %%mm3, %%mm6 \n\t" "pandn 24(%%edi), %%mm6 \n\t" "por %%mm6, %%mm7 \n\t" "movq %%mm7, 24(%%edi) \n\t" "movq 32(%%esi), %%mm6 \n\t" "pand %%mm4, %%mm6 \n\t" "movq %%mm4, %%mm7 \n\t" "pandn 32(%%edi), %%mm7 \n\t" "por %%mm7, %%mm6 \n\t" "movq %%mm6, 32(%%edi) \n\t" "movq 40(%%esi), %%mm7 \n\t" "pand %%mm5, %%mm7 \n\t" "movq %%mm5, %%mm6 \n\t" "pandn 40(%%edi), %%mm6 \n\t" "por %%mm6, %%mm7 \n\t" "movq %%mm7, 40(%%edi) \n\t" "addl $48, %%esi \n\t" // inc by 48 bytes processed "addl $48, %%edi \n\t" "subl $8, %%ecx \n\t" // dec by 8 pixels processed "ja mainloop48 \n\t" "mainloop48end: \n\t" // preload "movl diff, %%ecx \n\t" // (diff is in eax) "movl %%eax, %%ecx \n\t" "cmpl $0, %%ecx \n\t" "jz end48 \n\t" // preload "movl mask, %%edx \n\t" "sall $24, %%edx \n\t" // make low byte, high byte "secondloop48: \n\t" "sall %%edx \n\t" // move high bit to CF "jnc skip48 \n\t" // if CF = 0 "movl (%%esi), %%eax \n\t" "movl %%eax, (%%edi) \n\t" "skip48: \n\t" "addl $4, %%esi \n\t" "addl $4, %%edi \n\t" "decl %%ecx \n\t" "jnz secondloop48 \n\t" "end48: \n\t" "EMMS \n\t" // DONE : "=a" (dummy_value_a), // output regs (dummy) "=d" (dummy_value_d), "=c" (dummy_value_c), "=S" (dummy_value_S), "=D" (dummy_value_D) : "3" (srcptr), // esi // input regs "4" (dstptr), // edi "0" (diff), // eax // was (unmask) "b" RESERVED // ebx // Global Offset Table idx "2" (len), // ecx "1" (mask) // edx #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list , "%mm4", "%mm5", "%mm6", "%mm7" #endif ); } else /* mmx _not supported - Use modified C routine */ #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ { register png_uint_32 i; png_uint_32 initial_val = BPP6 * png_pass_start[png_ptr->pass]; /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ register int stride = BPP6 * png_pass_inc[png_ptr->pass]; /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ register int rep_bytes = BPP6 * png_pass_width[png_ptr->pass]; /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ int diff = (int) (png_ptr->width & 7); /* amount lost */ register png_uint_32 final_val = BPP6 * len; /* GRR bugfix */ srcptr = png_ptr->row_buf + 1 + initial_val; dstptr = row + initial_val; for (i = initial_val; i < final_val; i += stride) { png_memcpy(dstptr, srcptr, rep_bytes); srcptr += stride; dstptr += stride; } if (diff) /* number of leftover pixels: 3 for pngtest */ { final_val+=diff*BPP6; for (; i < final_val; i += stride) { if (rep_bytes > (int)(final_val-i)) rep_bytes = (int)(final_val-i); png_memcpy(dstptr, srcptr, rep_bytes); srcptr += stride; dstptr += stride; } } } /* end of else (_mmx_supported) */ break; } /* end 48 bpp */ case 64: /* png_ptr->row_info.pixel_depth */ { png_bytep srcptr; png_bytep dstptr; register png_uint_32 i; png_uint_32 initial_val = BPP8 * png_pass_start[png_ptr->pass]; /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ register int stride = BPP8 * png_pass_inc[png_ptr->pass]; /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ register int rep_bytes = BPP8 * png_pass_width[png_ptr->pass]; /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ int diff = (int) (png_ptr->width & 7); /* amount lost */ register png_uint_32 final_val = BPP8 * len; /* GRR bugfix */ srcptr = png_ptr->row_buf + 1 + initial_val; dstptr = row + initial_val; for (i = initial_val; i < final_val; i += stride) { png_memcpy(dstptr, srcptr, rep_bytes); srcptr += stride; dstptr += stride; } if (diff) /* number of leftover pixels: 3 for pngtest */ { final_val+=diff*BPP8; for (; i < final_val; i += stride) { if (rep_bytes > (int)(final_val-i)) rep_bytes = (int)(final_val-i); png_memcpy(dstptr, srcptr, rep_bytes); srcptr += stride; dstptr += stride; } } break; } /* end 64 bpp */ default: /* png_ptr->row_info.pixel_depth != 1,2,4,8,16,24,32,48,64 */ { /* this should never happen */ png_warning(png_ptr, "Invalid row_info.pixel_depth in pnggccrd"); break; } } /* end switch (png_ptr->row_info.pixel_depth) */ } /* end if (non-trivial mask) */ } /* end png_combine_row() */ #endif /* PNG_HAVE_ASSEMBLER_COMBINE_ROW */ /*===========================================================================*/ /* */ /* P N G _ D O _ R E A D _ I N T E R L A C E */ /* */ /*===========================================================================*/ #if defined(PNG_READ_INTERLACING_SUPPORTED) #if defined(PNG_HAVE_ASSEMBLER_READ_INTERLACE) /* png_do_read_interlace() is called after any 16-bit to 8-bit conversion * has taken place. [GRR: what other steps come before and/or after?] */ void /* PRIVATE */ png_do_read_interlace(png_structp png_ptr) { png_row_infop row_info = &(png_ptr->row_info); png_bytep row = png_ptr->row_buf + 1; int pass = png_ptr->pass; #if defined(PNG_READ_PACKSWAP_SUPPORTED) png_uint_32 transformations = png_ptr->transformations; #endif png_debug(1, "in png_do_read_interlace (pnggccrd.c)\n"); #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) if (_mmx_supported == 2) { #if !defined(PNG_1_0_X) /* this should have happened in png_init_mmx_flags() already */ png_warning(png_ptr, "asm_flags may not have been initialized"); #endif png_mmx_support(); } #endif if (row != NULL && row_info != NULL) { png_uint_32 final_width; final_width = row_info->width * png_pass_inc[pass]; switch (row_info->pixel_depth) { case 1: { png_bytep sp, dp; int sshift, dshift; int s_start, s_end, s_inc; png_byte v; png_uint_32 i; int j; sp = row + (png_size_t)((row_info->width - 1) >> 3); dp = row + (png_size_t)((final_width - 1) >> 3); #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (transformations & PNG_PACKSWAP) { sshift = (int)((row_info->width + 7) & 7); dshift = (int)((final_width + 7) & 7); s_start = 7; s_end = 0; s_inc = -1; } else #endif { sshift = 7 - (int)((row_info->width + 7) & 7); dshift = 7 - (int)((final_width + 7) & 7); s_start = 0; s_end = 7; s_inc = 1; } for (i = row_info->width; i; i--) { v = (png_byte)((*sp >> sshift) & 0x1); for (j = 0; j < png_pass_inc[pass]; j++) { *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); if (dshift == s_end) { dshift = s_start; dp--; } else dshift += s_inc; } if (sshift == s_end) { sshift = s_start; sp--; } else sshift += s_inc; } break; } case 2: { png_bytep sp, dp; int sshift, dshift; int s_start, s_end, s_inc; png_uint_32 i; sp = row + (png_size_t)((row_info->width - 1) >> 2); dp = row + (png_size_t)((final_width - 1) >> 2); #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (transformations & PNG_PACKSWAP) { sshift = (png_size_t)(((row_info->width + 3) & 3) << 1); dshift = (png_size_t)(((final_width + 3) & 3) << 1); s_start = 6; s_end = 0; s_inc = -2; } else #endif { sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1); dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1); s_start = 0; s_end = 6; s_inc = 2; } for (i = row_info->width; i; i--) { png_byte v; int j; v = (png_byte)((*sp >> sshift) & 0x3); for (j = 0; j < png_pass_inc[pass]; j++) { *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); if (dshift == s_end) { dshift = s_start; dp--; } else dshift += s_inc; } if (sshift == s_end) { sshift = s_start; sp--; } else sshift += s_inc; } break; } case 4: { png_bytep sp, dp; int sshift, dshift; int s_start, s_end, s_inc; png_uint_32 i; sp = row + (png_size_t)((row_info->width - 1) >> 1); dp = row + (png_size_t)((final_width - 1) >> 1); #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (transformations & PNG_PACKSWAP) { sshift = (png_size_t)(((row_info->width + 1) & 1) << 2); dshift = (png_size_t)(((final_width + 1) & 1) << 2); s_start = 4; s_end = 0; s_inc = -4; } else #endif { sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2); dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2); s_start = 0; s_end = 4; s_inc = 4; } for (i = row_info->width; i; i--) { png_byte v; int j; v = (png_byte)((*sp >> sshift) & 0xf); for (j = 0; j < png_pass_inc[pass]; j++) { *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); if (dshift == s_end) { dshift = s_start; dp--; } else dshift += s_inc; } if (sshift == s_end) { sshift = s_start; sp--; } else sshift += s_inc; } break; } /*====================================================================*/ default: /* 8-bit or larger (this is where the routine is modified) */ { #if 0 // static unsigned long long _const4 = 0x0000000000FFFFFFLL; no good // static unsigned long long const4 = 0x0000000000FFFFFFLL; no good // unsigned long long _const4 = 0x0000000000FFFFFFLL; no good // unsigned long long const4 = 0x0000000000FFFFFFLL; no good #endif png_bytep sptr, dp; png_uint_32 i; png_size_t pixel_bytes; int width = (int)row_info->width; pixel_bytes = (row_info->pixel_depth >> 3); /* point sptr at the last pixel in the pre-expanded row: */ sptr = row + (width - 1) * pixel_bytes; /* point dp at the last pixel position in the expanded row: */ dp = row + (final_width - 1) * pixel_bytes; /* New code by Nirav Chhatrapati - Intel Corporation */ #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE) /* && _mmx_supported */ ) #else if (_mmx_supported) #endif { //-------------------------------------------------------------- if (pixel_bytes == 3) { if (((pass == 0) || (pass == 1)) && width) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $21, %%edi \n\t" // (png_pass_inc[pass] - 1)*pixel_bytes ".loop3_pass0: \n\t" "movd (%%esi), %%mm0 \n\t" // x x x x x 2 1 0 "pand _const4, %%mm0 \n\t" // z z z z z 2 1 0 "movq %%mm0, %%mm1 \n\t" // z z z z z 2 1 0 "psllq $16, %%mm0 \n\t" // z z z 2 1 0 z z "movq %%mm0, %%mm2 \n\t" // z z z 2 1 0 z z "psllq $24, %%mm0 \n\t" // 2 1 0 z z z z z "psrlq $8, %%mm1 \n\t" // z z z z z z 2 1 "por %%mm2, %%mm0 \n\t" // 2 1 0 2 1 0 z z "por %%mm1, %%mm0 \n\t" // 2 1 0 2 1 0 2 1 "movq %%mm0, %%mm3 \n\t" // 2 1 0 2 1 0 2 1 "psllq $16, %%mm0 \n\t" // 0 2 1 0 2 1 z z "movq %%mm3, %%mm4 \n\t" // 2 1 0 2 1 0 2 1 "punpckhdq %%mm0, %%mm3 \n\t" // 0 2 1 0 2 1 0 2 "movq %%mm4, 16(%%edi) \n\t" "psrlq $32, %%mm0 \n\t" // z z z z 0 2 1 0 "movq %%mm3, 8(%%edi) \n\t" "punpckldq %%mm4, %%mm0 \n\t" // 1 0 2 1 0 2 1 0 "subl $3, %%esi \n\t" "movq %%mm0, (%%edi) \n\t" "subl $24, %%edi \n\t" "decl %%ecx \n\t" "jnz .loop3_pass0 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width), // ecx "rim" (_const4) // %1(?) (0x0000000000FFFFFFLL) #if 0 /* %mm0, ..., %mm4 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1", "%mm2" // clobber list , "%mm3", "%mm4" #endif ); } else if (((pass == 2) || (pass == 3)) && width) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $9, %%edi \n\t" // (png_pass_inc[pass] - 1)*pixel_bytes ".loop3_pass2: \n\t" "movd (%%esi), %%mm0 \n\t" // x x x x x 2 1 0 "pand _const4, %%mm0 \n\t" // z z z z z 2 1 0 "movq %%mm0, %%mm1 \n\t" // z z z z z 2 1 0 "psllq $16, %%mm0 \n\t" // z z z 2 1 0 z z "movq %%mm0, %%mm2 \n\t" // z z z 2 1 0 z z "psllq $24, %%mm0 \n\t" // 2 1 0 z z z z z "psrlq $8, %%mm1 \n\t" // z z z z z z 2 1 "por %%mm2, %%mm0 \n\t" // 2 1 0 2 1 0 z z "por %%mm1, %%mm0 \n\t" // 2 1 0 2 1 0 2 1 "movq %%mm0, 4(%%edi) \n\t" "psrlq $16, %%mm0 \n\t" // z z 2 1 0 2 1 0 "subl $3, %%esi \n\t" "movd %%mm0, (%%edi) \n\t" "subl $12, %%edi \n\t" "decl %%ecx \n\t" "jnz .loop3_pass2 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width), // ecx "rim" (_const4) // (0x0000000000FFFFFFLL) #if 0 /* %mm0, ..., %mm2 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1", "%mm2" // clobber list #endif ); } else if (width) /* && ((pass == 4) || (pass == 5)) */ { int width_mmx = ((width >> 1) << 1) - 8; // GRR: huh? if (width_mmx < 0) width_mmx = 0; width -= width_mmx; // 8 or 9 pix, 24 or 27 bytes if (width_mmx) { // png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; // sptr points at last pixel in pre-expanded row // dp points at last pixel position in expanded row int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $3, %%esi \n\t" "subl $9, %%edi \n\t" // (png_pass_inc[pass] + 1)*pixel_bytes ".loop3_pass4: \n\t" "movq (%%esi), %%mm0 \n\t" // x x 5 4 3 2 1 0 "movq %%mm0, %%mm1 \n\t" // x x 5 4 3 2 1 0 "movq %%mm0, %%mm2 \n\t" // x x 5 4 3 2 1 0 "psllq $24, %%mm0 \n\t" // 4 3 2 1 0 z z z "pand _const4, %%mm1 \n\t" // z z z z z 2 1 0 "psrlq $24, %%mm2 \n\t" // z z z x x 5 4 3 "por %%mm1, %%mm0 \n\t" // 4 3 2 1 0 2 1 0 "movq %%mm2, %%mm3 \n\t" // z z z x x 5 4 3 "psllq $8, %%mm2 \n\t" // z z x x 5 4 3 z "movq %%mm0, (%%edi) \n\t" "psrlq $16, %%mm3 \n\t" // z z z z z x x 5 "pand _const6, %%mm3 \n\t" // z z z z z z z 5 "por %%mm3, %%mm2 \n\t" // z z x x 5 4 3 5 "subl $6, %%esi \n\t" "movd %%mm2, 8(%%edi) \n\t" "subl $12, %%edi \n\t" "subl $2, %%ecx \n\t" "jnz .loop3_pass4 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width_mmx), // ecx "rim" (_const4), // 0x0000000000FFFFFFLL "rim" (_const6) // 0x00000000000000FFLL #if 0 /* %mm0, ..., %mm3 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1" // clobber list , "%mm2", "%mm3" #endif ); } sptr -= width_mmx*3; dp -= width_mmx*6; for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, 3); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, 3); dp -= 3; } sptr -= 3; } } } /* end of pixel_bytes == 3 */ //-------------------------------------------------------------- else if (pixel_bytes == 1) { if (((pass == 0) || (pass == 1)) && width) { int width_mmx = ((width >> 2) << 2); width -= width_mmx; // 0-3 pixels => 0-3 bytes if (width_mmx) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $3, %%esi \n\t" "subl $31, %%edi \n\t" ".loop1_pass0: \n\t" "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 "movq %%mm0, %%mm1 \n\t" // x x x x 3 2 1 0 "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0 "movq %%mm0, %%mm2 \n\t" // 3 3 2 2 1 1 0 0 "punpcklwd %%mm0, %%mm0 \n\t" // 1 1 1 1 0 0 0 0 "movq %%mm0, %%mm3 \n\t" // 1 1 1 1 0 0 0 0 "punpckldq %%mm0, %%mm0 \n\t" // 0 0 0 0 0 0 0 0 "punpckhdq %%mm3, %%mm3 \n\t" // 1 1 1 1 1 1 1 1 "movq %%mm0, (%%edi) \n\t" "punpckhwd %%mm2, %%mm2 \n\t" // 3 3 3 3 2 2 2 2 "movq %%mm3, 8(%%edi) \n\t" "movq %%mm2, %%mm4 \n\t" // 3 3 3 3 2 2 2 2 "punpckldq %%mm2, %%mm2 \n\t" // 2 2 2 2 2 2 2 2 "punpckhdq %%mm4, %%mm4 \n\t" // 3 3 3 3 3 3 3 3 "movq %%mm2, 16(%%edi) \n\t" "subl $4, %%esi \n\t" "movq %%mm4, 24(%%edi) \n\t" "subl $32, %%edi \n\t" "subl $4, %%ecx \n\t" "jnz .loop1_pass0 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width_mmx) // ecx #if 0 /* %mm0, ..., %mm4 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1", "%mm2" // clobber list , "%mm3", "%mm4" #endif ); } sptr -= width_mmx; dp -= width_mmx*8; for (i = width; i; i--) { int j; /* I simplified this part in version 1.0.4e * here and in several other instances where * pixel_bytes == 1 -- GR-P * * Original code: * * png_byte v[8]; * png_memcpy(v, sptr, pixel_bytes); * for (j = 0; j < png_pass_inc[pass]; j++) * { * png_memcpy(dp, v, pixel_bytes); * dp -= pixel_bytes; * } * sptr -= pixel_bytes; * * Replacement code is in the next three lines: */ for (j = 0; j < png_pass_inc[pass]; j++) { *dp-- = *sptr; } --sptr; } } else if (((pass == 2) || (pass == 3)) && width) { int width_mmx = ((width >> 2) << 2); width -= width_mmx; // 0-3 pixels => 0-3 bytes if (width_mmx) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $3, %%esi \n\t" "subl $15, %%edi \n\t" ".loop1_pass2: \n\t" "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0 "movq %%mm0, %%mm1 \n\t" // 3 3 2 2 1 1 0 0 "punpcklwd %%mm0, %%mm0 \n\t" // 1 1 1 1 0 0 0 0 "punpckhwd %%mm1, %%mm1 \n\t" // 3 3 3 3 2 2 2 2 "movq %%mm0, (%%edi) \n\t" "subl $4, %%esi \n\t" "movq %%mm1, 8(%%edi) \n\t" "subl $16, %%edi \n\t" "subl $4, %%ecx \n\t" "jnz .loop1_pass2 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width_mmx) // ecx #if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1" // clobber list #endif ); } sptr -= width_mmx; dp -= width_mmx*4; for (i = width; i; i--) { int j; for (j = 0; j < png_pass_inc[pass]; j++) { *dp-- = *sptr; } --sptr; } } else if (width) /* && ((pass == 4) || (pass == 5)) */ { int width_mmx = ((width >> 3) << 3); width -= width_mmx; // 0-3 pixels => 0-3 bytes if (width_mmx) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $7, %%esi \n\t" "subl $15, %%edi \n\t" ".loop1_pass4: \n\t" "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0 "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0 "punpckhbw %%mm1, %%mm1 \n\t" // 7 7 6 6 5 5 4 4 "movq %%mm1, 8(%%edi) \n\t" "subl $8, %%esi \n\t" "movq %%mm0, (%%edi) \n\t" "subl $16, %%edi \n\t" "subl $8, %%ecx \n\t" "jnz .loop1_pass4 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (none) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width_mmx) // ecx #if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1" // clobber list #endif ); } sptr -= width_mmx; dp -= width_mmx*2; for (i = width; i; i--) { int j; for (j = 0; j < png_pass_inc[pass]; j++) { *dp-- = *sptr; } --sptr; } } } /* end of pixel_bytes == 1 */ //-------------------------------------------------------------- else if (pixel_bytes == 2) { if (((pass == 0) || (pass == 1)) && width) { int width_mmx = ((width >> 1) << 1); width -= width_mmx; // 0,1 pixels => 0,2 bytes if (width_mmx) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $2, %%esi \n\t" "subl $30, %%edi \n\t" ".loop2_pass0: \n\t" "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0 "movq %%mm0, %%mm1 \n\t" // 3 2 3 2 1 0 1 0 "punpckldq %%mm0, %%mm0 \n\t" // 1 0 1 0 1 0 1 0 "punpckhdq %%mm1, %%mm1 \n\t" // 3 2 3 2 3 2 3 2 "movq %%mm0, (%%edi) \n\t" "movq %%mm0, 8(%%edi) \n\t" "movq %%mm1, 16(%%edi) \n\t" "subl $4, %%esi \n\t" "movq %%mm1, 24(%%edi) \n\t" "subl $32, %%edi \n\t" "subl $2, %%ecx \n\t" "jnz .loop2_pass0 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width_mmx) // ecx #if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1" // clobber list #endif ); } sptr -= (width_mmx*2 - 2); // sign fixed dp -= (width_mmx*16 - 2); // sign fixed for (i = width; i; i--) { png_byte v[8]; int j; sptr -= 2; png_memcpy(v, sptr, 2); for (j = 0; j < png_pass_inc[pass]; j++) { dp -= 2; png_memcpy(dp, v, 2); } } } else if (((pass == 2) || (pass == 3)) && width) { int width_mmx = ((width >> 1) << 1) ; width -= width_mmx; // 0,1 pixels => 0,2 bytes if (width_mmx) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $2, %%esi \n\t" "subl $14, %%edi \n\t" ".loop2_pass2: \n\t" "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0 "movq %%mm0, %%mm1 \n\t" // 3 2 3 2 1 0 1 0 "punpckldq %%mm0, %%mm0 \n\t" // 1 0 1 0 1 0 1 0 "punpckhdq %%mm1, %%mm1 \n\t" // 3 2 3 2 3 2 3 2 "movq %%mm0, (%%edi) \n\t" "subl $4, %%esi \n\t" "movq %%mm1, 8(%%edi) \n\t" "subl $16, %%edi \n\t" "subl $2, %%ecx \n\t" "jnz .loop2_pass2 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width_mmx) // ecx #if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1" // clobber list #endif ); } sptr -= (width_mmx*2 - 2); // sign fixed dp -= (width_mmx*8 - 2); // sign fixed for (i = width; i; i--) { png_byte v[8]; int j; sptr -= 2; png_memcpy(v, sptr, 2); for (j = 0; j < png_pass_inc[pass]; j++) { dp -= 2; png_memcpy(dp, v, 2); } } } else if (width) // pass == 4 or 5 { int width_mmx = ((width >> 1) << 1) ; width -= width_mmx; // 0,1 pixels => 0,2 bytes if (width_mmx) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $2, %%esi \n\t" "subl $6, %%edi \n\t" ".loop2_pass4: \n\t" "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0 "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0 "subl $4, %%esi \n\t" "movq %%mm0, (%%edi) \n\t" "subl $8, %%edi \n\t" "subl $2, %%ecx \n\t" "jnz .loop2_pass4 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width_mmx) // ecx #if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0" // clobber list #endif ); } sptr -= (width_mmx*2 - 2); // sign fixed dp -= (width_mmx*4 - 2); // sign fixed for (i = width; i; i--) { png_byte v[8]; int j; sptr -= 2; png_memcpy(v, sptr, 2); for (j = 0; j < png_pass_inc[pass]; j++) { dp -= 2; png_memcpy(dp, v, 2); } } } } /* end of pixel_bytes == 2 */ //-------------------------------------------------------------- else if (pixel_bytes == 4) { if (((pass == 0) || (pass == 1)) && width) { int width_mmx = ((width >> 1) << 1); width -= width_mmx; // 0,1 pixels => 0,4 bytes if (width_mmx) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $4, %%esi \n\t" "subl $60, %%edi \n\t" ".loop4_pass0: \n\t" "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0 "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0 "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4 "movq %%mm0, (%%edi) \n\t" "movq %%mm0, 8(%%edi) \n\t" "movq %%mm0, 16(%%edi) \n\t" "movq %%mm0, 24(%%edi) \n\t" "movq %%mm1, 32(%%edi) \n\t" "movq %%mm1, 40(%%edi) \n\t" "movq %%mm1, 48(%%edi) \n\t" "subl $8, %%esi \n\t" "movq %%mm1, 56(%%edi) \n\t" "subl $64, %%edi \n\t" "subl $2, %%ecx \n\t" "jnz .loop4_pass0 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width_mmx) // ecx #if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1" // clobber list #endif ); } sptr -= (width_mmx*4 - 4); // sign fixed dp -= (width_mmx*32 - 4); // sign fixed for (i = width; i; i--) { png_byte v[8]; int j; sptr -= 4; png_memcpy(v, sptr, 4); for (j = 0; j < png_pass_inc[pass]; j++) { dp -= 4; png_memcpy(dp, v, 4); } } } else if (((pass == 2) || (pass == 3)) && width) { int width_mmx = ((width >> 1) << 1); width -= width_mmx; // 0,1 pixels => 0,4 bytes if (width_mmx) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $4, %%esi \n\t" "subl $28, %%edi \n\t" ".loop4_pass2: \n\t" "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0 "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0 "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4 "movq %%mm0, (%%edi) \n\t" "movq %%mm0, 8(%%edi) \n\t" "movq %%mm1, 16(%%edi) \n\t" "movq %%mm1, 24(%%edi) \n\t" "subl $8, %%esi \n\t" "subl $32, %%edi \n\t" "subl $2, %%ecx \n\t" "jnz .loop4_pass2 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width_mmx) // ecx #if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1" // clobber list #endif ); } sptr -= (width_mmx*4 - 4); // sign fixed dp -= (width_mmx*16 - 4); // sign fixed for (i = width; i; i--) { png_byte v[8]; int j; sptr -= 4; png_memcpy(v, sptr, 4); for (j = 0; j < png_pass_inc[pass]; j++) { dp -= 4; png_memcpy(dp, v, 4); } } } else if (width) // pass == 4 or 5 { int width_mmx = ((width >> 1) << 1) ; width -= width_mmx; // 0,1 pixels => 0,4 bytes if (width_mmx) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $4, %%esi \n\t" "subl $12, %%edi \n\t" ".loop4_pass4: \n\t" "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0 "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0 "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4 "movq %%mm0, (%%edi) \n\t" "subl $8, %%esi \n\t" "movq %%mm1, 8(%%edi) \n\t" "subl $16, %%edi \n\t" "subl $2, %%ecx \n\t" "jnz .loop4_pass4 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width_mmx) // ecx #if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0", "%mm1" // clobber list #endif ); } sptr -= (width_mmx*4 - 4); // sign fixed dp -= (width_mmx*8 - 4); // sign fixed for (i = width; i; i--) { png_byte v[8]; int j; sptr -= 4; png_memcpy(v, sptr, 4); for (j = 0; j < png_pass_inc[pass]; j++) { dp -= 4; png_memcpy(dp, v, 4); } } } } /* end of pixel_bytes == 4 */ //-------------------------------------------------------------- else if (pixel_bytes == 8) { // GRR TEST: should work, but needs testing (special 64-bit version of rpng2?) // GRR NOTE: no need to combine passes here! if (((pass == 0) || (pass == 1)) && width) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; // source is 8-byte RRGGBBAA // dest is 64-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA ... __asm__ __volatile__ ( "subl $56, %%edi \n\t" // start of last block ".loop8_pass0: \n\t" "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 "movq %%mm0, (%%edi) \n\t" "movq %%mm0, 8(%%edi) \n\t" "movq %%mm0, 16(%%edi) \n\t" "movq %%mm0, 24(%%edi) \n\t" "movq %%mm0, 32(%%edi) \n\t" "movq %%mm0, 40(%%edi) \n\t" "movq %%mm0, 48(%%edi) \n\t" "subl $8, %%esi \n\t" "movq %%mm0, 56(%%edi) \n\t" "subl $64, %%edi \n\t" "decl %%ecx \n\t" "jnz .loop8_pass0 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width) // ecx #if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0" // clobber list #endif ); } else if (((pass == 2) || (pass == 3)) && width) { // source is 8-byte RRGGBBAA // dest is 32-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA // (recall that expansion is _in place_: sptr and dp // both point at locations within same row buffer) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $24, %%edi \n\t" // start of last block ".loop8_pass2: \n\t" "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 "movq %%mm0, (%%edi) \n\t" "movq %%mm0, 8(%%edi) \n\t" "movq %%mm0, 16(%%edi) \n\t" "subl $8, %%esi \n\t" "movq %%mm0, 24(%%edi) \n\t" "subl $32, %%edi \n\t" "decl %%ecx \n\t" "jnz .loop8_pass2 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width) // ecx #if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0" // clobber list #endif ); } } else if (width) // pass == 4 or 5 { // source is 8-byte RRGGBBAA // dest is 16-byte RRGGBBAA RRGGBBAA { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; int dummy_value_D; __asm__ __volatile__ ( "subl $8, %%edi \n\t" // start of last block ".loop8_pass4: \n\t" "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0 "movq %%mm0, (%%edi) \n\t" "subl $8, %%esi \n\t" "movq %%mm0, 8(%%edi) \n\t" "subl $16, %%edi \n\t" "decl %%ecx \n\t" "jnz .loop8_pass4 \n\t" "EMMS \n\t" // DONE : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "1" (sptr), // esi // input regs "2" (dp), // edi "0" (width) // ecx #if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ : "%mm0" // clobber list #endif ); } } } /* end of pixel_bytes == 8 */ //-------------------------------------------------------------- else if (pixel_bytes == 6) { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, 6); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, 6); dp -= 6; } sptr -= 6; } } /* end of pixel_bytes == 6 */ //-------------------------------------------------------------- else { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, pixel_bytes); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, pixel_bytes); dp -= pixel_bytes; } sptr-= pixel_bytes; } } } // end of _mmx_supported ======================================== else /* MMX not supported: use modified C code - takes advantage * of inlining of png_memcpy for a constant */ /* GRR 19991007: does it? or should pixel_bytes in each * block be replaced with immediate value (e.g., 1)? */ /* GRR 19991017: replaced with constants in each case */ #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ { if (pixel_bytes == 1) { for (i = width; i; i--) { int j; for (j = 0; j < png_pass_inc[pass]; j++) { *dp-- = *sptr; } --sptr; } } else if (pixel_bytes == 3) { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, 3); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, 3); dp -= 3; } sptr -= 3; } } else if (pixel_bytes == 2) { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, 2); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, 2); dp -= 2; } sptr -= 2; } } else if (pixel_bytes == 4) { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, 4); for (j = 0; j < png_pass_inc[pass]; j++) { #ifdef PNG_DEBUG if (dp < row || dp+3 > row+png_ptr->row_buf_size) { printf("dp out of bounds: row=%d, dp=%d, rp=%d\n", row, dp, row+png_ptr->row_buf_size); printf("row_buf=%d\n",png_ptr->row_buf_size); } #endif png_memcpy(dp, v, 4); dp -= 4; } sptr -= 4; } } else if (pixel_bytes == 6) { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, 6); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, 6); dp -= 6; } sptr -= 6; } } else if (pixel_bytes == 8) { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, 8); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, 8); dp -= 8; } sptr -= 8; } } else /* GRR: should never be reached */ { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, pixel_bytes); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, pixel_bytes); dp -= pixel_bytes; } sptr -= pixel_bytes; } } } /* end if (MMX not supported) */ break; } } /* end switch (row_info->pixel_depth) */ row_info->width = final_width; row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); } } /* end png_do_read_interlace() */ #endif /* PNG_HAVE_ASSEMBLER_READ_INTERLACE */ #endif /* PNG_READ_INTERLACING_SUPPORTED */ #if defined(PNG_HAVE_ASSEMBLER_READ_FILTER_ROW) #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) // These variables are utilized in the functions below. They are declared // globally here to ensure alignment on 8-byte boundaries. union uAll { long long use; double align; } _LBCarryMask = {0x0101010101010101LL}, _HBClearMask = {0x7f7f7f7f7f7f7f7fLL}, _ActiveMask, _ActiveMask2, _ActiveMaskEnd, _ShiftBpp, _ShiftRem; #ifdef PNG_THREAD_UNSAFE_OK //===========================================================================// // // // P N G _ R E A D _ F I L T E R _ R O W _ M M X _ A V G // // // //===========================================================================// // Optimized code for PNG Average filter decoder static void /* PRIVATE */ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, png_bytep prev_row) { int bpp; int dummy_value_c; // fix 'forbidden register 2 (cx) was spilled' error int dummy_value_S; int dummy_value_D; bpp = (row_info->pixel_depth + 7) >> 3; // get # bytes per pixel _FullLength = row_info->rowbytes; // # of bytes to filter __asm__ __volatile__ ( // initialize address pointers and offset #ifdef __PIC__ "pushl %%ebx \n\t" // save index to Global Offset Table #endif //pre "movl row, %%edi \n\t" // edi: Avg(x) "xorl %%ebx, %%ebx \n\t" // ebx: x "movl %%edi, %%edx \n\t" //pre "movl prev_row, %%esi \n\t" // esi: Prior(x) //pre "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) "subl %%ecx, %%edx \n\t" // edx: Raw(x-bpp) "xorl %%eax,%%eax \n\t" // Compute the Raw value for the first bpp bytes // Raw(x) = Avg(x) + (Prior(x)/2) "avg_rlp: \n\t" "movb (%%esi,%%ebx,),%%al \n\t" // load al with Prior(x) "incl %%ebx \n\t" "shrb %%al \n\t" // divide by 2 "addb -1(%%edi,%%ebx,),%%al \n\t" // add Avg(x); -1 to offset inc ebx //pre "cmpl bpp, %%ebx \n\t" // (bpp is preloaded into ecx) "cmpl %%ecx, %%ebx \n\t" "movb %%al,-1(%%edi,%%ebx,) \n\t" // write Raw(x); -1 to offset inc ebx "jb avg_rlp \n\t" // mov does not affect flags // get # of bytes to alignment "movl %%edi, _dif \n\t" // take start of row "addl %%ebx, _dif \n\t" // add bpp "addl $0xf, _dif \n\t" // add 7+8 to incr past alignment bdry "andl $0xfffffff8, _dif \n\t" // mask to alignment boundary "subl %%edi, _dif \n\t" // subtract from start => value ebx at "jz avg_go \n\t" // alignment // fix alignment // Compute the Raw value for the bytes up to the alignment boundary // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) "xorl %%ecx, %%ecx \n\t" "avg_lp1: \n\t" "xorl %%eax, %%eax \n\t" "movb (%%esi,%%ebx,), %%cl \n\t" // load cl with Prior(x) "movb (%%edx,%%ebx,), %%al \n\t" // load al with Raw(x-bpp) "addw %%cx, %%ax \n\t" "incl %%ebx \n\t" "shrw %%ax \n\t" // divide by 2 "addb -1(%%edi,%%ebx,), %%al \n\t" // add Avg(x); -1 to offset inc ebx "cmpl _dif, %%ebx \n\t" // check if at alignment boundary "movb %%al, -1(%%edi,%%ebx,) \n\t" // write Raw(x); -1 to offset inc ebx "jb avg_lp1 \n\t" // repeat until at alignment boundary "avg_go: \n\t" "movl _FullLength, %%eax \n\t" "movl %%eax, %%ecx \n\t" "subl %%ebx, %%eax \n\t" // subtract alignment fix "andl $0x00000007, %%eax \n\t" // calc bytes over mult of 8 "subl %%eax, %%ecx \n\t" // drop over bytes from original length "movl %%ecx, _MMXLength \n\t" #ifdef __PIC__ "popl %%ebx \n\t" // restore index to Global Offset Table #endif : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "0" (bpp), // ecx // input regs "1" (prev_row), // esi "2" (row) // edi : "%eax", "%edx" // clobber list #ifndef __PIC__ , "%ebx" #endif // GRR: INCLUDE "memory" as clobbered? (_dif, _MMXLength) // (seems to work fine without...) ); // now do the math for the rest of the row switch (bpp) { case 3: { _ActiveMask.use = 0x0000000000ffffffLL; _ShiftBpp.use = 24; // == 3 * 8 _ShiftRem.use = 40; // == 64 - 24 __asm__ __volatile__ ( // re-init address pointers and offset "movq _ActiveMask, %%mm7 \n\t" "movl _dif, %%ecx \n\t" // ecx: x = offset to "movq _LBCarryMask, %%mm5 \n\t" // alignment boundary // preload "movl row, %%edi \n\t" // edi: Avg(x) "movq _HBClearMask, %%mm4 \n\t" // preload "movl prev_row, %%esi \n\t" // esi: Prior(x) // prime the pump: load the first Raw(x-bpp) data set "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes // (correct pos. in loop below) "avg_3lp: \n\t" "movq (%%edi,%%ecx,), %%mm0 \n\t" // load mm0 with Avg(x) "movq %%mm5, %%mm3 \n\t" "psrlq _ShiftRem, %%mm2 \n\t" // correct position Raw(x-bpp) // data "movq (%%esi,%%ecx,), %%mm1 \n\t" // load mm1 with Prior(x) "movq %%mm7, %%mm6 \n\t" "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for // each byte // add 1st active group (Raw(x-bpp)/2) to average with LBCarry "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting // LBCarrys "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte // where both // lsb's were == 1 (only valid for active group) "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) // for each byte "pand %%mm6, %%mm2 \n\t" // leave only Active Group 1 // bytes to add to Avg "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to // Avg for each Active // byte // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 mask to cover // bytes 3-5 "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting // LBCarrys "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte // where both // lsb's were == 1 (only valid for active group) "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) // for each byte "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 // bytes to add to Avg "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to // Avg for each Active // byte // add 3rd active group (Raw(x-bpp)/2) to average with _LBCarry "psllq _ShiftBpp, %%mm6 \n\t" // shift mm6 mask to cover last // two // bytes "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly // Data only needs to be shifted once here to // get the correct x-bpp offset. "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting // LBCarrys "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte // where both // lsb's were == 1 (only valid for active group) "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) // for each byte "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 // bytes to add to Avg "addl $8, %%ecx \n\t" "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to // Avg for each Active // byte // now ready to write back to memory "movq %%mm0, -8(%%edi,%%ecx,) \n\t" // move updated Raw(x) to use as Raw(x-bpp) for next loop "cmpl _MMXLength, %%ecx \n\t" "movq %%mm0, %%mm2 \n\t" // mov updated Raw(x) to mm2 "jb avg_3lp \n\t" : "=S" (dummy_value_S), // output regs (dummy) "=D" (dummy_value_D) : "0" (prev_row), // esi // input regs "1" (row) // edi : "%ecx" // clobber list #if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm2", "%mm3" , "%mm4", "%mm5", "%mm6", "%mm7" #endif ); } break; // end 3 bpp case 6: case 4: //case 7: // who wrote this? PNG doesn't support 5 or 7 bytes/pixel //case 5: // GRR BOGUS { _ActiveMask.use = 0xffffffffffffffffLL; // use shift below to clear // appropriate inactive bytes _ShiftBpp.use = bpp << 3; _ShiftRem.use = 64 - _ShiftBpp.use; __asm__ __volatile__ ( "movq _HBClearMask, %%mm4 \n\t" // re-init address pointers and offset "movl _dif, %%ecx \n\t" // ecx: x = offset to // alignment boundary // load _ActiveMask and clear all bytes except for 1st active group "movq _ActiveMask, %%mm7 \n\t" // preload "movl row, %%edi \n\t" // edi: Avg(x) "psrlq _ShiftRem, %%mm7 \n\t" // preload "movl prev_row, %%esi \n\t" // esi: Prior(x) "movq %%mm7, %%mm6 \n\t" "movq _LBCarryMask, %%mm5 \n\t" "psllq _ShiftBpp, %%mm6 \n\t" // create mask for 2nd active // group // prime the pump: load the first Raw(x-bpp) data set "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes // (we correct pos. in loop below) "avg_4lp: \n\t" "movq (%%edi,%%ecx,), %%mm0 \n\t" "psrlq _ShiftRem, %%mm2 \n\t" // shift data to pos. correctly "movq (%%esi,%%ecx,), %%mm1 \n\t" // add (Prev_row/2) to average "movq %%mm5, %%mm3 \n\t" "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for // each byte // add 1st active group (Raw(x-bpp)/2) to average with _LBCarry "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting // LBCarrys "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte // where both // lsb's were == 1 (only valid for active group) "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) // for each byte "pand %%mm7, %%mm2 \n\t" // leave only Active Group 1 // bytes to add to Avg "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to Avg // for each Active // byte // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly "addl $8, %%ecx \n\t" "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting // LBCarrys "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte // where both // lsb's were == 1 (only valid for active group) "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) // for each byte "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 // bytes to add to Avg "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to // Avg for each Active // byte "cmpl _MMXLength, %%ecx \n\t" // now ready to write back to memory "movq %%mm0, -8(%%edi,%%ecx,) \n\t" // prep Raw(x-bpp) for next loop "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 "jb avg_4lp \n\t" : "=S" (dummy_value_S), // output regs (dummy) "=D" (dummy_value_D) : "0" (prev_row), // esi // input regs "1" (row) // edi : "%ecx" // clobber list #if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm2", "%mm3" , "%mm4", "%mm5", "%mm6", "%mm7" #endif ); } break; // end 4,6 bpp case 2: { _ActiveMask.use = 0x000000000000ffffLL; _ShiftBpp.use = 16; // == 2 * 8 _ShiftRem.use = 48; // == 64 - 16 __asm__ __volatile__ ( // load _ActiveMask "movq _ActiveMask, %%mm7 \n\t" // re-init address pointers and offset "movl _dif, %%ecx \n\t" // ecx: x = offset to alignment // boundary "movq _LBCarryMask, %%mm5 \n\t" // preload "movl row, %%edi \n\t" // edi: Avg(x) "movq _HBClearMask, %%mm4 \n\t" // preload "movl prev_row, %%esi \n\t" // esi: Prior(x) // prime the pump: load the first Raw(x-bpp) data set "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes // (we correct pos. in loop below) "avg_2lp: \n\t" "movq (%%edi,%%ecx,), %%mm0 \n\t" "psrlq _ShiftRem, %%mm2 \n\t" // shift data to pos. correctly "movq (%%esi,%%ecx,), %%mm1 \n\t" // (GRR BUGFIX: was psllq) // add (Prev_row/2) to average "movq %%mm5, %%mm3 \n\t" "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each // byte "movq %%mm7, %%mm6 \n\t" "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for // each byte // add 1st active group (Raw(x-bpp)/2) to average with _LBCarry "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting // LBCarrys "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte // where both // lsb's were == 1 (only valid // for active group) "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) // for each byte "pand %%mm6, %%mm2 \n\t" // leave only Active Group 1 // bytes to add to Avg "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to Avg // for each Active byte // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 mask to cover // bytes 2 & 3 "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting // LBCarrys "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte // where both // lsb's were == 1 (only valid // for active group) "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) // for each byte "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 // bytes to add to Avg "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to // Avg for each Active byte // add 3rd active group (Raw(x-bpp)/2) to average with _LBCarry "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 mask to cover // bytes 4 & 5 "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting // LBCarrys "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte // where both lsb's were == 1 // (only valid for active group) "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) // for each byte "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 // bytes to add to Avg "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to // Avg for each Active byte // add 4th active group (Raw(x-bpp)/2) to average with _LBCarry "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 mask to cover // bytes 6 & 7 "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly "addl $8, %%ecx \n\t" "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting // LBCarrys "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte // where both // lsb's were == 1 (only valid // for active group) "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2) // for each byte "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2 // bytes to add to Avg "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to // Avg for each Active byte "cmpl _MMXLength, %%ecx \n\t" // now ready to write back to memory "movq %%mm0, -8(%%edi,%%ecx,) \n\t" // prep Raw(x-bpp) for next loop "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2 "jb avg_2lp \n\t" : "=S" (dummy_value_S), // output regs (dummy) "=D" (dummy_value_D) : "0" (prev_row), // esi // input regs "1" (row) // edi : "%ecx" // clobber list #if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm2", "%mm3" , "%mm4", "%mm5", "%mm6", "%mm7" #endif ); } break; // end 2 bpp case 1: { __asm__ __volatile__ ( // re-init address pointers and offset #ifdef __PIC__ "pushl %%ebx \n\t" // save Global Offset Table index #endif "movl _dif, %%ebx \n\t" // ebx: x = offset to alignment // boundary // preload "movl row, %%edi \n\t" // edi: Avg(x) "cmpl _FullLength, %%ebx \n\t" // test if offset at end of array "jnb avg_1end \n\t" // do Paeth decode for remaining bytes // preload "movl prev_row, %%esi \n\t" // esi: Prior(x) "movl %%edi, %%edx \n\t" // preload "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) "subl %%ecx, %%edx \n\t" // edx: Raw(x-bpp) "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx // in loop below "avg_1lp: \n\t" // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) "xorl %%eax, %%eax \n\t" "movb (%%esi,%%ebx,), %%cl \n\t" // load cl with Prior(x) "movb (%%edx,%%ebx,), %%al \n\t" // load al with Raw(x-bpp) "addw %%cx, %%ax \n\t" "incl %%ebx \n\t" "shrw %%ax \n\t" // divide by 2 "addb -1(%%edi,%%ebx,), %%al \n\t" // add Avg(x); -1 to offset // inc ebx "cmpl _FullLength, %%ebx \n\t" // check if at end of array "movb %%al, -1(%%edi,%%ebx,) \n\t" // write back Raw(x); // mov does not affect flags; -1 to offset inc ebx "jb avg_1lp \n\t" "avg_1end: \n\t" #ifdef __PIC__ "popl %%ebx \n\t" // Global Offset Table index #endif : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "0" (bpp), // ecx // input regs "1" (prev_row), // esi "2" (row) // edi : "%eax", "%edx" // clobber list #ifndef __PIC__ , "%ebx" #endif ); } return; // end 1 bpp case 8: { __asm__ __volatile__ ( // re-init address pointers and offset "movl _dif, %%ecx \n\t" // ecx: x == offset to alignment "movq _LBCarryMask, %%mm5 \n\t" // boundary // preload "movl row, %%edi \n\t" // edi: Avg(x) "movq _HBClearMask, %%mm4 \n\t" // preload "movl prev_row, %%esi \n\t" // esi: Prior(x) // prime the pump: load the first Raw(x-bpp) data set "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes // (NO NEED to correct pos. in loop below) "avg_8lp: \n\t" "movq (%%edi,%%ecx,), %%mm0 \n\t" "movq %%mm5, %%mm3 \n\t" "movq (%%esi,%%ecx,), %%mm1 \n\t" "addl $8, %%ecx \n\t" "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 "pand %%mm2, %%mm3 \n\t" // get LBCarrys for each byte // where both lsb's were == 1 "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7, each byte "paddb %%mm3, %%mm0 \n\t" // add LBCarrys to Avg, each byte "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7, each byte "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg, each "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) to Avg for each "cmpl _MMXLength, %%ecx \n\t" "movq %%mm0, -8(%%edi,%%ecx,) \n\t" "movq %%mm0, %%mm2 \n\t" // reuse as Raw(x-bpp) "jb avg_8lp \n\t" : "=S" (dummy_value_S), // output regs (dummy) "=D" (dummy_value_D) : "0" (prev_row), // esi // input regs "1" (row) // edi : "%ecx" // clobber list #if 0 /* %mm0, ..., %mm5 not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm2" , "%mm3", "%mm4", "%mm5" #endif ); } break; // end 8 bpp default: // bpp greater than 8 (!= 1,2,3,4,[5],6,[7],8) { #ifdef PNG_DEBUG // GRR: PRINT ERROR HERE: SHOULD NEVER BE REACHED png_debug(1, "Internal logic error in pnggccrd (png_read_filter_row_mmx_avg())\n"); #endif #if 0 __asm__ __volatile__ ( "movq _LBCarryMask, %%mm5 \n\t" // re-init address pointers and offset "movl _dif, %%ebx \n\t" // ebx: x = offset to // alignment boundary "movl row, %%edi \n\t" // edi: Avg(x) "movq _HBClearMask, %%mm4 \n\t" "movl %%edi, %%edx \n\t" "movl prev_row, %%esi \n\t" // esi: Prior(x) "subl bpp, %%edx \n\t" // edx: Raw(x-bpp) "avg_Alp: \n\t" "movq (%%edi,%%ebx,), %%mm0 \n\t" "movq %%mm5, %%mm3 \n\t" "movq (%%esi,%%ebx,), %%mm1 \n\t" "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte "movq (%%edx,%%ebx,), %%mm2 \n\t" "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2 "pand %%mm2, %%mm3 \n\t" // get LBCarrys for each byte // where both lsb's were == 1 "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2 "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm3, %%mm0 \n\t" // add LBCarrys to Avg for each // byte "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each // byte "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for // each byte "addl $8, %%ebx \n\t" "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) to Avg for each // byte "cmpl _MMXLength, %%ebx \n\t" "movq %%mm0, -8(%%edi,%%ebx,) \n\t" "jb avg_Alp \n\t" : // FIXASM: output regs/vars go here, e.g.: "=m" (memory_var) : // FIXASM: input regs, e.g.: "c" (count), "S" (src), "D" (dest) : "%ebx", "%edx", "%edi", "%esi" // CHECKASM: clobber list ); #endif /* 0 - NEVER REACHED */ } break; } // end switch (bpp) __asm__ __volatile__ ( // MMX acceleration complete; now do clean-up // check if any remaining bytes left to decode #ifdef __PIC__ "pushl %%ebx \n\t" // save index to Global Offset Table #endif "movl _MMXLength, %%ebx \n\t" // ebx: x == offset bytes after MMX //pre "movl row, %%edi \n\t" // edi: Avg(x) "cmpl _FullLength, %%ebx \n\t" // test if offset at end of array "jnb avg_end \n\t" // do Avg decode for remaining bytes //pre "movl prev_row, %%esi \n\t" // esi: Prior(x) "movl %%edi, %%edx \n\t" //pre "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) "subl %%ecx, %%edx \n\t" // edx: Raw(x-bpp) "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx below "avg_lp2: \n\t" // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) "xorl %%eax, %%eax \n\t" "movb (%%esi,%%ebx,), %%cl \n\t" // load cl with Prior(x) "movb (%%edx,%%ebx,), %%al \n\t" // load al with Raw(x-bpp) "addw %%cx, %%ax \n\t" "incl %%ebx \n\t" "shrw %%ax \n\t" // divide by 2 "addb -1(%%edi,%%ebx,), %%al \n\t" // add Avg(x); -1 to offset inc ebx "cmpl _FullLength, %%ebx \n\t" // check if at end of array "movb %%al, -1(%%edi,%%ebx,) \n\t" // write back Raw(x) [mov does not "jb avg_lp2 \n\t" // affect flags; -1 to offset inc ebx] "avg_end: \n\t" "EMMS \n\t" // end MMX; prep for poss. FP instrs. #ifdef __PIC__ "popl %%ebx \n\t" // restore index to Global Offset Table #endif : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "0" (bpp), // ecx // input regs "1" (prev_row), // esi "2" (row) // edi : "%eax", "%edx" // clobber list #ifndef __PIC__ , "%ebx" #endif ); } /* end png_read_filter_row_mmx_avg() */ #endif #ifdef PNG_THREAD_UNSAFE_OK //===========================================================================// // // // P N G _ R E A D _ F I L T E R _ R O W _ M M X _ P A E T H // // // //===========================================================================// // Optimized code for PNG Paeth filter decoder static void /* PRIVATE */ png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, png_bytep prev_row) { int bpp; int dummy_value_c; // fix 'forbidden register 2 (cx) was spilled' error int dummy_value_S; int dummy_value_D; bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel _FullLength = row_info->rowbytes; // # of bytes to filter __asm__ __volatile__ ( #ifdef __PIC__ "pushl %%ebx \n\t" // save index to Global Offset Table #endif "xorl %%ebx, %%ebx \n\t" // ebx: x offset //pre "movl row, %%edi \n\t" "xorl %%edx, %%edx \n\t" // edx: x-bpp offset //pre "movl prev_row, %%esi \n\t" "xorl %%eax, %%eax \n\t" // Compute the Raw value for the first bpp bytes // Note: the formula works out to be always // Paeth(x) = Raw(x) + Prior(x) where x < bpp "paeth_rlp: \n\t" "movb (%%edi,%%ebx,), %%al \n\t" "addb (%%esi,%%ebx,), %%al \n\t" "incl %%ebx \n\t" //pre "cmpl bpp, %%ebx \n\t" (bpp is preloaded into ecx) "cmpl %%ecx, %%ebx \n\t" "movb %%al, -1(%%edi,%%ebx,) \n\t" "jb paeth_rlp \n\t" // get # of bytes to alignment "movl %%edi, _dif \n\t" // take start of row "addl %%ebx, _dif \n\t" // add bpp "xorl %%ecx, %%ecx \n\t" "addl $0xf, _dif \n\t" // add 7 + 8 to incr past alignment // boundary "andl $0xfffffff8, _dif \n\t" // mask to alignment boundary "subl %%edi, _dif \n\t" // subtract from start ==> value ebx // at alignment "jz paeth_go \n\t" // fix alignment "paeth_lp1: \n\t" "xorl %%eax, %%eax \n\t" // pav = p - a = (a + b - c) - a = b - c "movb (%%esi,%%ebx,), %%al \n\t" // load Prior(x) into al "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) "movl %%eax, _patemp \n\t" // Save pav for later use "xorl %%eax, %%eax \n\t" // pbv = p - b = (a + b - c) - b = a - c "movb (%%edi,%%edx,), %%al \n\t" // load Raw(x-bpp) into al "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) "movl %%eax, %%ecx \n\t" // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv "addl _patemp, %%eax \n\t" // pcv = pav + pbv // pc = abs(pcv) "testl $0x80000000, %%eax \n\t" "jz paeth_pca \n\t" "negl %%eax \n\t" // reverse sign of neg values "paeth_pca: \n\t" "movl %%eax, _pctemp \n\t" // save pc for later use // pb = abs(pbv) "testl $0x80000000, %%ecx \n\t" "jz paeth_pba \n\t" "negl %%ecx \n\t" // reverse sign of neg values "paeth_pba: \n\t" "movl %%ecx, _pbtemp \n\t" // save pb for later use // pa = abs(pav) "movl _patemp, %%eax \n\t" "testl $0x80000000, %%eax \n\t" "jz paeth_paa \n\t" "negl %%eax \n\t" // reverse sign of neg values "paeth_paa: \n\t" "movl %%eax, _patemp \n\t" // save pa for later use // test if pa <= pb "cmpl %%ecx, %%eax \n\t" "jna paeth_abb \n\t" // pa > pb; now test if pb <= pc "cmpl _pctemp, %%ecx \n\t" "jna paeth_bbc \n\t" // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl "jmp paeth_paeth \n\t" "paeth_bbc: \n\t" // pb <= pc; Raw(x) = Paeth(x) + Prior(x) "movb (%%esi,%%ebx,), %%cl \n\t" // load Prior(x) into cl "jmp paeth_paeth \n\t" "paeth_abb: \n\t" // pa <= pb; now test if pa <= pc "cmpl _pctemp, %%eax \n\t" "jna paeth_abc \n\t" // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl "jmp paeth_paeth \n\t" "paeth_abc: \n\t" // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) "movb (%%edi,%%edx,), %%cl \n\t" // load Raw(x-bpp) into cl "paeth_paeth: \n\t" "incl %%ebx \n\t" "incl %%edx \n\t" // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 "addb %%cl, -1(%%edi,%%ebx,) \n\t" "cmpl _dif, %%ebx \n\t" "jb paeth_lp1 \n\t" "paeth_go: \n\t" "movl _FullLength, %%ecx \n\t" "movl %%ecx, %%eax \n\t" "subl %%ebx, %%eax \n\t" // subtract alignment fix "andl $0x00000007, %%eax \n\t" // calc bytes over mult of 8 "subl %%eax, %%ecx \n\t" // drop over bytes from original length "movl %%ecx, _MMXLength \n\t" #ifdef __PIC__ "popl %%ebx \n\t" // restore index to Global Offset Table #endif : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "0" (bpp), // ecx // input regs "1" (prev_row), // esi "2" (row) // edi : "%eax", "%edx" // clobber list #ifndef __PIC__ , "%ebx" #endif ); // now do the math for the rest of the row switch (bpp) { case 3: { _ActiveMask.use = 0x0000000000ffffffLL; _ActiveMaskEnd.use = 0xffff000000000000LL; _ShiftBpp.use = 24; // == bpp(3) * 8 _ShiftRem.use = 40; // == 64 - 24 __asm__ __volatile__ ( "movl _dif, %%ecx \n\t" // preload "movl row, %%edi \n\t" // preload "movl prev_row, %%esi \n\t" "pxor %%mm0, %%mm0 \n\t" // prime the pump: load the first Raw(x-bpp) data set "movq -8(%%edi,%%ecx,), %%mm1 \n\t" "paeth_3lp: \n\t" "psrlq _ShiftRem, %%mm1 \n\t" // shift last 3 bytes to 1st // 3 bytes "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) "punpcklbw %%mm0, %%mm1 \n\t" // unpack High bytes of a "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // prep c=Prior(x-bpp) bytes "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b "psrlq _ShiftRem, %%mm3 \n\t" // shift last 3 bytes to 1st // 3 bytes // pav = p - a = (a + b - c) - a = b - c "movq %%mm2, %%mm4 \n\t" "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c // pbv = p - b = (a + b - c) - b = a - c "movq %%mm1, %%mm5 \n\t" "psubw %%mm3, %%mm4 \n\t" "pxor %%mm7, %%mm7 \n\t" // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv "movq %%mm4, %%mm6 \n\t" "psubw %%mm3, %%mm5 \n\t" // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 "paddw %%mm5, %%mm6 \n\t" "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 "psubw %%mm0, %%mm4 \n\t" "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 "psubw %%mm0, %%mm4 \n\t" "psubw %%mm7, %%mm5 \n\t" "pxor %%mm0, %%mm0 \n\t" "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 "psubw %%mm7, %%mm5 \n\t" "psubw %%mm0, %%mm6 \n\t" // test pa <= pb "movq %%mm4, %%mm7 \n\t" "psubw %%mm0, %%mm6 \n\t" "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? "movq %%mm7, %%mm0 \n\t" // use mm7 mask to merge pa & pb "pand %%mm7, %%mm5 \n\t" // use mm0 mask copy to merge a & b "pand %%mm0, %%mm2 \n\t" "pandn %%mm4, %%mm7 \n\t" "pandn %%mm1, %%mm0 \n\t" "paddw %%mm5, %%mm7 \n\t" "paddw %%mm2, %%mm0 \n\t" // test ((pa <= pb)? pa:pb) <= pc "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? "pxor %%mm1, %%mm1 \n\t" "pand %%mm7, %%mm3 \n\t" "pandn %%mm0, %%mm7 \n\t" "paddw %%mm3, %%mm7 \n\t" "pxor %%mm0, %%mm0 \n\t" "packuswb %%mm1, %%mm7 \n\t" "movq (%%esi,%%ecx,), %%mm3 \n\t" // load c=Prior(x-bpp) "pand _ActiveMask, %%mm7 \n\t" "movq %%mm3, %%mm2 \n\t" // load b=Prior(x) step 1 "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x) "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value "movq %%mm7, %%mm1 \n\t" // now mm1 will be used as // Raw(x-bpp) // now do Paeth for 2nd set of bytes (3-5) "psrlq _ShiftBpp, %%mm2 \n\t" // load b=Prior(x) step 2 "punpcklbw %%mm0, %%mm1 \n\t" // unpack High bytes of a "pxor %%mm7, %%mm7 \n\t" "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b // pbv = p - b = (a + b - c) - b = a - c "movq %%mm1, %%mm5 \n\t" // pav = p - a = (a + b - c) - a = b - c "movq %%mm2, %%mm4 \n\t" "psubw %%mm3, %%mm5 \n\t" "psubw %%mm3, %%mm4 \n\t" // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = // pav + pbv = pbv + pav "movq %%mm5, %%mm6 \n\t" "paddw %%mm4, %%mm6 \n\t" // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) "pcmpgtw %%mm5, %%mm0 \n\t" // create mask pbv bytes < 0 "pcmpgtw %%mm4, %%mm7 \n\t" // create mask pav bytes < 0 "pand %%mm5, %%mm0 \n\t" // only pbv bytes < 0 in mm0 "pand %%mm4, %%mm7 \n\t" // only pav bytes < 0 in mm7 "psubw %%mm0, %%mm5 \n\t" "psubw %%mm7, %%mm4 \n\t" "psubw %%mm0, %%mm5 \n\t" "psubw %%mm7, %%mm4 \n\t" "pxor %%mm0, %%mm0 \n\t" "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 "psubw %%mm0, %%mm6 \n\t" // test pa <= pb "movq %%mm4, %%mm7 \n\t" "psubw %%mm0, %%mm6 \n\t" "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? "movq %%mm7, %%mm0 \n\t" // use mm7 mask to merge pa & pb "pand %%mm7, %%mm5 \n\t" // use mm0 mask copy to merge a & b "pand %%mm0, %%mm2 \n\t" "pandn %%mm4, %%mm7 \n\t" "pandn %%mm1, %%mm0 \n\t" "paddw %%mm5, %%mm7 \n\t" "paddw %%mm2, %%mm0 \n\t" // test ((pa <= pb)? pa:pb) <= pc "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) "pand %%mm7, %%mm3 \n\t" "pandn %%mm0, %%mm7 \n\t" "pxor %%mm1, %%mm1 \n\t" "paddw %%mm3, %%mm7 \n\t" "pxor %%mm0, %%mm0 \n\t" "packuswb %%mm1, %%mm7 \n\t" "movq %%mm2, %%mm3 \n\t" // load c=Prior(x-bpp) step 1 "pand _ActiveMask, %%mm7 \n\t" "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b "psllq _ShiftBpp, %%mm7 \n\t" // shift bytes to 2nd group of // 3 bytes // pav = p - a = (a + b - c) - a = b - c "movq %%mm2, %%mm4 \n\t" "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x) "psllq _ShiftBpp, %%mm3 \n\t" // load c=Prior(x-bpp) step 2 "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value "movq %%mm7, %%mm1 \n\t" "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c "psllq _ShiftBpp, %%mm1 \n\t" // shift bytes // now mm1 will be used as Raw(x-bpp) // now do Paeth for 3rd, and final, set of bytes (6-7) "pxor %%mm7, %%mm7 \n\t" "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a "psubw %%mm3, %%mm4 \n\t" // pbv = p - b = (a + b - c) - b = a - c "movq %%mm1, %%mm5 \n\t" // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv "movq %%mm4, %%mm6 \n\t" "psubw %%mm3, %%mm5 \n\t" "pxor %%mm0, %%mm0 \n\t" "paddw %%mm5, %%mm6 \n\t" // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 "psubw %%mm0, %%mm4 \n\t" "psubw %%mm7, %%mm5 \n\t" "psubw %%mm0, %%mm4 \n\t" "psubw %%mm7, %%mm5 \n\t" "pxor %%mm0, %%mm0 \n\t" "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 "psubw %%mm0, %%mm6 \n\t" // test pa <= pb "movq %%mm4, %%mm7 \n\t" "psubw %%mm0, %%mm6 \n\t" "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? "movq %%mm7, %%mm0 \n\t" // use mm0 mask copy to merge a & b "pand %%mm0, %%mm2 \n\t" // use mm7 mask to merge pa & pb "pand %%mm7, %%mm5 \n\t" "pandn %%mm1, %%mm0 \n\t" "pandn %%mm4, %%mm7 \n\t" "paddw %%mm2, %%mm0 \n\t" "paddw %%mm5, %%mm7 \n\t" // test ((pa <= pb)? pa:pb) <= pc "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? "pand %%mm7, %%mm3 \n\t" "pandn %%mm0, %%mm7 \n\t" "paddw %%mm3, %%mm7 \n\t" "pxor %%mm1, %%mm1 \n\t" "packuswb %%mm7, %%mm1 \n\t" // step ecx to next set of 8 bytes and repeat loop til done "addl $8, %%ecx \n\t" "pand _ActiveMaskEnd, %%mm1 \n\t" "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add Paeth predictor with // Raw(x) "cmpl _MMXLength, %%ecx \n\t" "pxor %%mm0, %%mm0 \n\t" // pxor does not affect flags "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value // mm1 will be used as Raw(x-bpp) next loop // mm3 ready to be used as Prior(x-bpp) next loop "jb paeth_3lp \n\t" : "=S" (dummy_value_S), // output regs (dummy) "=D" (dummy_value_D) : "0" (prev_row), // esi // input regs "1" (row) // edi : "%ecx" // clobber list #if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm2", "%mm3" , "%mm4", "%mm5", "%mm6", "%mm7" #endif ); } break; // end 3 bpp case 6: //case 7: // GRR BOGUS //case 5: // GRR BOGUS { _ActiveMask.use = 0x00000000ffffffffLL; _ActiveMask2.use = 0xffffffff00000000LL; _ShiftBpp.use = bpp << 3; // == bpp * 8 _ShiftRem.use = 64 - _ShiftBpp.use; __asm__ __volatile__ ( "movl _dif, %%ecx \n\t" // preload "movl row, %%edi \n\t" // preload "movl prev_row, %%esi \n\t" // prime the pump: load the first Raw(x-bpp) data set "movq -8(%%edi,%%ecx,), %%mm1 \n\t" "pxor %%mm0, %%mm0 \n\t" "paeth_6lp: \n\t" // must shift to position Raw(x-bpp) data "psrlq _ShiftRem, %%mm1 \n\t" // do first set of 4 bytes "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) "punpcklbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b // must shift to position Prior(x-bpp) data "psrlq _ShiftRem, %%mm3 \n\t" // pav = p - a = (a + b - c) - a = b - c "movq %%mm2, %%mm4 \n\t" "punpcklbw %%mm0, %%mm3 \n\t" // unpack Low bytes of c // pbv = p - b = (a + b - c) - b = a - c "movq %%mm1, %%mm5 \n\t" "psubw %%mm3, %%mm4 \n\t" "pxor %%mm7, %%mm7 \n\t" // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv "movq %%mm4, %%mm6 \n\t" "psubw %%mm3, %%mm5 \n\t" // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 "paddw %%mm5, %%mm6 \n\t" "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 "psubw %%mm0, %%mm4 \n\t" "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 "psubw %%mm0, %%mm4 \n\t" "psubw %%mm7, %%mm5 \n\t" "pxor %%mm0, %%mm0 \n\t" "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 "psubw %%mm7, %%mm5 \n\t" "psubw %%mm0, %%mm6 \n\t" // test pa <= pb "movq %%mm4, %%mm7 \n\t" "psubw %%mm0, %%mm6 \n\t" "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? "movq %%mm7, %%mm0 \n\t" // use mm7 mask to merge pa & pb "pand %%mm7, %%mm5 \n\t" // use mm0 mask copy to merge a & b "pand %%mm0, %%mm2 \n\t" "pandn %%mm4, %%mm7 \n\t" "pandn %%mm1, %%mm0 \n\t" "paddw %%mm5, %%mm7 \n\t" "paddw %%mm2, %%mm0 \n\t" // test ((pa <= pb)? pa:pb) <= pc "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? "pxor %%mm1, %%mm1 \n\t" "pand %%mm7, %%mm3 \n\t" "pandn %%mm0, %%mm7 \n\t" "paddw %%mm3, %%mm7 \n\t" "pxor %%mm0, %%mm0 \n\t" "packuswb %%mm1, %%mm7 \n\t" "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // load c=Prior(x-bpp) "pand _ActiveMask, %%mm7 \n\t" "psrlq _ShiftRem, %%mm3 \n\t" "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) step 1 "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor and Raw(x) "movq %%mm2, %%mm6 \n\t" "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value "movq -8(%%edi,%%ecx,), %%mm1 \n\t" "psllq _ShiftBpp, %%mm6 \n\t" "movq %%mm7, %%mm5 \n\t" "psrlq _ShiftRem, %%mm1 \n\t" "por %%mm6, %%mm3 \n\t" "psllq _ShiftBpp, %%mm5 \n\t" "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c "por %%mm5, %%mm1 \n\t" // do second set of 4 bytes "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a // pav = p - a = (a + b - c) - a = b - c "movq %%mm2, %%mm4 \n\t" // pbv = p - b = (a + b - c) - b = a - c "movq %%mm1, %%mm5 \n\t" "psubw %%mm3, %%mm4 \n\t" "pxor %%mm7, %%mm7 \n\t" // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv "movq %%mm4, %%mm6 \n\t" "psubw %%mm3, %%mm5 \n\t" // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 "paddw %%mm5, %%mm6 \n\t" "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 "psubw %%mm0, %%mm4 \n\t" "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 "psubw %%mm0, %%mm4 \n\t" "psubw %%mm7, %%mm5 \n\t" "pxor %%mm0, %%mm0 \n\t" "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 "psubw %%mm7, %%mm5 \n\t" "psubw %%mm0, %%mm6 \n\t" // test pa <= pb "movq %%mm4, %%mm7 \n\t" "psubw %%mm0, %%mm6 \n\t" "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? "movq %%mm7, %%mm0 \n\t" // use mm7 mask to merge pa & pb "pand %%mm7, %%mm5 \n\t" // use mm0 mask copy to merge a & b "pand %%mm0, %%mm2 \n\t" "pandn %%mm4, %%mm7 \n\t" "pandn %%mm1, %%mm0 \n\t" "paddw %%mm5, %%mm7 \n\t" "paddw %%mm2, %%mm0 \n\t" // test ((pa <= pb)? pa:pb) <= pc "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? "pxor %%mm1, %%mm1 \n\t" "pand %%mm7, %%mm3 \n\t" "pandn %%mm0, %%mm7 \n\t" "pxor %%mm1, %%mm1 \n\t" "paddw %%mm3, %%mm7 \n\t" "pxor %%mm0, %%mm0 \n\t" // step ecx to next set of 8 bytes and repeat loop til done "addl $8, %%ecx \n\t" "packuswb %%mm7, %%mm1 \n\t" "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add Paeth predictor with Raw(x) "cmpl _MMXLength, %%ecx \n\t" "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value // mm1 will be used as Raw(x-bpp) next loop "jb paeth_6lp \n\t" : "=S" (dummy_value_S), // output regs (dummy) "=D" (dummy_value_D) : "0" (prev_row), // esi // input regs "1" (row) // edi : "%ecx" // clobber list #if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm2", "%mm3" , "%mm4", "%mm5", "%mm6", "%mm7" #endif ); } break; // end 6 bpp case 4: { _ActiveMask.use = 0x00000000ffffffffLL; __asm__ __volatile__ ( "movl _dif, %%ecx \n\t" // preload "movl row, %%edi \n\t" // preload "movl prev_row, %%esi \n\t" "pxor %%mm0, %%mm0 \n\t" // prime the pump: load the first Raw(x-bpp) data set "movq -8(%%edi,%%ecx,), %%mm1 \n\t" // only time should need to read // a=Raw(x-bpp) bytes "paeth_4lp: \n\t" // do first set of 4 bytes "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes "punpckhbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b // pav = p - a = (a + b - c) - a = b - c "movq %%mm2, %%mm4 \n\t" "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c // pbv = p - b = (a + b - c) - b = a - c "movq %%mm1, %%mm5 \n\t" "psubw %%mm3, %%mm4 \n\t" "pxor %%mm7, %%mm7 \n\t" // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv "movq %%mm4, %%mm6 \n\t" "psubw %%mm3, %%mm5 \n\t" // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 "paddw %%mm5, %%mm6 \n\t" "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 "psubw %%mm0, %%mm4 \n\t" "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 "psubw %%mm0, %%mm4 \n\t" "psubw %%mm7, %%mm5 \n\t" "pxor %%mm0, %%mm0 \n\t" "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 "psubw %%mm7, %%mm5 \n\t" "psubw %%mm0, %%mm6 \n\t" // test pa <= pb "movq %%mm4, %%mm7 \n\t" "psubw %%mm0, %%mm6 \n\t" "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? "movq %%mm7, %%mm0 \n\t" // use mm7 mask to merge pa & pb "pand %%mm7, %%mm5 \n\t" // use mm0 mask copy to merge a & b "pand %%mm0, %%mm2 \n\t" "pandn %%mm4, %%mm7 \n\t" "pandn %%mm1, %%mm0 \n\t" "paddw %%mm5, %%mm7 \n\t" "paddw %%mm2, %%mm0 \n\t" // test ((pa <= pb)? pa:pb) <= pc "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? "pxor %%mm1, %%mm1 \n\t" "pand %%mm7, %%mm3 \n\t" "pandn %%mm0, %%mm7 \n\t" "paddw %%mm3, %%mm7 \n\t" "pxor %%mm0, %%mm0 \n\t" "packuswb %%mm1, %%mm7 \n\t" "movq (%%esi,%%ecx,), %%mm3 \n\t" // load c=Prior(x-bpp) "pand _ActiveMask, %%mm7 \n\t" "movq %%mm3, %%mm2 \n\t" // load b=Prior(x) step 1 "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x) "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value "movq %%mm7, %%mm1 \n\t" // now mm1 will be used as Raw(x-bpp) // do second set of 4 bytes "punpckhbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a // pav = p - a = (a + b - c) - a = b - c "movq %%mm2, %%mm4 \n\t" // pbv = p - b = (a + b - c) - b = a - c "movq %%mm1, %%mm5 \n\t" "psubw %%mm3, %%mm4 \n\t" "pxor %%mm7, %%mm7 \n\t" // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv "movq %%mm4, %%mm6 \n\t" "psubw %%mm3, %%mm5 \n\t" // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 "paddw %%mm5, %%mm6 \n\t" "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 "psubw %%mm0, %%mm4 \n\t" "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 "psubw %%mm0, %%mm4 \n\t" "psubw %%mm7, %%mm5 \n\t" "pxor %%mm0, %%mm0 \n\t" "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 "psubw %%mm7, %%mm5 \n\t" "psubw %%mm0, %%mm6 \n\t" // test pa <= pb "movq %%mm4, %%mm7 \n\t" "psubw %%mm0, %%mm6 \n\t" "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? "movq %%mm7, %%mm0 \n\t" // use mm7 mask to merge pa & pb "pand %%mm7, %%mm5 \n\t" // use mm0 mask copy to merge a & b "pand %%mm0, %%mm2 \n\t" "pandn %%mm4, %%mm7 \n\t" "pandn %%mm1, %%mm0 \n\t" "paddw %%mm5, %%mm7 \n\t" "paddw %%mm2, %%mm0 \n\t" // test ((pa <= pb)? pa:pb) <= pc "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? "pxor %%mm1, %%mm1 \n\t" "pand %%mm7, %%mm3 \n\t" "pandn %%mm0, %%mm7 \n\t" "pxor %%mm1, %%mm1 \n\t" "paddw %%mm3, %%mm7 \n\t" "pxor %%mm0, %%mm0 \n\t" // step ecx to next set of 8 bytes and repeat loop til done "addl $8, %%ecx \n\t" "packuswb %%mm7, %%mm1 \n\t" "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add predictor with Raw(x) "cmpl _MMXLength, %%ecx \n\t" "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value // mm1 will be used as Raw(x-bpp) next loop "jb paeth_4lp \n\t" : "=S" (dummy_value_S), // output regs (dummy) "=D" (dummy_value_D) : "0" (prev_row), // esi // input regs "1" (row) // edi : "%ecx" // clobber list #if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm2", "%mm3" , "%mm4", "%mm5", "%mm6", "%mm7" #endif ); } break; // end 4 bpp case 8: // bpp == 8 { _ActiveMask.use = 0x00000000ffffffffLL; __asm__ __volatile__ ( "movl _dif, %%ecx \n\t" // preload "movl row, %%edi \n\t" // preload "movl prev_row, %%esi \n\t" "pxor %%mm0, %%mm0 \n\t" // prime the pump: load the first Raw(x-bpp) data set "movq -8(%%edi,%%ecx,), %%mm1 \n\t" // only time should need to read // a=Raw(x-bpp) bytes "paeth_8lp: \n\t" // do first set of 4 bytes "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) "punpcklbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b // pav = p - a = (a + b - c) - a = b - c "movq %%mm2, %%mm4 \n\t" "punpcklbw %%mm0, %%mm3 \n\t" // unpack Low bytes of c // pbv = p - b = (a + b - c) - b = a - c "movq %%mm1, %%mm5 \n\t" "psubw %%mm3, %%mm4 \n\t" "pxor %%mm7, %%mm7 \n\t" // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv "movq %%mm4, %%mm6 \n\t" "psubw %%mm3, %%mm5 \n\t" // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 "paddw %%mm5, %%mm6 \n\t" "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 "psubw %%mm0, %%mm4 \n\t" "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 "psubw %%mm0, %%mm4 \n\t" "psubw %%mm7, %%mm5 \n\t" "pxor %%mm0, %%mm0 \n\t" "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 "psubw %%mm7, %%mm5 \n\t" "psubw %%mm0, %%mm6 \n\t" // test pa <= pb "movq %%mm4, %%mm7 \n\t" "psubw %%mm0, %%mm6 \n\t" "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? "movq %%mm7, %%mm0 \n\t" // use mm7 mask to merge pa & pb "pand %%mm7, %%mm5 \n\t" // use mm0 mask copy to merge a & b "pand %%mm0, %%mm2 \n\t" "pandn %%mm4, %%mm7 \n\t" "pandn %%mm1, %%mm0 \n\t" "paddw %%mm5, %%mm7 \n\t" "paddw %%mm2, %%mm0 \n\t" // test ((pa <= pb)? pa:pb) <= pc "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? "pxor %%mm1, %%mm1 \n\t" "pand %%mm7, %%mm3 \n\t" "pandn %%mm0, %%mm7 \n\t" "paddw %%mm3, %%mm7 \n\t" "pxor %%mm0, %%mm0 \n\t" "packuswb %%mm1, %%mm7 \n\t" "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes "pand _ActiveMask, %%mm7 \n\t" "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x) "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value "movq -8(%%edi,%%ecx,), %%mm1 \n\t" // read a=Raw(x-bpp) bytes // do second set of 4 bytes "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a // pav = p - a = (a + b - c) - a = b - c "movq %%mm2, %%mm4 \n\t" // pbv = p - b = (a + b - c) - b = a - c "movq %%mm1, %%mm5 \n\t" "psubw %%mm3, %%mm4 \n\t" "pxor %%mm7, %%mm7 \n\t" // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv "movq %%mm4, %%mm6 \n\t" "psubw %%mm3, %%mm5 \n\t" // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0 "paddw %%mm5, %%mm6 \n\t" "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7 "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0 "psubw %%mm0, %%mm4 \n\t" "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0 "psubw %%mm0, %%mm4 \n\t" "psubw %%mm7, %%mm5 \n\t" "pxor %%mm0, %%mm0 \n\t" "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0 "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7 "psubw %%mm7, %%mm5 \n\t" "psubw %%mm0, %%mm6 \n\t" // test pa <= pb "movq %%mm4, %%mm7 \n\t" "psubw %%mm0, %%mm6 \n\t" "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb? "movq %%mm7, %%mm0 \n\t" // use mm7 mask to merge pa & pb "pand %%mm7, %%mm5 \n\t" // use mm0 mask copy to merge a & b "pand %%mm0, %%mm2 \n\t" "pandn %%mm4, %%mm7 \n\t" "pandn %%mm1, %%mm0 \n\t" "paddw %%mm5, %%mm7 \n\t" "paddw %%mm2, %%mm0 \n\t" // test ((pa <= pb)? pa:pb) <= pc "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc? "pxor %%mm1, %%mm1 \n\t" "pand %%mm7, %%mm3 \n\t" "pandn %%mm0, %%mm7 \n\t" "pxor %%mm1, %%mm1 \n\t" "paddw %%mm3, %%mm7 \n\t" "pxor %%mm0, %%mm0 \n\t" // step ecx to next set of 8 bytes and repeat loop til done "addl $8, %%ecx \n\t" "packuswb %%mm7, %%mm1 \n\t" "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add Paeth predictor with Raw(x) "cmpl _MMXLength, %%ecx \n\t" "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value // mm1 will be used as Raw(x-bpp) next loop "jb paeth_8lp \n\t" : "=S" (dummy_value_S), // output regs (dummy) "=D" (dummy_value_D) : "0" (prev_row), // esi // input regs "1" (row) // edi : "%ecx" // clobber list #if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm2", "%mm3" , "%mm4", "%mm5", "%mm6", "%mm7" #endif ); } break; // end 8 bpp case 1: // bpp = 1 case 2: // bpp = 2 default: // bpp > 8 { __asm__ __volatile__ ( #ifdef __PIC__ "pushl %%ebx \n\t" // save Global Offset Table index #endif "movl _dif, %%ebx \n\t" "cmpl _FullLength, %%ebx \n\t" "jnb paeth_dend \n\t" // preload "movl row, %%edi \n\t" // preload "movl prev_row, %%esi \n\t" // do Paeth decode for remaining bytes "movl %%ebx, %%edx \n\t" // preload "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) "subl %%ecx, %%edx \n\t" // edx = ebx - bpp "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx "paeth_dlp: \n\t" "xorl %%eax, %%eax \n\t" // pav = p - a = (a + b - c) - a = b - c "movb (%%esi,%%ebx,), %%al \n\t" // load Prior(x) into al "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) "movl %%eax, _patemp \n\t" // Save pav for later use "xorl %%eax, %%eax \n\t" // pbv = p - b = (a + b - c) - b = a - c "movb (%%edi,%%edx,), %%al \n\t" // load Raw(x-bpp) into al "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) "movl %%eax, %%ecx \n\t" // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv "addl _patemp, %%eax \n\t" // pcv = pav + pbv // pc = abs(pcv) "testl $0x80000000, %%eax \n\t" "jz paeth_dpca \n\t" "negl %%eax \n\t" // reverse sign of neg values "paeth_dpca: \n\t" "movl %%eax, _pctemp \n\t" // save pc for later use // pb = abs(pbv) "testl $0x80000000, %%ecx \n\t" "jz paeth_dpba \n\t" "negl %%ecx \n\t" // reverse sign of neg values "paeth_dpba: \n\t" "movl %%ecx, _pbtemp \n\t" // save pb for later use // pa = abs(pav) "movl _patemp, %%eax \n\t" "testl $0x80000000, %%eax \n\t" "jz paeth_dpaa \n\t" "negl %%eax \n\t" // reverse sign of neg values "paeth_dpaa: \n\t" "movl %%eax, _patemp \n\t" // save pa for later use // test if pa <= pb "cmpl %%ecx, %%eax \n\t" "jna paeth_dabb \n\t" // pa > pb; now test if pb <= pc "cmpl _pctemp, %%ecx \n\t" "jna paeth_dbbc \n\t" // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl "jmp paeth_dpaeth \n\t" "paeth_dbbc: \n\t" // pb <= pc; Raw(x) = Paeth(x) + Prior(x) "movb (%%esi,%%ebx,), %%cl \n\t" // load Prior(x) into cl "jmp paeth_dpaeth \n\t" "paeth_dabb: \n\t" // pa <= pb; now test if pa <= pc "cmpl _pctemp, %%eax \n\t" "jna paeth_dabc \n\t" // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl "jmp paeth_dpaeth \n\t" "paeth_dabc: \n\t" // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) "movb (%%edi,%%edx,), %%cl \n\t" // load Raw(x-bpp) into cl "paeth_dpaeth: \n\t" "incl %%ebx \n\t" "incl %%edx \n\t" // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 "addb %%cl, -1(%%edi,%%ebx,) \n\t" "cmpl _FullLength, %%ebx \n\t" "jb paeth_dlp \n\t" "paeth_dend: \n\t" #ifdef __PIC__ "popl %%ebx \n\t" // index to Global Offset Table #endif : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "0" (bpp), // ecx // input regs "1" (prev_row), // esi "2" (row) // edi : "%eax", "%edx" // clobber list #ifndef __PIC__ , "%ebx" #endif ); } return; // No need to go further with this one } // end switch (bpp) __asm__ __volatile__ ( // MMX acceleration complete; now do clean-up // check if any remaining bytes left to decode #ifdef __PIC__ "pushl %%ebx \n\t" // save index to Global Offset Table #endif "movl _MMXLength, %%ebx \n\t" "cmpl _FullLength, %%ebx \n\t" "jnb paeth_end \n\t" //pre "movl row, %%edi \n\t" //pre "movl prev_row, %%esi \n\t" // do Paeth decode for remaining bytes "movl %%ebx, %%edx \n\t" //pre "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) "subl %%ecx, %%edx \n\t" // edx = ebx - bpp "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx below "paeth_lp2: \n\t" "xorl %%eax, %%eax \n\t" // pav = p - a = (a + b - c) - a = b - c "movb (%%esi,%%ebx,), %%al \n\t" // load Prior(x) into al "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) "movl %%eax, _patemp \n\t" // Save pav for later use "xorl %%eax, %%eax \n\t" // pbv = p - b = (a + b - c) - b = a - c "movb (%%edi,%%edx,), %%al \n\t" // load Raw(x-bpp) into al "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp) "movl %%eax, %%ecx \n\t" // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv "addl _patemp, %%eax \n\t" // pcv = pav + pbv // pc = abs(pcv) "testl $0x80000000, %%eax \n\t" "jz paeth_pca2 \n\t" "negl %%eax \n\t" // reverse sign of neg values "paeth_pca2: \n\t" "movl %%eax, _pctemp \n\t" // save pc for later use // pb = abs(pbv) "testl $0x80000000, %%ecx \n\t" "jz paeth_pba2 \n\t" "negl %%ecx \n\t" // reverse sign of neg values "paeth_pba2: \n\t" "movl %%ecx, _pbtemp \n\t" // save pb for later use // pa = abs(pav) "movl _patemp, %%eax \n\t" "testl $0x80000000, %%eax \n\t" "jz paeth_paa2 \n\t" "negl %%eax \n\t" // reverse sign of neg values "paeth_paa2: \n\t" "movl %%eax, _patemp \n\t" // save pa for later use // test if pa <= pb "cmpl %%ecx, %%eax \n\t" "jna paeth_abb2 \n\t" // pa > pb; now test if pb <= pc "cmpl _pctemp, %%ecx \n\t" "jna paeth_bbc2 \n\t" // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl "jmp paeth_paeth2 \n\t" "paeth_bbc2: \n\t" // pb <= pc; Raw(x) = Paeth(x) + Prior(x) "movb (%%esi,%%ebx,), %%cl \n\t" // load Prior(x) into cl "jmp paeth_paeth2 \n\t" "paeth_abb2: \n\t" // pa <= pb; now test if pa <= pc "cmpl _pctemp, %%eax \n\t" "jna paeth_abc2 \n\t" // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl "jmp paeth_paeth2 \n\t" "paeth_abc2: \n\t" // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) "movb (%%edi,%%edx,), %%cl \n\t" // load Raw(x-bpp) into cl "paeth_paeth2: \n\t" "incl %%ebx \n\t" "incl %%edx \n\t" // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 "addb %%cl, -1(%%edi,%%ebx,) \n\t" "cmpl _FullLength, %%ebx \n\t" "jb paeth_lp2 \n\t" "paeth_end: \n\t" "EMMS \n\t" // end MMX; prep for poss. FP instrs. #ifdef __PIC__ "popl %%ebx \n\t" // restore index to Global Offset Table #endif : "=c" (dummy_value_c), // output regs (dummy) "=S" (dummy_value_S), "=D" (dummy_value_D) : "0" (bpp), // ecx // input regs "1" (prev_row), // esi "2" (row) // edi : "%eax", "%edx" // clobber list (no input regs!) #ifndef __PIC__ , "%ebx" #endif ); } /* end png_read_filter_row_mmx_paeth() */ #endif #ifdef PNG_THREAD_UNSAFE_OK //===========================================================================// // // // P N G _ R E A D _ F I L T E R _ R O W _ M M X _ S U B // // // //===========================================================================// // Optimized code for PNG Sub filter decoder static void /* PRIVATE */ png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row) { int bpp; int dummy_value_a; int dummy_value_D; bpp = (row_info->pixel_depth + 7) >> 3; // calc number of bytes per pixel _FullLength = row_info->rowbytes - bpp; // number of bytes to filter __asm__ __volatile__ ( //pre "movl row, %%edi \n\t" "movl %%edi, %%esi \n\t" // lp = row //pre "movl bpp, %%eax \n\t" "addl %%eax, %%edi \n\t" // rp = row + bpp //irr "xorl %%eax, %%eax \n\t" // get # of bytes to alignment "movl %%edi, _dif \n\t" // take start of row "addl $0xf, _dif \n\t" // add 7 + 8 to incr past // alignment boundary "xorl %%ecx, %%ecx \n\t" "andl $0xfffffff8, _dif \n\t" // mask to alignment boundary "subl %%edi, _dif \n\t" // subtract from start ==> value "jz sub_go \n\t" // ecx at alignment "sub_lp1: \n\t" // fix alignment "movb (%%esi,%%ecx,), %%al \n\t" "addb %%al, (%%edi,%%ecx,) \n\t" "incl %%ecx \n\t" "cmpl _dif, %%ecx \n\t" "jb sub_lp1 \n\t" "sub_go: \n\t" "movl _FullLength, %%eax \n\t" "movl %%eax, %%edx \n\t" "subl %%ecx, %%edx \n\t" // subtract alignment fix "andl $0x00000007, %%edx \n\t" // calc bytes over mult of 8 "subl %%edx, %%eax \n\t" // drop over bytes from length "movl %%eax, _MMXLength \n\t" : "=a" (dummy_value_a), // 0 // output regs (dummy) "=D" (dummy_value_D) // 1 : "0" (bpp), // eax // input regs "1" (row) // edi : "%esi", "%ecx", "%edx" // clobber list #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm2", "%mm3" , "%mm4", "%mm5", "%mm6", "%mm7" #endif ); // now do the math for the rest of the row switch (bpp) { case 3: { _ActiveMask.use = 0x0000ffffff000000LL; _ShiftBpp.use = 24; // == 3 * 8 _ShiftRem.use = 40; // == 64 - 24 __asm__ __volatile__ ( // preload "movl row, %%edi \n\t" "movq _ActiveMask, %%mm7 \n\t" // load _ActiveMask for 2nd // active byte group "movl %%edi, %%esi \n\t" // lp = row // preload "movl bpp, %%eax \n\t" "addl %%eax, %%edi \n\t" // rp = row + bpp "movq %%mm7, %%mm6 \n\t" "movl _dif, %%edx \n\t" "psllq _ShiftBpp, %%mm6 \n\t" // move mask in mm6 to cover // 3rd active byte group // prime the pump: load the first Raw(x-bpp) data set "movq -8(%%edi,%%edx,), %%mm1 \n\t" "sub_3lp: \n\t" // shift data for adding first "psrlq _ShiftRem, %%mm1 \n\t" // bpp bytes (no need for mask; // shift clears inactive bytes) // add 1st active group "movq (%%edi,%%edx,), %%mm0 \n\t" "paddb %%mm1, %%mm0 \n\t" // add 2nd active group "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly "pand %%mm7, %%mm1 \n\t" // mask to use 2nd active group "paddb %%mm1, %%mm0 \n\t" // add 3rd active group "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly "pand %%mm6, %%mm1 \n\t" // mask to use 3rd active group "addl $8, %%edx \n\t" "paddb %%mm1, %%mm0 \n\t" "cmpl _MMXLength, %%edx \n\t" "movq %%mm0, -8(%%edi,%%edx,) \n\t" // write updated Raws to array "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop "jb sub_3lp \n\t" : "=a" (dummy_value_a), // 0 // output regs (dummy) "=D" (dummy_value_D) // 1 : "0" (bpp), // eax // input regs "1" (row) // edi : "%edx", "%esi" // clobber list #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm6", "%mm7" #endif ); } break; case 1: { __asm__ __volatile__ ( "movl _dif, %%edx \n\t" // preload "movl row, %%edi \n\t" "cmpl _FullLength, %%edx \n\t" "jnb sub_1end \n\t" "movl %%edi, %%esi \n\t" // lp = row "xorl %%eax, %%eax \n\t" // preload "movl bpp, %%eax \n\t" "addl %%eax, %%edi \n\t" // rp = row + bpp "sub_1lp: \n\t" "movb (%%esi,%%edx,), %%al \n\t" "addb %%al, (%%edi,%%edx,) \n\t" "incl %%edx \n\t" "cmpl _FullLength, %%edx \n\t" "jb sub_1lp \n\t" "sub_1end: \n\t" : "=a" (dummy_value_a), // 0 // output regs (dummy) "=D" (dummy_value_D) // 1 : "0" (bpp), // eax // input regs "1" (row) // edi : "%edx", "%esi" // clobber list ); } return; case 6: case 4: //case 7: // GRR BOGUS //case 5: // GRR BOGUS { _ShiftBpp.use = bpp << 3; _ShiftRem.use = 64 - _ShiftBpp.use; __asm__ __volatile__ ( // preload "movl row, %%edi \n\t" "movl _dif, %%edx \n\t" "movl %%edi, %%esi \n\t" // lp = row // preload "movl bpp, %%eax \n\t" "addl %%eax, %%edi \n\t" // rp = row + bpp // prime the pump: load the first Raw(x-bpp) data set "movq -8(%%edi,%%edx,), %%mm1 \n\t" "sub_4lp: \n\t" // shift data for adding first "psrlq _ShiftRem, %%mm1 \n\t" // bpp bytes (no need for mask; // shift clears inactive bytes) "movq (%%edi,%%edx,), %%mm0 \n\t" "paddb %%mm1, %%mm0 \n\t" // add 2nd active group "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly "addl $8, %%edx \n\t" "paddb %%mm1, %%mm0 \n\t" "cmpl _MMXLength, %%edx \n\t" "movq %%mm0, -8(%%edi,%%edx,) \n\t" "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop "jb sub_4lp \n\t" : "=a" (dummy_value_a), // 0 // output regs (dummy) "=D" (dummy_value_D) // 1 : "0" (bpp), // eax // input regs "1" (row) // edi : "%edx", "%esi" // clobber list #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1" #endif ); } break; case 2: { _ActiveMask.use = 0x00000000ffff0000LL; _ShiftBpp.use = 16; // == 2 * 8 _ShiftRem.use = 48; // == 64 - 16 __asm__ __volatile__ ( "movq _ActiveMask, %%mm7 \n\t" // load _ActiveMask for 2nd // active byte group "movl _dif, %%edx \n\t" "movq %%mm7, %%mm6 \n\t" // preload "movl row, %%edi \n\t" "psllq _ShiftBpp, %%mm6 \n\t" // move mask in mm6 to cover // 3rd active byte group "movl %%edi, %%esi \n\t" // lp = row "movq %%mm6, %%mm5 \n\t" // preload "movl bpp, %%eax \n\t" "addl %%eax, %%edi \n\t" // rp = row + bpp "psllq _ShiftBpp, %%mm5 \n\t" // move mask in mm5 to cover // 4th active byte group // prime the pump: load the first Raw(x-bpp) data set "movq -8(%%edi,%%edx,), %%mm1 \n\t" "sub_2lp: \n\t" // shift data for adding first "psrlq _ShiftRem, %%mm1 \n\t" // bpp bytes (no need for mask; // shift clears inactive bytes) // add 1st active group "movq (%%edi,%%edx,), %%mm0 \n\t" "paddb %%mm1, %%mm0 \n\t" // add 2nd active group "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly "pand %%mm7, %%mm1 \n\t" // mask to use 2nd active group "paddb %%mm1, %%mm0 \n\t" // add 3rd active group "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly "pand %%mm6, %%mm1 \n\t" // mask to use 3rd active group "paddb %%mm1, %%mm0 \n\t" // add 4th active group "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1 "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly "pand %%mm5, %%mm1 \n\t" // mask to use 4th active group "addl $8, %%edx \n\t" "paddb %%mm1, %%mm0 \n\t" "cmpl _MMXLength, %%edx \n\t" "movq %%mm0, -8(%%edi,%%edx,) \n\t" // write updated Raws to array "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop "jb sub_2lp \n\t" : "=a" (dummy_value_a), // 0 // output regs (dummy) "=D" (dummy_value_D) // 1 : "0" (bpp), // eax // input regs "1" (row) // edi : "%edx", "%esi" // clobber list #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm5", "%mm6", "%mm7" #endif ); } break; case 8: { __asm__ __volatile__ ( // preload "movl row, %%edi \n\t" "movl _dif, %%edx \n\t" "movl %%edi, %%esi \n\t" // lp = row // preload "movl bpp, %%eax \n\t" "addl %%eax, %%edi \n\t" // rp = row + bpp "movl _MMXLength, %%ecx \n\t" // prime the pump: load the first Raw(x-bpp) data set "movq -8(%%edi,%%edx,), %%mm7 \n\t" "andl $0x0000003f, %%ecx \n\t" // calc bytes over mult of 64 "sub_8lp: \n\t" "movq (%%edi,%%edx,), %%mm0 \n\t" // load Sub(x) for 1st 8 bytes "paddb %%mm7, %%mm0 \n\t" "movq 8(%%edi,%%edx,), %%mm1 \n\t" // load Sub(x) for 2nd 8 bytes "movq %%mm0, (%%edi,%%edx,) \n\t" // write Raw(x) for 1st 8 bytes // Now mm0 will be used as Raw(x-bpp) for the 2nd group of 8 bytes. // This will be repeated for each group of 8 bytes with the 8th // group being used as the Raw(x-bpp) for the 1st group of the // next loop. "paddb %%mm0, %%mm1 \n\t" "movq 16(%%edi,%%edx,), %%mm2 \n\t" // load Sub(x) for 3rd 8 bytes "movq %%mm1, 8(%%edi,%%edx,) \n\t" // write Raw(x) for 2nd 8 bytes "paddb %%mm1, %%mm2 \n\t" "movq 24(%%edi,%%edx,), %%mm3 \n\t" // load Sub(x) for 4th 8 bytes "movq %%mm2, 16(%%edi,%%edx,) \n\t" // write Raw(x) for 3rd 8 bytes "paddb %%mm2, %%mm3 \n\t" "movq 32(%%edi,%%edx,), %%mm4 \n\t" // load Sub(x) for 5th 8 bytes "movq %%mm3, 24(%%edi,%%edx,) \n\t" // write Raw(x) for 4th 8 bytes "paddb %%mm3, %%mm4 \n\t" "movq 40(%%edi,%%edx,), %%mm5 \n\t" // load Sub(x) for 6th 8 bytes "movq %%mm4, 32(%%edi,%%edx,) \n\t" // write Raw(x) for 5th 8 bytes "paddb %%mm4, %%mm5 \n\t" "movq 48(%%edi,%%edx,), %%mm6 \n\t" // load Sub(x) for 7th 8 bytes "movq %%mm5, 40(%%edi,%%edx,) \n\t" // write Raw(x) for 6th 8 bytes "paddb %%mm5, %%mm6 \n\t" "movq 56(%%edi,%%edx,), %%mm7 \n\t" // load Sub(x) for 8th 8 bytes "movq %%mm6, 48(%%edi,%%edx,) \n\t" // write Raw(x) for 7th 8 bytes "addl $64, %%edx \n\t" "paddb %%mm6, %%mm7 \n\t" "cmpl %%ecx, %%edx \n\t" "movq %%mm7, -8(%%edi,%%edx,) \n\t" // write Raw(x) for 8th 8 bytes "jb sub_8lp \n\t" "cmpl _MMXLength, %%edx \n\t" "jnb sub_8lt8 \n\t" "sub_8lpA: \n\t" "movq (%%edi,%%edx,), %%mm0 \n\t" "addl $8, %%edx \n\t" "paddb %%mm7, %%mm0 \n\t" "cmpl _MMXLength, %%edx \n\t" "movq %%mm0, -8(%%edi,%%edx,) \n\t" // -8 to offset early addl edx "movq %%mm0, %%mm7 \n\t" // move calculated Raw(x) data // to mm1 to be new Raw(x-bpp) // for next loop "jb sub_8lpA \n\t" "sub_8lt8: \n\t" : "=a" (dummy_value_a), // 0 // output regs (dummy) "=D" (dummy_value_D) // 1 : "0" (bpp), // eax // input regs "1" (row) // edi : "%ecx", "%edx", "%esi" // clobber list #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" #endif ); } break; default: // bpp greater than 8 bytes GRR BOGUS { __asm__ __volatile__ ( "movl _dif, %%edx \n\t" // preload "movl row, %%edi \n\t" "movl %%edi, %%esi \n\t" // lp = row // preload "movl bpp, %%eax \n\t" "addl %%eax, %%edi \n\t" // rp = row + bpp "sub_Alp: \n\t" "movq (%%edi,%%edx,), %%mm0 \n\t" "movq (%%esi,%%edx,), %%mm1 \n\t" "addl $8, %%edx \n\t" "paddb %%mm1, %%mm0 \n\t" "cmpl _MMXLength, %%edx \n\t" "movq %%mm0, -8(%%edi,%%edx,) \n\t" // mov does not affect flags; // -8 to offset addl edx "jb sub_Alp \n\t" : "=a" (dummy_value_a), // 0 // output regs (dummy) "=D" (dummy_value_D) // 1 : "0" (bpp), // eax // input regs "1" (row) // edi : "%edx", "%esi" // clobber list #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1" #endif ); } break; } // end switch (bpp) __asm__ __volatile__ ( "movl _MMXLength, %%edx \n\t" //pre "movl row, %%edi \n\t" "cmpl _FullLength, %%edx \n\t" "jnb sub_end \n\t" "movl %%edi, %%esi \n\t" // lp = row //pre "movl bpp, %%eax \n\t" "addl %%eax, %%edi \n\t" // rp = row + bpp "xorl %%eax, %%eax \n\t" "sub_lp2: \n\t" "movb (%%esi,%%edx,), %%al \n\t" "addb %%al, (%%edi,%%edx,) \n\t" "incl %%edx \n\t" "cmpl _FullLength, %%edx \n\t" "jb sub_lp2 \n\t" "sub_end: \n\t" "EMMS \n\t" // end MMX instructions : "=a" (dummy_value_a), // 0 // output regs (dummy) "=D" (dummy_value_D) // 1 : "0" (bpp), // eax // input regs "1" (row) // edi : "%edx", "%esi" // clobber list ); } // end of png_read_filter_row_mmx_sub() #endif //===========================================================================// // // // P N G _ R E A D _ F I L T E R _ R O W _ M M X _ U P // // // //===========================================================================// // Optimized code for PNG Up filter decoder static void /* PRIVATE */ png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row, png_bytep prev_row) { png_uint_32 len; int dummy_value_d; // fix 'forbidden register 3 (dx) was spilled' error int dummy_value_S; int dummy_value_D; len = row_info->rowbytes; // number of bytes to filter __asm__ __volatile__ ( //pre "movl row, %%edi \n\t" // get # of bytes to alignment #ifdef __PIC__ "pushl %%ebx \n\t" #endif "movl %%edi, %%ecx \n\t" "xorl %%ebx, %%ebx \n\t" "addl $0x7, %%ecx \n\t" "xorl %%eax, %%eax \n\t" "andl $0xfffffff8, %%ecx \n\t" //pre "movl prev_row, %%esi \n\t" "subl %%edi, %%ecx \n\t" "jz up_go \n\t" "up_lp1: \n\t" // fix alignment "movb (%%edi,%%ebx,), %%al \n\t" "addb (%%esi,%%ebx,), %%al \n\t" "incl %%ebx \n\t" "cmpl %%ecx, %%ebx \n\t" "movb %%al, -1(%%edi,%%ebx,) \n\t" // mov does not affect flags; -1 to "jb up_lp1 \n\t" // offset incl ebx "up_go: \n\t" //pre "movl len, %%edx \n\t" "movl %%edx, %%ecx \n\t" "subl %%ebx, %%edx \n\t" // subtract alignment fix "andl $0x0000003f, %%edx \n\t" // calc bytes over mult of 64 "subl %%edx, %%ecx \n\t" // drop over bytes from length // unrolled loop - use all MMX registers and interleave to reduce // number of branch instructions (loops) and reduce partial stalls "up_loop: \n\t" "movq (%%esi,%%ebx,), %%mm1 \n\t" "movq (%%edi,%%ebx,), %%mm0 \n\t" "movq 8(%%esi,%%ebx,), %%mm3 \n\t" "paddb %%mm1, %%mm0 \n\t" "movq 8(%%edi,%%ebx,), %%mm2 \n\t" "movq %%mm0, (%%edi,%%ebx,) \n\t" "paddb %%mm3, %%mm2 \n\t" "movq 16(%%esi,%%ebx,), %%mm5 \n\t" "movq %%mm2, 8(%%edi,%%ebx,) \n\t" "movq 16(%%edi,%%ebx,), %%mm4 \n\t" "movq 24(%%esi,%%ebx,), %%mm7 \n\t" "paddb %%mm5, %%mm4 \n\t" "movq 24(%%edi,%%ebx,), %%mm6 \n\t" "movq %%mm4, 16(%%edi,%%ebx,) \n\t" "paddb %%mm7, %%mm6 \n\t" "movq 32(%%esi,%%ebx,), %%mm1 \n\t" "movq %%mm6, 24(%%edi,%%ebx,) \n\t" "movq 32(%%edi,%%ebx,), %%mm0 \n\t" "movq 40(%%esi,%%ebx,), %%mm3 \n\t" "paddb %%mm1, %%mm0 \n\t" "movq 40(%%edi,%%ebx,), %%mm2 \n\t" "movq %%mm0, 32(%%edi,%%ebx,) \n\t" "paddb %%mm3, %%mm2 \n\t" "movq 48(%%esi,%%ebx,), %%mm5 \n\t" "movq %%mm2, 40(%%edi,%%ebx,) \n\t" "movq 48(%%edi,%%ebx,), %%mm4 \n\t" "movq 56(%%esi,%%ebx,), %%mm7 \n\t" "paddb %%mm5, %%mm4 \n\t" "movq 56(%%edi,%%ebx,), %%mm6 \n\t" "movq %%mm4, 48(%%edi,%%ebx,) \n\t" "addl $64, %%ebx \n\t" "paddb %%mm7, %%mm6 \n\t" "cmpl %%ecx, %%ebx \n\t" "movq %%mm6, -8(%%edi,%%ebx,) \n\t" // (+56)movq does not affect flags; "jb up_loop \n\t" // -8 to offset addl ebx "cmpl $0, %%edx \n\t" // test for bytes over mult of 64 "jz up_end \n\t" "cmpl $8, %%edx \n\t" // test for less than 8 bytes "jb up_lt8 \n\t" // [added by lcreeve at netins.net] "addl %%edx, %%ecx \n\t" "andl $0x00000007, %%edx \n\t" // calc bytes over mult of 8 "subl %%edx, %%ecx \n\t" // drop over bytes from length "jz up_lt8 \n\t" "up_lpA: \n\t" // use MMX regs to update 8 bytes sim. "movq (%%esi,%%ebx,), %%mm1 \n\t" "movq (%%edi,%%ebx,), %%mm0 \n\t" "addl $8, %%ebx \n\t" "paddb %%mm1, %%mm0 \n\t" "cmpl %%ecx, %%ebx \n\t" "movq %%mm0, -8(%%edi,%%ebx,) \n\t" // movq does not affect flags; -8 to "jb up_lpA \n\t" // offset add ebx "cmpl $0, %%edx \n\t" // test for bytes over mult of 8 "jz up_end \n\t" "up_lt8: \n\t" "xorl %%eax, %%eax \n\t" "addl %%edx, %%ecx \n\t" // move over byte count into counter "up_lp2: \n\t" // use x86 regs for remaining bytes "movb (%%edi,%%ebx,), %%al \n\t" "addb (%%esi,%%ebx,), %%al \n\t" "incl %%ebx \n\t" "cmpl %%ecx, %%ebx \n\t" "movb %%al, -1(%%edi,%%ebx,) \n\t" // mov does not affect flags; -1 to "jb up_lp2 \n\t" // offset inc ebx "up_end: \n\t" "EMMS \n\t" // conversion of filtered row complete #ifdef __PIC__ "popl %%ebx \n\t" #endif : "=d" (dummy_value_d), // 0 // output regs (dummy) "=S" (dummy_value_S), // 1 "=D" (dummy_value_D) // 2 : "0" (len), // edx // input regs "1" (prev_row), // esi "2" (row) // edi : "%eax", "%ecx" // clobber list (no input regs!) #ifndef __PIC__ , "%ebx" #endif #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ , "%mm0", "%mm1", "%mm2", "%mm3" , "%mm4", "%mm5", "%mm6", "%mm7" #endif ); } // end of png_read_filter_row_mmx_up() #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ /*===========================================================================*/ /* */ /* P N G _ R E A D _ F I L T E R _ R O W */ /* */ /*===========================================================================*/ /* Optimized png_read_filter_row routines */ void /* PRIVATE */ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter) { #ifdef PNG_DEBUG char filnm[10]; #endif #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) /* GRR: these are superseded by png_ptr->asm_flags: */ #define UseMMX_sub 1 // GRR: converted 20000730 #define UseMMX_up 1 // GRR: converted 20000729 #define UseMMX_avg 1 // GRR: converted 20000828 (+ 16-bit bugfix 20000916) #define UseMMX_paeth 1 // GRR: converted 20000828 if (_mmx_supported == 2) { /* this should have happened in png_init_mmx_flags() already */ #if !defined(PNG_1_0_X) png_warning(png_ptr, "asm_flags may not have been initialized"); #endif png_mmx_support(); } #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ #ifdef PNG_DEBUG png_debug(1, "in png_read_filter_row (pnggccrd.c)\n"); switch (filter) { case 0: sprintf(filnm, "none"); break; case 1: sprintf(filnm, "sub-%s", #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) #if !defined(PNG_1_0_X) (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : #endif #endif "x86"); break; case 2: sprintf(filnm, "up-%s", #ifdef PNG_ASSEMBLER_CODE_SUPPORTED #if !defined(PNG_1_0_X) (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" : #endif #endif "x86"); break; case 3: sprintf(filnm, "avg-%s", #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) #if !defined(PNG_1_0_X) (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" : #endif #endif "x86"); break; case 4: sprintf(filnm, "Paeth-%s", #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) #if !defined(PNG_1_0_X) (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX": #endif #endif "x86"); break; default: sprintf(filnm, "unknw"); break; } png_debug2(0, "row_number=%5ld, %5s, ", png_ptr->row_number, filnm); png_debug1(0, "row=0x%08lx, ", (unsigned long)row); png_debug2(0, "pixdepth=%2d, bytes=%d, ", (int)row_info->pixel_depth, (int)((row_info->pixel_depth + 7) >> 3)); png_debug1(0,"rowbytes=%8ld\n", row_info->rowbytes); #endif /* PNG_DEBUG */ switch (filter) { case PNG_FILTER_VALUE_NONE: break; case PNG_FILTER_VALUE_SUB: #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) #else if (_mmx_supported) #endif { png_read_filter_row_mmx_sub(row_info, row); } else #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ { png_uint_32 i; png_uint_32 istop = row_info->rowbytes; png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; png_bytep rp = row + bpp; png_bytep lp = row; for (i = bpp; i < istop; i++) { *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); rp++; } } /* end !UseMMX_sub */ break; case PNG_FILTER_VALUE_UP: #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) #else if (_mmx_supported) #endif { png_read_filter_row_mmx_up(row_info, row, prev_row); } else #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ { png_uint_32 i; png_uint_32 istop = row_info->rowbytes; png_bytep rp = row; png_bytep pp = prev_row; for (i = 0; i < istop; ++i) { *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); rp++; } } /* end !UseMMX_up */ break; case PNG_FILTER_VALUE_AVG: #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) #else if (_mmx_supported) #endif { png_read_filter_row_mmx_avg(row_info, row, prev_row); } else #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ { png_uint_32 i; png_bytep rp = row; png_bytep pp = prev_row; png_bytep lp = row; png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; png_uint_32 istop = row_info->rowbytes - bpp; for (i = 0; i < bpp; i++) { *rp = (png_byte)(((int)(*rp) + ((int)(*pp++) >> 1)) & 0xff); rp++; } for (i = 0; i < istop; i++) { *rp = (png_byte)(((int)(*rp) + ((int)(*pp++ + *lp++) >> 1)) & 0xff); rp++; } } /* end !UseMMX_avg */ break; case PNG_FILTER_VALUE_PAETH: #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) #else if (_mmx_supported) #endif { png_read_filter_row_mmx_paeth(row_info, row, prev_row); } else #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ { png_uint_32 i; png_bytep rp = row; png_bytep pp = prev_row; png_bytep lp = row; png_bytep cp = prev_row; png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; png_uint_32 istop = row_info->rowbytes - bpp; for (i = 0; i < bpp; i++) { *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); rp++; } for (i = 0; i < istop; i++) /* use leftover rp,pp */ { int a, b, c, pa, pb, pc, p; a = *lp++; b = *pp++; c = *cp++; p = b - c; pc = a - c; #ifdef PNG_USE_ABS pa = abs(p); pb = abs(pc); pc = abs(p + pc); #else pa = p < 0 ? -p : p; pb = pc < 0 ? -pc : pc; pc = (p + pc) < 0 ? -(p + pc) : p + pc; #endif /* if (pa <= pb && pa <= pc) p = a; else if (pb <= pc) p = b; else p = c; */ p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; *rp = (png_byte)(((int)(*rp) + p) & 0xff); rp++; } } /* end !UseMMX_paeth */ break; default: png_warning(png_ptr, "Ignoring bad row-filter type"); *row=0; break; } } #endif /* PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */ /*===========================================================================*/ /* */ /* P N G _ M M X _ S U P P O R T */ /* */ /*===========================================================================*/ /* GRR NOTES: (1) the following code assumes 386 or better (pushfl/popfl) * (2) all instructions compile with gcc 2.7.2.3 and later * (3) the function is moved down here to prevent gcc from * inlining it in multiple places and then barfing be- * cause the ".NOT_SUPPORTED" label is multiply defined * [is there a way to signal that a *single* function should * not be inlined? is there a way to modify the label for * each inlined instance, e.g., by appending _1, _2, etc.? * maybe if don't use leading "." in label name? (nope...sigh)] */ int PNGAPI png_mmx_support(void) { #if defined(PNG_MMX_CODE_SUPPORTED) __asm__ __volatile__ ( "pushl %%ebx \n\t" // ebx gets clobbered by CPUID instruction "pushl %%ecx \n\t" // so does ecx... "pushl %%edx \n\t" // ...and edx (but ecx & edx safe on Linux) // ".byte 0x66 \n\t" // convert 16-bit pushf to 32-bit pushfd // "pushf \n\t" // 16-bit pushf "pushfl \n\t" // save Eflag to stack "popl %%eax \n\t" // get Eflag from stack into eax "movl %%eax, %%ecx \n\t" // make another copy of Eflag in ecx "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21) "pushl %%eax \n\t" // save modified Eflag back to stack // ".byte 0x66 \n\t" // convert 16-bit popf to 32-bit popfd // "popf \n\t" // 16-bit popf "popfl \n\t" // restore modified value to Eflag reg "pushfl \n\t" // save Eflag to stack "popl %%eax \n\t" // get Eflag from stack "pushl %%ecx \n\t" // save original Eflag to stack "popfl \n\t" // restore original Eflag "xorl %%ecx, %%eax \n\t" // compare new Eflag with original Eflag "jz 0f \n\t" // if same, CPUID instr. is not supported "xorl %%eax, %%eax \n\t" // set eax to zero // ".byte 0x0f, 0xa2 \n\t" // CPUID instruction (two-byte opcode) "cpuid \n\t" // get the CPU identification info "cmpl $1, %%eax \n\t" // make sure eax return non-zero value "jl 0f \n\t" // if eax is zero, MMX is not supported "xorl %%eax, %%eax \n\t" // set eax to zero and... "incl %%eax \n\t" // ...increment eax to 1. This pair is // faster than the instruction "mov eax, 1" "cpuid \n\t" // get the CPU identification info again "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23) "cmpl $0, %%edx \n\t" // 0 = MMX not supported "jz 0f \n\t" // non-zero = yes, MMX IS supported "movl $1, %%eax \n\t" // set return value to 1 "jmp 1f \n\t" // DONE: have MMX support "0: \n\t" // .NOT_SUPPORTED: target label for jump instructions "movl $0, %%eax \n\t" // set return value to 0 "1: \n\t" // .RETURN: target label for jump instructions "movl %%eax, _mmx_supported \n\t" // save in global static variable, too "popl %%edx \n\t" // restore edx "popl %%ecx \n\t" // restore ecx "popl %%ebx \n\t" // restore ebx // "ret \n\t" // DONE: no MMX support // (fall through to standard C "ret") : // output list (none) : // any variables used on input (none) : "%eax" // clobber list // , "%ebx", "%ecx", "%edx" // GRR: we handle these manually // , "memory" // if write to a variable gcc thought was in a reg // , "cc" // "condition codes" (flag bits) ); #else _mmx_supported = 0; #endif /* PNG_MMX_CODE_SUPPORTED */ return _mmx_supported; } #endif /* PNG_USE_PNGGCCRD */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngwtran.c0000664000175000017500000004122210777447272021164 0ustar evanevan /* pngwtran.c - transforms the data in a row for PNG writers * * libpng version 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ #define PNG_INTERNAL #include "png.h" #ifdef PNG_WRITE_SUPPORTED /* Transform the data according to the user's wishes. The order of * transformations is significant. */ void /* PRIVATE */ png_do_write_transformations(png_structp png_ptr) { png_debug(1, "in png_do_write_transformations\n"); if (png_ptr == NULL) return; #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) if (png_ptr->transformations & PNG_USER_TRANSFORM) if(png_ptr->write_user_transform_fn != NULL) (*(png_ptr->write_user_transform_fn)) /* user write transform function */ (png_ptr, /* png_ptr */ &(png_ptr->row_info), /* row_info: */ /* png_uint_32 width; width of row */ /* png_uint_32 rowbytes; number of bytes in row */ /* png_byte color_type; color type of pixels */ /* png_byte bit_depth; bit depth of samples */ /* png_byte channels; number of channels (1-4) */ /* png_byte pixel_depth; bits per pixel (depth*channels) */ png_ptr->row_buf + 1); /* start of pixel data for row */ #endif #if defined(PNG_WRITE_FILLER_SUPPORTED) if (png_ptr->transformations & PNG_FILLER) png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->flags); #endif #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_WRITE_PACK_SUPPORTED) if (png_ptr->transformations & PNG_PACK) png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, (png_uint_32)png_ptr->bit_depth); #endif #if defined(PNG_WRITE_SWAP_SUPPORTED) if (png_ptr->transformations & PNG_SWAP_BYTES) png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_WRITE_SHIFT_SUPPORTED) if (png_ptr->transformations & PNG_SHIFT) png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, &(png_ptr->shift)); #endif #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) if (png_ptr->transformations & PNG_INVERT_ALPHA) png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) if (png_ptr->transformations & PNG_SWAP_ALPHA) png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_WRITE_BGR_SUPPORTED) if (png_ptr->transformations & PNG_BGR) png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif #if defined(PNG_WRITE_INVERT_SUPPORTED) if (png_ptr->transformations & PNG_INVERT_MONO) png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif } #if defined(PNG_WRITE_PACK_SUPPORTED) /* Pack pixels into bytes. Pass the true bit depth in bit_depth. The * row_info bit depth should be 8 (one pixel per byte). The channels * should be 1 (this only happens on grayscale and paletted images). */ void /* PRIVATE */ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) { png_debug(1, "in png_do_pack\n"); if (row_info->bit_depth == 8 && #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif row_info->channels == 1) { switch ((int)bit_depth) { case 1: { png_bytep sp, dp; int mask, v; png_uint_32 i; png_uint_32 row_width = row_info->width; sp = row; dp = row; mask = 0x80; v = 0; for (i = 0; i < row_width; i++) { if (*sp != 0) v |= mask; sp++; if (mask > 1) mask >>= 1; else { mask = 0x80; *dp = (png_byte)v; dp++; v = 0; } } if (mask != 0x80) *dp = (png_byte)v; break; } case 2: { png_bytep sp, dp; int shift, v; png_uint_32 i; png_uint_32 row_width = row_info->width; sp = row; dp = row; shift = 6; v = 0; for (i = 0; i < row_width; i++) { png_byte value; value = (png_byte)(*sp & 0x03); v |= (value << shift); if (shift == 0) { shift = 6; *dp = (png_byte)v; dp++; v = 0; } else shift -= 2; sp++; } if (shift != 6) *dp = (png_byte)v; break; } case 4: { png_bytep sp, dp; int shift, v; png_uint_32 i; png_uint_32 row_width = row_info->width; sp = row; dp = row; shift = 4; v = 0; for (i = 0; i < row_width; i++) { png_byte value; value = (png_byte)(*sp & 0x0f); v |= (value << shift); if (shift == 0) { shift = 4; *dp = (png_byte)v; dp++; v = 0; } else shift -= 4; sp++; } if (shift != 4) *dp = (png_byte)v; break; } } row_info->bit_depth = (png_byte)bit_depth; row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); } } #endif #if defined(PNG_WRITE_SHIFT_SUPPORTED) /* Shift pixel values to take advantage of whole range. Pass the * true number of bits in bit_depth. The row should be packed * according to row_info->bit_depth. Thus, if you had a row of * bit depth 4, but the pixels only had values from 0 to 7, you * would pass 3 as bit_depth, and this routine would translate the * data to 0 to 15. */ void /* PRIVATE */ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) { png_debug(1, "in png_do_shift\n"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL && #else if ( #endif row_info->color_type != PNG_COLOR_TYPE_PALETTE) { int shift_start[4], shift_dec[4]; int channels = 0; if (row_info->color_type & PNG_COLOR_MASK_COLOR) { shift_start[channels] = row_info->bit_depth - bit_depth->red; shift_dec[channels] = bit_depth->red; channels++; shift_start[channels] = row_info->bit_depth - bit_depth->green; shift_dec[channels] = bit_depth->green; channels++; shift_start[channels] = row_info->bit_depth - bit_depth->blue; shift_dec[channels] = bit_depth->blue; channels++; } else { shift_start[channels] = row_info->bit_depth - bit_depth->gray; shift_dec[channels] = bit_depth->gray; channels++; } if (row_info->color_type & PNG_COLOR_MASK_ALPHA) { shift_start[channels] = row_info->bit_depth - bit_depth->alpha; shift_dec[channels] = bit_depth->alpha; channels++; } /* with low row depths, could only be grayscale, so one channel */ if (row_info->bit_depth < 8) { png_bytep bp = row; png_uint_32 i; png_byte mask; png_uint_32 row_bytes = row_info->rowbytes; if (bit_depth->gray == 1 && row_info->bit_depth == 2) mask = 0x55; else if (row_info->bit_depth == 4 && bit_depth->gray == 3) mask = 0x11; else mask = 0xff; for (i = 0; i < row_bytes; i++, bp++) { png_uint_16 v; int j; v = *bp; *bp = 0; for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) { if (j > 0) *bp |= (png_byte)((v << j) & 0xff); else *bp |= (png_byte)((v >> (-j)) & mask); } } } else if (row_info->bit_depth == 8) { png_bytep bp = row; png_uint_32 i; png_uint_32 istop = channels * row_info->width; for (i = 0; i < istop; i++, bp++) { png_uint_16 v; int j; int c = (int)(i%channels); v = *bp; *bp = 0; for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) { if (j > 0) *bp |= (png_byte)((v << j) & 0xff); else *bp |= (png_byte)((v >> (-j)) & 0xff); } } } else { png_bytep bp; png_uint_32 i; png_uint_32 istop = channels * row_info->width; for (bp = row, i = 0; i < istop; i++) { int c = (int)(i%channels); png_uint_16 value, v; int j; v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1)); value = 0; for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) { if (j > 0) value |= (png_uint_16)((v << j) & (png_uint_16)0xffff); else value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff); } *bp++ = (png_byte)(value >> 8); *bp++ = (png_byte)(value & 0xff); } } } } #endif #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) void /* PRIVATE */ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_write_swap_alpha\n"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif { if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { /* This converts from ARGB to RGBA */ if (row_info->bit_depth == 8) { png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; for (i = 0, sp = dp = row; i < row_width; i++) { png_byte save = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = save; } } /* This converts from AARRGGBB to RRGGBBAA */ else { png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; for (i = 0, sp = dp = row; i < row_width; i++) { png_byte save[2]; save[0] = *(sp++); save[1] = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = save[0]; *(dp++) = save[1]; } } } else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { /* This converts from AG to GA */ if (row_info->bit_depth == 8) { png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; for (i = 0, sp = dp = row; i < row_width; i++) { png_byte save = *(sp++); *(dp++) = *(sp++); *(dp++) = save; } } /* This converts from AAGG to GGAA */ else { png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; for (i = 0, sp = dp = row; i < row_width; i++) { png_byte save[2]; save[0] = *(sp++); save[1] = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = save[0]; *(dp++) = save[1]; } } } } } #endif #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) void /* PRIVATE */ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_write_invert_alpha\n"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif { if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { /* This inverts the alpha channel in RGBA */ if (row_info->bit_depth == 8) { png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; for (i = 0, sp = dp = row; i < row_width; i++) { *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = (png_byte)(255 - *(sp++)); } } /* This inverts the alpha channel in RRGGBBAA */ else { png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; for (i = 0, sp = dp = row; i < row_width; i++) { *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = (png_byte)(255 - *(sp++)); *(dp++) = (png_byte)(255 - *(sp++)); } } } else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { /* This inverts the alpha channel in GA */ if (row_info->bit_depth == 8) { png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; for (i = 0, sp = dp = row; i < row_width; i++) { *(dp++) = *(sp++); *(dp++) = (png_byte)(255 - *(sp++)); } } /* This inverts the alpha channel in GGAA */ else { png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; for (i = 0, sp = dp = row; i < row_width; i++) { *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = (png_byte)(255 - *(sp++)); *(dp++) = (png_byte)(255 - *(sp++)); } } } } } #endif #if defined(PNG_MNG_FEATURES_SUPPORTED) /* undoes intrapixel differencing */ void /* PRIVATE */ png_do_write_intrapixel(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_write_intrapixel\n"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif (row_info->color_type & PNG_COLOR_MASK_COLOR)) { int bytes_per_pixel; png_uint_32 row_width = row_info->width; if (row_info->bit_depth == 8) { png_bytep rp; png_uint_32 i; if (row_info->color_type == PNG_COLOR_TYPE_RGB) bytes_per_pixel = 3; else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) bytes_per_pixel = 4; else return; for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) { *(rp) = (png_byte)((*rp - *(rp+1))&0xff); *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff); } } else if (row_info->bit_depth == 16) { png_bytep rp; png_uint_32 i; if (row_info->color_type == PNG_COLOR_TYPE_RGB) bytes_per_pixel = 6; else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) bytes_per_pixel = 8; else return; for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) { png_uint_32 s0 = (*(rp ) << 8) | *(rp+1); png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3); png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5); png_uint_32 red = (png_uint_32)((s0-s1) & 0xffffL); png_uint_32 blue = (png_uint_32)((s2-s1) & 0xffffL); *(rp ) = (png_byte)((red >> 8) & 0xff); *(rp+1) = (png_byte)(red & 0xff); *(rp+4) = (png_byte)((blue >> 8) & 0xff); *(rp+5) = (png_byte)(blue & 0xff); } } } } #endif /* PNG_MNG_FEATURES_SUPPORTED */ #endif /* PNG_WRITE_SUPPORTED */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngwio.c0000664000175000017500000001641710777447272020637 0ustar evanevan /* pngwio.c - functions for data output * * libpng 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * * This file provides a location for all output. Users who need * special handling are expected to write functions that have the same * arguments as these and perform similar functions, but that possibly * use different output methods. Note that you shouldn't change these * functions, but rather write replacement functions and then change * them at run time with png_set_write_fn(...). */ #define PNG_INTERNAL #include "png.h" #ifdef PNG_WRITE_SUPPORTED /* Write the data to whatever output you are using. The default routine writes to a file pointer. Note that this routine sometimes gets called with very small lengths, so you should implement some kind of simple buffering if you are using unbuffered writes. This should never be asked to write more than 64K on a 16 bit machine. */ void /* PRIVATE */ png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { if (png_ptr->write_data_fn != NULL ) (*(png_ptr->write_data_fn))(png_ptr, data, length); else png_error(png_ptr, "Call to NULL write function"); } #if !defined(PNG_NO_STDIO) /* This is the function that does the actual writing of data. If you are not writing to a standard C stream, you should create a replacement write_data function and use it at run time with png_set_write_fn(), rather than changing the library. */ #ifndef USE_FAR_KEYWORD void PNGAPI png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_uint_32 check; #if defined(_WIN32_WCE) if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) ) check = 0; #else check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); #endif if (check != length) png_error(png_ptr, "Write Error"); } #else /* this is the model-independent version. Since the standard I/O library can't handle far buffers in the medium and small models, we have to copy the data. */ #define NEAR_BUF_SIZE 1024 #define MIN(a,b) (a <= b ? a : b) void PNGAPI png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_uint_32 check; png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ png_FILE_p io_ptr; /* Check if data really is near. If so, use usual code. */ near_data = (png_byte *)CVT_PTR_NOCHECK(data); io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); if ((png_bytep)near_data == data) { #if defined(_WIN32_WCE) if ( !WriteFile(io_ptr, near_data, length, &check, NULL) ) check = 0; #else check = fwrite(near_data, 1, length, io_ptr); #endif } else { png_byte buf[NEAR_BUF_SIZE]; png_size_t written, remaining, err; check = 0; remaining = length; do { written = MIN(NEAR_BUF_SIZE, remaining); png_memcpy(buf, data, written); /* copy far buffer to near buffer */ #if defined(_WIN32_WCE) if ( !WriteFile(io_ptr, buf, written, &err, NULL) ) err = 0; #else err = fwrite(buf, 1, written, io_ptr); #endif if (err != written) break; else check += err; data += written; remaining -= written; } while (remaining != 0); } if (check != length) png_error(png_ptr, "Write Error"); } #endif #endif /* This function is called to output any data pending writing (normally to disk). After png_flush is called, there should be no data pending writing in any buffers. */ #if defined(PNG_WRITE_FLUSH_SUPPORTED) void /* PRIVATE */ png_flush(png_structp png_ptr) { if (png_ptr->output_flush_fn != NULL) (*(png_ptr->output_flush_fn))(png_ptr); } #if !defined(PNG_NO_STDIO) void PNGAPI png_default_flush(png_structp png_ptr) { #if !defined(_WIN32_WCE) png_FILE_p io_ptr; io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); if (io_ptr != NULL) fflush(io_ptr); #endif } #endif #endif /* This function allows the application to supply new output functions for libpng if standard C streams aren't being used. This function takes as its arguments: png_ptr - pointer to a png output data structure io_ptr - pointer to user supplied structure containing info about the output functions. May be NULL. write_data_fn - pointer to a new output function that takes as its arguments a pointer to a png_struct, a pointer to data to be written, and a 32-bit unsigned int that is the number of bytes to be written. The new write function should call png_error(png_ptr, "Error msg") to exit and output any fatal error messages. flush_data_fn - pointer to a new flush function that takes as its arguments a pointer to a png_struct. After a call to the flush function, there should be no data in any buffers or pending transmission. If the output method doesn't do any buffering of ouput, a function prototype must still be supplied although it doesn't have to do anything. If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time, output_flush_fn will be ignored, although it must be supplied for compatibility. */ void PNGAPI png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) { png_ptr->io_ptr = io_ptr; #if !defined(PNG_NO_STDIO) if (write_data_fn != NULL) png_ptr->write_data_fn = write_data_fn; else png_ptr->write_data_fn = png_default_write_data; #else png_ptr->write_data_fn = write_data_fn; #endif #if defined(PNG_WRITE_FLUSH_SUPPORTED) #if !defined(PNG_NO_STDIO) if (output_flush_fn != NULL) png_ptr->output_flush_fn = output_flush_fn; else png_ptr->output_flush_fn = png_default_flush; #else png_ptr->output_flush_fn = output_flush_fn; #endif #endif /* PNG_WRITE_FLUSH_SUPPORTED */ /* It is an error to read while writing a png file */ if (png_ptr->read_data_fn != NULL) { png_ptr->read_data_fn = NULL; png_warning(png_ptr, "Attempted to set both read_data_fn and write_data_fn in"); png_warning(png_ptr, "the same structure. Resetting read_data_fn to NULL."); } } #if defined(USE_FAR_KEYWORD) #if defined(_MSC_VER) void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check) { void *near_ptr; void FAR *far_ptr; FP_OFF(near_ptr) = FP_OFF(ptr); far_ptr = (void FAR *)near_ptr; if(check != 0) if(FP_SEG(ptr) != FP_SEG(far_ptr)) png_error(png_ptr,"segment lost in conversion"); return(near_ptr); } # else void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check) { void *near_ptr; void FAR *far_ptr; near_ptr = (void FAR *)ptr; far_ptr = (void FAR *)near_ptr; if(check != 0) if(far_ptr != ptr) png_error(png_ptr,"segment lost in conversion"); return(near_ptr); } # endif # endif #endif /* PNG_WRITE_SUPPORTED */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/libpng.30000664000175000017500000050104210777447272020520 0ustar evanevan.TH LIBPNG 3 "December 3, 2004" .SH NAME libpng \- Portable Network Graphics (PNG) Reference Library 1.2.8 .SH SYNOPSIS \fI\fB \fB#include \fP \fI\fB \fBpng_uint_32 png_access_version_number \fI(void\fP\fB);\fP \fI\fB \fBint png_check_sig (png_bytep \fP\fIsig\fP\fB, int \fInum\fP\fB);\fP \fI\fB \fBvoid png_chunk_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP \fI\fB \fBvoid png_chunk_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP \fI\fB \fBvoid png_convert_from_struct_tm (png_timep \fP\fIptime\fP\fB, struct tm FAR * \fIttime\fP\fB);\fP \fI\fB \fBvoid png_convert_from_time_t (png_timep \fP\fIptime\fP\fB, time_t \fIttime\fP\fB);\fP \fI\fB \fBpng_charp png_convert_to_rfc1123 (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fIptime\fP\fB);\fP \fI\fB \fBpng_infop png_create_info_struct (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_structp png_create_read_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP \fI\fB \fBpng_structp png_create_read_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP \fI\fB \fBpng_structp png_create_write_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP \fI\fB \fBpng_structp png_create_write_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP \fI\fB \fBint png_debug(int \fP\fIlevel\fP\fB, png_const_charp \fImessage\fP\fB);\fP \fI\fB \fBint png_debug1(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fIp1\fP\fB);\fP \fI\fB \fBint png_debug2(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fP\fIp1\fP\fB, \fIp2\fP\fB);\fP \fI\fB \fBvoid png_destroy_info_struct (png_structp \fP\fIpng_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP \fI\fB \fBvoid png_destroy_read_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fP\fIinfo_ptr_ptr\fP\fB, png_infopp \fIend_info_ptr_ptr\fP\fB);\fP \fI\fB \fBvoid png_destroy_write_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP \fI\fB \fBvoid png_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP \fI\fB \fBvoid png_free (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP \fI\fB \fBvoid png_free_chunk_list (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_free_default(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP \fI\fB \fBvoid png_free_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fInum\fP\fB);\fP \fI\fB \fBpng_byte png_get_bit_depth (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fI*background\fP\fB);\fP \fI\fB \fBpng_byte png_get_channels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*white_x\fP\fB, double \fP\fI*white_y\fP\fB, double \fP\fI*red_x\fP\fB, double \fP\fI*red_y\fP\fB, double \fP\fI*green_x\fP\fB, double \fP\fI*green_y\fP\fB, double \fP\fI*blue_x\fP\fB, double \fI*blue_y\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*white_x\fP\fB, png_uint_32 \fP\fI*white_y\fP\fB, png_uint_32 \fP\fI*red_x\fP\fB, png_uint_32 \fP\fI*red_y\fP\fB, png_uint_32 \fP\fI*green_x\fP\fB, png_uint_32 \fP\fI*green_y\fP\fB, png_uint_32 \fP\fI*blue_x\fP\fB, png_uint_32 \fI*blue_y\fP\fB);\fP \fI\fB \fBpng_byte png_get_color_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_byte png_get_compression_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_byte png_get_copyright (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_voidp png_get_error_ptr (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_byte png_get_filter_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fI*file_gamma\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fI*int_file_gamma\fP\fB);\fP \fI\fB \fBpng_byte png_get_header_ver (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_byte png_get_header_version (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fI*hist\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charpp \fP\fIname\fP\fB, int \fP\fI*compression_type\fP\fB, png_charpp \fP\fIprofile\fP\fB, png_uint_32 \fI*proflen\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*width\fP\fB, png_uint_32 \fP\fI*height\fP\fB, int \fP\fI*bit_depth\fP\fB, int \fP\fI*color_type\fP\fB, int \fP\fI*interlace_type\fP\fB, int \fP\fI*compression_type\fP\fB, int \fI*filter_type\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_image_height (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_image_width (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_byte png_get_interlace_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_voidp png_get_io_ptr (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_byte png_get_libpng_ver (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_voidp png_get_mem_ptr(png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*offset_x\fP\fB, png_uint_32 \fP\fI*offset_y\fP\fB, int \fI*unit_type\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fI*purpose\fP\fB, png_int_32 \fP\fI*X0\fP\fB, png_int_32 \fP\fI*X1\fP\fB, int \fP\fI*type\fP\fB, int \fP\fI*nparams\fP\fB, png_charp \fP\fI*units\fP\fB, png_charpp \fI*params\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*res_x\fP\fB, png_uint_32 \fP\fI*res_y\fP\fB, int \fI*unit_type\fP\fB);\fP \fI\fB \fBfloat png_get_pixel_aspect_ratio (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_voidp png_get_progressive_ptr (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fI*palette\fP\fB, int \fI*num_palette\fP\fB);\fP \fI\fB \fBpng_byte png_get_rgb_to_gray_status (png_structp \fIpng_ptr) \fBpng_uint_32 png_get_rowbytes (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_bytepp png_get_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fI*sig_bit\fP\fB);\fP \fI\fB \fBpng_bytep png_get_signature (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fI*splt_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fI*intent\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fI*text_ptr\fP\fB, int \fI*num_text\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fI*mod_time\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fI*trans\fP\fB, int \fP\fI*num_trans\fP\fB, png_color_16p \fI*trans_values\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkpp \fIunknowns\fP\fB);\fP \fI\fB \fBpng_voidp png_get_user_chunk_ptr (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_user_height_max( png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_voidp png_get_user_transform_ptr (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_user_width_max (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_valid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIflag\fP\fB);\fP \fI\fB \fBpng_int_32 png_get_x_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_int_32 png_get_x_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_x_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_int_32 png_get_y_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_int_32 png_get_y_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_y_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_get_compression_buffer_size (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBint png_handle_as_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP \fI\fB \fBvoid png_init_io (png_structp \fP\fIpng_ptr\fP\fB, FILE \fI*fp\fP\fB);\fP \fI\fB \fBDEPRECATED: void png_info_init (png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBDEPRECATED: void png_info_init_2 (png_infopp \fP\fIptr_ptr\fP\fB, png_size_t \fIpng_info_struct_size\fP\fB);\fP \fI\fB \fBpng_voidp png_malloc (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP \fI\fB \fBpng_voidp png_malloc_default(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP \fI\fB \fBvoidp png_memcpy (png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_size_t \fIsize\fP\fB);\fP \fI\fB \fBpng_voidp png_memcpy_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_uint_32 \fIsize\fP\fB);\fP \fI\fB \fBvoidp png_memset (png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_size_t \fIsize\fP\fB);\fP \fI\fB \fBpng_voidp png_memset_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_uint_32 \fIsize\fP\fB);\fP \fI\fB \fBDEPRECATED: void png_permit_empty_plte (png_structp \fP\fIpng_ptr\fP\fB, int \fIempty_plte_permitted\fP\fB);\fP \fI\fB \fBvoid png_process_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_size\fP\fB);\fP \fI\fB \fBvoid png_progressive_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIold_row\fP\fB, png_bytep \fInew_row\fP\fB);\fP \fI\fB \fBvoid png_read_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_infop \fIend_info_ptr\fP\fB);\fP \fI\fB \fBvoid png_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBvoid png_read_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP \fI\fB \fBDEPRECATED: void png_read_init (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBDEPRECATED: void png_read_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP \fI\fB \fBvoid png_read_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBvoid png_read_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP \fI\fB \fBvoid png_read_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fIdisplay_row\fP\fB);\fP \fI\fB \fBvoid png_read_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_bytepp \fP\fIdisplay_row\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP \fI\fB \fBvoid png_read_update_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fB#if \fI!defined(PNG_1_0_X) \fBvoid png_set_add_alpha (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP \fI\fB#endif \fI\fB \fBvoid png_set_background (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIbackground_color\fP\fB, int \fP\fIbackground_gamma_code\fP\fB, int \fP\fIneed_expand\fP\fB, double \fIbackground_gamma\fP\fB);\fP \fI\fB \fBvoid png_set_bgr (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fIbackground\fP\fB);\fP \fI\fB \fBvoid png_set_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP \fI\fB \fBvoid png_set_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP \fI\fB \fBvoid png_set_compression_level (png_structp \fP\fIpng_ptr\fP\fB, int \fIlevel\fP\fB);\fP \fI\fB \fBvoid png_set_compression_mem_level (png_structp \fP\fIpng_ptr\fP\fB, int \fImem_level\fP\fB);\fP \fI\fB \fBvoid png_set_compression_method (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod\fP\fB);\fP \fI\fB \fBvoid png_set_compression_strategy (png_structp \fP\fIpng_ptr\fP\fB, int \fIstrategy\fP\fB);\fP \fI\fB \fBvoid png_set_compression_window_bits (png_structp \fP\fIpng_ptr\fP\fB, int \fIwindow_bits\fP\fB);\fP \fI\fB \fBvoid png_set_crc_action (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcrit_action\fP\fB, int \fIancil_action\fP\fB);\fP \fI\fB \fBvoid png_set_dither (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fP\fInum_palette\fP\fB, int \fP\fImaximum_colors\fP\fB, png_uint_16p \fP\fIhistogram\fP\fB, int \fIfull_dither\fP\fB);\fP \fI\fB \fBvoid png_set_error_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarning_fn\fP\fB);\fP \fI\fB \fBvoid png_set_expand (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_filler (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP \fI\fB \fBvoid png_set_filter (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fImethod\fP\fB, int \fIfilters\fP\fB);\fP \fI\fB \fBvoid png_set_filter_heuristics (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIheuristic_method\fP\fB, int \fP\fInum_weights\fP\fB, png_doublep \fP\fIfilter_weights\fP\fB, png_doublep \fIfilter_costs\fP\fB);\fP \fI\fB \fBvoid png_set_flush (png_structp \fP\fIpng_ptr\fP\fB, int \fInrows\fP\fB);\fP \fI\fB \fBvoid png_set_gamma (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIscreen_gamma\fP\fB, double \fIdefault_file_gamma\fP\fB);\fP \fI\fB \fBvoid png_set_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP \fI\fB \fBvoid png_set_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIfile_gamma\fP\fB);\fP \fI\fB \fBvoid png_set_gray_1_2_4_to_8(png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fIhist\fP\fB);\fP \fI\fB \fBvoid png_set_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_charp \fP\fIprofile\fP\fB, png_uint_32 \fIproflen\fP\fB);\fP \fI\fB \fBint png_set_interlace_handling (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_invalid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fImask\fP\fB);\fP \fI\fB \fBvoid png_set_invert_alpha (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_invert_mono (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIinterlace_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fIfilter_type\fP\fB);\fP \fI\fB \fBvoid png_set_keep_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIkeep\fP\fB, png_bytep \fP\fIchunk_list\fP\fB, int \fInum_chunks\fP\fB);\fP \fI\fB \fBvoid png_set_mem_fn(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP \fI\fB \fBvoid png_set_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIoffset_x\fP\fB, png_uint_32 \fP\fIoffset_y\fP\fB, int \fIunit_type\fP\fB);\fP \fI\fB \fBvoid png_set_packing (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_packswap (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_palette_to_rgb(png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP \fI\fB \fBvoid png_set_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIres_x\fP\fB, png_uint_32 \fP\fIres_y\fP\fB, int \fIunit_type\fP\fB);\fP \fI\fB \fBvoid png_set_progressive_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIprogressive_ptr\fP\fB, png_progressive_info_ptr \fP\fIinfo_fn\fP\fB, png_progressive_row_ptr \fP\fIrow_fn\fP\fB, png_progressive_end_ptr \fIend_fn\fP\fB);\fP \fI\fB \fBvoid png_set_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP \fI\fB \fBvoid png_set_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fIread_data_fn\fP\fB);\fP \fI\fB \fBvoid png_set_read_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_read_status_ptr \fIread_row_fn\fP\fB);\fP \fI\fB \fBvoid png_set_read_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIread_user_transform_fn\fP\fB);\fP \fI\fB \fBvoid png_set_rgb_to_gray (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIerror_action\fP\fB, double \fP\fIred\fP\fB, double \fIgreen\fP\fB);\fP \fI\fB \fBvoid png_set_rgb_to_gray_fixed (png_structp \fP\fIpng_ptr\fP\fB, int error_action png_fixed_point \fP\fIred\fP\fB, png_fixed_point \fIgreen\fP\fB);\fP \fI\fB \fBvoid png_set_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytepp \fIrow_pointers\fP\fB);\fP \fI\fB \fBvoid png_set_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fIsig_bit\fP\fB);\fP \fI\fB \fBvoid png_set_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP \fI\fB \fBvoid png_set_shift (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fItrue_bits\fP\fB);\fP \fI\fB \fBvoid png_set_sig_bytes (png_structp \fP\fIpng_ptr\fP\fB, int \fInum_bytes\fP\fB);\fP \fI\fB \fBvoid png_set_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fP\fIsplt_ptr\fP\fB, int \fInum_spalettes\fP\fB);\fP \fI\fB \fBvoid png_set_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP \fI\fB \fBvoid png_set_sRGB_gAMA_and_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP \fI\fB \fBvoid png_set_strip_16 (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_strip_alpha (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_swap (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_swap_alpha (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_set_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP \fI\fB \fBvoid png_set_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP \fI\fB \fBvoid png_set_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fP\fInum_trans\fP\fB, png_color_16p \fItrans_values\fP\fB);\fP \fI\fB \fBvoid png_set_tRNS_to_alpha(png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBpng_uint_32 png_set_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkp \fP\fIunknowns\fP\fB, int \fP\fInum\fP\fB, int \fIlocation\fP\fB);\fP \fI\fB \fBvoid png_set_unknown_chunk_location(png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIchunk\fP\fB, int \fIlocation\fP\fB);\fP \fI\fB \fBvoid png_set_read_user_chunk_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_chunk_ptr\fP\fB, png_user_chunk_ptr \fIread_user_chunk_fn\fP\fB);\fP \fI\fB \fBvoid png_set_user_limits (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIuser_width_max\fP\fB, png_uint_32 \fIuser_height_max\fP\fB);\fP \fI\fB \fBvoid png_set_user_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_transform_ptr\fP\fB, int \fP\fIuser_transform_depth\fP\fB, int \fIuser_transform_channels\fP\fB);\fP \fI\fB \fBvoid png_set_write_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fP\fIwrite_data_fn\fP\fB, png_flush_ptr \fIoutput_flush_fn\fP\fB);\fP \fI\fB \fBvoid png_set_write_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_write_status_ptr \fIwrite_row_fn\fP\fB);\fP \fI\fB \fBvoid png_set_write_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIwrite_user_transform_fn\fP\fB);\fP \fI\fB \fBvoid png_set_compression_buffer_size(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP \fI\fB \fBint png_sig_cmp (png_bytep \fP\fIsig\fP\fB, png_size_t \fP\fIstart\fP\fB, png_size_t \fInum_to_check\fP\fB);\fP \fI\fB \fBvoid png_start_read_image (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP \fI\fB \fBvoid png_write_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP \fI\fB \fBvoid png_write_chunk_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP \fI\fB \fBvoid png_write_chunk_end (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_write_chunk_start (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_uint_32 \fIlength\fP\fB);\fP \fI\fB \fBvoid png_write_destroy (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_write_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBvoid png_write_flush (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBvoid png_write_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP \fI\fB \fBDEPRECATED: void png_write_init (png_structp \fIpng_ptr\fP\fB);\fP \fI\fB \fBDEPRECATED: void png_write_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP \fI\fB \fBvoid png_write_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBvoid png_write_info_before_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP \fI\fB \fBvoid png_write_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP \fI\fB \fBvoid png_write_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP \fI\fB \fBvoid png_write_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP \fI\fB \fBvoidpf png_zalloc (voidpf \fP\fIpng_ptr\fP\fB, uInt \fP\fIitems\fP\fB, uInt \fIsize\fP\fB);\fP \fI\fB \fBvoid png_zfree (voidpf \fP\fIpng_ptr\fP\fB, voidpf \fIptr\fP\fB);\fP \fI\fB .SH DESCRIPTION The .I libpng library supports encoding, decoding, and various manipulations of the Portable Network Graphics (PNG) format image files. It uses the .IR zlib(3) compression library. Following is a copy of the libpng.txt file that accompanies libpng. .SH LIBPNG.TXT libpng.txt - A description on how to use and modify libpng libpng version 1.2.8 - December 3, 2004 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2004 Glenn Randers-Pehrson For conditions of distribution and use, see copyright notice in png.h. based on: libpng 1.0 beta 6 version 0.96 May 28, 1997 Updated and distributed by Andreas Dilger Copyright (c) 1996, 1997 Andreas Dilger libpng 1.0 beta 2 - version 0.88 January 26, 1996 For conditions of distribution and use, see copyright notice in png.h. Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. Updated/rewritten per request in the libpng FAQ Copyright (c) 1995, 1996 Frank J. T. Wojcik December 18, 1995 & January 20, 1996 .SH I. Introduction This file describes how to use and modify the PNG reference library (known as libpng) for your own use. There are five sections to this file: introduction, structures, reading, writing, and modification and configuration notes for various special platforms. In addition to this file, example.c is a good starting point for using the library, as it is heavily commented and should include everything most people will need. We assume that libpng is already installed; see the INSTALL file for instructions on how to install libpng. Libpng was written as a companion to the PNG specification, as a way of reducing the amount of time and effort it takes to support the PNG file format in application programs. The PNG specification (second edition), November 2003, is available as a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at The PNG-1.0 specification is available as RFC 2083 and as a W3C Recommendation . Some additional chunks are described in the special-purpose public chunks documents at . Other information about PNG, and the latest version of libpng, can be found at the PNG home page, . Most users will not have to modify the library significantly; advanced users may want to modify it more. All attempts were made to make it as complete as possible, while keeping the code easy to understand. Currently, this library only supports C. Support for other languages is being considered. Libpng has been designed to handle multiple sessions at one time, to be easily modifiable, to be portable to the vast majority of machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy to use. The ultimate goal of libpng is to promote the acceptance of the PNG file format in whatever way possible. While there is still work to be done (see the TODO file), libpng should cover the majority of the needs of its users. Libpng uses zlib for its compression and decompression of PNG files. Further information about zlib, and the latest version of zlib, can be found at the zlib home page, . The zlib compression utility is a general purpose utility that is useful for more than PNG files, and can be used without libpng. See the documentation delivered with zlib for more details. You can usually find the source files for the zlib utility wherever you find the libpng source files. Libpng is thread safe, provided the threads are using different instances of the structures. Each thread should have its own png_struct and png_info instances, and thus its own image. Libpng does not protect itself against two threads using the same instance of a structure. Note: thread safety may be defeated by use of some of the MMX assembler code in pnggccrd.c, which is only compiled when the user defines PNG_THREAD_UNSAFE_OK. .SH II. Structures There are two main structures that are important to libpng, png_struct and png_info. The first, png_struct, is an internal structure that will not, for the most part, be used by a user except as the first variable passed to every libpng function call. The png_info structure is designed to provide information about the PNG file. At one time, the fields of png_info were intended to be directly accessible to the user. However, this tended to cause problems with applications using dynamically loaded libraries, and as a result a set of interface functions for png_info (the png_get_*() and png_set_*() functions) was developed. The fields of png_info are still available for older applications, but it is suggested that applications use the new interfaces if at all possible. Applications that do make direct access to the members of png_struct (except for png_ptr->jmpbuf) must be recompiled whenever the library is updated, and applications that make direct access to the members of png_info must be recompiled if they were compiled or loaded with libpng version 1.0.6, in which the members were in a different order. In version 1.0.7, the members of the png_info structure reverted to the old order, as they were in versions 0.97c through 1.0.5. Starting with version 2.0.0, both structures are going to be hidden, and the contents of the structures will only be accessible through the png_get/png_set functions. The png.h header file is an invaluable reference for programming with libpng. And while I'm on the topic, make sure you include the libpng header file: #include .SH III. Reading We'll now walk you through the possible functions to call when reading in a PNG file sequentially, briefly explaining the syntax and purpose of each one. See example.c and png.h for more detail. While progressive reading is covered in the next section, you will still need some of the functions discussed in this section to read a PNG file. .SS Setup You will want to do the I/O initialization(*) before you get into libpng, so if it doesn't work, you don't have much to undo. Of course, you will also want to insure that you are, in fact, dealing with a PNG file. Libpng provides a simple check to see if a file is a PNG file. To use it, pass in the first 1 to 8 bytes of the file to the function png_sig_cmp(), and it will return 0 if the bytes match the corresponding bytes of the PNG signature, or nonzero otherwise. Of course, the more bytes you pass in, the greater the accuracy of the prediction. If you are intending to keep the file pointer open for use in libpng, you must ensure you don't read more than 8 bytes from the beginning of the file, and you also have to make a call to png_set_sig_bytes_read() with the number of bytes you read from the beginning. Libpng will then only check the bytes (if any) that your program didn't read. (*): If you are not using the standard I/O functions, you will need to replace them with custom functions. See the discussion under Customizing libpng. FILE *fp = fopen(file_name, "rb"); if (!fp) { return (ERROR); } fread(header, 1, number, fp); is_png = !png_sig_cmp(header, 0, number); if (!is_png) { return (NOT_PNG); } Next, png_struct and png_info need to be allocated and initialized. In order to ensure that the size of these structures is correct even with a dynamically linked libpng, there are functions to initialize and allocate the structures. We also pass the library version, optional pointers to error handling functions, and a pointer to a data struct for use by the error functions, if necessary (the pointer and functions can be NULL if the default error handlers are to be used). See the section on Changes to Libpng below regarding the old initialization functions. The structure allocation functions quietly return NULL if they fail to create the structure, so your application should check for that. png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn); if (!png_ptr) return (ERROR); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return (ERROR); } png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return (ERROR); } If you want to use your own memory allocation routines, define PNG_USER_MEM_SUPPORTED and use png_create_read_struct_2() instead of png_create_read_struct(): png_structp png_ptr = png_create_read_struct_2 (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn, (png_voidp) user_mem_ptr, user_malloc_fn, user_free_fn); The error handling routines passed to png_create_read_struct() and the memory alloc/free routines passed to png_create_struct_2() are only necessary if you are not using the libpng supplied error handling and memory alloc/free functions. When libpng encounters an error, it expects to longjmp back to your routine. Therefore, you will need to call setjmp and pass your png_jmpbuf(png_ptr). If you read the file from different routines, you will need to update the jmpbuf field every time you enter a new routine that will call a png_*() function. See your documentation of setjmp/longjmp for your compiler for more information on setjmp/longjmp. See the discussion on libpng error handling in the Customizing Libpng section below for more information on the libpng error handling. If an error occurs, and libpng longjmp's back to your setjmp, you will want to call png_destroy_read_struct() to free any memory. if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return (ERROR); } If you would rather avoid the complexity of setjmp/longjmp issues, you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case errors will result in a call to PNG_ABORT() which defaults to abort(). Now you need to set up the input code. The default for libpng is to use the C function fread(). If you use this, you will need to pass a valid FILE * in the function png_init_io(). Be sure that the file is opened in binary mode. If you wish to handle reading data in another way, you need not call the png_init_io() function, but you must then implement the libpng I/O methods discussed in the Customizing Libpng section below. png_init_io(png_ptr, fp); If you had previously opened the file and read any of the signature from the beginning in order to see if this was a PNG file, you need to let libpng know that there are some bytes missing from the start of the file. png_set_sig_bytes(png_ptr, number); .SS Setting up callback code You can set up a callback function to handle any unknown chunks in the input stream. You must supply the function read_chunk_callback(png_ptr ptr, png_unknown_chunkp chunk); { /* The unknown chunk structure contains your chunk data: */ png_byte name[5]; png_byte *data; png_size_t size; /* Note that libpng has already taken care of the CRC handling */ /* put your code here. Return one of the following: */ return (-n); /* chunk had an error */ return (0); /* did not recognize */ return (n); /* success */ } (You can give your function another name that you like instead of "read_chunk_callback") To inform libpng about your function, use png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, read_chunk_callback); This names not only the callback function, but also a user pointer that you can retrieve with png_get_user_chunk_ptr(png_ptr); At this point, you can set up a callback function that will be called after each row has been read, which you can use to control a progress meter or the like. It's demonstrated in pngtest.c. You must supply a function void read_row_callback(png_ptr ptr, png_uint_32 row, int pass); { /* put your code here */ } (You can give it another name that you like instead of "read_row_callback") To inform libpng about your function, use png_set_read_status_fn(png_ptr, read_row_callback); .SS Width and height limits The PNG specification allows the width and height of an image to be as large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns. Since very few applications really need to process such large images, we have imposed an arbitrary 1-million limit on rows and columns. Larger images will be rejected immediately with a png_error() call. If you wish to override this limit, you can use png_set_user_limits(png_ptr, width_max, height_max); to set your own limits, or use width_max = height_max = 0x7fffffffL to allow all valid dimensions (libpng may reject some very large images anyway because of potential buffer overflow conditions). You should put this statement after you create the PNG structure and before calling png_read_info(), png_read_png(), or png_process_data(). If you need to retrieve the limits that are being applied, use width_max = png_get_user_width_max(png_ptr); height_max = png_get_user_height_max(png_ptr); .SS Unknown-chunk handling Now you get to set the way the library processes unknown chunks in the input PNG stream. Both known and unknown chunks will be read. Normal behavior is that known chunks will be parsed into information in various info_ptr members; unknown chunks will be discarded. To change this, you can call: png_set_keep_unknown_chunks(png_ptr, keep, chunk_list, num_chunks); keep - 0: do not handle as unknown 1: do not keep 2: keep only if safe-to-copy 3: keep even if unsafe-to-copy You can use these definitions: PNG_HANDLE_CHUNK_AS_DEFAULT 0 PNG_HANDLE_CHUNK_NEVER 1 PNG_HANDLE_CHUNK_IF_SAFE 2 PNG_HANDLE_CHUNK_ALWAYS 3 chunk_list - list of chunks affected (a byte string, five bytes per chunk, NULL or '\0' if num_chunks is 0) num_chunks - number of chunks affected; if 0, all unknown chunks are affected. If nonzero, only the chunks in the list are affected Unknown chunks declared in this way will be saved as raw data onto a list of png_unknown_chunk structures. If a chunk that is normally known to libpng is named in the list, it will be handled as unknown, according to the "keep" directive. If a chunk is named in successive instances of png_set_keep_unknown_chunks(), the final instance will take precedence. The IHDR and IEND chunks should not be named in chunk_list; if they are, libpng will process them normally anyway. .SS The high-level read interface At this point there are two ways to proceed; through the high-level read interface, or through a sequence of low-level read operations. You can use the high-level interface if (a) you are willing to read the entire image into memory, and (b) the input transformations you want to do are limited to the following set: PNG_TRANSFORM_IDENTITY No transformation PNG_TRANSFORM_STRIP_16 Strip 16-bit samples to 8 bits PNG_TRANSFORM_STRIP_ALPHA Discard the alpha channel PNG_TRANSFORM_PACKING Expand 1, 2 and 4-bit samples to bytes PNG_TRANSFORM_PACKSWAP Change order of packed pixels to LSB first PNG_TRANSFORM_EXPAND Perform set_expand() PNG_TRANSFORM_INVERT_MONO Invert monochrome images PNG_TRANSFORM_SHIFT Normalize pixels to the sBIT depth PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA to BGRA PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA to AG PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity to transparency PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples (This excludes setting a background color, doing gamma transformation, dithering, and setting filler.) If this is the case, simply do this: png_read_png(png_ptr, info_ptr, png_transforms, NULL) where png_transforms is an integer containing the logical OR of some set of transformation flags. This call is equivalent to png_read_info(), followed the set of transformations indicated by the transform mask, then png_read_image(), and finally png_read_end(). (The final parameter of this call is not yet used. Someday it might point to transformation parameters required by some future input transform.) You must use png_transforms and not call any png_set_transform() functions when you use png_read_png(). After you have called png_read_png(), you can retrieve the image data with row_pointers = png_get_rows(png_ptr, info_ptr); where row_pointers is an array of pointers to the pixel data for each row: png_bytep row_pointers[height]; If you know your image size and pixel size ahead of time, you can allocate row_pointers prior to calling png_read_png() with if (height > PNG_UINT_32_MAX/png_sizeof(png_byte)) png_error (png_ptr, "Image is too tall to process in memory"); if (width > PNG_UINT_32_MAX/pixel_size) png_error (png_ptr, "Image is too wide to process in memory"); row_pointers = png_malloc(png_ptr, height*png_sizeof(png_bytep)); for (int i=0; i) and png_get_(png_ptr, info_ptr, ...) functions return non-zero if the data has been read, or zero if it is missing. The parameters to the png_get_ are set directly if they are simple data types, or a pointer into the info_ptr is returned for any complex types. png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); palette - the palette for the file (array of png_color) num_palette - number of entries in the palette png_get_gAMA(png_ptr, info_ptr, &gamma); gamma - the gamma the file is written at (PNG_INFO_gAMA) png_get_sRGB(png_ptr, info_ptr, &srgb_intent); srgb_intent - the rendering intent (PNG_INFO_sRGB) The presence of the sRGB chunk means that the pixel data is in the sRGB color space. This chunk also implies specific values of gAMA and cHRM. png_get_iCCP(png_ptr, info_ptr, &name, &compression_type, &profile, &proflen); name - The profile name. compression - The compression type; always PNG_COMPRESSION_TYPE_BASE for PNG 1.0. You may give NULL to this argument to ignore it. profile - International Color Consortium color profile data. May contain NULs. proflen - length of profile data in bytes. png_get_sBIT(png_ptr, info_ptr, &sig_bit); sig_bit - the number of significant bits for (PNG_INFO_sBIT) each of the gray, red, green, and blue channels, whichever are appropriate for the given color type (png_color_16) png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values); trans - array of transparent entries for palette (PNG_INFO_tRNS) trans_values - graylevel or color sample values of the single transparent color for non-paletted images (PNG_INFO_tRNS) num_trans - number of transparent entries (PNG_INFO_tRNS) png_get_hIST(png_ptr, info_ptr, &hist); (PNG_INFO_hIST) hist - histogram of palette (array of png_uint_16) png_get_tIME(png_ptr, info_ptr, &mod_time); mod_time - time image was last modified (PNG_VALID_tIME) png_get_bKGD(png_ptr, info_ptr, &background); background - background color (PNG_VALID_bKGD) valid 16-bit red, green and blue values, regardless of color_type num_comments = png_get_text(png_ptr, info_ptr, &text_ptr, &num_text); num_comments - number of comments text_ptr - array of png_text holding image comments text_ptr[i].compression - type of compression used on "text" PNG_TEXT_COMPRESSION_NONE PNG_TEXT_COMPRESSION_zTXt PNG_ITXT_COMPRESSION_NONE PNG_ITXT_COMPRESSION_zTXt text_ptr[i].key - keyword for comment. Must contain 1-79 characters. text_ptr[i].text - text comments for current keyword. Can be empty. text_ptr[i].text_length - length of text string, after decompression, 0 for iTXt text_ptr[i].itxt_length - length of itxt string, after decompression, 0 for tEXt/zTXt text_ptr[i].lang - language of comment (empty string for unknown). text_ptr[i].lang_key - keyword in UTF-8 (empty string for unknown). num_text - number of comments (same as num_comments; you can put NULL here to avoid the duplication) Note while png_set_text() will accept text, language, and translated keywords that can be NULL pointers, the structure returned by png_get_text will always contain regular zero-terminated C strings. They might be empty strings but they will never be NULL pointers. num_spalettes = png_get_sPLT(png_ptr, info_ptr, &palette_ptr); palette_ptr - array of palette structures holding contents of one or more sPLT chunks read. num_spalettes - number of sPLT chunks read. png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, &unit_type); offset_x - positive offset from the left edge of the screen offset_y - positive offset from the top edge of the screen unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type); res_x - pixels/unit physical resolution in x direction res_y - pixels/unit physical resolution in x direction unit_type - PNG_RESOLUTION_UNKNOWN, PNG_RESOLUTION_METER png_get_sCAL(png_ptr, info_ptr, &unit, &width, &height) unit - physical scale units (an integer) width - width of a pixel in physical scale units height - height of a pixel in physical scale units (width and height are doubles) png_get_sCAL_s(png_ptr, info_ptr, &unit, &width, &height) unit - physical scale units (an integer) width - width of a pixel in physical scale units height - height of a pixel in physical scale units (width and height are strings like "2.54") num_unknown_chunks = png_get_unknown_chunks(png_ptr, info_ptr, &unknowns) unknowns - array of png_unknown_chunk structures holding unknown chunks unknowns[i].name - name of unknown chunk unknowns[i].data - data of unknown chunk unknowns[i].size - size of unknown chunk's data unknowns[i].location - position of chunk in file The value of "i" corresponds to the order in which the chunks were read from the PNG file or inserted with the png_set_unknown_chunks() function. The data from the pHYs chunk can be retrieved in several convenient forms: res_x = png_get_x_pixels_per_meter(png_ptr, info_ptr) res_y = png_get_y_pixels_per_meter(png_ptr, info_ptr) res_x_and_y = png_get_pixels_per_meter(png_ptr, info_ptr) res_x = png_get_x_pixels_per_inch(png_ptr, info_ptr) res_y = png_get_y_pixels_per_inch(png_ptr, info_ptr) res_x_and_y = png_get_pixels_per_inch(png_ptr, info_ptr) aspect_ratio = png_get_pixel_aspect_ratio(png_ptr, info_ptr) (Each of these returns 0 [signifying "unknown"] if the data is not present or if res_x is 0; res_x_and_y is 0 if res_x != res_y) The data from the oFFs chunk can be retrieved in several convenient forms: x_offset = png_get_x_offset_microns(png_ptr, info_ptr); y_offset = png_get_y_offset_microns(png_ptr, info_ptr); x_offset = png_get_x_offset_inches(png_ptr, info_ptr); y_offset = png_get_y_offset_inches(png_ptr, info_ptr); (Each of these returns 0 [signifying "unknown" if both x and y are 0] if the data is not present or if the chunk is present but the unit is the pixel) For more information, see the png_info definition in png.h and the PNG specification for chunk contents. Be careful with trusting rowbytes, as some of the transformations could increase the space needed to hold a row (expand, filler, gray_to_rgb, etc.). See png_read_update_info(), below. A quick word about text_ptr and num_text. PNG stores comments in keyword/text pairs, one pair per chunk, with no limit on the number of text chunks, and a 2^31 byte limit on their size. While there are suggested keywords, there is no requirement to restrict the use to these strings. It is strongly suggested that keywords and text be sensible to humans (that's the point), so don't use abbreviations. Non-printing symbols are not allowed. See the PNG specification for more details. There is also no requirement to have text after the keyword. Keywords should be limited to 79 Latin-1 characters without leading or trailing spaces, but non-consecutive spaces are allowed within the keyword. It is possible to have the same keyword any number of times. The text_ptr is an array of png_text structures, each holding a pointer to a language string, a pointer to a keyword and a pointer to a text string. The text string, language code, and translated keyword may be empty or NULL pointers. The keyword/text pairs are put into the array in the order that they are received. However, some or all of the text chunks may be after the image, so, to make sure you have read all the text chunks, don't mess with these until after you read the stuff after the image. This will be mentioned again below in the discussion that goes with png_read_end(). .SS Input transformations After you've read the header information, you can set up the library to handle any special transformations of the image data. The various ways to transform the data will be described in the order that they should occur. This is important, as some of these change the color type and/or bit depth of the data, and some others only work on certain color types and bit depths. Even though each transformation checks to see if it has data that it can do something with, you should make sure to only enable a transformation if it will be valid for the data. For example, don't swap red and blue on grayscale data. The colors used for the background and transparency values should be supplied in the same format/depth as the current image data. They are stored in the same format/depth as the image data in a bKGD or tRNS chunk, so this is what libpng expects for this data. The colors are transformed to keep in sync with the image data when an application calls the png_read_update_info() routine (see below). Data will be decoded into the supplied row buffers packed into bytes unless the library has been told to transform it into another format. For example, 4 bit/pixel paletted or grayscale data will be returned 2 pixels/byte with the leftmost pixel in the high-order bits of the byte, unless png_set_packing() is called. 8-bit RGB data will be stored in RGB RGB RGB format unless png_set_filler() or png_set_add_alpha() is called to insert filler bytes, either before or after each RGB triplet. 16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant byte of the color value first, unless png_set_strip_16() is called to transform it to regular RGB RGB triplets, or png_set_filler() or png_set_add alpha() is called to insert filler bytes, either before or after each RRGGBB triplet. Similarly, 8-bit or 16-bit grayscale data can be modified with png_set_filler(), png_set_add_alpha(), or png_set_strip_16(). The following code transforms grayscale images of less than 8 to 8 bits, changes paletted images to RGB, and adds a full alpha channel if there is transparency information in a tRNS chunk. This is most useful on grayscale images with bit depths of 2 or 4 or if there is a multiple-image viewing application that wishes to treat all images in the same way. if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); These three functions are actually aliases for png_set_expand(), added in libpng version 1.0.4, with the function names expanded to improve code readability. In some future version they may actually do different things. PNG can have files with 16 bits per channel. If you only can handle 8 bits per channel, this will strip the pixels down to 8 bit. if (bit_depth == 16) png_set_strip_16(png_ptr); If, for some reason, you don't need the alpha channel on an image, and you want to remove it rather than combining it with the background (but the image author certainly had in mind that you *would* combine it with the background, so that's what you should probably do): if (color_type & PNG_COLOR_MASK_ALPHA) png_set_strip_alpha(png_ptr); In PNG files, the alpha channel in an image is the level of opacity. If you need the alpha channel in an image to be the level of transparency instead of opacity, you can invert the alpha channel (or the tRNS chunk data) after it's read, so that 0 is fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit images) is fully transparent, with png_set_invert_alpha(png_ptr); PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as they can, resulting in, for example, 8 pixels per byte for 1 bit files. This code expands to 1 pixel per byte without changing the values of the pixels: if (bit_depth < 8) png_set_packing(png_ptr); PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixels stored in a PNG image have been "scaled" or "shifted" up to the next higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to 8 bits/sample in the range [0, 255]). However, it is also possible to convert the PNG pixel data back to the original bit depth of the image. This call reduces the pixels back down to the original bit depth: png_color_8p sig_bit; if (png_get_sBIT(png_ptr, info_ptr, &sig_bit)) png_set_shift(png_ptr, sig_bit); PNG files store 3-color pixels in red, green, blue order. This code changes the storage of the pixels to blue, green, red: if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_bgr(png_ptr); PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them into 4 or 8 bytes for windowing systems that need them in this format: if (color_type == PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE); where "filler" is the 8 or 16-bit number to fill with, and the location is either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether you want the filler before the RGB or after. This transformation does not affect images that already have full alpha channels. To add an opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which will generate RGBA pixels. Note that png_set_filler() does not change the color type. If you want to do that, you can add a true alpha channel with if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY) png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER); where "filler" contains the alpha value to assign to each pixel. This function was added in libpng-1.2.7. If you are reading an image with an alpha channel, and you need the data as ARGB instead of the normal PNG format RGBA: if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_swap_alpha(png_ptr); For some uses, you may want a grayscale image to be represented as RGB. This code will do that conversion: if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); Conversely, you can convert an RGB or RGBA image to grayscale or grayscale with alpha. if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_rgb_to_gray_fixed(png_ptr, error_action, int red_weight, int green_weight); error_action = 1: silently do the conversion error_action = 2: issue a warning if the original image has any pixel where red != green or red != blue error_action = 3: issue an error and abort the conversion if the original image has any pixel where red != green or red != blue red_weight: weight of red component times 100000 green_weight: weight of green component times 100000 If either weight is negative, default weights (21268, 71514) are used. If you have set error_action = 1 or 2, you can later check whether the image really was gray, after processing the image rows, with the png_get_rgb_to_gray_status(png_ptr) function. It will return a png_byte that is zero if the image was gray or 1 if there were any non-gray pixels. bKGD and sBIT data will be silently converted to grayscale, using the green channel data, regardless of the error_action setting. With red_weight+green_weight<=100000, the normalized graylevel is computed: int rw = red_weight * 65536; int gw = green_weight * 65536; int bw = 65536 - (rw + gw); gray = (rw*red + gw*green + bw*blue)/65536; The default values approximate those recommended in the Charles Poynton's Color FAQ, Copyright (c) 1998-01-04 Charles Poynton Y = 0.212671 * R + 0.715160 * G + 0.072169 * B Libpng approximates this with Y = 0.21268 * R + 0.7151 * G + 0.07217 * B which can be expressed with integers as Y = (6969 * R + 23434 * G + 2365 * B)/32768 The calculation is done in a linear colorspace, if the image gamma is known. If you have a grayscale and you are using png_set_expand_depth(), png_set_expand(), or png_set_gray_to_rgb to change to truecolor or to a higher bit-depth, you must either supply the background color as a gray value at the original file bit-depth (need_expand = 1) or else supply the background color as an RGB triplet at the final, expanded bit depth (need_expand = 0). Similarly, if you are reading a paletted image, you must either supply the background color as a palette index (need_expand = 1) or as an RGB triplet that may or may not be in the palette (need_expand = 0). png_color_16 my_background; png_color_16p image_background; if (png_get_bKGD(png_ptr, info_ptr, &image_background)) png_set_background(png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); else png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); The png_set_background() function tells libpng to composite images with alpha or simple transparency against the supplied background color. If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid), you may use this color, or supply another color more suitable for the current display (e.g., the background color from a web page). You need to tell libpng whether the color is in the gamma space of the display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file (PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't know why anyone would use this, but it's here). To properly display PNG images on any kind of system, the application needs to know what the display gamma is. Ideally, the user will know this, and the application will allow them to set it. One method of allowing the user to set the display gamma separately for each system is to check for a SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be correctly set. Note that display_gamma is the overall gamma correction required to produce pleasing results, which depends on the lighting conditions in the surrounding environment. In a dim or brightly lit room, no compensation other than the physical gamma exponent of the monitor is needed, while in a dark room a slightly smaller exponent is better. double gamma, screen_gamma; if (/* We have a user-defined screen gamma value */) { screen_gamma = user_defined_screen_gamma; } /* One way that applications can share the same screen gamma value */ else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL) { screen_gamma = (double)atof(gamma_str); } /* If we don't have another value */ else { screen_gamma = 2.2; /* A good guess for a PC monitor in a bright office or a dim room */ screen_gamma = 2.0; /* A good guess for a PC monitor in a dark room */ screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */ } The png_set_gamma() function handles gamma transformations of the data. Pass both the file gamma and the current screen_gamma. If the file does not have a gamma value, you can pass one anyway if you have an idea what it is (usually 0.45455 is a good guess for GIF images on PCs). Note that file gammas are inverted from screen gammas. See the discussions on gamma in the PNG specification for an excellent description of what gamma is, and why all applications should support it. It is strongly recommended that PNG viewers support gamma correction. if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, screen_gamma, gamma); else png_set_gamma(png_ptr, screen_gamma, 0.45455); If you need to reduce an RGB file to a paletted file, or if a paletted file has more entries then will fit on your screen, png_set_dither() will do that. Note that this is a simple match dither that merely finds the closest color available. This should work fairly well with optimized palettes, and fairly badly with linear color cubes. If you pass a palette that is larger then maximum_colors, the file will reduce the number of colors in the palette so it will fit into maximum_colors. If there is a histogram, it will use it to make more intelligent choices when reducing the palette. If there is no histogram, it may not do as good a job. if (color_type & PNG_COLOR_MASK_COLOR) { if (png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) { png_uint_16p histogram = NULL; png_get_hIST(png_ptr, info_ptr, &histogram); png_set_dither(png_ptr, palette, num_palette, max_screen_colors, histogram, 1); } else { png_color std_color_cube[MAX_SCREEN_COLORS] = { ... colors ... }; png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS, MAX_SCREEN_COLORS, NULL,0); } } PNG files describe monochrome as black being zero and white being one. The following code will reverse this (make black be one and white be zero): if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY) png_set_invert_mono(png_ptr); This function can also be used to invert grayscale and gray-alpha images: if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_invert_mono(png_ptr); PNG files store 16 bit pixels in network byte order (big-endian, ie. most significant bits first). This code changes the storage to the other way (little-endian, i.e. least significant bits first, the way PCs store them): if (bit_depth == 16) png_set_swap(png_ptr); If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you need to change the order the pixels are packed into bytes, you can use: if (bit_depth < 8) png_set_packswap(png_ptr); Finally, you can write your own transformation function if none of the existing ones meets your needs. This is done by setting a callback with png_set_read_user_transform_fn(png_ptr, read_transform_fn); You must supply the function void read_transform_fn(png_ptr ptr, row_info_ptr row_info, png_bytep data) See pngtest.c for a working example. Your function will be called after all of the other transformations have been processed. You can also set up a pointer to a user structure for use by your callback function, and you can inform libpng that your transform function will change the number of channels or bit depth with the function png_set_user_transform_info(png_ptr, user_ptr, user_depth, user_channels); The user's application, not libpng, is responsible for allocating and freeing any memory required for the user structure. You can retrieve the pointer via the function png_get_user_transform_ptr(). For example: voidp read_user_transform_ptr = png_get_user_transform_ptr(png_ptr); The last thing to handle is interlacing; this is covered in detail below, but you must call the function here if you want libpng to handle expansion of the interlaced image. number_of_passes = png_set_interlace_handling(png_ptr); After setting the transformations, libpng can update your png_info structure to reflect any transformations you've requested with this call. This is most useful to update the info structure's rowbytes field so you can use it to allocate your image memory. This function will also update your palette with the correct screen_gamma and background if these have been given with the calls above. png_read_update_info(png_ptr, info_ptr); After you call png_read_update_info(), you can allocate any memory you need to hold the image. The row data is simply raw byte data for all forms of images. As the actual allocation varies among applications, no example will be given. If you are allocating one large chunk, you will need to build an array of pointers to each row, as it will be needed for some of the functions below. .SS Reading image data After you've allocated memory, you can read the image data. The simplest way to do this is in one function call. If you are allocating enough memory to hold the whole image, you can just call png_read_image() and libpng will read in all the image data and put it in the memory area supplied. You will need to pass in an array of pointers to each row. This function automatically handles interlacing, so you don't need to call png_set_interlace_handling() or call this function multiple times, or any of that other stuff necessary with png_read_rows(). png_read_image(png_ptr, row_pointers); where row_pointers is: png_bytep row_pointers[height]; You can point to void or char or whatever you use for pixels. If you don't want to read in the whole image at once, you can use png_read_rows() instead. If there is no interlacing (check interlace_type == PNG_INTERLACE_NONE), this is simple: png_read_rows(png_ptr, row_pointers, NULL, number_of_rows); where row_pointers is the same as in the png_read_image() call. If you are doing this just one row at a time, you can do this with a single row_pointer instead of an array of row_pointers: png_bytep row_pointer = row; png_read_row(png_ptr, row_pointer, NULL); If the file is interlaced (interlace_type != 0 in the IHDR chunk), things get somewhat harder. The only current (PNG Specification version 1.2) interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7) is a somewhat complicated 2D interlace scheme, known as Adam7, that breaks down an image into seven smaller images of varying size, based on an 8x8 grid. libpng can fill out those images or it can give them to you "as is". If you want them filled out, there are two ways to do that. The one mentioned in the PNG specification is to expand each pixel to cover those pixels that have not been read yet (the "rectangle" method). This results in a blocky image for the first pass, which gradually smooths out as more pixels are read. The other method is the "sparkle" method, where pixels are drawn only in their final locations, with the rest of the image remaining whatever colors they were initialized to before the start of the read. The first method usually looks better, but tends to be slower, as there are more pixels to put in the rows. If you don't want libpng to handle the interlacing details, just call png_read_rows() seven times to read in all seven images. Each of the images is a valid image by itself, or they can all be combined on an 8x8 grid to form a single image (although if you intend to combine them you would be far better off using the libpng interlace handling). The first pass will return an image 1/8 as wide as the entire image (every 8th column starting in column 0) and 1/8 as high as the original (every 8th row starting in row 0), the second will be 1/8 as wide (starting in column 4) and 1/8 as high (also starting in row 0). The third pass will be 1/4 as wide (every 4th pixel starting in column 0) and 1/8 as high (every 8th row starting in row 4), and the fourth pass will be 1/4 as wide and 1/4 as high (every 4th column starting in column 2, and every 4th row starting in row 0). The fifth pass will return an image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2), while the sixth pass will be 1/2 as wide and 1/2 as high as the original (starting in column 1 and row 0). The seventh and final pass will be as wide as the original, and 1/2 as high, containing all of the odd numbered scanlines. Phew! If you want libpng to expand the images, call this before calling png_start_read_image() or png_read_update_info(): if (interlace_type == PNG_INTERLACE_ADAM7) number_of_passes = png_set_interlace_handling(png_ptr); This will return the number of passes needed. Currently, this is seven, but may change if another interlace type is added. This function can be called even if the file is not interlaced, where it will return one pass. If you are not going to display the image after each pass, but are going to wait until the entire image is read in, use the sparkle effect. This effect is faster and the end result of either method is exactly the same. If you are planning on displaying the image after each pass, the "rectangle" effect is generally considered the better looking one. If you only want the "sparkle" effect, just call png_read_rows() as normal, with the third parameter NULL. Make sure you make pass over the image number_of_passes times, and you don't change the data in the rows between calls. You can change the locations of the data, just not the data. Each pass only writes the pixels appropriate for that pass, and assumes the data from previous passes is still valid. png_read_rows(png_ptr, row_pointers, NULL, number_of_rows); If you only want the first effect (the rectangles), do the same as before except pass the row buffer in the third parameter, and leave the second parameter NULL. png_read_rows(png_ptr, NULL, row_pointers, number_of_rows); .SS Finishing a sequential read After you are finished reading the image through either the high- or low-level interfaces, you can finish reading the file. If you are interested in comments or time, which may be stored either before or after the image data, you should pass the separate png_info struct if you want to keep the comments from before and after the image separate. If you are not interested, you can pass NULL. png_read_end(png_ptr, end_info); When you are done, you can free all memory allocated by libpng like this: png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); It is also possible to individually free the info_ptr members that point to libpng-allocated storage with the following function: png_free_data(png_ptr, info_ptr, mask, seq) mask - identifies data to be freed, a mask containing the logical OR of one or more of PNG_FREE_PLTE, PNG_FREE_TRNS, PNG_FREE_HIST, PNG_FREE_ICCP, PNG_FREE_PCAL, PNG_FREE_ROWS, PNG_FREE_SCAL, PNG_FREE_SPLT, PNG_FREE_TEXT, PNG_FREE_UNKN, or simply PNG_FREE_ALL seq - sequence number of item to be freed (-1 for all items) This function may be safely called when the relevant storage has already been freed, or has not yet been allocated, or was allocated by the user and not by libpng, and will in those cases do nothing. The "seq" parameter is ignored if only one item of the selected data type, such as PLTE, is allowed. If "seq" is not -1, and multiple items are allowed for the data type identified in the mask, such as text or sPLT, only the n'th item in the structure is freed, where n is "seq". The default behavior is only to free data that was allocated internally by libpng. This can be changed, so that libpng will not free the data, or so that it will free data that was allocated by the user with png_malloc() or png_zalloc() and passed in via a png_set_*() function, with png_data_freer(png_ptr, info_ptr, freer, mask) mask - which data elements are affected same choices as in png_free_data() freer - one of PNG_DESTROY_WILL_FREE_DATA PNG_SET_WILL_FREE_DATA PNG_USER_WILL_FREE_DATA This function only affects data that has already been allocated. You can call this function after reading the PNG data but before calling any png_set_*() functions, to control whether the user or the png_set_*() function is responsible for freeing any existing data that might be present, and again after the png_set_*() functions to control whether the user or png_destroy_*() is supposed to free the data. When the user assumes responsibility for libpng-allocated data, the application must use png_free() to free it, and when the user transfers responsibility to libpng for data that the user has allocated, the user must have used png_malloc() or png_zalloc() to allocate it. If you allocated your row_pointers in a single block, as suggested above in the description of the high level read interface, you must not transfer responsibility for freeing it to the png_set_rows or png_read_destroy function, because they would also try to free the individual row_pointers[i]. If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword separately, do not transfer responsibility for freeing text_ptr to libpng, because when libpng fills a png_text structure it combines these members with the key member, and png_free_data() will free only text_ptr.key. Similarly, if you transfer responsibility for free'ing text_ptr from libpng to your application, your application must not separately free those members. The png_free_data() function will turn off the "valid" flag for anything it frees. If you need to turn the flag off for a chunk that was freed by your application instead of by libpng, you can use png_set_invalid(png_ptr, info_ptr, mask); mask - identifies the chunks to be made invalid, containing the logical OR of one or more of PNG_INFO_gAMA, PNG_INFO_sBIT, PNG_INFO_cHRM, PNG_INFO_PLTE, PNG_INFO_tRNS, PNG_INFO_bKGD, PNG_INFO_hIST, PNG_INFO_pHYs, PNG_INFO_oFFs, PNG_INFO_tIME, PNG_INFO_pCAL, PNG_INFO_sRGB, PNG_INFO_iCCP, PNG_INFO_sPLT, PNG_INFO_sCAL, PNG_INFO_IDAT For a more compact example of reading a PNG image, see the file example.c. .SS Reading PNG files progressively The progressive reader is slightly different then the non-progressive reader. Instead of calling png_read_info(), png_read_rows(), and png_read_end(), you make one call to png_process_data(), which calls callbacks when it has the info, a row, or the end of the image. You set up these callbacks with png_set_progressive_read_fn(). You don't have to worry about the input/output functions of libpng, as you are giving the library the data directly in png_process_data(). I will assume that you have read the section on reading PNG files above, so I will only highlight the differences (although I will show all of the code). png_structp png_ptr; png_infop info_ptr; /* An example code fragment of how you would initialize the progressive reader in your application. */ int initialize_png_reader() { png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn); if (!png_ptr) return (ERROR); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return (ERROR); } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return (ERROR); } /* This one's new. You can provide functions to be called when the header info is valid, when each row is completed, and when the image is finished. If you aren't using all functions, you can specify NULL parameters. Even when all three functions are NULL, you need to call png_set_progressive_read_fn(). You can use any struct as the user_ptr (cast to a void pointer for the function call), and retrieve the pointer from inside the callbacks using the function png_get_progressive_ptr(png_ptr); which will return a void pointer, which you have to cast appropriately. */ png_set_progressive_read_fn(png_ptr, (void *)user_ptr, info_callback, row_callback, end_callback); return 0; } /* A code fragment that you call as you receive blocks of data */ int process_data(png_bytep buffer, png_uint_32 length) { if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return (ERROR); } /* This one's new also. Simply give it a chunk of data from the file stream (in order, of course). On machines with segmented memory models machines, don't give it any more than 64K. The library seems to run fine with sizes of 4K. Although you can give it much less if necessary (I assume you can give it chunks of 1 byte, I haven't tried less then 256 bytes yet). When this function returns, you may want to display any rows that were generated in the row callback if you don't already do so there. */ png_process_data(png_ptr, info_ptr, buffer, length); return 0; } /* This function is called (as set by png_set_progressive_read_fn() above) when enough data has been supplied so all of the header has been read. */ void info_callback(png_structp png_ptr, png_infop info) { /* Do any setup here, including setting any of the transformations mentioned in the Reading PNG files section. For now, you _must_ call either png_start_read_image() or png_read_update_info() after all the transformations are set (even if you don't set any). You may start getting rows before png_process_data() returns, so this is your last chance to prepare for that. */ } /* This function is called when each row of image data is complete */ void row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass) { /* If the image is interlaced, and you turned on the interlace handler, this function will be called for every row in every pass. Some of these rows will not be changed from the previous pass. When the row is not changed, the new_row variable will be NULL. The rows and passes are called in order, so you don't really need the row_num and pass, but I'm supplying them because it may make your life easier. For the non-NULL rows of interlaced images, you must call png_progressive_combine_row() passing in the row and the old row. You can call this function for NULL rows (it will just return) and for non-interlaced images (it just does the memcpy for you) if it will make the code easier. Thus, you can just do this for all cases: */ png_progressive_combine_row(png_ptr, old_row, new_row); /* where old_row is what was displayed for previously for the row. Note that the first pass (pass == 0, really) will completely cover the old row, so the rows do not have to be initialized. After the first pass (and only for interlaced images), you will have to pass the current row, and the function will combine the old row and the new row. */ } void end_callback(png_structp png_ptr, png_infop info) { /* This function is called after the whole image has been read, including any chunks after the image (up to and including the IEND). You will usually have the same info chunk as you had in the header, although some data may have been added to the comments and time fields. Most people won't do much here, perhaps setting a flag that marks the image as finished. */ } .SH IV. Writing Much of this is very similar to reading. However, everything of importance is repeated here, so you won't have to constantly look back up in the reading section to understand writing. .SS Setup You will want to do the I/O initialization before you get into libpng, so if it doesn't work, you don't have anything to undo. If you are not using the standard I/O functions, you will need to replace them with custom writing functions. See the discussion under Customizing libpng. FILE *fp = fopen(file_name, "wb"); if (!fp) { return (ERROR); } Next, png_struct and png_info need to be allocated and initialized. As these can be both relatively large, you may not want to store these on the stack, unless you have stack space to spare. Of course, you will want to check if they return NULL. If you are also reading, you won't want to name your read structure and your write structure both "png_ptr"; you can call them anything you like, such as "read_ptr" and "write_ptr". Look at pngtest.c, for example. png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn); if (!png_ptr) return (ERROR); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return (ERROR); } If you want to use your own memory allocation routines, define PNG_USER_MEM_SUPPORTED and use png_create_write_struct_2() instead of png_create_write_struct(): png_structp png_ptr = png_create_write_struct_2 (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn, (png_voidp) user_mem_ptr, user_malloc_fn, user_free_fn); After you have these structures, you will need to set up the error handling. When libpng encounters an error, it expects to longjmp() back to your routine. Therefore, you will need to call setjmp() and pass the png_jmpbuf(png_ptr). If you write the file from different routines, you will need to update the png_jmpbuf(png_ptr) every time you enter a new routine that will call a png_*() function. See your documentation of setjmp/longjmp for your compiler for more information on setjmp/longjmp. See the discussion on libpng error handling in the Customizing Libpng section below for more information on the libpng error handling. if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return (ERROR); } ... return; If you would rather avoid the complexity of setjmp/longjmp issues, you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case errors will result in a call to PNG_ABORT() which defaults to abort(). Now you need to set up the output code. The default for libpng is to use the C function fwrite(). If you use this, you will need to pass a valid FILE * in the function png_init_io(). Be sure that the file is opened in binary mode. Again, if you wish to handle writing data in another way, see the discussion on libpng I/O handling in the Customizing Libpng section below. png_init_io(png_ptr, fp); .SS Write callbacks At this point, you can set up a callback function that will be called after each row has been written, which you can use to control a progress meter or the like. It's demonstrated in pngtest.c. You must supply a function void write_row_callback(png_ptr, png_uint_32 row, int pass); { /* put your code here */ } (You can give it another name that you like instead of "write_row_callback") To inform libpng about your function, use png_set_write_status_fn(png_ptr, write_row_callback); You now have the option of modifying how the compression library will run. The following functions are mainly for testing, but may be useful in some cases, like if you need to write PNG files extremely fast and are willing to give up some compression, or if you want to get the maximum possible compression at the expense of slower writing. If you have no special needs in this area, let the library do what it wants by not calling this function at all, as it has been tuned to deliver a good speed/compression ratio. The second parameter to png_set_filter() is the filter method, for which the only valid values are 0 (as of the July 1999 PNG specification, version 1.2) or 64 (if you are writing a PNG datastream that is to be embedded in a MNG datastream). The third parameter is a flag that indicates which filter type(s) are to be tested for each scanline. See the PNG specification for details on the specific filter types. /* turn on or off filtering, and/or choose specific filters. You can use either a single PNG_FILTER_VALUE_NAME or the logical OR of one or more PNG_FILTER_NAME masks. */ png_set_filter(png_ptr, 0, PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | PNG_FILTER_UP | PNG_FILTER_VALUE_UP | PNG_FILTER_AVE | PNG_FILTER_VALUE_AVE | PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH| PNG_ALL_FILTERS); If an application wants to start and stop using particular filters during compression, it should start out with all of the filters (to ensure that the previous row of pixels will be stored in case it's needed later), and then add and remove them after the start of compression. If you are writing a PNG datastream that is to be embedded in a MNG datastream, the second parameter can be either 0 or 64. The png_set_compression_*() functions interface to the zlib compression library, and should mostly be ignored unless you really know what you are doing. The only generally useful call is png_set_compression_level() which changes how much time zlib spends on trying to compress the image data. See the Compression Library (zlib.h and algorithm.txt, distributed with zlib) for details on the compression levels. /* set the zlib compression level */ png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); /* set other zlib parameters */ png_set_compression_mem_level(png_ptr, 8); png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY); png_set_compression_window_bits(png_ptr, 15); png_set_compression_method(png_ptr, 8); png_set_compression_buffer_size(png_ptr, 8192) extern PNG_EXPORT(void,png_set_zbuf_size) .SS Setting the contents of info for output You now need to fill in the png_info structure with all the data you wish to write before the actual image. Note that the only thing you are allowed to write after the image is the text chunks and the time chunk (as of PNG Specification 1.2, anyway). See png_write_end() and the latest PNG specification for more information on that. If you wish to write them before the image, fill them in now, and flag that data as being valid. If you want to wait until after the data, don't fill them until png_write_end(). For all the fields in png_info and their data types, see png.h. For explanations of what the fields contain, see the PNG specification. Some of the more important parts of the png_info are: png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type, compression_type, filter_method) width - holds the width of the image in pixels (up to 2^31). height - holds the height of the image in pixels (up to 2^31). bit_depth - holds the bit depth of one of the image channels. (valid values are 1, 2, 4, 8, 16 and depend also on the color_type. See also significant bits (sBIT) below). color_type - describes which color/alpha channels are present. PNG_COLOR_TYPE_GRAY (bit depths 1, 2, 4, 8, 16) PNG_COLOR_TYPE_GRAY_ALPHA (bit depths 8, 16) PNG_COLOR_TYPE_PALETTE (bit depths 1, 2, 4, 8) PNG_COLOR_TYPE_RGB (bit_depths 8, 16) PNG_COLOR_TYPE_RGB_ALPHA (bit_depths 8, 16) PNG_COLOR_MASK_PALETTE PNG_COLOR_MASK_COLOR PNG_COLOR_MASK_ALPHA interlace_type - PNG_INTERLACE_NONE or PNG_INTERLACE_ADAM7 compression_type - (must be PNG_COMPRESSION_TYPE_DEFAULT) filter_method - (must be PNG_FILTER_TYPE_DEFAULT or, if you are writing a PNG to be embedded in a MNG datastream, can also be PNG_INTRAPIXEL_DIFFERENCING) png_set_PLTE(png_ptr, info_ptr, palette, num_palette); palette - the palette for the file (array of png_color) num_palette - number of entries in the palette png_set_gAMA(png_ptr, info_ptr, gamma); gamma - the gamma the image was created at (PNG_INFO_gAMA) png_set_sRGB(png_ptr, info_ptr, srgb_intent); srgb_intent - the rendering intent (PNG_INFO_sRGB) The presence of the sRGB chunk means that the pixel data is in the sRGB color space. This chunk also implies specific values of gAMA and cHRM. Rendering intent is the CSS-1 property that has been defined by the International Color Consortium (http://www.color.org). It can be one of PNG_sRGB_INTENT_SATURATION, PNG_sRGB_INTENT_PERCEPTUAL, PNG_sRGB_INTENT_ABSOLUTE, or PNG_sRGB_INTENT_RELATIVE. png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, srgb_intent); srgb_intent - the rendering intent (PNG_INFO_sRGB) The presence of the sRGB chunk means that the pixel data is in the sRGB color space. This function also causes gAMA and cHRM chunks with the specific values that are consistent with sRGB to be written. png_set_iCCP(png_ptr, info_ptr, name, compression_type, profile, proflen); name - The profile name. compression - The compression type; always PNG_COMPRESSION_TYPE_BASE for PNG 1.0. You may give NULL to this argument to ignore it. profile - International Color Consortium color profile data. May contain NULs. proflen - length of profile data in bytes. png_set_sBIT(png_ptr, info_ptr, sig_bit); sig_bit - the number of significant bits for (PNG_INFO_sBIT) each of the gray, red, green, and blue channels, whichever are appropriate for the given color type (png_color_16) png_set_tRNS(png_ptr, info_ptr, trans, num_trans, trans_values); trans - array of transparent entries for palette (PNG_INFO_tRNS) trans_values - graylevel or color sample values of the single transparent color for non-paletted images (PNG_INFO_tRNS) num_trans - number of transparent entries (PNG_INFO_tRNS) png_set_hIST(png_ptr, info_ptr, hist); (PNG_INFO_hIST) hist - histogram of palette (array of png_uint_16) png_set_tIME(png_ptr, info_ptr, mod_time); mod_time - time image was last modified (PNG_VALID_tIME) png_set_bKGD(png_ptr, info_ptr, background); background - background color (PNG_VALID_bKGD) png_set_text(png_ptr, info_ptr, text_ptr, num_text); text_ptr - array of png_text holding image comments text_ptr[i].compression - type of compression used on "text" PNG_TEXT_COMPRESSION_NONE PNG_TEXT_COMPRESSION_zTXt PNG_ITXT_COMPRESSION_NONE PNG_ITXT_COMPRESSION_zTXt text_ptr[i].key - keyword for comment. Must contain 1-79 characters. text_ptr[i].text - text comments for current keyword. Can be NULL or empty. text_ptr[i].text_length - length of text string, after decompression, 0 for iTXt text_ptr[i].itxt_length - length of itxt string, after decompression, 0 for tEXt/zTXt text_ptr[i].lang - language of comment (NULL or empty for unknown). text_ptr[i].translated_keyword - keyword in UTF-8 (NULL or empty for unknown). num_text - number of comments png_set_sPLT(png_ptr, info_ptr, &palette_ptr, num_spalettes); palette_ptr - array of png_sPLT_struct structures to be added to the list of palettes in the info structure. num_spalettes - number of palette structures to be added. png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); offset_x - positive offset from the left edge of the screen offset_y - positive offset from the top edge of the screen unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); res_x - pixels/unit physical resolution in x direction res_y - pixels/unit physical resolution in y direction unit_type - PNG_RESOLUTION_UNKNOWN, PNG_RESOLUTION_METER png_set_sCAL(png_ptr, info_ptr, unit, width, height) unit - physical scale units (an integer) width - width of a pixel in physical scale units height - height of a pixel in physical scale units (width and height are doubles) png_set_sCAL_s(png_ptr, info_ptr, unit, width, height) unit - physical scale units (an integer) width - width of a pixel in physical scale units height - height of a pixel in physical scale units (width and height are strings like "2.54") png_set_unknown_chunks(png_ptr, info_ptr, &unknowns, num_unknowns) unknowns - array of png_unknown_chunk structures holding unknown chunks unknowns[i].name - name of unknown chunk unknowns[i].data - data of unknown chunk unknowns[i].size - size of unknown chunk's data unknowns[i].location - position to write chunk in file 0: do not write chunk PNG_HAVE_IHDR: before PLTE PNG_HAVE_PLTE: before IDAT PNG_AFTER_IDAT: after IDAT The "location" member is set automatically according to what part of the output file has already been written. You can change its value after calling png_set_unknown_chunks() as demonstrated in pngtest.c. Within each of the "locations", the chunks are sequenced according to their position in the structure (that is, the value of "i", which is the order in which the chunk was either read from the input file or defined with png_set_unknown_chunks). A quick word about text and num_text. text is an array of png_text structures. num_text is the number of valid structures in the array. Each png_text structure holds a language code, a keyword, a text value, and a compression type. The compression types have the same valid numbers as the compression types of the image data. Currently, the only valid number is zero. However, you can store text either compressed or uncompressed, unlike images, which always have to be compressed. So if you don't want the text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE. Because tEXt and zTXt chunks don't have a language field, if you specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt any language code or translated keyword will not be written out. Until text gets around 1000 bytes, it is not worth compressing it. After the text has been written out to the file, the compression type is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR, so that it isn't written out again at the end (in case you are calling png_write_end() with the same struct. The keywords that are given in the PNG Specification are: Title Short (one line) title or caption for image Author Name of image's creator Description Description of image (possibly long) Copyright Copyright notice Creation Time Time of original image creation (usually RFC 1123 format, see below) Software Software used to create the image Disclaimer Legal disclaimer Warning Warning of nature of content Source Device used to create the image Comment Miscellaneous comment; conversion from other image format The keyword-text pairs work like this. Keywords should be short simple descriptions of what the comment is about. Some typical keywords are found in the PNG specification, as is some recommendations on keywords. You can repeat keywords in a file. You can even write some text before the image and some after. For example, you may want to put a description of the image before the image, but leave the disclaimer until after, so viewers working over modem connections don't have to wait for the disclaimer to go over the modem before they start seeing the image. Finally, keywords should be full words, not abbreviations. Keywords and text are in the ISO 8859-1 (Latin-1) character set (a superset of regular ASCII) and can not contain NUL characters, and should not contain control or other unprintable characters. To make the comments widely readable, stick with basic ASCII, and avoid machine specific character set extensions like the IBM-PC character set. The keyword must be present, but you can leave off the text string on non-compressed pairs. Compressed pairs must have a text string, as only the text string is compressed anyway, so the compression would be meaningless. PNG supports modification time via the png_time structure. Two conversion routines are provided, png_convert_from_time_t() for time_t and png_convert_from_struct_tm() for struct tm. The time_t routine uses gmtime(). You don't have to use either of these, but if you wish to fill in the png_time structure directly, you should provide the time in universal time (GMT) if possible instead of your local time. Note that the year number is the full year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and that months start with 1. If you want to store the time of the original image creation, you should use a plain tEXt chunk with the "Creation Time" keyword. This is necessary because the "creation time" of a PNG image is somewhat vague, depending on whether you mean the PNG file, the time the image was created in a non-PNG format, a still photo from which the image was scanned, or possibly the subject matter itself. In order to facilitate machine-readable dates, it is recommended that the "Creation Time" tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"), although this isn't a requirement. Unlike the tIME chunk, the "Creation Time" tEXt chunk is not expected to be automatically changed by the software. To facilitate the use of RFC 1123 dates, a function png_convert_to_rfc1123(png_timep) is provided to convert from PNG time to an RFC 1123 format string. .SS Writing unknown chunks You can use the png_set_unknown_chunks function to queue up chunks for writing. You give it a chunk name, raw data, and a size; that's all there is to it. The chunks will be written by the next following png_write_info_before_PLTE, png_write_info, or png_write_end function. Any chunks previously read into the info structure's unknown-chunk list will also be written out in a sequence that satisfies the PNG specification's ordering rules. .SS The high-level write interface At this point there are two ways to proceed; through the high-level write interface, or through a sequence of low-level write operations. You can use the high-level interface if your image data is present in the info structure. All defined output transformations are permitted, enabled by the following masks. PNG_TRANSFORM_IDENTITY No transformation PNG_TRANSFORM_PACKING Pack 1, 2 and 4-bit samples PNG_TRANSFORM_PACKSWAP Change order of packed pixels to LSB first PNG_TRANSFORM_INVERT_MONO Invert monochrome images PNG_TRANSFORM_SHIFT Normalize pixels to the sBIT depth PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA to BGRA PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA to AG PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity to transparency PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples PNG_TRANSFORM_STRIP_FILLER Strip out filler bytes. If you have valid image data in the info structure (you can use png_set_rows() to put image data in the info structure), simply do this: png_write_png(png_ptr, info_ptr, png_transforms, NULL) where png_transforms is an integer containing the logical OR of some set of transformation flags. This call is equivalent to png_write_info(), followed the set of transformations indicated by the transform mask, then png_write_image(), and finally png_write_end(). (The final parameter of this call is not yet used. Someday it might point to transformation parameters required by some future output transform.) You must use png_transforms and not call any png_set_transform() functions when you use png_write_png(). .SS The low-level write interface If you are going the low-level route instead, you are now ready to write all the file information up to the actual image data. You do this with a call to png_write_info(). png_write_info(png_ptr, info_ptr); Note that there is one transformation you may need to do before png_write_info(). In PNG files, the alpha channel in an image is the level of opacity. If your data is supplied as a level of transparency, you can invert the alpha channel before you write it, so that 0 is fully transparent and 255 (in 8-bit or paletted images) or 65535 (in 16-bit images) is fully opaque, with png_set_invert_alpha(png_ptr); This must appear before png_write_info() instead of later with the other transformations because in the case of paletted images the tRNS chunk data has to be inverted before the tRNS chunk is written. If your image is not a paletted image, the tRNS data (which in such cases represents a single color to be rendered as transparent) won't need to be changed, and you can safely do this transformation after your png_write_info() call. If you need to write a private chunk that you want to appear before the PLTE chunk when PLTE is present, you can write the PNG info in two steps, and insert code to write your own chunk between them: png_write_info_before_PLTE(png_ptr, info_ptr); png_set_unknown_chunks(png_ptr, info_ptr, ...); png_write_info(png_ptr, info_ptr); After you've written the file information, you can set up the library to handle any special transformations of the image data. The various ways to transform the data will be described in the order that they should occur. This is important, as some of these change the color type and/or bit depth of the data, and some others only work on certain color types and bit depths. Even though each transformation checks to see if it has data that it can do something with, you should make sure to only enable a transformation if it will be valid for the data. For example, don't swap red and blue on grayscale data. PNG files store RGB pixels packed into 3 or 6 bytes. This code tells the library to strip input data that has 4 or 8 bytes per pixel down to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2 bytes per pixel). png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); where the 0 is unused, and the location is either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel is stored XRGB or RGBX. PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as they can, resulting in, for example, 8 pixels per byte for 1 bit files. If the data is supplied at 1 pixel per byte, use this code, which will correctly pack the pixels into a single byte: png_set_packing(png_ptr); PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If your data is of another bit depth, you can write an sBIT chunk into the file so that decoders can recover the original data if desired. /* Set the true bit depth of the image data */ if (color_type & PNG_COLOR_MASK_COLOR) { sig_bit.red = true_bit_depth; sig_bit.green = true_bit_depth; sig_bit.blue = true_bit_depth; } else { sig_bit.gray = true_bit_depth; } if (color_type & PNG_COLOR_MASK_ALPHA) { sig_bit.alpha = true_bit_depth; } png_set_sBIT(png_ptr, info_ptr, &sig_bit); If the data is stored in the row buffer in a bit depth other than one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG), this will scale the values to appear to be the correct bit depth as is required by PNG. png_set_shift(png_ptr, &sig_bit); PNG files store 16 bit pixels in network byte order (big-endian, ie. most significant bits first). This code would be used if they are supplied the other way (little-endian, i.e. least significant bits first, the way PCs store them): if (bit_depth > 8) png_set_swap(png_ptr); If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you need to change the order the pixels are packed into bytes, you can use: if (bit_depth < 8) png_set_packswap(png_ptr); PNG files store 3 color pixels in red, green, blue order. This code would be used if they are supplied as blue, green, red: png_set_bgr(png_ptr); PNG files describe monochrome as black being zero and white being one. This code would be used if the pixels are supplied with this reversed (black being one and white being zero): png_set_invert_mono(png_ptr); Finally, you can write your own transformation function if none of the existing ones meets your needs. This is done by setting a callback with png_set_write_user_transform_fn(png_ptr, write_transform_fn); You must supply the function void write_transform_fn(png_ptr ptr, row_info_ptr row_info, png_bytep data) See pngtest.c for a working example. Your function will be called before any of the other transformations are processed. You can also set up a pointer to a user structure for use by your callback function. png_set_user_transform_info(png_ptr, user_ptr, 0, 0); The user_channels and user_depth parameters of this function are ignored when writing; you can set them to zero as shown. You can retrieve the pointer via the function png_get_user_transform_ptr(). For example: voidp write_user_transform_ptr = png_get_user_transform_ptr(png_ptr); It is possible to have libpng flush any pending output, either manually, or automatically after a certain number of lines have been written. To flush the output stream a single time call: png_write_flush(png_ptr); and to have libpng flush the output stream periodically after a certain number of scanlines have been written, call: png_set_flush(png_ptr, nrows); Note that the distance between rows is from the last time png_write_flush() was called, or the first row of the image if it has never been called. So if you write 50 lines, and then png_set_flush 25, it will flush the output on the next scanline, and every 25 lines thereafter, unless png_write_flush() is called before 25 more lines have been written. If nrows is too small (less than about 10 lines for a 640 pixel wide RGB image) the image compression may decrease noticeably (although this may be acceptable for real-time applications). Infrequent flushing will only degrade the compression performance by a few percent over images that do not use flushing. .SS Writing the image data That's it for the transformations. Now you can write the image data. The simplest way to do this is in one function call. If you have the whole image in memory, you can just call png_write_image() and libpng will write the image. You will need to pass in an array of pointers to each row. This function automatically handles interlacing, so you don't need to call png_set_interlace_handling() or call this function multiple times, or any of that other stuff necessary with png_write_rows(). png_write_image(png_ptr, row_pointers); where row_pointers is: png_byte *row_pointers[height]; You can point to void or char or whatever you use for pixels. If you don't want to write the whole image at once, you can use png_write_rows() instead. If the file is not interlaced, this is simple: png_write_rows(png_ptr, row_pointers, number_of_rows); row_pointers is the same as in the png_write_image() call. If you are just writing one row at a time, you can do this with a single row_pointer instead of an array of row_pointers: png_bytep row_pointer = row; png_write_row(png_ptr, row_pointer); When the file is interlaced, things can get a good deal more complicated. The only currently (as of the PNG Specification version 1.2, dated July 1999) defined interlacing scheme for PNG files is the "Adam7" interlace scheme, that breaks down an image into seven smaller images of varying size. libpng will build these images for you, or you can do them yourself. If you want to build them yourself, see the PNG specification for details of which pixels to write when. If you don't want libpng to handle the interlacing details, just use png_set_interlace_handling() and call png_write_rows() the correct number of times to write all seven sub-images. If you want libpng to build the sub-images, call this before you start writing any rows: number_of_passes = png_set_interlace_handling(png_ptr); This will return the number of passes needed. Currently, this is seven, but may change if another interlace type is added. Then write the complete image number_of_passes times. png_write_rows(png_ptr, row_pointers, number_of_rows); As some of these rows are not used, and thus return immediately, you may want to read about interlacing in the PNG specification, and only update the rows that are actually used. .SS Finishing a sequential write After you are finished writing the image, you should finish writing the file. If you are interested in writing comments or time, you should pass an appropriately filled png_info pointer. If you are not interested, you can pass NULL. png_write_end(png_ptr, info_ptr); When you are done, you can free all memory used by libpng like this: png_destroy_write_struct(&png_ptr, &info_ptr); It is also possible to individually free the info_ptr members that point to libpng-allocated storage with the following function: png_free_data(png_ptr, info_ptr, mask, seq) mask - identifies data to be freed, a mask containing the logical OR of one or more of PNG_FREE_PLTE, PNG_FREE_TRNS, PNG_FREE_HIST, PNG_FREE_ICCP, PNG_FREE_PCAL, PNG_FREE_ROWS, PNG_FREE_SCAL, PNG_FREE_SPLT, PNG_FREE_TEXT, PNG_FREE_UNKN, or simply PNG_FREE_ALL seq - sequence number of item to be freed (-1 for all items) This function may be safely called when the relevant storage has already been freed, or has not yet been allocated, or was allocated by the user and not by libpng, and will in those cases do nothing. The "seq" parameter is ignored if only one item of the selected data type, such as PLTE, is allowed. If "seq" is not -1, and multiple items are allowed for the data type identified in the mask, such as text or sPLT, only the n'th item in the structure is freed, where n is "seq". If you allocated data such as a palette that you passed in to libpng with png_set_*, you must not free it until just before the call to png_destroy_write_struct(). The default behavior is only to free data that was allocated internally by libpng. This can be changed, so that libpng will not free the data, or so that it will free data that was allocated by the user with png_malloc() or png_zalloc() and passed in via a png_set_*() function, with png_data_freer(png_ptr, info_ptr, freer, mask) mask - which data elements are affected same choices as in png_free_data() freer - one of PNG_DESTROY_WILL_FREE_DATA PNG_SET_WILL_FREE_DATA PNG_USER_WILL_FREE_DATA For example, to transfer responsibility for some data from a read structure to a write structure, you could use png_data_freer(read_ptr, read_info_ptr, PNG_USER_WILL_FREE_DATA, PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) png_data_freer(write_ptr, write_info_ptr, PNG_DESTROY_WILL_FREE_DATA, PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) thereby briefly reassigning responsibility for freeing to the user but immediately afterwards reassigning it once more to the write_destroy function. Having done this, it would then be safe to destroy the read structure and continue to use the PLTE, tRNS, and hIST data in the write structure. This function only affects data that has already been allocated. You can call this function before calling after the png_set_*() functions to control whether the user or png_destroy_*() is supposed to free the data. When the user assumes responsibility for libpng-allocated data, the application must use png_free() to free it, and when the user transfers responsibility to libpng for data that the user has allocated, the user must have used png_malloc() or png_zalloc() to allocate it. If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword separately, do not transfer responsibility for freeing text_ptr to libpng, because when libpng fills a png_text structure it combines these members with the key member, and png_free_data() will free only text_ptr.key. Similarly, if you transfer responsibility for free'ing text_ptr from libpng to your application, your application must not separately free those members. For a more compact example of writing a PNG image, see the file example.c. .SH V. Modifying/Customizing libpng: There are three issues here. The first is changing how libpng does standard things like memory allocation, input/output, and error handling. The second deals with more complicated things like adding new chunks, adding new transformations, and generally changing how libpng works. Both of those are compile-time issues; that is, they are generally determined at the time the code is written, and there is rarely a need to provide the user with a means of changing them. The third is a run-time issue: choosing between and/or tuning one or more alternate versions of computationally intensive routines; specifically, optimized assembly-language (and therefore compiler- and platform-dependent) versions. Memory allocation, input/output, and error handling All of the memory allocation, input/output, and error handling in libpng goes through callbacks that are user-settable. The default routines are in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively. To change these functions, call the appropriate png_set_*_fn() function. Memory allocation is done through the functions png_malloc() and png_free(). These currently just call the standard C functions. If your pointers can't access more then 64K at a time, you will want to set MAXSEG_64K in zlib.h. Since it is unlikely that the method of handling memory allocation on a platform will change between applications, these functions must be modified in the library at compile time. If you prefer to use a different method of allocating and freeing data, you can use png_create_read_struct_2() or png_create_write_struct_2() to register your own functions as described above. These functions also provide a void pointer that can be retrieved via mem_ptr=png_get_mem_ptr(png_ptr); Your replacement memory functions must have prototypes as follows: png_voidp malloc_fn(png_structp png_ptr, png_size_t size); void free_fn(png_structp png_ptr, png_voidp ptr); Your malloc_fn() must return NULL in case of failure. The png_malloc() function will normally call png_error() if it receives a NULL from the system memory allocator or from your replacement malloc_fn(). Input/Output in libpng is done through png_read() and png_write(), which currently just call fread() and fwrite(). The FILE * is stored in png_struct and is initialized via png_init_io(). If you wish to change the method of I/O, the library supplies callbacks that you can set through the function png_set_read_fn() and png_set_write_fn() at run time, instead of calling the png_init_io() function. These functions also provide a void pointer that can be retrieved via the function png_get_io_ptr(). For example: png_set_read_fn(png_structp read_ptr, voidp read_io_ptr, png_rw_ptr read_data_fn) png_set_write_fn(png_structp write_ptr, voidp write_io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn); voidp read_io_ptr = png_get_io_ptr(read_ptr); voidp write_io_ptr = png_get_io_ptr(write_ptr); The replacement I/O functions must have prototypes as follows: void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length); void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length); void user_flush_data(png_structp png_ptr); Supplying NULL for the read, write, or flush functions sets them back to using the default C stream functions. It is an error to read from a write stream, and vice versa. Error handling in libpng is done through png_error() and png_warning(). Errors handled through png_error() are fatal, meaning that png_error() should never return to its caller. Currently, this is handled via setjmp() and longjmp() (unless you have compiled libpng with PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()), but you could change this to do things like exit() if you should wish. On non-fatal errors, png_warning() is called to print a warning message, and then control returns to the calling code. By default png_error() and png_warning() print a message on stderr via fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined (because you don't want the messages) or PNG_NO_STDIO defined (because fprintf() isn't available). If you wish to change the behavior of the error functions, you will need to set up your own message callbacks. These functions are normally supplied at the time that the png_struct is created. It is also possible to redirect errors and warnings to your own replacement functions after png_create_*_struct() has been called by calling: png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn); png_voidp error_ptr = png_get_error_ptr(png_ptr); If NULL is supplied for either error_fn or warning_fn, then the libpng default function will be used, calling fprintf() and/or longjmp() if a problem is encountered. The replacement error functions should have parameters as follows: void user_error_fn(png_structp png_ptr, png_const_charp error_msg); void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg); The motivation behind using setjmp() and longjmp() is the C++ throw and catch exception handling methods. This makes the code much easier to write, as there is no need to check every return code of every function call. However, there are some uncertainties about the status of local variables after a longjmp, so the user may want to be careful about doing anything after setjmp returns non-zero besides returning itself. Consult your compiler documentation for more details. For an alternative approach, you may wish to use the "cexcept" facility (see http://cexcept.sourceforge.net). .SS Custom chunks If you need to read or write custom chunks, you may need to get deeper into the libpng code. The library now has mechanisms for storing and writing chunks of unknown type; you can even declare callbacks for custom chunks. Hoewver, this may not be good enough if the library code itself needs to know about interactions between your chunk and existing `intrinsic' chunks. If you need to write a new intrinsic chunk, first read the PNG specification. Acquire a first level of understanding of how it works. Pay particular attention to the sections that describe chunk names, and look at how other chunks were designed, so you can do things similarly. Second, check out the sections of libpng that read and write chunks. Try to find a chunk that is similar to yours and use it as a template. More details can be found in the comments inside the code. It is best to handle unknown chunks in a generic method, via callback functions, instead of by modifying libpng functions. If you wish to write your own transformation for the data, look through the part of the code that does the transformations, and check out some of the simpler ones to get an idea of how they work. Try to find a similar transformation to the one you want to add and copy off of it. More details can be found in the comments inside the code itself. .SS Configuring for 16 bit platforms You will want to look into zconf.h to tell zlib (and thus libpng) that it cannot allocate more then 64K at a time. Even if you can, the memory won't be accessible. So limit zlib and libpng to 64K by defining MAXSEG_64K. .SS Configuring for DOS For DOS users who only have access to the lower 640K, you will have to limit zlib's memory usage via a png_set_compression_mem_level() call. See zlib.h or zconf.h in the zlib library for more information. .SS Configuring for Medium Model Libpng's support for medium model has been tested on most of the popular compilers. Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets defined, and FAR gets defined to far in pngconf.h, and you should be all set. Everything in the library (except for zlib's structure) is expecting far data. You must use the typedefs with the p or pp on the end for pointers (or at least look at them and be careful). Make note that the rows of data are defined as png_bytepp, which is an unsigned char far * far *. .SS Configuring for gui/windowing platforms: You will need to write new error and warning functions that use the GUI interface, as described previously, and set them to be the error and warning functions at the time that png_create_*_struct() is called, in order to have them available during the structure initialization. They can be changed later via png_set_error_fn(). On some compilers, you may also have to change the memory allocators (png_malloc, etc.). .SS Configuring for compiler xxx: All includes for libpng are in pngconf.h. If you need to add/change/delete an include, this is the place to do it. The includes that are not needed outside libpng are protected by the PNG_INTERNAL definition, which is only defined for those routines inside libpng itself. The files in libpng proper only include png.h, which includes pngconf.h. .SS Configuring zlib: There are special functions to configure the compression. Perhaps the most useful one changes the compression level, which currently uses input compression values in the range 0 - 9. The library normally uses the default compression level (Z_DEFAULT_COMPRESSION = 6). Tests have shown that for a large majority of images, compression values in the range 3-6 compress nearly as well as higher levels, and do so much faster. For online applications it may be desirable to have maximum speed (Z_BEST_SPEED = 1). With versions of zlib after v0.99, you can also specify no compression (Z_NO_COMPRESSION = 0), but this would create files larger than just storing the raw bitmap. You can specify the compression level by calling: png_set_compression_level(png_ptr, level); Another useful one is to reduce the memory level used by the library. The memory level defaults to 8, but it can be lowered if you are short on memory (running DOS, for example, where you only have 640K). Note that the memory level does have an effect on compression; among other things, lower levels will result in sections of incompressible data being emitted in smaller stored blocks, with a correspondingly larger relative overhead of up to 15% in the worst case. png_set_compression_mem_level(png_ptr, level); The other functions are for configuring zlib. They are not recommended for normal use and may result in writing an invalid PNG file. See zlib.h for more information on what these mean. png_set_compression_strategy(png_ptr, strategy); png_set_compression_window_bits(png_ptr, window_bits); png_set_compression_method(png_ptr, method); png_set_compression_buffer_size(png_ptr, size); .SS Controlling row filtering If you want to control whether libpng uses filtering or not, which filters are used, and how it goes about picking row filters, you can call one of these functions. The selection and configuration of row filters can have a significant impact on the size and encoding speed and a somewhat lesser impact on the decoding speed of an image. Filtering is enabled by default for RGB and grayscale images (with and without alpha), but not for paletted images nor for any images with bit depths less than 8 bits/pixel. The 'method' parameter sets the main filtering method, which is currently only '0' in the PNG 1.2 specification. The 'filters' parameter sets which filter(s), if any, should be used for each scanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS to turn filtering on and off, respectively. Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB, PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise ORed together with '|' to specify one or more filters to use. These filters are described in more detail in the PNG specification. If you intend to change the filter type during the course of writing the image, you should start with flags set for all of the filters you intend to use so that libpng can initialize its internal structures appropriately for all of the filter types. (Note that this means the first row must always be adaptively filtered, because libpng currently does not allocate the filter buffers until png_write_row() is called for the first time.) filters = PNG_FILTER_NONE | PNG_FILTER_SUB PNG_FILTER_UP | PNG_FILTER_AVE | PNG_FILTER_PAETH | PNG_ALL_FILTERS; png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, filters); The second parameter can also be PNG_INTRAPIXEL_DIFFERENCING if you are writing a PNG to be embedded in a MNG datastream. This parameter must be the same as the value of filter_method used in png_set_IHDR(). It is also possible to influence how libpng chooses from among the available filters. This is done in one or both of two ways - by telling it how important it is to keep the same filter for successive rows, and by telling it the relative computational costs of the filters. double weights[3] = {1.5, 1.3, 1.1}, costs[PNG_FILTER_VALUE_LAST] = {1.0, 1.3, 1.3, 1.5, 1.7}; png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_WEIGHTED, 3, weights, costs); The weights are multiplying factors that indicate to libpng that the row filter should be the same for successive rows unless another row filter is that many times better than the previous filter. In the above example, if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a "sum of absolute differences" 1.5 x 1.3 times higher than other filters and still be chosen, while the NONE filter could have a sum 1.1 times higher than other filters and still be chosen. Unspecified weights are taken to be 1.0, and the specified weights should probably be declining like those above in order to emphasize recent filters over older filters. The filter costs specify for each filter type a relative decoding cost to be considered when selecting row filters. This means that filters with higher costs are less likely to be chosen over filters with lower costs, unless their "sum of absolute differences" is that much smaller. The costs do not necessarily reflect the exact computational speeds of the various filters, since this would unduly influence the final image size. Note that the numbers above were invented purely for this example and are given only to help explain the function usage. Little testing has been done to find optimum values for either the costs or the weights. .SS Removing unwanted object code There are a bunch of #define's in pngconf.h that control what parts of libpng are compiled. All the defines end in _SUPPORTED. If you are never going to use a capability, you can change the #define to #undef before recompiling libpng and save yourself code and data space, or you can turn off individual capabilities with defines that begin with PNG_NO_. You can also turn all of the transforms and ancillary chunk capabilities off en masse with compiler directives that define PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS, or all four, along with directives to turn on any of the capabilities that you do want. The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable the extra transformations but still leave the library fully capable of reading and writing PNG files with all known public chunks Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive produces a library that is incapable of reading or writing ancillary chunks. If you are not using the progressive reading capability, you can turn that off with PNG_NO_PROGRESSIVE_READ (don't confuse this with the INTERLACING capability, which you'll still have). All the reading and writing specific code are in separate files, so the linker should only grab the files it needs. However, if you want to make sure, or if you are building a stand alone library, all the reading files start with pngr and all the writing files start with pngw. The files that don't match either (like png.c, pngtrans.c, etc.) are used for both reading and writing, and always need to be included. The progressive reader is in pngpread.c If you are creating or distributing a dynamically linked library (a .so or DLL file), you should not remove or disable any parts of the library, as this will cause applications linked with different versions of the library to fail if they call functions not available in your library. The size of the library itself should not be an issue, because only those sections that are actually used will be loaded into memory. .SS Requesting debug printout The macro definition PNG_DEBUG can be used to request debugging printout. Set it to an integer value in the range 0 to 3. Higher numbers result in increasing amounts of debugging information. The information is printed to the "stderr" file, unless another file name is specified in the PNG_DEBUG_FILE macro definition. When PNG_DEBUG > 0, the following functions (macros) become available: png_debug(level, message) png_debug1(level, message, p1) png_debug2(level, message, p1, p2) in which "level" is compared to PNG_DEBUG to decide whether to print the message, "message" is the formatted string to be printed, and p1 and p2 are parameters that are to be embedded in the string according to printf-style formatting directives. For example, png_debug1(2, "foo=%d\n", foo); is expanded to if(PNG_DEBUG > 2) fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo); When PNG_DEBUG is defined but is zero, the macros aren't defined, but you can still use PNG_DEBUG to control your own debugging: #ifdef PNG_DEBUG fprintf(stderr, ... #endif When PNG_DEBUG = 1, the macros are defined, but only png_debug statements having level = 0 will be printed. There aren't any such statements in this version of libpng, but if you insert some they will be printed. .SH VI. Runtime optimization A new feature in libpng 1.2.0 is the ability to dynamically switch between standard and optimized versions of some routines. Currently these are limited to three computationally intensive tasks when reading PNG files: decoding row filters, expanding interlacing, and combining interlaced or transparent row data with previous row data. Currently the optimized versions are available only for x86 (Intel, AMD, etc.) platforms with MMX support, though this may change in future versions. (For example, the non-MMX assembler optimizations for zlib might become similarly runtime-selectable in future releases, in which case libpng could be extended to support them. Alternatively, the compile-time choice of floating-point versus integer routines for gamma correction might become runtime-selectable.) Because such optimizations tend to be very platform- and compiler-dependent, both in how they are written and in how they perform, the new runtime code in libpng has been written to allow programs to query, enable, and disable either specific optimizations or all such optimizations. For example, to enable all possible optimizations (bearing in mind that some "optimizations" may actually run more slowly in rare cases): #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) png_uint_32 mask, flags; flags = png_get_asm_flags(png_ptr); mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); png_set_asm_flags(png_ptr, flags | mask); #endif To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ by itself when calling png_get_asm_flagmask(); similarly for optimizing only writing. To disable all optimizations: #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) flags = png_get_asm_flags(png_ptr); mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); png_set_asm_flags(png_ptr, flags & ~mask); #endif To enable or disable only MMX-related features, use png_get_mmx_flagmask() in place of png_get_asm_flagmask(). The mmx version takes one additional parameter: #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) int selection = PNG_SELECT_READ | PNG_SELECT_WRITE; int compilerID; mask = png_get_mmx_flagmask(selection, &compilerID); #endif On return, compilerID will indicate which version of the MMX assembler optimizations was compiled. Currently two flavors exist: Microsoft Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2). On non-x86 platforms or on systems compiled without MMX optimizations, a value of -1 is used. Note that both png_get_asm_flagmask() and png_get_mmx_flagmask() return all valid, settable optimization bits for the version of the library that's currently in use. In the case of shared (dynamically linked) libraries, this may include optimizations that did not exist at the time the code was written and compiled. It is also possible, of course, to enable only known, specific optimizations; for example: #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ | PNG_ASM_FLAG_MMX_READ_INTERLACE \ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; png_set_asm_flags(png_ptr, flags); #endif This method would enable only the MMX read-optimizations available at the time of libpng 1.2.0's release, regardless of whether a later version of the DLL were actually being used. (Also note that these functions did not exist in versions older than 1.2.0, so any attempt to run a dynamically linked app on such an older version would fail.) To determine whether the processor supports MMX instructions at all, use the png_mmx_support() function: #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) mmxsupport = png_mmx_support(); #endif It returns -1 if MMX support is not compiled into libpng, 0 if MMX code is compiled but MMX is not supported by the processor, or 1 if MMX support is fully available. Note that png_mmx_support(), png_get_mmx_flagmask(), and png_get_asm_flagmask() all may be called without allocating and ini- tializing any PNG structures (for example, as part of a usage screen or "about" box). The following code can be used to prevent an application from using the thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK defined: #if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \ && defined(PNG_THREAD_UNSAFE_OK) /* Disable thread-unsafe features of pnggccrd */ if (png_access_version() >= 10200) { png_uint_32 mmx_disable_mask = 0; png_uint_32 asm_flags; mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ); asm_flags = png_get_asm_flags(png_ptr); png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask); } #endif For more extensive examples of runtime querying, enabling and disabling of optimized features, see contrib/gregbook/readpng2.c in the libpng source-code distribution. .SH VII. MNG support The MNG specification (available at http://www.libpng.org/pub/mng) allows certain extensions to PNG for PNG images that are embedded in MNG datastreams. Libpng can support some of these extensions. To enable them, use the png_permit_mng_features() function: feature_set = png_permit_mng_features(png_ptr, mask) mask is a png_uint_32 containing the logical OR of the features you want to enable. These include PNG_FLAG_MNG_EMPTY_PLTE PNG_FLAG_MNG_FILTER_64 PNG_ALL_MNG_FEATURES feature_set is a png_uint_32 that is the logical AND of your mask with the set of MNG features that is supported by the version of libpng that you are using. It is an error to use this function when reading or writing a standalone PNG file with the PNG 8-byte signature. The PNG datastream must be wrapped in a MNG datastream. As a minimum, it must have the MNG 8-byte signature and the MHDR and MEND chunks. Libpng does not provide support for these or any other MNG chunks; your application must provide its own support for them. You may wish to consider using libmng (available at http://www.libmng.com) instead. .SH VIII. Changes to Libpng from version 0.88 It should be noted that versions of libpng later than 0.96 are not distributed by the original libpng author, Guy Schalnat, nor by Andreas Dilger, who had taken over from Guy during 1996 and 1997, and distributed versions 0.89 through 0.96, but rather by another member of the original PNG Group, Glenn Randers-Pehrson. Guy and Andreas are still alive and well, but they have moved on to other things. The old libpng functions png_read_init(), png_write_init(), png_info_init(), png_read_destroy(), and png_write_destroy() have been moved to PNG_INTERNAL in version 0.95 to discourage their use. These functions will be removed from libpng version 2.0.0. The preferred method of creating and initializing the libpng structures is via the png_create_read_struct(), png_create_write_struct(), and png_create_info_struct() because they isolate the size of the structures from the application, allow version error checking, and also allow the use of custom error handling routines during the initialization, which the old functions do not. The functions png_read_destroy() and png_write_destroy() do not actually free the memory that libpng allocated for these structs, but just reset the data structures, so they can be used instead of png_destroy_read_struct() and png_destroy_write_struct() if you feel there is too much system overhead allocating and freeing the png_struct for each image read. Setting the error callbacks via png_set_message_fn() before png_read_init() as was suggested in libpng-0.88 is no longer supported because this caused applications that do not use custom error functions to fail if the png_ptr was not initialized to zero. It is still possible to set the error callbacks AFTER png_read_init(), or to change them with png_set_error_fn(), which is essentially the same function, but with a new name to force compilation errors with applications that try to use the old method. Starting with version 1.0.7, you can find out which version of the library you are using at run-time: png_uint_32 libpng_vn = png_access_version_number(); The number libpng_vn is constructed from the major version, minor version with leading zero, and release number with leading zero, (e.g., libpng_vn for version 1.0.7 is 10007). You can also check which version of png.h you used when compiling your application: png_uint_32 application_vn = PNG_LIBPNG_VER; .SH IX. Y2K Compliance in libpng December 3, 2004 Since the PNG Development group is an ad-hoc body, we can't make an official declaration. This is your unofficial assurance that libpng from version 0.71 and upward through 1.2.8 are Y2K compliant. It is my belief that earlier versions were also Y2K compliant. Libpng only has three year fields. One is a 2-byte unsigned integer that will hold years up to 65535. The other two hold the date in text format, and will hold years up to 9999. The integer is "png_uint_16 year" in png_time_struct. The strings are "png_charp time_buffer" in png_struct and "near_time_buffer", which is a local character string in png.c. There are seven time-related functions: png_convert_to_rfc_1123() in png.c (formerly png_convert_to_rfc_1152() in error) png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c png_convert_from_time_t() in pngwrite.c png_get_tIME() in pngget.c png_handle_tIME() in pngrutil.c, called in pngread.c png_set_tIME() in pngset.c png_write_tIME() in pngwutil.c, called in pngwrite.c All appear to handle dates properly in a Y2K environment. The png_convert_from_time_t() function calls gmtime() to convert from system clock time, which returns (year - 1900), which we properly convert to the full 4-digit year. There is a possibility that applications using libpng are not passing 4-digit years into the png_convert_to_rfc_1123() function, or that they are incorrectly passing only a 2-digit year instead of "year - 1900" into the png_convert_from_struct_tm() function, but this is not under our control. The libpng documentation has always stated that it works with 4-digit years, and the APIs have been documented as such. The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned integer to hold the year, and can hold years as large as 65535. zlib, upon which libpng depends, is also Y2K compliant. It contains no date-related code. Glenn Randers-Pehrson libpng maintainer PNG Development Group .SH NOTE Note about libpng version numbers: Due to various miscommunications, unforeseen code incompatibilities and occasional factors outside the authors' control, version numbering on the library has not always been consistent and straightforward. The following table summarizes matters since version 0.89c, which was the first widely used release: source png.h png.h shared-lib version string int version ------- ------ ----- ---------- 0.89c ("beta 3") 0.89 89 1.0.89 0.90 ("beta 4") 0.90 90 0.90 0.95 ("beta 5") 0.95 95 0.95 0.96 ("beta 6") 0.96 96 0.96 0.97b ("beta 7") 1.00.97 97 1.0.1 0.97c 0.97 97 2.0.97 0.98 0.98 98 2.0.98 0.99 0.99 98 2.0.99 0.99a-m 0.99 99 2.0.99 1.00 1.00 100 2.1.0 1.0.0 1.0.0 100 2.1.0 1.0.0 (from here on, the 100 2.1.0 1.0.1 png.h string is 10001 2.1.0 1.0.1a-e identical to the 10002 from here on, the 1.0.2 source version) 10002 shared library is 2.V 1.0.2a-b 10003 where V is the source 1.0.1 10001 code version except as 1.0.1a-e 10002 2.1.0.1a-e noted. 1.0.2 10002 2.1.0.2 1.0.2a-b 10003 2.1.0.2a-b 1.0.3 10003 2.1.0.3 1.0.3a-d 10004 2.1.0.3a-d 1.0.4 10004 2.1.0.4 1.0.4a-f 10005 2.1.0.4a-f 1.0.5 (+ 2 patches) 10005 2.1.0.5 1.0.5a-d 10006 2.1.0.5a-d 1.0.5e-r 10100 2.1.0.5e-r 1.0.5s-v 10006 2.1.0.5s-v 1.0.6 (+ 3 patches) 10006 2.1.0.6 1.0.6d-g 10007 2.1.0.6d-g 1.0.6h 10007 10.6h 1.0.6i 10007 10.6i 1.0.6j 10007 2.1.0.6j 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 1.0.7 1 10007 2.1.0.7 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 1.0.8rc1 1 10008 2.1.0.8rc1 1.0.8 1 10008 2.1.0.8 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 1.0.9rc1 1 10009 2.1.0.9rc1 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 1.0.9rc2 1 10009 2.1.0.9rc2 1.0.9 1 10009 2.1.0.9 1.0.10beta1 1 10010 2.1.0.10beta1 1.0.10rc1 1 10010 2.1.0.10rc1 1.0.10 1 10010 2.1.0.10 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 1.0.11rc1 1 10011 2.1.0.11rc1 1.0.11 1 10011 2.1.0.11 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 1.0.12rc1 2 10012 2.1.0.12rc1 1.0.12 2 10012 2.1.0.12 1.1.0a-f - 10100 2.1.1.0a-f abandoned 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 1.2.0rc1 3 10200 3.1.2.0rc1 1.2.0 3 10200 3.1.2.0 1.2.1beta-4 3 10201 3.1.2.1beta1-4 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 1.2.1 3 10201 3.1.2.1 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 1.0.13 10 10013 10.so.0.1.0.13 1.2.2 12 10202 12.so.0.1.2.2 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 1.2.3 12 10203 12.so.0.1.2.3 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 1.0.14 10 10014 10.so.0.1.0.14 1.2.4 13 10204 12.so.0.1.2.4 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 1.0.15rc1 10 10015 10.so.0.1.0.15rc1 1.0.15 10 10015 10.so.0.1.0.15 1.2.5 13 10205 12.so.0.1.2.5 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 1.2.6rc1-5 13 10206 12.so.0.1.2.6rc1-5 1.0.16 10 10016 10.so.0.1.0.16 1.2.6 13 10206 12.so.0.1.2.6 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 1.0.17rc1 10 10017 12.so.0.1.0.17rc1 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 1.0.17 10 10017 12.so.0.1.0.17 1.2.7 13 10207 12.so.0.1.2.7 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 1.0.18rc1-5 10 10018 12.so.0.1.0.18rc1-5 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 1.0.18 10 10018 12.so.0.1.0.18 1.2.8 13 10208 12.so.0.1.2.8 Henceforth the source version will match the shared-library minor and patch numbers; the shared-library major version number will be used for changes in backward compatibility, as it is intended. The PNG_PNGLIB_VER macro, which is not used within libpng but is available for applications, is an unsigned integer of the form xyyzz corresponding to the source version x.y.z (leading zeros in y and z). Beta versions were given the previous public release number plus a letter, until version 1.0.6j; from then on they were given the upcoming public release number plus "betaNN" or "rcN". .SH "SEE ALSO" libpngpf(3), png(5) .LP .IR libpng : .IP http://libpng.sourceforge.net (follow the [DOWNLOAD] link) http://www.libpng.org/pub/png .LP .IR zlib : .IP (generally) at the same location as .I libpng or at .br ftp://ftp.info-zip.org/pub/infozip/zlib .LP .IR PNG specification: RFC 2083 .IP (generally) at the same location as .I libpng or at .br ftp://ds.internic.net/rfc/rfc2083.txt .br or (as a W3C Recommendation) at .br http://www.w3.org/TR/REC-png.html .LP In the case of any inconsistency between the PNG specification and this library, the specification takes precedence. .SH AUTHORS This man page: Glenn Randers-Pehrson The contributing authors would like to thank all those who helped with testing, bug fixes, and patience. This wouldn't have been possible without all of you. Thanks to Frank J. T. Wojcik for helping with the documentation. Libpng version 1.2.8 - December 3, 2004: Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc. Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net). Supported by the PNG development group .br png-implement at ccrc.wustl.edu (subscription required; write to majordomo at ccrc.wustl.edu with "subscribe png-implement" in the message). .SH COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: (This copy of the libpng notices is provided for your convenience. In case of any discrepancy between this copy and the notices in the file png.h that is included in the libpng distribution, the latter shall prevail.) If you modify libpng you may insert additional notices immediately following this sentence. libpng version 1.2.6, December 3, 2004, is Copyright (c) 2004 Glenn Randers-Pehrson, and is distributed according to the same disclaimer and license as libpng-1.2.5 with the following individual added to the list of Contributing Authors Cosmin Truta libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals added to the list of Contributing Authors Simon-Pierre Cadieux Eric S. Raymond Gilles Vollant and with the following additions to the disclaimer: There is no warranty against interference with your enjoyment of the library or against infringement. There is no warranty that our efforts or the library will fulfill any of your particular purposes or needs. This library is provided with all faults, and the entire risk of satisfactory quality, performance, accuracy, and effort is with the user. libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are Copyright (c) 1998, 1999 Glenn Randers-Pehrson Distributed according to the same disclaimer and license as libpng-0.96, with the following individuals added to the list of Contributing Authors: Tom Lane Glenn Randers-Pehrson Willem van Schaik libpng versions 0.89, June 1996, through 0.96, May 1997, are Copyright (c) 1996, 1997 Andreas Dilger Distributed according to the same disclaimer and license as libpng-0.88, with the following individuals added to the list of Contributing Authors: John Bowler Kevin Bracey Sam Bushell Magnus Holmgren Greg Roelofs Tom Tanner libpng versions 0.5, May 1995, through 0.88, January 1996, are Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. For the purposes of this copyright and license, "Contributing Authors" is defined as the following set of individuals: Andreas Dilger Dave Martindale Guy Eric Schalnat Paul Schmidt Tim Wegner The PNG Reference Library is supplied "AS IS". The Contributing Authors and Group 42, Inc. disclaim all warranties, expressed or implied, including, without limitation, the warranties of merchantability and of fitness for any purpose. The Contributing Authors and Group 42, Inc. assume no liability for direct, indirect, incidental, special, exemplary, or consequential damages, which may result from the use of the PNG Reference Library, even if advised of the possibility of such damage. Permission is hereby granted to use, copy, modify, and distribute this source code, or portions hereof, for any purpose, without fee, subject to the following restrictions: 1. The origin of this source code must not be misrepresented. 2. Altered versions must be plainly marked as such and must not be misrepresented as being the original source. 3. This Copyright notice may not be removed or altered from any source or altered source distribution. The Contributing Authors and Group 42, Inc. specifically permit, without fee, and encourage the use of this source code as a component to supporting the PNG file format in commercial products. If you use this source code in a product, acknowledgment is not required but would be appreciated. A "png_get_copyright" function is available, for convenient use in "about" boxes and the like: printf("%s",png_get_copyright(NULL)); Also, the PNG logo (in PNG format, of course) is supplied in the files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a certification mark of the Open Source Initiative. Glenn Randers-Pehrson glennrp at users.sourceforge.net December 3, 2004 .\" end of man page syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngwrite.c0000664000175000017500000013541610777447272021174 0ustar evanevan /* pngwrite.c - general routines to write a PNG file * * libpng 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ /* get internal access to png.h */ #define PNG_INTERNAL #include "png.h" #ifdef PNG_WRITE_SUPPORTED /* Writes all the PNG information. This is the suggested way to use the * library. If you have a new chunk to add, make a function to write it, * and put it in the correct location here. If you want the chunk written * after the image data, put it in png_write_end(). I strongly encourage * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing * the chunk, as that will keep the code from breaking if you want to just * write a plain PNG file. If you have long comments, I suggest writing * them in png_write_end(), and compressing them. */ void PNGAPI png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) { png_debug(1, "in png_write_info_before_PLTE\n"); if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) { png_write_sig(png_ptr); /* write PNG signature */ #if defined(PNG_MNG_FEATURES_SUPPORTED) if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted)) { png_warning(png_ptr,"MNG features are not allowed in a PNG datastream\n"); png_ptr->mng_features_permitted=0; } #endif /* write IHDR information. */ png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, info_ptr->filter_type, #if defined(PNG_WRITE_INTERLACING_SUPPORTED) info_ptr->interlace_type); #else 0); #endif /* the rest of these check to see if the valid field has the appropriate flag set, and if it does, writes the chunk. */ #if defined(PNG_WRITE_gAMA_SUPPORTED) if (info_ptr->valid & PNG_INFO_gAMA) { # ifdef PNG_FLOATING_POINT_SUPPORTED png_write_gAMA(png_ptr, info_ptr->gamma); #else #ifdef PNG_FIXED_POINT_SUPPORTED png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma); # endif #endif } #endif #if defined(PNG_WRITE_sRGB_SUPPORTED) if (info_ptr->valid & PNG_INFO_sRGB) png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); #endif #if defined(PNG_WRITE_iCCP_SUPPORTED) if (info_ptr->valid & PNG_INFO_iCCP) png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); #endif #if defined(PNG_WRITE_sBIT_SUPPORTED) if (info_ptr->valid & PNG_INFO_sBIT) png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); #endif #if defined(PNG_WRITE_cHRM_SUPPORTED) if (info_ptr->valid & PNG_INFO_cHRM) { #ifdef PNG_FLOATING_POINT_SUPPORTED png_write_cHRM(png_ptr, info_ptr->x_white, info_ptr->y_white, info_ptr->x_red, info_ptr->y_red, info_ptr->x_green, info_ptr->y_green, info_ptr->x_blue, info_ptr->y_blue); #else # ifdef PNG_FIXED_POINT_SUPPORTED png_write_cHRM_fixed(png_ptr, info_ptr->int_x_white, info_ptr->int_y_white, info_ptr->int_x_red, info_ptr->int_y_red, info_ptr->int_x_green, info_ptr->int_y_green, info_ptr->int_x_blue, info_ptr->int_y_blue); # endif #endif } #endif #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) if (info_ptr->unknown_chunks_num) { png_unknown_chunk *up; png_debug(5, "writing extra chunks\n"); for (up = info_ptr->unknown_chunks; up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; up++) { int keep=png_handle_as_unknown(png_ptr, up->name); if (keep != PNG_HANDLE_CHUNK_NEVER && up->location && !(up->location & PNG_HAVE_PLTE) && !(up->location & PNG_HAVE_IDAT) && ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) { png_write_chunk(png_ptr, up->name, up->data, up->size); } } } #endif png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; } } void PNGAPI png_write_info(png_structp png_ptr, png_infop info_ptr) { #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) int i; #endif png_debug(1, "in png_write_info\n"); png_write_info_before_PLTE(png_ptr, info_ptr); if (info_ptr->valid & PNG_INFO_PLTE) png_write_PLTE(png_ptr, info_ptr->palette, (png_uint_32)info_ptr->num_palette); else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) png_error(png_ptr, "Valid palette required for paletted images\n"); #if defined(PNG_WRITE_tRNS_SUPPORTED) if (info_ptr->valid & PNG_INFO_tRNS) { #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) /* invert the alpha channel (in tRNS) */ if ((png_ptr->transformations & PNG_INVERT_ALPHA) && info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { int j; for (j=0; j<(int)info_ptr->num_trans; j++) info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]); } #endif png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values), info_ptr->num_trans, info_ptr->color_type); } #endif #if defined(PNG_WRITE_bKGD_SUPPORTED) if (info_ptr->valid & PNG_INFO_bKGD) png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); #endif #if defined(PNG_WRITE_hIST_SUPPORTED) if (info_ptr->valid & PNG_INFO_hIST) png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); #endif #if defined(PNG_WRITE_oFFs_SUPPORTED) if (info_ptr->valid & PNG_INFO_oFFs) png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, info_ptr->offset_unit_type); #endif #if defined(PNG_WRITE_pCAL_SUPPORTED) if (info_ptr->valid & PNG_INFO_pCAL) png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, info_ptr->pcal_units, info_ptr->pcal_params); #endif #if defined(PNG_WRITE_sCAL_SUPPORTED) if (info_ptr->valid & PNG_INFO_sCAL) #if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) png_write_sCAL(png_ptr, (int)info_ptr->scal_unit, info_ptr->scal_pixel_width, info_ptr->scal_pixel_height); #else #ifdef PNG_FIXED_POINT_SUPPORTED png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, info_ptr->scal_s_width, info_ptr->scal_s_height); #else png_warning(png_ptr, "png_write_sCAL not supported; sCAL chunk not written.\n"); #endif #endif #endif #if defined(PNG_WRITE_pHYs_SUPPORTED) if (info_ptr->valid & PNG_INFO_pHYs) png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); #endif #if defined(PNG_WRITE_tIME_SUPPORTED) if (info_ptr->valid & PNG_INFO_tIME) { png_write_tIME(png_ptr, &(info_ptr->mod_time)); png_ptr->mode |= PNG_WROTE_tIME; } #endif #if defined(PNG_WRITE_sPLT_SUPPORTED) if (info_ptr->valid & PNG_INFO_sPLT) for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); #endif #if defined(PNG_WRITE_TEXT_SUPPORTED) /* Check to see if we need to write text chunks */ for (i = 0; i < info_ptr->num_text; i++) { png_debug2(2, "Writing header text chunk %d, type %d\n", i, info_ptr->text[i].compression); /* an internationalized chunk? */ if (info_ptr->text[i].compression > 0) { #if defined(PNG_WRITE_iTXt_SUPPORTED) /* write international chunk */ png_write_iTXt(png_ptr, info_ptr->text[i].compression, info_ptr->text[i].key, info_ptr->text[i].lang, info_ptr->text[i].lang_key, info_ptr->text[i].text); #else png_warning(png_ptr, "Unable to write international text\n"); #endif /* Mark this chunk as written */ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; } /* If we want a compressed text chunk */ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) { #if defined(PNG_WRITE_zTXt_SUPPORTED) /* write compressed chunk */ png_write_zTXt(png_ptr, info_ptr->text[i].key, info_ptr->text[i].text, 0, info_ptr->text[i].compression); #else png_warning(png_ptr, "Unable to write compressed text\n"); #endif /* Mark this chunk as written */ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; } else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) { #if defined(PNG_WRITE_tEXt_SUPPORTED) /* write uncompressed chunk */ png_write_tEXt(png_ptr, info_ptr->text[i].key, info_ptr->text[i].text, 0); #else png_warning(png_ptr, "Unable to write uncompressed text\n"); #endif /* Mark this chunk as written */ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; } } #endif #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) if (info_ptr->unknown_chunks_num) { png_unknown_chunk *up; png_debug(5, "writing extra chunks\n"); for (up = info_ptr->unknown_chunks; up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; up++) { int keep=png_handle_as_unknown(png_ptr, up->name); if (keep != PNG_HANDLE_CHUNK_NEVER && up->location && (up->location & PNG_HAVE_PLTE) && !(up->location & PNG_HAVE_IDAT) && ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) { png_write_chunk(png_ptr, up->name, up->data, up->size); } } } #endif } /* Writes the end of the PNG file. If you don't want to write comments or * time information, you can pass NULL for info. If you already wrote these * in png_write_info(), do not write them again here. If you have long * comments, I suggest writing them here, and compressing them. */ void PNGAPI png_write_end(png_structp png_ptr, png_infop info_ptr) { png_debug(1, "in png_write_end\n"); if (!(png_ptr->mode & PNG_HAVE_IDAT)) png_error(png_ptr, "No IDATs written into file"); /* see if user wants us to write information chunks */ if (info_ptr != NULL) { #if defined(PNG_WRITE_TEXT_SUPPORTED) int i; /* local index variable */ #endif #if defined(PNG_WRITE_tIME_SUPPORTED) /* check to see if user has supplied a time chunk */ if ((info_ptr->valid & PNG_INFO_tIME) && !(png_ptr->mode & PNG_WROTE_tIME)) png_write_tIME(png_ptr, &(info_ptr->mod_time)); #endif #if defined(PNG_WRITE_TEXT_SUPPORTED) /* loop through comment chunks */ for (i = 0; i < info_ptr->num_text; i++) { png_debug2(2, "Writing trailer text chunk %d, type %d\n", i, info_ptr->text[i].compression); /* an internationalized chunk? */ if (info_ptr->text[i].compression > 0) { #if defined(PNG_WRITE_iTXt_SUPPORTED) /* write international chunk */ png_write_iTXt(png_ptr, info_ptr->text[i].compression, info_ptr->text[i].key, info_ptr->text[i].lang, info_ptr->text[i].lang_key, info_ptr->text[i].text); #else png_warning(png_ptr, "Unable to write international text\n"); #endif /* Mark this chunk as written */ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; } else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) { #if defined(PNG_WRITE_zTXt_SUPPORTED) /* write compressed chunk */ png_write_zTXt(png_ptr, info_ptr->text[i].key, info_ptr->text[i].text, 0, info_ptr->text[i].compression); #else png_warning(png_ptr, "Unable to write compressed text\n"); #endif /* Mark this chunk as written */ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; } else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) { #if defined(PNG_WRITE_tEXt_SUPPORTED) /* write uncompressed chunk */ png_write_tEXt(png_ptr, info_ptr->text[i].key, info_ptr->text[i].text, 0); #else png_warning(png_ptr, "Unable to write uncompressed text\n"); #endif /* Mark this chunk as written */ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; } } #endif #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) if (info_ptr->unknown_chunks_num) { png_unknown_chunk *up; png_debug(5, "writing extra chunks\n"); for (up = info_ptr->unknown_chunks; up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; up++) { int keep=png_handle_as_unknown(png_ptr, up->name); if (keep != PNG_HANDLE_CHUNK_NEVER && up->location && (up->location & PNG_AFTER_IDAT) && ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) { png_write_chunk(png_ptr, up->name, up->data, up->size); } } } #endif } png_ptr->mode |= PNG_AFTER_IDAT; /* write end of PNG file */ png_write_IEND(png_ptr); #if 0 /* This flush, added in libpng-1.0.8, causes some applications to crash because they do not set png_ptr->output_flush_fn */ png_flush(png_ptr); #endif } #if defined(PNG_WRITE_tIME_SUPPORTED) #if !defined(_WIN32_WCE) /* "time.h" functions are not supported on WindowsCE */ void PNGAPI png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime) { png_debug(1, "in png_convert_from_struct_tm\n"); ptime->year = (png_uint_16)(1900 + ttime->tm_year); ptime->month = (png_byte)(ttime->tm_mon + 1); ptime->day = (png_byte)ttime->tm_mday; ptime->hour = (png_byte)ttime->tm_hour; ptime->minute = (png_byte)ttime->tm_min; ptime->second = (png_byte)ttime->tm_sec; } void PNGAPI png_convert_from_time_t(png_timep ptime, time_t ttime) { struct tm *tbuf; png_debug(1, "in png_convert_from_time_t\n"); tbuf = gmtime(&ttime); png_convert_from_struct_tm(ptime, tbuf); } #endif #endif /* Initialize png_ptr structure, and allocate any memory needed */ png_structp PNGAPI png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn) { #ifdef PNG_USER_MEM_SUPPORTED return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL)); } /* Alternate initialize png_ptr structure, and allocate any memory needed */ png_structp PNGAPI png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn) { #endif /* PNG_USER_MEM_SUPPORTED */ png_structp png_ptr; #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD jmp_buf jmpbuf; #endif #endif int i; png_debug(1, "in png_create_write_struct\n"); #ifdef PNG_USER_MEM_SUPPORTED png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); #else png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); #endif /* PNG_USER_MEM_SUPPORTED */ if (png_ptr == NULL) return (NULL); #if !defined(PNG_1_0_X) #ifdef PNG_ASSEMBLER_CODE_SUPPORTED png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ #endif #endif /* PNG_1_0_X */ /* added at libpng-1.2.6 */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED png_ptr->user_width_max=PNG_USER_WIDTH_MAX; png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; #endif #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD if (setjmp(jmpbuf)) #else if (setjmp(png_ptr->jmpbuf)) #endif { png_free(png_ptr, png_ptr->zbuf); png_ptr->zbuf=NULL; png_destroy_struct(png_ptr); return (NULL); } #ifdef USE_FAR_KEYWORD png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); #endif #endif #ifdef PNG_USER_MEM_SUPPORTED png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); #endif /* PNG_USER_MEM_SUPPORTED */ png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); i=0; do { if(user_png_ver[i] != png_libpng_ver[i]) png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; } while (png_libpng_ver[i++]); if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) { /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so * we must recompile any applications that use any older library version. * For versions after libpng 1.0, we will be compatible, so we need * only check the first digit. */ if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || (user_png_ver[0] == '0' && user_png_ver[2] < '9')) { #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) char msg[80]; if (user_png_ver) { sprintf(msg, "Application was compiled with png.h from libpng-%.20s", user_png_ver); png_warning(png_ptr, msg); } sprintf(msg, "Application is running with png.c from libpng-%.20s", png_libpng_ver); png_warning(png_ptr, msg); #endif #ifdef PNG_ERROR_NUMBERS_SUPPORTED png_ptr->flags=0; #endif png_error(png_ptr, "Incompatible libpng version in application and library"); } } /* initialize zbuf - compression buffer */ png_ptr->zbuf_size = PNG_ZBUF_SIZE; png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL, png_flush_ptr_NULL); #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT, 1, png_doublep_NULL, png_doublep_NULL); #endif #ifdef PNG_SETJMP_SUPPORTED /* Applications that neglect to set up their own setjmp() and then encounter a png_error() will longjmp here. Since the jmpbuf is then meaningless we abort instead of returning. */ #ifdef USE_FAR_KEYWORD if (setjmp(jmpbuf)) PNG_ABORT(); png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); #else if (setjmp(png_ptr->jmpbuf)) PNG_ABORT(); #endif #endif return (png_ptr); } /* Initialize png_ptr structure, and allocate any memory needed */ #undef png_write_init void PNGAPI png_write_init(png_structp png_ptr) { /* We only come here via pre-1.0.7-compiled applications */ png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0); } void PNGAPI png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t png_info_size) { /* We only come here via pre-1.0.12-compiled applications */ #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) if(png_sizeof(png_struct) > png_struct_size || png_sizeof(png_info) > png_info_size) { char msg[80]; png_ptr->warning_fn=NULL; if (user_png_ver) { sprintf(msg, "Application was compiled with png.h from libpng-%.20s", user_png_ver); png_warning(png_ptr, msg); } sprintf(msg, "Application is running with png.c from libpng-%.20s", png_libpng_ver); png_warning(png_ptr, msg); } #endif if(png_sizeof(png_struct) > png_struct_size) { png_ptr->error_fn=NULL; #ifdef PNG_ERROR_NUMBERS_SUPPORTED png_ptr->flags=0; #endif png_error(png_ptr, "The png struct allocated by the application for writing is too small."); } if(png_sizeof(png_info) > png_info_size) { png_ptr->error_fn=NULL; #ifdef PNG_ERROR_NUMBERS_SUPPORTED png_ptr->flags=0; #endif png_error(png_ptr, "The info struct allocated by the application for writing is too small."); } png_write_init_3(&png_ptr, user_png_ver, png_struct_size); } void PNGAPI png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, png_size_t png_struct_size) { png_structp png_ptr=*ptr_ptr; #ifdef PNG_SETJMP_SUPPORTED jmp_buf tmp_jmp; /* to save current jump buffer */ #endif int i = 0; do { if (user_png_ver[i] != png_libpng_ver[i]) { #ifdef PNG_LEGACY_SUPPORTED png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; #else png_ptr->warning_fn=NULL; png_warning(png_ptr, "Application uses deprecated png_write_init() and should be recompiled."); break; #endif } } while (png_libpng_ver[i++]); png_debug(1, "in png_write_init_3\n"); #ifdef PNG_SETJMP_SUPPORTED /* save jump buffer and error functions */ png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); #endif if (png_sizeof(png_struct) > png_struct_size) { png_destroy_struct(png_ptr); png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); *ptr_ptr = png_ptr; } /* reset all variables to 0 */ png_memset(png_ptr, 0, png_sizeof (png_struct)); /* added at libpng-1.2.6 */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED png_ptr->user_width_max=PNG_USER_WIDTH_MAX; png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; #endif #if !defined(PNG_1_0_X) #ifdef PNG_ASSEMBLER_CODE_SUPPORTED png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ #endif #endif /* PNG_1_0_X */ #ifdef PNG_SETJMP_SUPPORTED /* restore jump buffer */ png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); #endif png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL, png_flush_ptr_NULL); /* initialize zbuf - compression buffer */ png_ptr->zbuf_size = PNG_ZBUF_SIZE; png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT, 1, png_doublep_NULL, png_doublep_NULL); #endif } /* Write a few rows of image data. If the image is interlaced, * either you will have to write the 7 sub images, or, if you * have called png_set_interlace_handling(), you will have to * "write" the image seven times. */ void PNGAPI png_write_rows(png_structp png_ptr, png_bytepp row, png_uint_32 num_rows) { png_uint_32 i; /* row counter */ png_bytepp rp; /* row pointer */ png_debug(1, "in png_write_rows\n"); /* loop through the rows */ for (i = 0, rp = row; i < num_rows; i++, rp++) { png_write_row(png_ptr, *rp); } } /* Write the image. You only need to call this function once, even * if you are writing an interlaced image. */ void PNGAPI png_write_image(png_structp png_ptr, png_bytepp image) { png_uint_32 i; /* row index */ int pass, num_pass; /* pass variables */ png_bytepp rp; /* points to current row */ png_debug(1, "in png_write_image\n"); #if defined(PNG_WRITE_INTERLACING_SUPPORTED) /* intialize interlace handling. If image is not interlaced, this will set pass to 1 */ num_pass = png_set_interlace_handling(png_ptr); #else num_pass = 1; #endif /* loop through passes */ for (pass = 0; pass < num_pass; pass++) { /* loop through image */ for (i = 0, rp = image; i < png_ptr->height; i++, rp++) { png_write_row(png_ptr, *rp); } } } /* called by user to write a row of image data */ void PNGAPI png_write_row(png_structp png_ptr, png_bytep row) { png_debug2(1, "in png_write_row (row %ld, pass %d)\n", png_ptr->row_number, png_ptr->pass); /* initialize transformations and other stuff if first time */ if (png_ptr->row_number == 0 && png_ptr->pass == 0) { /* make sure we wrote the header info */ if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) png_error(png_ptr, "png_write_info was never called before png_write_row."); /* check for transforms that have been set but were defined out */ #if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) if (png_ptr->transformations & PNG_INVERT_MONO) png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined."); #endif #if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) if (png_ptr->transformations & PNG_FILLER) png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined."); #endif #if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined."); #endif #if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) if (png_ptr->transformations & PNG_PACK) png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined."); #endif #if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) if (png_ptr->transformations & PNG_SHIFT) png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined."); #endif #if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) if (png_ptr->transformations & PNG_BGR) png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined."); #endif #if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) if (png_ptr->transformations & PNG_SWAP_BYTES) png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined."); #endif png_write_start_row(png_ptr); } #if defined(PNG_WRITE_INTERLACING_SUPPORTED) /* if interlaced and not interested in row, return */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { switch (png_ptr->pass) { case 0: if (png_ptr->row_number & 0x07) { png_write_finish_row(png_ptr); return; } break; case 1: if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) { png_write_finish_row(png_ptr); return; } break; case 2: if ((png_ptr->row_number & 0x07) != 4) { png_write_finish_row(png_ptr); return; } break; case 3: if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) { png_write_finish_row(png_ptr); return; } break; case 4: if ((png_ptr->row_number & 0x03) != 2) { png_write_finish_row(png_ptr); return; } break; case 5: if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) { png_write_finish_row(png_ptr); return; } break; case 6: if (!(png_ptr->row_number & 0x01)) { png_write_finish_row(png_ptr); return; } break; } } #endif /* set up row info for transformations */ png_ptr->row_info.color_type = png_ptr->color_type; png_ptr->row_info.width = png_ptr->usr_width; png_ptr->row_info.channels = png_ptr->usr_channels; png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth; png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * png_ptr->row_info.channels); png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->row_info.width); png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type); png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width); png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels); png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth); png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth); png_debug1(3, "row_info->rowbytes = %lu\n", png_ptr->row_info.rowbytes); /* Copy user's row into buffer, leaving room for filter byte. */ png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row, png_ptr->row_info.rowbytes); #if defined(PNG_WRITE_INTERLACING_SUPPORTED) /* handle interlacing */ if (png_ptr->interlaced && png_ptr->pass < 6 && (png_ptr->transformations & PNG_INTERLACE)) { png_do_write_interlace(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->pass); /* this should always get caught above, but still ... */ if (!(png_ptr->row_info.width)) { png_write_finish_row(png_ptr); return; } } #endif /* handle other transformations */ if (png_ptr->transformations) png_do_write_transformations(png_ptr); #if defined(PNG_MNG_FEATURES_SUPPORTED) /* Write filter_method 64 (intrapixel differencing) only if * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and * 2. Libpng did not write a PNG signature (this filter_method is only * used in PNG datastreams that are embedded in MNG datastreams) and * 3. The application called png_permit_mng_features with a mask that * included PNG_FLAG_MNG_FILTER_64 and * 4. The filter_method is 64 and * 5. The color_type is RGB or RGBA */ if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) { /* Intrapixel differencing */ png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); } #endif /* Find a filter if necessary, filter the row and write it out. */ png_write_find_filter(png_ptr, &(png_ptr->row_info)); if (png_ptr->write_row_fn != NULL) (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); } #if defined(PNG_WRITE_FLUSH_SUPPORTED) /* Set the automatic flush interval or 0 to turn flushing off */ void PNGAPI png_set_flush(png_structp png_ptr, int nrows) { png_debug(1, "in png_set_flush\n"); png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); } /* flush the current output buffers now */ void PNGAPI png_write_flush(png_structp png_ptr) { int wrote_IDAT; png_debug(1, "in png_write_flush\n"); /* We have already written out all of the data */ if (png_ptr->row_number >= png_ptr->num_rows) return; do { int ret; /* compress the data */ ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH); wrote_IDAT = 0; /* check for compression errors */ if (ret != Z_OK) { if (png_ptr->zstream.msg != NULL) png_error(png_ptr, png_ptr->zstream.msg); else png_error(png_ptr, "zlib error"); } if (!(png_ptr->zstream.avail_out)) { /* write the IDAT and reset the zlib output buffer */ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; wrote_IDAT = 1; } } while(wrote_IDAT == 1); /* If there is any data left to be output, write it into a new IDAT */ if (png_ptr->zbuf_size != png_ptr->zstream.avail_out) { /* write the IDAT and reset the zlib output buffer */ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - png_ptr->zstream.avail_out); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; } png_ptr->flush_rows = 0; png_flush(png_ptr); } #endif /* PNG_WRITE_FLUSH_SUPPORTED */ /* free all memory used by the write */ void PNGAPI png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) { png_structp png_ptr = NULL; png_infop info_ptr = NULL; #ifdef PNG_USER_MEM_SUPPORTED png_free_ptr free_fn = NULL; png_voidp mem_ptr = NULL; #endif png_debug(1, "in png_destroy_write_struct\n"); if (png_ptr_ptr != NULL) { png_ptr = *png_ptr_ptr; #ifdef PNG_USER_MEM_SUPPORTED free_fn = png_ptr->free_fn; mem_ptr = png_ptr->mem_ptr; #endif } if (info_ptr_ptr != NULL) info_ptr = *info_ptr_ptr; if (info_ptr != NULL) { png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) if (png_ptr->num_chunk_list) { png_free(png_ptr, png_ptr->chunk_list); png_ptr->chunk_list=NULL; png_ptr->num_chunk_list=0; } #endif #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)info_ptr); #endif *info_ptr_ptr = NULL; } if (png_ptr != NULL) { png_write_destroy(png_ptr); #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)png_ptr); #endif *png_ptr_ptr = NULL; } } /* Free any memory used in png_ptr struct (old method) */ void /* PRIVATE */ png_write_destroy(png_structp png_ptr) { #ifdef PNG_SETJMP_SUPPORTED jmp_buf tmp_jmp; /* save jump buffer */ #endif png_error_ptr error_fn; png_error_ptr warning_fn; png_voidp error_ptr; #ifdef PNG_USER_MEM_SUPPORTED png_free_ptr free_fn; #endif png_debug(1, "in png_write_destroy\n"); /* free any memory zlib uses */ deflateEnd(&png_ptr->zstream); /* free our memory. png_free checks NULL for us. */ png_free(png_ptr, png_ptr->zbuf); png_free(png_ptr, png_ptr->row_buf); png_free(png_ptr, png_ptr->prev_row); png_free(png_ptr, png_ptr->sub_row); png_free(png_ptr, png_ptr->up_row); png_free(png_ptr, png_ptr->avg_row); png_free(png_ptr, png_ptr->paeth_row); #if defined(PNG_TIME_RFC1123_SUPPORTED) png_free(png_ptr, png_ptr->time_buffer); #endif #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) png_free(png_ptr, png_ptr->prev_filters); png_free(png_ptr, png_ptr->filter_weights); png_free(png_ptr, png_ptr->inv_filter_weights); png_free(png_ptr, png_ptr->filter_costs); png_free(png_ptr, png_ptr->inv_filter_costs); #endif #ifdef PNG_SETJMP_SUPPORTED /* reset structure */ png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); #endif error_fn = png_ptr->error_fn; warning_fn = png_ptr->warning_fn; error_ptr = png_ptr->error_ptr; #ifdef PNG_USER_MEM_SUPPORTED free_fn = png_ptr->free_fn; #endif png_memset(png_ptr, 0, png_sizeof (png_struct)); png_ptr->error_fn = error_fn; png_ptr->warning_fn = warning_fn; png_ptr->error_ptr = error_ptr; #ifdef PNG_USER_MEM_SUPPORTED png_ptr->free_fn = free_fn; #endif #ifdef PNG_SETJMP_SUPPORTED png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); #endif } /* Allow the application to select one or more row filters to use. */ void PNGAPI png_set_filter(png_structp png_ptr, int method, int filters) { png_debug(1, "in png_set_filter\n"); #if defined(PNG_MNG_FEATURES_SUPPORTED) if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && (method == PNG_INTRAPIXEL_DIFFERENCING)) method = PNG_FILTER_TYPE_BASE; #endif if (method == PNG_FILTER_TYPE_BASE) { switch (filters & (PNG_ALL_FILTERS | 0x07)) { case 5: case 6: case 7: png_warning(png_ptr, "Unknown row filter for method 0"); case PNG_FILTER_VALUE_NONE: png_ptr->do_filter=PNG_FILTER_NONE; break; case PNG_FILTER_VALUE_SUB: png_ptr->do_filter=PNG_FILTER_SUB; break; case PNG_FILTER_VALUE_UP: png_ptr->do_filter=PNG_FILTER_UP; break; case PNG_FILTER_VALUE_AVG: png_ptr->do_filter=PNG_FILTER_AVG; break; case PNG_FILTER_VALUE_PAETH: png_ptr->do_filter=PNG_FILTER_PAETH;break; default: png_ptr->do_filter = (png_byte)filters; break; } /* If we have allocated the row_buf, this means we have already started * with the image and we should have allocated all of the filter buffers * that have been selected. If prev_row isn't already allocated, then * it is too late to start using the filters that need it, since we * will be missing the data in the previous row. If an application * wants to start and stop using particular filters during compression, * it should start out with all of the filters, and then add and * remove them after the start of compression. */ if (png_ptr->row_buf != NULL) { if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) { png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, (png_ptr->rowbytes + 1)); png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; } if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL) { if (png_ptr->prev_row == NULL) { png_warning(png_ptr, "Can't add Up filter after starting"); png_ptr->do_filter &= ~PNG_FILTER_UP; } else { png_ptr->up_row = (png_bytep)png_malloc(png_ptr, (png_ptr->rowbytes + 1)); png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; } } if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL) { if (png_ptr->prev_row == NULL) { png_warning(png_ptr, "Can't add Average filter after starting"); png_ptr->do_filter &= ~PNG_FILTER_AVG; } else { png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, (png_ptr->rowbytes + 1)); png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; } } if ((png_ptr->do_filter & PNG_FILTER_PAETH) && png_ptr->paeth_row == NULL) { if (png_ptr->prev_row == NULL) { png_warning(png_ptr, "Can't add Paeth filter after starting"); png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH); } else { png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, (png_ptr->rowbytes + 1)); png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; } } if (png_ptr->do_filter == PNG_NO_FILTERS) png_ptr->do_filter = PNG_FILTER_NONE; } } else png_error(png_ptr, "Unknown custom filter method"); } /* This allows us to influence the way in which libpng chooses the "best" * filter for the current scanline. While the "minimum-sum-of-absolute- * differences metric is relatively fast and effective, there is some * question as to whether it can be improved upon by trying to keep the * filtered data going to zlib more consistent, hopefully resulting in * better compression. */ #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* GRR 970116 */ void PNGAPI png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, int num_weights, png_doublep filter_weights, png_doublep filter_costs) { int i; png_debug(1, "in png_set_filter_heuristics\n"); if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST) { png_warning(png_ptr, "Unknown filter heuristic method"); return; } if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT) { heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; } if (num_weights < 0 || filter_weights == NULL || heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) { num_weights = 0; } png_ptr->num_prev_filters = (png_byte)num_weights; png_ptr->heuristic_method = (png_byte)heuristic_method; if (num_weights > 0) { if (png_ptr->prev_filters == NULL) { png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, (png_uint_32)(png_sizeof(png_byte) * num_weights)); /* To make sure that the weighting starts out fairly */ for (i = 0; i < num_weights; i++) { png_ptr->prev_filters[i] = 255; } } if (png_ptr->filter_weights == NULL) { png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); for (i = 0; i < num_weights; i++) { png_ptr->inv_filter_weights[i] = png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; } } for (i = 0; i < num_weights; i++) { if (filter_weights[i] < 0.0) { png_ptr->inv_filter_weights[i] = png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; } else { png_ptr->inv_filter_weights[i] = (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5); png_ptr->filter_weights[i] = (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5); } } } /* If, in the future, there are other filter methods, this would * need to be based on png_ptr->filter. */ if (png_ptr->filter_costs == NULL) { png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) { png_ptr->inv_filter_costs[i] = png_ptr->filter_costs[i] = PNG_COST_FACTOR; } } /* Here is where we set the relative costs of the different filters. We * should take the desired compression level into account when setting * the costs, so that Paeth, for instance, has a high relative cost at low * compression levels, while it has a lower relative cost at higher * compression settings. The filter types are in order of increasing * relative cost, so it would be possible to do this with an algorithm. */ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) { if (filter_costs == NULL || filter_costs[i] < 0.0) { png_ptr->inv_filter_costs[i] = png_ptr->filter_costs[i] = PNG_COST_FACTOR; } else if (filter_costs[i] >= 1.0) { png_ptr->inv_filter_costs[i] = (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5); png_ptr->filter_costs[i] = (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5); } } } #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ void PNGAPI png_set_compression_level(png_structp png_ptr, int level) { png_debug(1, "in png_set_compression_level\n"); png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; png_ptr->zlib_level = level; } void PNGAPI png_set_compression_mem_level(png_structp png_ptr, int mem_level) { png_debug(1, "in png_set_compression_mem_level\n"); png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; png_ptr->zlib_mem_level = mem_level; } void PNGAPI png_set_compression_strategy(png_structp png_ptr, int strategy) { png_debug(1, "in png_set_compression_strategy\n"); png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; png_ptr->zlib_strategy = strategy; } void PNGAPI png_set_compression_window_bits(png_structp png_ptr, int window_bits) { if (window_bits > 15) png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); else if (window_bits < 8) png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); #ifndef WBITS_8_OK /* avoid libpng bug with 256-byte windows */ if (window_bits == 8) { png_warning(png_ptr, "Compression window is being reset to 512"); window_bits=9; } #endif png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; png_ptr->zlib_window_bits = window_bits; } void PNGAPI png_set_compression_method(png_structp png_ptr, int method) { png_debug(1, "in png_set_compression_method\n"); if (method != 8) png_warning(png_ptr, "Only compression method 8 is supported by PNG"); png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; png_ptr->zlib_method = method; } void PNGAPI png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) { png_ptr->write_row_fn = write_row_fn; } #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) void PNGAPI png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr write_user_transform_fn) { png_debug(1, "in png_set_write_user_transform_fn\n"); png_ptr->transformations |= PNG_USER_TRANSFORM; png_ptr->write_user_transform_fn = write_user_transform_fn; } #endif #if defined(PNG_INFO_IMAGE_SUPPORTED) void PNGAPI png_write_png(png_structp png_ptr, png_infop info_ptr, int transforms, voidp params) { #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) /* invert the alpha channel from opacity to transparency */ if (transforms & PNG_TRANSFORM_INVERT_ALPHA) png_set_invert_alpha(png_ptr); #endif /* Write the file header information. */ png_write_info(png_ptr, info_ptr); /* ------ these transformations don't touch the info structure ------- */ #if defined(PNG_WRITE_INVERT_SUPPORTED) /* invert monochrome pixels */ if (transforms & PNG_TRANSFORM_INVERT_MONO) png_set_invert_mono(png_ptr); #endif #if defined(PNG_WRITE_SHIFT_SUPPORTED) /* Shift the pixels up to a legal bit depth and fill in * as appropriate to correctly scale the image. */ if ((transforms & PNG_TRANSFORM_SHIFT) && (info_ptr->valid & PNG_INFO_sBIT)) png_set_shift(png_ptr, &info_ptr->sig_bit); #endif #if defined(PNG_WRITE_PACK_SUPPORTED) /* pack pixels into bytes */ if (transforms & PNG_TRANSFORM_PACKING) png_set_packing(png_ptr); #endif #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) /* swap location of alpha bytes from ARGB to RGBA */ if (transforms & PNG_TRANSFORM_SWAP_ALPHA) png_set_swap_alpha(png_ptr); #endif #if defined(PNG_WRITE_FILLER_SUPPORTED) /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into * RGB (4 channels -> 3 channels). The second parameter is not used. */ if (transforms & PNG_TRANSFORM_STRIP_FILLER) png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); #endif #if defined(PNG_WRITE_BGR_SUPPORTED) /* flip BGR pixels to RGB */ if (transforms & PNG_TRANSFORM_BGR) png_set_bgr(png_ptr); #endif #if defined(PNG_WRITE_SWAP_SUPPORTED) /* swap bytes of 16-bit files to most significant byte first */ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) png_set_swap(png_ptr); #endif #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) /* swap bits of 1, 2, 4 bit packed pixel formats */ if (transforms & PNG_TRANSFORM_PACKSWAP) png_set_packswap(png_ptr); #endif /* ----------------------- end of transformations ------------------- */ /* write the bits */ if (info_ptr->valid & PNG_INFO_IDAT) png_write_image(png_ptr, info_ptr->row_pointers); /* It is REQUIRED to call this to finish writing the rest of the file */ png_write_end(png_ptr, info_ptr); if(transforms == 0 || params == NULL) /* quiet compiler warnings */ return; } #endif #endif /* PNG_WRITE_SUPPORTED */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/example.c0000664000175000017500000007213710777447272020770 0ustar evanevan #if 0 /* in case someone actually tries to compile this */ /* example.c - an example of using libpng */ /* This is an example of how to use libpng to read and write PNG files. * The file libpng.txt is much more verbose then this. If you have not * read it, do so first. This was designed to be a starting point of an * implementation. This is not officially part of libpng, is hereby placed * in the public domain, and therefore does not require a copyright notice. * * This file does not currently compile, because it is missing certain * parts, like allocating memory to hold an image. You will have to * supply these parts to get it to compile. For an example of a minimal * working PNG reader/writer, see pngtest.c, included in this distribution; * see also the programs in the contrib directory. */ #include "png.h" /* The png_jmpbuf() macro, used in error handling, became available in * libpng version 1.0.6. If you want to be able to run your code with older * versions of libpng, you must define the macro yourself (but only if it * is not already defined by libpng!). */ #ifndef png_jmpbuf # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) #endif /* Check to see if a file is a PNG file using png_sig_cmp(). png_sig_cmp() * returns zero if the image is a PNG and nonzero if it isn't a PNG. * * The function check_if_png() shown here, but not used, returns nonzero (true) * if the file can be opened and is a PNG, 0 (false) otherwise. * * If this call is successful, and you are going to keep the file open, * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once * you have created the png_ptr, so that libpng knows your application * has read that many bytes from the start of the file. Make sure you * don't call png_set_sig_bytes() with more than 8 bytes read or give it * an incorrect number of bytes read, or you will either have read too * many bytes (your fault), or you are telling libpng to read the wrong * number of magic bytes (also your fault). * * Many applications already read the first 2 or 4 bytes from the start * of the image to determine the file type, so it would be easiest just * to pass the bytes to png_sig_cmp() or even skip that if you know * you have a PNG file, and call png_set_sig_bytes(). */ #define PNG_BYTES_TO_CHECK 4 int check_if_png(char *file_name, FILE **fp) { char buf[PNG_BYTES_TO_CHECK]; /* Open the prospective PNG file. */ if ((*fp = fopen(file_name, "rb")) == NULL) return 0; /* Read in some of the signature bytes */ if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK) return 0; /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature. Return nonzero (true) if they match */ return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK)); } /* Read a PNG file. You may want to return an error code if the read * fails (depending upon the failure). There are two "prototypes" given * here - one where we are given the filename, and we need to open the * file, and the other where we are given an open file (possibly with * some or all of the magic bytes read - see comments above). */ #ifdef open_file /* prototype 1 */ void read_png(char *file_name) /* We need to open the file */ { png_structp png_ptr; png_infop info_ptr; unsigned int sig_read = 0; png_uint_32 width, height; int bit_depth, color_type, interlace_type; FILE *fp; if ((fp = fopen(file_name, "rb")) == NULL) return (ERROR); #else no_open_file /* prototype 2 */ void read_png(FILE *fp, unsigned int sig_read) /* file is already open */ { png_structp png_ptr; png_infop info_ptr; png_uint_32 width, height; int bit_depth, color_type, interlace_type; #endif no_open_file /* only use one prototype! */ /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also supply the * the compiler header file version, so that we know if the application * was compiled with a compatible version of the library. REQUIRED */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp user_error_ptr, user_error_fn, user_warning_fn); if (png_ptr == NULL) { fclose(fp); return (ERROR); } /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); return (ERROR); } /* Set error handling if you are using the setjmp/longjmp method (this is * the normal method of doing things with libpng). REQUIRED unless you * set up your own error handlers in the png_create_read_struct() earlier. */ if (setjmp(png_jmpbuf(png_ptr))) { /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); fclose(fp); /* If we get here, we had a problem reading the file */ return (ERROR); } /* One of the following I/O initialization methods is REQUIRED */ #ifdef streams /* PNG file I/O method 1 */ /* Set up the input control if you are using standard C streams */ png_init_io(png_ptr, fp); #else no_streams /* PNG file I/O method 2 */ /* If you are using replacement read functions, instead of calling * png_init_io() here you would call: */ png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn); /* where user_io_ptr is a structure you want available to the callbacks */ #endif no_streams /* Use only one I/O method! */ /* If we have already read some of the signature */ png_set_sig_bytes(png_ptr, sig_read); #ifdef hilevel /* * If you have enough memory to read in the entire image at once, * and you need to specify only transforms that can be controlled * with one of the PNG_TRANSFORM_* bits (this presently excludes * dithering, filling, setting background, and doing gamma * adjustment), then you can read the entire image (including * pixels) into the info structure with this call: */ png_read_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL); #else /* OK, you're doing it the hard way, with the lower-level functions */ /* The call to png_read_info() gives us all of the information from the * PNG file before the first IDAT (image data chunk). REQUIRED */ png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL); /* Set up the data transformations you want. Note that these are all * optional. Only call them if you want/need them. Many of the * transformations only work on specific types of images, and many * are mutually exclusive. */ /* tell libpng to strip 16 bit/color files down to 8 bits/color */ png_set_strip_16(png_ptr); /* Strip alpha bytes from the input data without combining with the * background (not recommended). */ png_set_strip_alpha(png_ptr); /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single * byte into separate bytes (useful for paletted and grayscale images). */ png_set_packing(png_ptr); /* Change the order of packed pixels to least significant bit first * (not useful if you are using png_set_packing). */ png_set_packswap(png_ptr); /* Expand paletted colors into true RGB triplets */ if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_rgb(png_ptr); /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr); /* Expand paletted or RGB images with transparency to full alpha channels * so the data will be available as RGBA quartets. */ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); /* Set the background color to draw transparent and alpha images over. * It is possible to set the red, green, and blue components directly * for paletted images instead of supplying a palette index. Note that * even if the PNG file supplies a background, you are not required to * use it - you should use the (solid) application background if it has one. */ png_color_16 my_background, *image_background; if (png_get_bKGD(png_ptr, info_ptr, &image_background)) png_set_background(png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); else png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); /* Some suggestions as to how to get a screen gamma value */ /* Note that screen gamma is the display_exponent, which includes * the CRT_exponent and any correction for viewing conditions */ if (/* We have a user-defined screen gamma value */) { screen_gamma = user-defined screen_gamma; } /* This is one way that applications share the same screen gamma value */ else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL) { screen_gamma = atof(gamma_str); } /* If we don't have another value */ else { screen_gamma = 2.2; /* A good guess for a PC monitors in a dimly lit room */ screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */ } /* Tell libpng to handle the gamma conversion for you. The final call * is a good guess for PC generated images, but it should be configurable * by the user at run time by the user. It is strongly suggested that * your application support gamma correction. */ int intent; if (png_get_sRGB(png_ptr, info_ptr, &intent)) png_set_gamma(png_ptr, screen_gamma, 0.45455); else { double image_gamma; if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) png_set_gamma(png_ptr, screen_gamma, image_gamma); else png_set_gamma(png_ptr, screen_gamma, 0.45455); } /* Dither RGB files down to 8 bit palette or reduce palettes * to the number of colors available on your screen. */ if (color_type & PNG_COLOR_MASK_COLOR) { int num_palette; png_colorp palette; /* This reduces the image to the application supplied palette */ if (/* we have our own palette */) { /* An array of colors to which the image should be dithered */ png_color std_color_cube[MAX_SCREEN_COLORS]; png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS, MAX_SCREEN_COLORS, png_uint_16p_NULL, 0); } /* This reduces the image to the palette supplied in the file */ else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) { png_uint_16p histogram = NULL; png_get_hIST(png_ptr, info_ptr, &histogram); png_set_dither(png_ptr, palette, num_palette, max_screen_colors, histogram, 0); } } /* invert monochrome files to have 0 as white and 1 as black */ png_set_invert_mono(png_ptr); /* If you want to shift the pixel values from the range [0,255] or * [0,65535] to the original [0,7] or [0,31], or whatever range the * colors were originally in: */ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) { png_color_8p sig_bit; png_get_sBIT(png_ptr, info_ptr, &sig_bit); png_set_shift(png_ptr, sig_bit); } /* flip the RGB pixels to BGR (or RGBA to BGRA) */ if (color_type & PNG_COLOR_MASK_COLOR) png_set_bgr(png_ptr); /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ png_set_swap_alpha(png_ptr); /* swap bytes of 16 bit files to least significant byte first */ png_set_swap(png_ptr); /* Add filler (or alpha) byte (before/after each RGB triplet) */ png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); /* Turn on interlace handling. REQUIRED if you are not using * png_read_image(). To see how to handle interlacing passes, * see the png_read_row() method below: */ number_passes = png_set_interlace_handling(png_ptr); /* Optional call to gamma correct and add the background to the palette * and update info structure. REQUIRED if you are expecting libpng to * update the palette for you (ie you selected such a transform above). */ png_read_update_info(png_ptr, info_ptr); /* Allocate the memory to hold the image using the fields of info_ptr. */ /* The easiest way to read the image: */ png_bytep row_pointers[height]; for (row = 0; row < height; row++) { row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); } /* Now it's time to read the image. One of these methods is REQUIRED */ #ifdef entire /* Read the entire image in one go */ png_read_image(png_ptr, row_pointers); #else no_entire /* Read the image one or more scanlines at a time */ /* The other way to read images - deal with interlacing: */ for (pass = 0; pass < number_passes; pass++) { #ifdef single /* Read the image a single row at a time */ for (y = 0; y < height; y++) { png_read_rows(png_ptr, &row_pointers[y], png_bytepp_NULL, 1); } #else no_single /* Read the image several rows at a time */ for (y = 0; y < height; y += number_of_rows) { #ifdef sparkle /* Read the image using the "sparkle" effect. */ png_read_rows(png_ptr, &row_pointers[y], png_bytepp_NULL, number_of_rows); #else no_sparkle /* Read the image using the "rectangle" effect */ png_read_rows(png_ptr, png_bytepp_NULL, &row_pointers[y], number_of_rows); #endif no_sparkle /* use only one of these two methods */ } /* if you want to display the image after every pass, do so here */ #endif no_single /* use only one of these two methods */ } #endif no_entire /* use only one of these two methods */ /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ png_read_end(png_ptr, info_ptr); #endif hilevel /* At this point you have read the entire image */ /* clean up after the read, and free any memory allocated - REQUIRED */ png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); /* close the file */ fclose(fp); /* that's it */ return (OK); } /* progressively read a file */ int initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr) { /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also check that * the library version is compatible in case we are using dynamically * linked libraries. */ *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp user_error_ptr, user_error_fn, user_warning_fn); if (*png_ptr == NULL) { *info_ptr = NULL; return (ERROR); } *info_ptr = png_create_info_struct(png_ptr); if (*info_ptr == NULL) { png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL); return (ERROR); } if (setjmp(png_jmpbuf((*png_ptr)))) { png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL); return (ERROR); } /* This one's new. You will need to provide all three * function callbacks, even if you aren't using them all. * If you aren't using all functions, you can specify NULL * parameters. Even when all three functions are NULL, * you need to call png_set_progressive_read_fn(). * These functions shouldn't be dependent on global or * static variables if you are decoding several images * simultaneously. You should store stream specific data * in a separate struct, given as the second parameter, * and retrieve the pointer from inside the callbacks using * the function png_get_progressive_ptr(png_ptr). */ png_set_progressive_read_fn(*png_ptr, (void *)stream_data, info_callback, row_callback, end_callback); return (OK); } int process_data(png_structp *png_ptr, png_infop *info_ptr, png_bytep buffer, png_uint_32 length) { if (setjmp(png_jmpbuf((*png_ptr)))) { /* Free the png_ptr and info_ptr memory on error */ png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL); return (ERROR); } /* This one's new also. Simply give it chunks of data as * they arrive from the data stream (in order, of course). * On Segmented machines, don't give it any more than 64K. * The library seems to run fine with sizes of 4K, although * you can give it much less if necessary (I assume you can * give it chunks of 1 byte, but I haven't tried with less * than 256 bytes yet). When this function returns, you may * want to display any rows that were generated in the row * callback, if you aren't already displaying them there. */ png_process_data(*png_ptr, *info_ptr, buffer, length); return (OK); } info_callback(png_structp png_ptr, png_infop info) { /* do any setup here, including setting any of the transformations * mentioned in the Reading PNG files section. For now, you _must_ * call either png_start_read_image() or png_read_update_info() * after all the transformations are set (even if you don't set * any). You may start getting rows before png_process_data() * returns, so this is your last chance to prepare for that. */ } row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass) { /* * This function is called for every row in the image. If the * image is interlaced, and you turned on the interlace handler, * this function will be called for every row in every pass. * * In this function you will receive a pointer to new row data from * libpng called new_row that is to replace a corresponding row (of * the same data format) in a buffer allocated by your application. * * The new row data pointer new_row may be NULL, indicating there is * no new data to be replaced (in cases of interlace loading). * * If new_row is not NULL then you need to call * png_progressive_combine_row() to replace the corresponding row as * shown below: */ /* Check if row_num is in bounds. */ if((row_num >= 0) && (row_num < height)) { /* Get pointer to corresponding row in our * PNG read buffer. */ png_bytep old_row = ((png_bytep *)our_data)[row_num]; /* If both rows are allocated then copy the new row * data to the corresponding row data. */ if((old_row != NULL) && (new_row != NULL)) png_progressive_combine_row(png_ptr, old_row, new_row); } /* * The rows and passes are called in order, so you don't really * need the row_num and pass, but I'm supplying them because it * may make your life easier. * * For the non-NULL rows of interlaced images, you must call * png_progressive_combine_row() passing in the new row and the * old row, as demonstrated above. You can call this function for * NULL rows (it will just return) and for non-interlaced images * (it just does the png_memcpy for you) if it will make the code * easier. Thus, you can just do this for all cases: */ png_progressive_combine_row(png_ptr, old_row, new_row); /* where old_row is what was displayed for previous rows. Note * that the first pass (pass == 0 really) will completely cover * the old row, so the rows do not have to be initialized. After * the first pass (and only for interlaced images), you will have * to pass the current row as new_row, and the function will combine * the old row and the new row. */ } end_callback(png_structp png_ptr, png_infop info) { /* this function is called when the whole image has been read, * including any chunks after the image (up to and including * the IEND). You will usually have the same info chunk as you * had in the header, although some data may have been added * to the comments and time fields. * * Most people won't do much here, perhaps setting a flag that * marks the image as finished. */ } /* write a png file */ void write_png(char *file_name /* , ... other image information ... */) { FILE *fp; png_structp png_ptr; png_infop info_ptr; png_colorp palette; /* open the file */ fp = fopen(file_name, "wb"); if (fp == NULL) return (ERROR); /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also check that * the library version is compatible with the one used at compile time, * in case we are using dynamically linked libraries. REQUIRED. */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp user_error_ptr, user_error_fn, user_warning_fn); if (png_ptr == NULL) { fclose(fp); return (ERROR); } /* Allocate/initialize the image information data. REQUIRED */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_write_struct(&png_ptr, png_infopp_NULL); return (ERROR); } /* Set error handling. REQUIRED if you aren't supplying your own * error handling functions in the png_create_write_struct() call. */ if (setjmp(png_jmpbuf(png_ptr))) { /* If we get here, we had a problem reading the file */ fclose(fp); png_destroy_write_struct(&png_ptr, &info_ptr); return (ERROR); } /* One of the following I/O initialization functions is REQUIRED */ #ifdef streams /* I/O initialization method 1 */ /* set up the output control if you are using standard C streams */ png_init_io(png_ptr, fp); #else no_streams /* I/O initialization method 2 */ /* If you are using replacement read functions, instead of calling * png_init_io() here you would call */ png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn, user_IO_flush_function); /* where user_io_ptr is a structure you want available to the callbacks */ #endif no_streams /* only use one initialization method */ #ifdef hilevel /* This is the easy way. Use it if you already have all the * image info living info in the structure. You could "|" many * PNG_TRANSFORM flags into the png_transforms integer here. */ png_write_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL); #else /* This is the hard way */ /* Set the image information here. Width and height are up to 2^31, * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED */ png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???, PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); /* set the palette if there is one. REQUIRED for indexed-color images */ palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * png_sizeof (png_color)); /* ... set palette colors ... */ png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH); /* You must not free palette here, because png_set_PLTE only makes a link to the palette that you malloced. Wait until you are about to destroy the png structure. */ /* optional significant bit chunk */ /* if we are dealing with a grayscale image then */ sig_bit.gray = true_bit_depth; /* otherwise, if we are dealing with a color image then */ sig_bit.red = true_red_bit_depth; sig_bit.green = true_green_bit_depth; sig_bit.blue = true_blue_bit_depth; /* if the image has an alpha channel then */ sig_bit.alpha = true_alpha_bit_depth; png_set_sBIT(png_ptr, info_ptr, sig_bit); /* Optional gamma chunk is strongly suggested if you have any guess * as to the correct gamma of the image. */ png_set_gAMA(png_ptr, info_ptr, gamma); /* Optionally write comments into the image */ text_ptr[0].key = "Title"; text_ptr[0].text = "Mona Lisa"; text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE; text_ptr[1].key = "Author"; text_ptr[1].text = "Leonardo DaVinci"; text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE; text_ptr[2].key = "Description"; text_ptr[2].text = ""; text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt; #ifdef PNG_iTXt_SUPPORTED text_ptr[0].lang = NULL; text_ptr[1].lang = NULL; text_ptr[2].lang = NULL; #endif png_set_text(png_ptr, info_ptr, text_ptr, 3); /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */ /* note that if sRGB is present the gAMA and cHRM chunks must be ignored * on read and must be written in accordance with the sRGB profile */ /* Write the file header information. REQUIRED */ png_write_info(png_ptr, info_ptr); /* If you want, you can write the info in two steps, in case you need to * write your private chunk ahead of PLTE: * * png_write_info_before_PLTE(write_ptr, write_info_ptr); * write_my_chunk(); * png_write_info(png_ptr, info_ptr); * * However, given the level of known- and unknown-chunk support in 1.1.0 * and up, this should no longer be necessary. */ /* Once we write out the header, the compression type on the text * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again * at the end. */ /* set up the transformations you want. Note that these are * all optional. Only call them if you want them. */ /* invert monochrome pixels */ png_set_invert_mono(png_ptr); /* Shift the pixels up to a legal bit depth and fill in * as appropriate to correctly scale the image. */ png_set_shift(png_ptr, &sig_bit); /* pack pixels into bytes */ png_set_packing(png_ptr); /* swap location of alpha bytes from ARGB to RGBA */ png_set_swap_alpha(png_ptr); /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into * RGB (4 channels -> 3 channels). The second parameter is not used. */ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); /* flip BGR pixels to RGB */ png_set_bgr(png_ptr); /* swap bytes of 16-bit files to most significant byte first */ png_set_swap(png_ptr); /* swap bits of 1, 2, 4 bit packed pixel formats */ png_set_packswap(png_ptr); /* turn on interlace handling if you are not using png_write_image() */ if (interlacing) number_passes = png_set_interlace_handling(png_ptr); else number_passes = 1; /* The easiest way to write the image (you may have a different memory * layout, however, so choose what fits your needs best). You need to * use the first method if you aren't handling interlacing yourself. */ png_uint_32 k, height, width; png_byte image[height][width*bytes_per_pixel]; png_bytep row_pointers[height]; if (height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) png_error (png_ptr, "Image is too tall to process in memory"); for (k = 0; k < height; k++) row_pointers[k] = image + k*width*bytes_per_pixel; /* One of the following output methods is REQUIRED */ #ifdef entire /* write out the entire image data in one call */ png_write_image(png_ptr, row_pointers); /* the other way to write the image - deal with interlacing */ #else no_entire /* write out the image data by one or more scanlines */ /* The number of passes is either 1 for non-interlaced images, * or 7 for interlaced images. */ for (pass = 0; pass < number_passes; pass++) { /* Write a few rows at a time. */ png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows); /* If you are only writing one row at a time, this works */ for (y = 0; y < height; y++) { png_write_rows(png_ptr, &row_pointers[y], 1); } } #endif no_entire /* use only one output method */ /* You can write optional chunks like tEXt, zTXt, and tIME at the end * as well. Shouldn't be necessary in 1.1.0 and up as all the public * chunks are supported and you can use png_set_unknown_chunks() to * register unknown chunks into the info structure to be written out. */ /* It is REQUIRED to call this to finish writing the rest of the file */ png_write_end(png_ptr, info_ptr); #endif hilevel /* If you png_malloced a palette, free it here (don't free info_ptr->palette, as recommended in versions 1.0.5m and earlier of this example; if libpng mallocs info_ptr->palette, libpng will free it). If you allocated it with malloc() instead of png_malloc(), use free() instead of png_free(). */ png_free(png_ptr, palette); palette=NULL; /* Similarly, if you png_malloced any data that you passed in with png_set_something(), such as a hist or trans array, free it here, when you can be sure that libpng is through with it. */ png_free(png_ptr, trans); trans=NULL; /* clean up after the write, and free any memory allocated */ png_destroy_write_struct(&png_ptr, &info_ptr); /* close the file */ fclose(fp); /* that's it */ return (OK); } #endif /* if 0 */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/TODO0000664000175000017500000000223610777447272017652 0ustar evanevanTODO - list of things to do for libpng: Final bug fixes. Improve API by hiding the png_struct and png_info structs. Finish work on the no-floating-point version (including gamma compensation) Better C++ wrapper/full C++ implementation? Fix problem with C++ and EXTERN "C". cHRM transformation. Improve setjmp/longjmp usage or remove it in favor of returning error codes. Add "grayscale->palette" transformation and "palette->grayscale" detection. Improved dithering. Multi-lingual error and warning message support. Complete sRGB transformation (presently it simply uses gamma=0.45455). Man pages for function calls. Better documentation. Better filter selection (counting huffman bits/precompression? filter inertia? filter costs?). Histogram creation. Text conversion between different code pages (Latin-1 -> Mac and DOS). Should we always malloc 2^bit_depth PLTE/tRNS/hIST entries for safety? Build gamma tables using fixed point (and do away with floating point entirely). Use greater precision when changing to linear gamma for compositing against background and doing rgb-to-gray transformation. Investigate pre-incremented loop counters and other loop constructions. syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngtrans.c0000664000175000017500000004763210777447272021173 0ustar evanevan /* pngtrans.c - transforms the data in a row (used by both readers and writers) * * libpng 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ #define PNG_INTERNAL #include "png.h" #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) /* turn on BGR-to-RGB mapping */ void PNGAPI png_set_bgr(png_structp png_ptr) { png_debug(1, "in png_set_bgr\n"); png_ptr->transformations |= PNG_BGR; } #endif #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) /* turn on 16 bit byte swapping */ void PNGAPI png_set_swap(png_structp png_ptr) { png_debug(1, "in png_set_swap\n"); if (png_ptr->bit_depth == 16) png_ptr->transformations |= PNG_SWAP_BYTES; } #endif #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) /* turn on pixel packing */ void PNGAPI png_set_packing(png_structp png_ptr) { png_debug(1, "in png_set_packing\n"); if (png_ptr->bit_depth < 8) { png_ptr->transformations |= PNG_PACK; png_ptr->usr_bit_depth = 8; } } #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) /* turn on packed pixel swapping */ void PNGAPI png_set_packswap(png_structp png_ptr) { png_debug(1, "in png_set_packswap\n"); if (png_ptr->bit_depth < 8) png_ptr->transformations |= PNG_PACKSWAP; } #endif #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) void PNGAPI png_set_shift(png_structp png_ptr, png_color_8p true_bits) { png_debug(1, "in png_set_shift\n"); png_ptr->transformations |= PNG_SHIFT; png_ptr->shift = *true_bits; } #endif #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ defined(PNG_WRITE_INTERLACING_SUPPORTED) int PNGAPI png_set_interlace_handling(png_structp png_ptr) { png_debug(1, "in png_set_interlace handling\n"); if (png_ptr->interlaced) { png_ptr->transformations |= PNG_INTERLACE; return (7); } return (1); } #endif #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) /* Add a filler byte on read, or remove a filler or alpha byte on write. * The filler type has changed in v0.95 to allow future 2-byte fillers * for 48-bit input data, as well as to avoid problems with some compilers * that don't like bytes as parameters. */ void PNGAPI png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) { png_debug(1, "in png_set_filler\n"); png_ptr->transformations |= PNG_FILLER; png_ptr->filler = (png_byte)filler; if (filler_loc == PNG_FILLER_AFTER) png_ptr->flags |= PNG_FLAG_FILLER_AFTER; else png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; /* This should probably go in the "do_read_filler" routine. * I attempted to do that in libpng-1.0.1a but that caused problems * so I restored it in libpng-1.0.2a */ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) { png_ptr->usr_channels = 4; } /* Also I added this in libpng-1.0.2a (what happens when we expand * a less-than-8-bit grayscale to GA? */ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8) { png_ptr->usr_channels = 2; } } #if !defined(PNG_1_0_X) /* Added to libpng-1.2.7 */ void PNGAPI png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) { png_debug(1, "in png_set_add_alpha\n"); png_set_filler(png_ptr, filler, filler_loc); png_ptr->transformations |= PNG_ADD_ALPHA; } #endif #endif #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) void PNGAPI png_set_swap_alpha(png_structp png_ptr) { png_debug(1, "in png_set_swap_alpha\n"); png_ptr->transformations |= PNG_SWAP_ALPHA; } #endif #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) void PNGAPI png_set_invert_alpha(png_structp png_ptr) { png_debug(1, "in png_set_invert_alpha\n"); png_ptr->transformations |= PNG_INVERT_ALPHA; } #endif #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) void PNGAPI png_set_invert_mono(png_structp png_ptr) { png_debug(1, "in png_set_invert_mono\n"); png_ptr->transformations |= PNG_INVERT_MONO; } /* invert monochrome grayscale data */ void /* PRIVATE */ png_do_invert(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_invert\n"); /* This test removed from libpng version 1.0.13 and 1.2.0: * if (row_info->bit_depth == 1 && */ #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row == NULL || row_info == NULL) return; #endif if (row_info->color_type == PNG_COLOR_TYPE_GRAY) { png_bytep rp = row; png_uint_32 i; png_uint_32 istop = row_info->rowbytes; for (i = 0; i < istop; i++) { *rp = (png_byte)(~(*rp)); rp++; } } else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && row_info->bit_depth == 8) { png_bytep rp = row; png_uint_32 i; png_uint_32 istop = row_info->rowbytes; for (i = 0; i < istop; i+=2) { *rp = (png_byte)(~(*rp)); rp+=2; } } else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && row_info->bit_depth == 16) { png_bytep rp = row; png_uint_32 i; png_uint_32 istop = row_info->rowbytes; for (i = 0; i < istop; i+=4) { *rp = (png_byte)(~(*rp)); *(rp+1) = (png_byte)(~(*(rp+1))); rp+=4; } } } #endif #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) /* swaps byte order on 16 bit depth images */ void /* PRIVATE */ png_do_swap(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_swap\n"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif row_info->bit_depth == 16) { png_bytep rp = row; png_uint_32 i; png_uint_32 istop= row_info->width * row_info->channels; for (i = 0; i < istop; i++, rp += 2) { png_byte t = *rp; *rp = *(rp + 1); *(rp + 1) = t; } } } #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) static png_byte onebppswaptable[256] = { 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF }; static png_byte twobppswaptable[256] = { 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4, 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8, 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8, 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC, 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC, 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1, 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1, 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5, 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5, 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9, 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9, 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD, 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD, 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2, 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2, 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6, 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6, 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA, 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA, 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE, 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE, 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3, 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3, 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7, 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7, 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB, 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB, 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF, 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF }; static png_byte fourbppswaptable[256] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF }; /* swaps pixel packing order within bytes */ void /* PRIVATE */ png_do_packswap(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_packswap\n"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif row_info->bit_depth < 8) { png_bytep rp, end, table; end = row + row_info->rowbytes; if (row_info->bit_depth == 1) table = onebppswaptable; else if (row_info->bit_depth == 2) table = twobppswaptable; else if (row_info->bit_depth == 4) table = fourbppswaptable; else return; for (rp = row; rp < end; rp++) *rp = table[*rp]; } } #endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */ #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ defined(PNG_READ_STRIP_ALPHA_SUPPORTED) /* remove filler or alpha byte(s) */ void /* PRIVATE */ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) { png_debug(1, "in png_do_strip_filler\n"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif { png_bytep sp=row; png_bytep dp=row; png_uint_32 row_width=row_info->width; png_uint_32 i; if ((row_info->color_type == PNG_COLOR_TYPE_RGB || (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && (flags & PNG_FLAG_STRIP_ALPHA))) && row_info->channels == 4) { if (row_info->bit_depth == 8) { /* This converts from RGBX or RGBA to RGB */ if (flags & PNG_FLAG_FILLER_AFTER) { dp+=3; sp+=4; for (i = 1; i < row_width; i++) { *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; sp++; } } /* This converts from XRGB or ARGB to RGB */ else { for (i = 0; i < row_width; i++) { sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; } } row_info->pixel_depth = 24; row_info->rowbytes = row_width * 3; } else /* if (row_info->bit_depth == 16) */ { if (flags & PNG_FLAG_FILLER_AFTER) { /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */ sp += 8; dp += 6; for (i = 1; i < row_width; i++) { /* This could be (although png_memcpy is probably slower): png_memcpy(dp, sp, 6); sp += 8; dp += 6; */ *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; sp += 2; } } else { /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */ for (i = 0; i < row_width; i++) { /* This could be (although png_memcpy is probably slower): png_memcpy(dp, sp, 6); sp += 8; dp += 6; */ sp+=2; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; } } row_info->pixel_depth = 48; row_info->rowbytes = row_width * 6; } row_info->channels = 3; } else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY || (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && (flags & PNG_FLAG_STRIP_ALPHA))) && row_info->channels == 2) { if (row_info->bit_depth == 8) { /* This converts from GX or GA to G */ if (flags & PNG_FLAG_FILLER_AFTER) { for (i = 0; i < row_width; i++) { *dp++ = *sp++; sp++; } } /* This converts from XG or AG to G */ else { for (i = 0; i < row_width; i++) { sp++; *dp++ = *sp++; } } row_info->pixel_depth = 8; row_info->rowbytes = row_width; } else /* if (row_info->bit_depth == 16) */ { if (flags & PNG_FLAG_FILLER_AFTER) { /* This converts from GGXX or GGAA to GG */ sp += 4; dp += 2; for (i = 1; i < row_width; i++) { *dp++ = *sp++; *dp++ = *sp++; sp += 2; } } else { /* This converts from XXGG or AAGG to GG */ for (i = 0; i < row_width; i++) { sp += 2; *dp++ = *sp++; *dp++ = *sp++; } } row_info->pixel_depth = 16; row_info->rowbytes = row_width * 2; } row_info->channels = 1; } if (flags & PNG_FLAG_STRIP_ALPHA) row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; } } #endif #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) /* swaps red and blue bytes within a pixel */ void /* PRIVATE */ png_do_bgr(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_bgr\n"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif (row_info->color_type & PNG_COLOR_MASK_COLOR)) { png_uint_32 row_width = row_info->width; if (row_info->bit_depth == 8) { if (row_info->color_type == PNG_COLOR_TYPE_RGB) { png_bytep rp; png_uint_32 i; for (i = 0, rp = row; i < row_width; i++, rp += 3) { png_byte save = *rp; *rp = *(rp + 2); *(rp + 2) = save; } } else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { png_bytep rp; png_uint_32 i; for (i = 0, rp = row; i < row_width; i++, rp += 4) { png_byte save = *rp; *rp = *(rp + 2); *(rp + 2) = save; } } } else if (row_info->bit_depth == 16) { if (row_info->color_type == PNG_COLOR_TYPE_RGB) { png_bytep rp; png_uint_32 i; for (i = 0, rp = row; i < row_width; i++, rp += 6) { png_byte save = *rp; *rp = *(rp + 4); *(rp + 4) = save; save = *(rp + 1); *(rp + 1) = *(rp + 5); *(rp + 5) = save; } } else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { png_bytep rp; png_uint_32 i; for (i = 0, rp = row; i < row_width; i++, rp += 8) { png_byte save = *rp; *rp = *(rp + 4); *(rp + 4) = save; save = *(rp + 1); *(rp + 1) = *(rp + 5); *(rp + 5) = save; } } } } } #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_LEGACY_SUPPORTED) void PNGAPI png_set_user_transform_info(png_structp png_ptr, png_voidp user_transform_ptr, int user_transform_depth, int user_transform_channels) { png_debug(1, "in png_set_user_transform_info\n"); #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) png_ptr->user_transform_ptr = user_transform_ptr; png_ptr->user_transform_depth = (png_byte)user_transform_depth; png_ptr->user_transform_channels = (png_byte)user_transform_channels; #else if(user_transform_ptr || user_transform_depth || user_transform_channels) png_warning(png_ptr, "This version of libpng does not support user transform info"); #endif } #endif /* This function returns a pointer to the user_transform_ptr associated with * the user transform functions. The application should free any memory * associated with this pointer before png_write_destroy and png_read_destroy * are called. */ png_voidp PNGAPI png_get_user_transform_ptr(png_structp png_ptr) { #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) return ((png_voidp)png_ptr->user_transform_ptr); #else if(png_ptr) return (NULL); return (NULL); #endif } syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngvcrd.c0000664000175000017500000043006610777447272020777 0ustar evanevan/* pngvcrd.c - mixed C/assembler version of utilities to read a PNG file * * For Intel x86 CPU and Microsoft Visual C++ compiler * * libpng version 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * Copyright (c) 1998, Intel Corporation * * Contributed by Nirav Chhatrapati, Intel Corporation, 1998 * Interface to libpng contributed by Gilles Vollant, 1999 * * * In png_do_read_interlace() in libpng versions 1.0.3a through 1.0.4d, * a sign error in the post-MMX cleanup code for each pixel_depth resulted * in bad pixels at the beginning of some rows of some images, and also * (due to out-of-range memory reads and writes) caused heap corruption * when compiled with MSVC 6.0. The error was fixed in version 1.0.4e. * * [png_read_filter_row_mmx_avg() bpp == 2 bugfix, GRR 20000916] * * [runtime MMX configuration, GRR 20010102] * */ #define PNG_INTERNAL #include "png.h" #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD) static int mmx_supported=2; int PNGAPI png_mmx_support(void) { int mmx_supported_local = 0; _asm { push ebx //CPUID will trash these push ecx push edx pushfd //Save Eflag to stack pop eax //Get Eflag from stack into eax mov ecx, eax //Make another copy of Eflag in ecx xor eax, 0x200000 //Toggle ID bit in Eflag [i.e. bit(21)] push eax //Save modified Eflag back to stack popfd //Restored modified value back to Eflag reg pushfd //Save Eflag to stack pop eax //Get Eflag from stack push ecx // save original Eflag to stack popfd // restore original Eflag xor eax, ecx //Compare the new Eflag with the original Eflag jz NOT_SUPPORTED //If the same, CPUID instruction is not supported, //skip following instructions and jump to //NOT_SUPPORTED label xor eax, eax //Set eax to zero _asm _emit 0x0f //CPUID instruction (two bytes opcode) _asm _emit 0xa2 cmp eax, 1 //make sure eax return non-zero value jl NOT_SUPPORTED //If eax is zero, mmx not supported xor eax, eax //set eax to zero inc eax //Now increment eax to 1. This instruction is //faster than the instruction "mov eax, 1" _asm _emit 0x0f //CPUID instruction _asm _emit 0xa2 and edx, 0x00800000 //mask out all bits but mmx bit(24) cmp edx, 0 // 0 = mmx not supported jz NOT_SUPPORTED // non-zero = Yes, mmx IS supported mov mmx_supported_local, 1 //set return value to 1 NOT_SUPPORTED: mov eax, mmx_supported_local //move return value to eax pop edx //CPUID trashed these pop ecx pop ebx } //mmx_supported_local=0; // test code for force don't support MMX //printf("MMX : %u (1=MMX supported)\n",mmx_supported_local); mmx_supported = mmx_supported_local; return mmx_supported_local; } /* Combines the row recently read in with the previous row. This routine takes care of alpha and transparency if requested. This routine also handles the two methods of progressive display of interlaced images, depending on the mask value. The mask value describes which pixels are to be combined with the row. The pattern always repeats every 8 pixels, so just 8 bits are needed. A one indicates the pixel is to be combined; a zero indicates the pixel is to be skipped. This is in addition to any alpha or transparency value associated with the pixel. If you want all pixels to be combined, pass 0xff (255) in mask. */ /* Use this routine for x86 platform - uses faster MMX routine if machine supports MMX */ void /* PRIVATE */ png_combine_row(png_structp png_ptr, png_bytep row, int mask) { #ifdef PNG_USE_LOCAL_ARRAYS const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; #endif png_debug(1,"in png_combine_row_asm\n"); if (mmx_supported == 2) { #if !defined(PNG_1_0_X) /* this should have happened in png_init_mmx_flags() already */ png_warning(png_ptr, "asm_flags may not have been initialized"); #endif png_mmx_support(); } if (mask == 0xff) { png_memcpy(row, png_ptr->row_buf + 1, (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); } /* GRR: add "else if (mask == 0)" case? * or does png_combine_row() not even get called in that case? */ else { switch (png_ptr->row_info.pixel_depth) { case 1: { png_bytep sp; png_bytep dp; int s_inc, s_start, s_end; int m; int shift; png_uint_32 i; sp = png_ptr->row_buf + 1; dp = row; m = 0x80; #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; s_end = 7; s_inc = 1; } else #endif { s_start = 7; s_end = 0; s_inc = -1; } shift = s_start; for (i = 0; i < png_ptr->width; i++) { if (m & mask) { int value; value = (*sp >> shift) & 0x1; *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); *dp |= (png_byte)(value << shift); } if (shift == s_end) { shift = s_start; sp++; dp++; } else shift += s_inc; if (m == 1) m = 0x80; else m >>= 1; } break; } case 2: { png_bytep sp; png_bytep dp; int s_start, s_end, s_inc; int m; int shift; png_uint_32 i; int value; sp = png_ptr->row_buf + 1; dp = row; m = 0x80; #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; s_end = 6; s_inc = 2; } else #endif { s_start = 6; s_end = 0; s_inc = -2; } shift = s_start; for (i = 0; i < png_ptr->width; i++) { if (m & mask) { value = (*sp >> shift) & 0x3; *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); *dp |= (png_byte)(value << shift); } if (shift == s_end) { shift = s_start; sp++; dp++; } else shift += s_inc; if (m == 1) m = 0x80; else m >>= 1; } break; } case 4: { png_bytep sp; png_bytep dp; int s_start, s_end, s_inc; int m; int shift; png_uint_32 i; int value; sp = png_ptr->row_buf + 1; dp = row; m = 0x80; #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; s_end = 4; s_inc = 4; } else #endif { s_start = 4; s_end = 0; s_inc = -4; } shift = s_start; for (i = 0; i < png_ptr->width; i++) { if (m & mask) { value = (*sp >> shift) & 0xf; *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); *dp |= (png_byte)(value << shift); } if (shift == s_end) { shift = s_start; sp++; dp++; } else shift += s_inc; if (m == 1) m = 0x80; else m >>= 1; } break; } case 8: { png_bytep srcptr; png_bytep dstptr; png_uint_32 len; int m; int diff, unmask; __int64 mask0=0x0102040810204080; #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && mmx_supported */ ) #else if (mmx_supported) #endif { srcptr = png_ptr->row_buf + 1; dstptr = row; m = 0x80; unmask = ~mask; len = png_ptr->width &~7; //reduce to multiple of 8 diff = png_ptr->width & 7; //amount lost _asm { movd mm7, unmask //load bit pattern psubb mm6,mm6 //zero mm6 punpcklbw mm7,mm7 punpcklwd mm7,mm7 punpckldq mm7,mm7 //fill register with 8 masks movq mm0,mask0 pand mm0,mm7 //nonzero if keep byte pcmpeqb mm0,mm6 //zeros->1s, v versa mov ecx,len //load length of line (pixels) mov esi,srcptr //load source mov ebx,dstptr //load dest cmp ecx,0 //lcr je mainloop8end mainloop8: movq mm4,[esi] pand mm4,mm0 movq mm6,mm0 pandn mm6,[ebx] por mm4,mm6 movq [ebx],mm4 add esi,8 //inc by 8 bytes processed add ebx,8 sub ecx,8 //dec by 8 pixels processed ja mainloop8 mainloop8end: mov ecx,diff cmp ecx,0 jz end8 mov edx,mask sal edx,24 //make low byte the high byte secondloop8: sal edx,1 //move high bit to CF jnc skip8 //if CF = 0 mov al,[esi] mov [ebx],al skip8: inc esi inc ebx dec ecx jnz secondloop8 end8: emms } } else /* mmx not supported - use modified C routine */ { register unsigned int incr1, initial_val, final_val; png_size_t pixel_bytes; png_uint_32 i; register int disp = png_pass_inc[png_ptr->pass]; int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* pixel_bytes; dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; initial_val = offset_table[png_ptr->pass]*pixel_bytes; final_val = png_ptr->width*pixel_bytes; incr1 = (disp)*pixel_bytes; for (i = initial_val; i < final_val; i += incr1) { png_memcpy(dstptr, srcptr, pixel_bytes); srcptr += incr1; dstptr += incr1; } } /* end of else */ break; } // end 8 bpp case 16: { png_bytep srcptr; png_bytep dstptr; png_uint_32 len; int unmask, diff; __int64 mask1=0x0101020204040808, mask0=0x1010202040408080; #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && mmx_supported */ ) #else if (mmx_supported) #endif { srcptr = png_ptr->row_buf + 1; dstptr = row; unmask = ~mask; len = (png_ptr->width)&~7; diff = (png_ptr->width)&7; _asm { movd mm7, unmask //load bit pattern psubb mm6,mm6 //zero mm6 punpcklbw mm7,mm7 punpcklwd mm7,mm7 punpckldq mm7,mm7 //fill register with 8 masks movq mm0,mask0 movq mm1,mask1 pand mm0,mm7 pand mm1,mm7 pcmpeqb mm0,mm6 pcmpeqb mm1,mm6 mov ecx,len //load length of line mov esi,srcptr //load source mov ebx,dstptr //load dest cmp ecx,0 //lcr jz mainloop16end mainloop16: movq mm4,[esi] pand mm4,mm0 movq mm6,mm0 movq mm7,[ebx] pandn mm6,mm7 por mm4,mm6 movq [ebx],mm4 movq mm5,[esi+8] pand mm5,mm1 movq mm7,mm1 movq mm6,[ebx+8] pandn mm7,mm6 por mm5,mm7 movq [ebx+8],mm5 add esi,16 //inc by 16 bytes processed add ebx,16 sub ecx,8 //dec by 8 pixels processed ja mainloop16 mainloop16end: mov ecx,diff cmp ecx,0 jz end16 mov edx,mask sal edx,24 //make low byte the high byte secondloop16: sal edx,1 //move high bit to CF jnc skip16 //if CF = 0 mov ax,[esi] mov [ebx],ax skip16: add esi,2 add ebx,2 dec ecx jnz secondloop16 end16: emms } } else /* mmx not supported - use modified C routine */ { register unsigned int incr1, initial_val, final_val; png_size_t pixel_bytes; png_uint_32 i; register int disp = png_pass_inc[png_ptr->pass]; int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* pixel_bytes; dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; initial_val = offset_table[png_ptr->pass]*pixel_bytes; final_val = png_ptr->width*pixel_bytes; incr1 = (disp)*pixel_bytes; for (i = initial_val; i < final_val; i += incr1) { png_memcpy(dstptr, srcptr, pixel_bytes); srcptr += incr1; dstptr += incr1; } } /* end of else */ break; } // end 16 bpp case 24: { png_bytep srcptr; png_bytep dstptr; png_uint_32 len; int unmask, diff; __int64 mask2=0x0101010202020404, //24bpp mask1=0x0408080810101020, mask0=0x2020404040808080; srcptr = png_ptr->row_buf + 1; dstptr = row; unmask = ~mask; len = (png_ptr->width)&~7; diff = (png_ptr->width)&7; #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && mmx_supported */ ) #else if (mmx_supported) #endif { _asm { movd mm7, unmask //load bit pattern psubb mm6,mm6 //zero mm6 punpcklbw mm7,mm7 punpcklwd mm7,mm7 punpckldq mm7,mm7 //fill register with 8 masks movq mm0,mask0 movq mm1,mask1 movq mm2,mask2 pand mm0,mm7 pand mm1,mm7 pand mm2,mm7 pcmpeqb mm0,mm6 pcmpeqb mm1,mm6 pcmpeqb mm2,mm6 mov ecx,len //load length of line mov esi,srcptr //load source mov ebx,dstptr //load dest cmp ecx,0 jz mainloop24end mainloop24: movq mm4,[esi] pand mm4,mm0 movq mm6,mm0 movq mm7,[ebx] pandn mm6,mm7 por mm4,mm6 movq [ebx],mm4 movq mm5,[esi+8] pand mm5,mm1 movq mm7,mm1 movq mm6,[ebx+8] pandn mm7,mm6 por mm5,mm7 movq [ebx+8],mm5 movq mm6,[esi+16] pand mm6,mm2 movq mm4,mm2 movq mm7,[ebx+16] pandn mm4,mm7 por mm6,mm4 movq [ebx+16],mm6 add esi,24 //inc by 24 bytes processed add ebx,24 sub ecx,8 //dec by 8 pixels processed ja mainloop24 mainloop24end: mov ecx,diff cmp ecx,0 jz end24 mov edx,mask sal edx,24 //make low byte the high byte secondloop24: sal edx,1 //move high bit to CF jnc skip24 //if CF = 0 mov ax,[esi] mov [ebx],ax xor eax,eax mov al,[esi+2] mov [ebx+2],al skip24: add esi,3 add ebx,3 dec ecx jnz secondloop24 end24: emms } } else /* mmx not supported - use modified C routine */ { register unsigned int incr1, initial_val, final_val; png_size_t pixel_bytes; png_uint_32 i; register int disp = png_pass_inc[png_ptr->pass]; int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* pixel_bytes; dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; initial_val = offset_table[png_ptr->pass]*pixel_bytes; final_val = png_ptr->width*pixel_bytes; incr1 = (disp)*pixel_bytes; for (i = initial_val; i < final_val; i += incr1) { png_memcpy(dstptr, srcptr, pixel_bytes); srcptr += incr1; dstptr += incr1; } } /* end of else */ break; } // end 24 bpp case 32: { png_bytep srcptr; png_bytep dstptr; png_uint_32 len; int unmask, diff; __int64 mask3=0x0101010102020202, //32bpp mask2=0x0404040408080808, mask1=0x1010101020202020, mask0=0x4040404080808080; srcptr = png_ptr->row_buf + 1; dstptr = row; unmask = ~mask; len = (png_ptr->width)&~7; diff = (png_ptr->width)&7; #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && mmx_supported */ ) #else if (mmx_supported) #endif { _asm { movd mm7, unmask //load bit pattern psubb mm6,mm6 //zero mm6 punpcklbw mm7,mm7 punpcklwd mm7,mm7 punpckldq mm7,mm7 //fill register with 8 masks movq mm0,mask0 movq mm1,mask1 movq mm2,mask2 movq mm3,mask3 pand mm0,mm7 pand mm1,mm7 pand mm2,mm7 pand mm3,mm7 pcmpeqb mm0,mm6 pcmpeqb mm1,mm6 pcmpeqb mm2,mm6 pcmpeqb mm3,mm6 mov ecx,len //load length of line mov esi,srcptr //load source mov ebx,dstptr //load dest cmp ecx,0 //lcr jz mainloop32end mainloop32: movq mm4,[esi] pand mm4,mm0 movq mm6,mm0 movq mm7,[ebx] pandn mm6,mm7 por mm4,mm6 movq [ebx],mm4 movq mm5,[esi+8] pand mm5,mm1 movq mm7,mm1 movq mm6,[ebx+8] pandn mm7,mm6 por mm5,mm7 movq [ebx+8],mm5 movq mm6,[esi+16] pand mm6,mm2 movq mm4,mm2 movq mm7,[ebx+16] pandn mm4,mm7 por mm6,mm4 movq [ebx+16],mm6 movq mm7,[esi+24] pand mm7,mm3 movq mm5,mm3 movq mm4,[ebx+24] pandn mm5,mm4 por mm7,mm5 movq [ebx+24],mm7 add esi,32 //inc by 32 bytes processed add ebx,32 sub ecx,8 //dec by 8 pixels processed ja mainloop32 mainloop32end: mov ecx,diff cmp ecx,0 jz end32 mov edx,mask sal edx,24 //make low byte the high byte secondloop32: sal edx,1 //move high bit to CF jnc skip32 //if CF = 0 mov eax,[esi] mov [ebx],eax skip32: add esi,4 add ebx,4 dec ecx jnz secondloop32 end32: emms } } else /* mmx _not supported - Use modified C routine */ { register unsigned int incr1, initial_val, final_val; png_size_t pixel_bytes; png_uint_32 i; register int disp = png_pass_inc[png_ptr->pass]; int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* pixel_bytes; dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; initial_val = offset_table[png_ptr->pass]*pixel_bytes; final_val = png_ptr->width*pixel_bytes; incr1 = (disp)*pixel_bytes; for (i = initial_val; i < final_val; i += incr1) { png_memcpy(dstptr, srcptr, pixel_bytes); srcptr += incr1; dstptr += incr1; } } /* end of else */ break; } // end 32 bpp case 48: { png_bytep srcptr; png_bytep dstptr; png_uint_32 len; int unmask, diff; __int64 mask5=0x0101010101010202, mask4=0x0202020204040404, mask3=0x0404080808080808, mask2=0x1010101010102020, mask1=0x2020202040404040, mask0=0x4040808080808080; #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && mmx_supported */ ) #else if (mmx_supported) #endif { srcptr = png_ptr->row_buf + 1; dstptr = row; unmask = ~mask; len = (png_ptr->width)&~7; diff = (png_ptr->width)&7; _asm { movd mm7, unmask //load bit pattern psubb mm6,mm6 //zero mm6 punpcklbw mm7,mm7 punpcklwd mm7,mm7 punpckldq mm7,mm7 //fill register with 8 masks movq mm0,mask0 movq mm1,mask1 movq mm2,mask2 movq mm3,mask3 movq mm4,mask4 movq mm5,mask5 pand mm0,mm7 pand mm1,mm7 pand mm2,mm7 pand mm3,mm7 pand mm4,mm7 pand mm5,mm7 pcmpeqb mm0,mm6 pcmpeqb mm1,mm6 pcmpeqb mm2,mm6 pcmpeqb mm3,mm6 pcmpeqb mm4,mm6 pcmpeqb mm5,mm6 mov ecx,len //load length of line mov esi,srcptr //load source mov ebx,dstptr //load dest cmp ecx,0 jz mainloop48end mainloop48: movq mm7,[esi] pand mm7,mm0 movq mm6,mm0 pandn mm6,[ebx] por mm7,mm6 movq [ebx],mm7 movq mm6,[esi+8] pand mm6,mm1 movq mm7,mm1 pandn mm7,[ebx+8] por mm6,mm7 movq [ebx+8],mm6 movq mm6,[esi+16] pand mm6,mm2 movq mm7,mm2 pandn mm7,[ebx+16] por mm6,mm7 movq [ebx+16],mm6 movq mm7,[esi+24] pand mm7,mm3 movq mm6,mm3 pandn mm6,[ebx+24] por mm7,mm6 movq [ebx+24],mm7 movq mm6,[esi+32] pand mm6,mm4 movq mm7,mm4 pandn mm7,[ebx+32] por mm6,mm7 movq [ebx+32],mm6 movq mm7,[esi+40] pand mm7,mm5 movq mm6,mm5 pandn mm6,[ebx+40] por mm7,mm6 movq [ebx+40],mm7 add esi,48 //inc by 32 bytes processed add ebx,48 sub ecx,8 //dec by 8 pixels processed ja mainloop48 mainloop48end: mov ecx,diff cmp ecx,0 jz end48 mov edx,mask sal edx,24 //make low byte the high byte secondloop48: sal edx,1 //move high bit to CF jnc skip48 //if CF = 0 mov eax,[esi] mov [ebx],eax skip48: add esi,4 add ebx,4 dec ecx jnz secondloop48 end48: emms } } else /* mmx _not supported - Use modified C routine */ { register unsigned int incr1, initial_val, final_val; png_size_t pixel_bytes; png_uint_32 i; register int disp = png_pass_inc[png_ptr->pass]; int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* pixel_bytes; dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; initial_val = offset_table[png_ptr->pass]*pixel_bytes; final_val = png_ptr->width*pixel_bytes; incr1 = (disp)*pixel_bytes; for (i = initial_val; i < final_val; i += incr1) { png_memcpy(dstptr, srcptr, pixel_bytes); srcptr += incr1; dstptr += incr1; } } /* end of else */ break; } // end 48 bpp default: { png_bytep sptr; png_bytep dp; png_size_t pixel_bytes; int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; unsigned int i; register int disp = png_pass_inc[png_ptr->pass]; // get the offset register unsigned int incr1, initial_val, final_val; pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); sptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* pixel_bytes; dp = row + offset_table[png_ptr->pass]*pixel_bytes; initial_val = offset_table[png_ptr->pass]*pixel_bytes; final_val = png_ptr->width*pixel_bytes; incr1 = (disp)*pixel_bytes; for (i = initial_val; i < final_val; i += incr1) { png_memcpy(dp, sptr, pixel_bytes); sptr += incr1; dp += incr1; } break; } } /* end switch (png_ptr->row_info.pixel_depth) */ } /* end if (non-trivial mask) */ } /* end png_combine_row() */ #if defined(PNG_READ_INTERLACING_SUPPORTED) void /* PRIVATE */ png_do_read_interlace(png_structp png_ptr) { png_row_infop row_info = &(png_ptr->row_info); png_bytep row = png_ptr->row_buf + 1; int pass = png_ptr->pass; png_uint_32 transformations = png_ptr->transformations; #ifdef PNG_USE_LOCAL_ARRAYS const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; #endif png_debug(1,"in png_do_read_interlace\n"); if (mmx_supported == 2) { #if !defined(PNG_1_0_X) /* this should have happened in png_init_mmx_flags() already */ png_warning(png_ptr, "asm_flags may not have been initialized"); #endif png_mmx_support(); } if (row != NULL && row_info != NULL) { png_uint_32 final_width; final_width = row_info->width * png_pass_inc[pass]; switch (row_info->pixel_depth) { case 1: { png_bytep sp, dp; int sshift, dshift; int s_start, s_end, s_inc; png_byte v; png_uint_32 i; int j; sp = row + (png_size_t)((row_info->width - 1) >> 3); dp = row + (png_size_t)((final_width - 1) >> 3); #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (transformations & PNG_PACKSWAP) { sshift = (int)((row_info->width + 7) & 7); dshift = (int)((final_width + 7) & 7); s_start = 7; s_end = 0; s_inc = -1; } else #endif { sshift = 7 - (int)((row_info->width + 7) & 7); dshift = 7 - (int)((final_width + 7) & 7); s_start = 0; s_end = 7; s_inc = 1; } for (i = row_info->width; i; i--) { v = (png_byte)((*sp >> sshift) & 0x1); for (j = 0; j < png_pass_inc[pass]; j++) { *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); if (dshift == s_end) { dshift = s_start; dp--; } else dshift += s_inc; } if (sshift == s_end) { sshift = s_start; sp--; } else sshift += s_inc; } break; } case 2: { png_bytep sp, dp; int sshift, dshift; int s_start, s_end, s_inc; png_uint_32 i; sp = row + (png_size_t)((row_info->width - 1) >> 2); dp = row + (png_size_t)((final_width - 1) >> 2); #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (transformations & PNG_PACKSWAP) { sshift = (png_size_t)(((row_info->width + 3) & 3) << 1); dshift = (png_size_t)(((final_width + 3) & 3) << 1); s_start = 6; s_end = 0; s_inc = -2; } else #endif { sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1); dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1); s_start = 0; s_end = 6; s_inc = 2; } for (i = row_info->width; i; i--) { png_byte v; int j; v = (png_byte)((*sp >> sshift) & 0x3); for (j = 0; j < png_pass_inc[pass]; j++) { *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); if (dshift == s_end) { dshift = s_start; dp--; } else dshift += s_inc; } if (sshift == s_end) { sshift = s_start; sp--; } else sshift += s_inc; } break; } case 4: { png_bytep sp, dp; int sshift, dshift; int s_start, s_end, s_inc; png_uint_32 i; sp = row + (png_size_t)((row_info->width - 1) >> 1); dp = row + (png_size_t)((final_width - 1) >> 1); #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (transformations & PNG_PACKSWAP) { sshift = (png_size_t)(((row_info->width + 1) & 1) << 2); dshift = (png_size_t)(((final_width + 1) & 1) << 2); s_start = 4; s_end = 0; s_inc = -4; } else #endif { sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2); dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2); s_start = 0; s_end = 4; s_inc = 4; } for (i = row_info->width; i; i--) { png_byte v; int j; v = (png_byte)((*sp >> sshift) & 0xf); for (j = 0; j < png_pass_inc[pass]; j++) { *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); if (dshift == s_end) { dshift = s_start; dp--; } else dshift += s_inc; } if (sshift == s_end) { sshift = s_start; sp--; } else sshift += s_inc; } break; } default: // This is the place where the routine is modified { __int64 const4 = 0x0000000000FFFFFF; // __int64 const5 = 0x000000FFFFFF0000; // unused... __int64 const6 = 0x00000000000000FF; png_bytep sptr, dp; png_uint_32 i; png_size_t pixel_bytes; int width = row_info->width; pixel_bytes = (row_info->pixel_depth >> 3); sptr = row + (width - 1) * pixel_bytes; dp = row + (final_width - 1) * pixel_bytes; // New code by Nirav Chhatrapati - Intel Corporation // sign fix by GRR // NOTE: there is NO MMX code for 48-bit and 64-bit images // use MMX routine if machine supports it #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE) /* && mmx_supported */ ) #else if (mmx_supported) #endif { if (pixel_bytes == 3) { if (((pass == 0) || (pass == 1)) && width) { _asm { mov esi, sptr mov edi, dp mov ecx, width sub edi, 21 // (png_pass_inc[pass] - 1)*pixel_bytes loop_pass0: movd mm0, [esi] ; X X X X X v2 v1 v0 pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0 movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0 psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0 movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0 psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0 psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1 por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0 por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1 movq mm3, mm0 ; v2 v1 v0 v2 v1 v0 v2 v1 psllq mm0, 16 ; v0 v2 v1 v0 v2 v1 0 0 movq mm4, mm3 ; v2 v1 v0 v2 v1 v0 v2 v1 punpckhdq mm3, mm0 ; v0 v2 v1 v0 v2 v1 v0 v2 movq [edi+16] , mm4 psrlq mm0, 32 ; 0 0 0 0 v0 v2 v1 v0 movq [edi+8] , mm3 punpckldq mm0, mm4 ; v1 v0 v2 v1 v0 v2 v1 v0 sub esi, 3 movq [edi], mm0 sub edi, 24 //sub esi, 3 dec ecx jnz loop_pass0 EMMS } } else if (((pass == 2) || (pass == 3)) && width) { _asm { mov esi, sptr mov edi, dp mov ecx, width sub edi, 9 // (png_pass_inc[pass] - 1)*pixel_bytes loop_pass2: movd mm0, [esi] ; X X X X X v2 v1 v0 pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0 movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0 psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0 movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0 psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0 psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1 por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0 por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1 movq [edi+4], mm0 ; move to memory psrlq mm0, 16 ; 0 0 v2 v1 v0 v2 v1 v0 movd [edi], mm0 ; move to memory sub esi, 3 sub edi, 12 dec ecx jnz loop_pass2 EMMS } } else if (width) /* && ((pass == 4) || (pass == 5)) */ { int width_mmx = ((width >> 1) << 1) - 8; if (width_mmx < 0) width_mmx = 0; width -= width_mmx; // 8 or 9 pix, 24 or 27 bytes if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub esi, 3 sub edi, 9 loop_pass4: movq mm0, [esi] ; X X v2 v1 v0 v5 v4 v3 movq mm7, mm0 ; X X v2 v1 v0 v5 v4 v3 movq mm6, mm0 ; X X v2 v1 v0 v5 v4 v3 psllq mm0, 24 ; v1 v0 v5 v4 v3 0 0 0 pand mm7, const4 ; 0 0 0 0 0 v5 v4 v3 psrlq mm6, 24 ; 0 0 0 X X v2 v1 v0 por mm0, mm7 ; v1 v0 v5 v4 v3 v5 v4 v3 movq mm5, mm6 ; 0 0 0 X X v2 v1 v0 psllq mm6, 8 ; 0 0 X X v2 v1 v0 0 movq [edi], mm0 ; move quad to memory psrlq mm5, 16 ; 0 0 0 0 0 X X v2 pand mm5, const6 ; 0 0 0 0 0 0 0 v2 por mm6, mm5 ; 0 0 X X v2 v1 v0 v2 movd [edi+8], mm6 ; move double to memory sub esi, 6 sub edi, 12 sub ecx, 2 jnz loop_pass4 EMMS } } sptr -= width_mmx*3; dp -= width_mmx*6; for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, 3); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, 3); dp -= 3; } sptr -= 3; } } } /* end of pixel_bytes == 3 */ else if (pixel_bytes == 1) { if (((pass == 0) || (pass == 1)) && width) { int width_mmx = ((width >> 2) << 2); width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub edi, 31 sub esi, 3 loop1_pass0: movd mm0, [esi] ; X X X X v0 v1 v2 v3 movq mm1, mm0 ; X X X X v0 v1 v2 v3 punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 movq mm2, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 movq mm3, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 punpckldq mm0, mm0 ; v3 v3 v3 v3 v3 v3 v3 v3 punpckhdq mm3, mm3 ; v2 v2 v2 v2 v2 v2 v2 v2 movq [edi], mm0 ; move to memory v3 punpckhwd mm2, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1 movq [edi+8], mm3 ; move to memory v2 movq mm4, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1 punpckldq mm2, mm2 ; v1 v1 v1 v1 v1 v1 v1 v1 punpckhdq mm4, mm4 ; v0 v0 v0 v0 v0 v0 v0 v0 movq [edi+16], mm2 ; move to memory v1 movq [edi+24], mm4 ; move to memory v0 sub esi, 4 sub edi, 32 sub ecx, 4 jnz loop1_pass0 EMMS } } sptr -= width_mmx; dp -= width_mmx*8; for (i = width; i; i--) { int j; /* I simplified this part in version 1.0.4e * here and in several other instances where * pixel_bytes == 1 -- GR-P * * Original code: * * png_byte v[8]; * png_memcpy(v, sptr, pixel_bytes); * for (j = 0; j < png_pass_inc[pass]; j++) * { * png_memcpy(dp, v, pixel_bytes); * dp -= pixel_bytes; * } * sptr -= pixel_bytes; * * Replacement code is in the next three lines: */ for (j = 0; j < png_pass_inc[pass]; j++) *dp-- = *sptr; sptr--; } } else if (((pass == 2) || (pass == 3)) && width) { int width_mmx = ((width >> 2) << 2); width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub edi, 15 sub esi, 3 loop1_pass2: movd mm0, [esi] ; X X X X v0 v1 v2 v3 punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 punpckhwd mm1, mm1 ; v0 v0 v0 v0 v1 v1 v1 v1 movq [edi], mm0 ; move to memory v2 and v3 sub esi, 4 movq [edi+8], mm1 ; move to memory v1 and v0 sub edi, 16 sub ecx, 4 jnz loop1_pass2 EMMS } } sptr -= width_mmx; dp -= width_mmx*4; for (i = width; i; i--) { int j; for (j = 0; j < png_pass_inc[pass]; j++) { *dp-- = *sptr; } sptr --; } } else if (width) /* && ((pass == 4) || (pass == 5))) */ { int width_mmx = ((width >> 3) << 3); width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub edi, 15 sub esi, 7 loop1_pass4: movq mm0, [esi] ; v0 v1 v2 v3 v4 v5 v6 v7 movq mm1, mm0 ; v0 v1 v2 v3 v4 v5 v6 v7 punpcklbw mm0, mm0 ; v4 v4 v5 v5 v6 v6 v7 v7 //movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 punpckhbw mm1, mm1 ;v0 v0 v1 v1 v2 v2 v3 v3 movq [edi+8], mm1 ; move to memory v0 v1 v2 and v3 sub esi, 8 movq [edi], mm0 ; move to memory v4 v5 v6 and v7 //sub esi, 4 sub edi, 16 sub ecx, 8 jnz loop1_pass4 EMMS } } sptr -= width_mmx; dp -= width_mmx*2; for (i = width; i; i--) { int j; for (j = 0; j < png_pass_inc[pass]; j++) { *dp-- = *sptr; } sptr --; } } } /* end of pixel_bytes == 1 */ else if (pixel_bytes == 2) { if (((pass == 0) || (pass == 1)) && width) { int width_mmx = ((width >> 1) << 1); width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub esi, 2 sub edi, 30 loop2_pass0: movd mm0, [esi] ; X X X X v1 v0 v3 v2 punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2 punpckhdq mm1, mm1 ; v1 v0 v1 v0 v1 v0 v1 v0 movq [edi], mm0 movq [edi + 8], mm0 movq [edi + 16], mm1 movq [edi + 24], mm1 sub esi, 4 sub edi, 32 sub ecx, 2 jnz loop2_pass0 EMMS } } sptr -= (width_mmx*2 - 2); // sign fixed dp -= (width_mmx*16 - 2); // sign fixed for (i = width; i; i--) { png_byte v[8]; int j; sptr -= 2; png_memcpy(v, sptr, 2); for (j = 0; j < png_pass_inc[pass]; j++) { dp -= 2; png_memcpy(dp, v, 2); } } } else if (((pass == 2) || (pass == 3)) && width) { int width_mmx = ((width >> 1) << 1) ; width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub esi, 2 sub edi, 14 loop2_pass2: movd mm0, [esi] ; X X X X v1 v0 v3 v2 punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2 punpckhdq mm1, mm1 ; v1 v0 v1 v0 v1 v0 v1 v0 movq [edi], mm0 sub esi, 4 movq [edi + 8], mm1 //sub esi, 4 sub edi, 16 sub ecx, 2 jnz loop2_pass2 EMMS } } sptr -= (width_mmx*2 - 2); // sign fixed dp -= (width_mmx*8 - 2); // sign fixed for (i = width; i; i--) { png_byte v[8]; int j; sptr -= 2; png_memcpy(v, sptr, 2); for (j = 0; j < png_pass_inc[pass]; j++) { dp -= 2; png_memcpy(dp, v, 2); } } } else if (width) // pass == 4 or 5 { int width_mmx = ((width >> 1) << 1) ; width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub esi, 2 sub edi, 6 loop2_pass4: movd mm0, [esi] ; X X X X v1 v0 v3 v2 punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 sub esi, 4 movq [edi], mm0 sub edi, 8 sub ecx, 2 jnz loop2_pass4 EMMS } } sptr -= (width_mmx*2 - 2); // sign fixed dp -= (width_mmx*4 - 2); // sign fixed for (i = width; i; i--) { png_byte v[8]; int j; sptr -= 2; png_memcpy(v, sptr, 2); for (j = 0; j < png_pass_inc[pass]; j++) { dp -= 2; png_memcpy(dp, v, 2); } } } } /* end of pixel_bytes == 2 */ else if (pixel_bytes == 4) { if (((pass == 0) || (pass == 1)) && width) { int width_mmx = ((width >> 1) << 1) ; width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub esi, 4 sub edi, 60 loop4_pass0: movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4 movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4 punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4 punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0 movq [edi], mm0 movq [edi + 8], mm0 movq [edi + 16], mm0 movq [edi + 24], mm0 movq [edi+32], mm1 movq [edi + 40], mm1 movq [edi+ 48], mm1 sub esi, 8 movq [edi + 56], mm1 sub edi, 64 sub ecx, 2 jnz loop4_pass0 EMMS } } sptr -= (width_mmx*4 - 4); // sign fixed dp -= (width_mmx*32 - 4); // sign fixed for (i = width; i; i--) { png_byte v[8]; int j; sptr -= 4; png_memcpy(v, sptr, 4); for (j = 0; j < png_pass_inc[pass]; j++) { dp -= 4; png_memcpy(dp, v, 4); } } } else if (((pass == 2) || (pass == 3)) && width) { int width_mmx = ((width >> 1) << 1) ; width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub esi, 4 sub edi, 28 loop4_pass2: movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4 movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4 punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4 punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0 movq [edi], mm0 movq [edi + 8], mm0 movq [edi+16], mm1 movq [edi + 24], mm1 sub esi, 8 sub edi, 32 sub ecx, 2 jnz loop4_pass2 EMMS } } sptr -= (width_mmx*4 - 4); // sign fixed dp -= (width_mmx*16 - 4); // sign fixed for (i = width; i; i--) { png_byte v[8]; int j; sptr -= 4; png_memcpy(v, sptr, 4); for (j = 0; j < png_pass_inc[pass]; j++) { dp -= 4; png_memcpy(dp, v, 4); } } } else if (width) // pass == 4 or 5 { int width_mmx = ((width >> 1) << 1) ; width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub esi, 4 sub edi, 12 loop4_pass4: movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4 movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4 punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4 punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0 movq [edi], mm0 sub esi, 8 movq [edi + 8], mm1 sub edi, 16 sub ecx, 2 jnz loop4_pass4 EMMS } } sptr -= (width_mmx*4 - 4); // sign fixed dp -= (width_mmx*8 - 4); // sign fixed for (i = width; i; i--) { png_byte v[8]; int j; sptr -= 4; png_memcpy(v, sptr, 4); for (j = 0; j < png_pass_inc[pass]; j++) { dp -= 4; png_memcpy(dp, v, 4); } } } } /* end of pixel_bytes == 4 */ else if (pixel_bytes == 6) { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, 6); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, 6); dp -= 6; } sptr -= 6; } } /* end of pixel_bytes == 6 */ else { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, pixel_bytes); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, pixel_bytes); dp -= pixel_bytes; } sptr-= pixel_bytes; } } } /* end of mmx_supported */ else /* MMX not supported: use modified C code - takes advantage * of inlining of memcpy for a constant */ { if (pixel_bytes == 1) { for (i = width; i; i--) { int j; for (j = 0; j < png_pass_inc[pass]; j++) *dp-- = *sptr; sptr--; } } else if (pixel_bytes == 3) { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, pixel_bytes); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, pixel_bytes); dp -= pixel_bytes; } sptr -= pixel_bytes; } } else if (pixel_bytes == 2) { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, pixel_bytes); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, pixel_bytes); dp -= pixel_bytes; } sptr -= pixel_bytes; } } else if (pixel_bytes == 4) { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, pixel_bytes); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, pixel_bytes); dp -= pixel_bytes; } sptr -= pixel_bytes; } } else if (pixel_bytes == 6) { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, pixel_bytes); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, pixel_bytes); dp -= pixel_bytes; } sptr -= pixel_bytes; } } else { for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, pixel_bytes); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, pixel_bytes); dp -= pixel_bytes; } sptr -= pixel_bytes; } } } /* end of MMX not supported */ break; } } /* end switch (row_info->pixel_depth) */ row_info->width = final_width; row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); } } #endif /* PNG_READ_INTERLACING_SUPPORTED */ // These variables are utilized in the functions below. They are declared // globally here to ensure alignment on 8-byte boundaries. union uAll { __int64 use; double align; } LBCarryMask = {0x0101010101010101}, HBClearMask = {0x7f7f7f7f7f7f7f7f}, ActiveMask, ActiveMask2, ActiveMaskEnd, ShiftBpp, ShiftRem; // Optimized code for PNG Average filter decoder void /* PRIVATE */ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row , png_bytep prev_row) { int bpp; png_uint_32 FullLength; png_uint_32 MMXLength; //png_uint_32 len; int diff; bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel FullLength = row_info->rowbytes; // # of bytes to filter _asm { // Init address pointers and offset mov edi, row // edi ==> Avg(x) xor ebx, ebx // ebx ==> x mov edx, edi mov esi, prev_row // esi ==> Prior(x) sub edx, bpp // edx ==> Raw(x-bpp) xor eax, eax // Compute the Raw value for the first bpp bytes // Raw(x) = Avg(x) + (Prior(x)/2) davgrlp: mov al, [esi + ebx] // Load al with Prior(x) inc ebx shr al, 1 // divide by 2 add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx cmp ebx, bpp mov [edi+ebx-1], al // Write back Raw(x); // mov does not affect flags; -1 to offset inc ebx jb davgrlp // get # of bytes to alignment mov diff, edi // take start of row add diff, ebx // add bpp add diff, 0xf // add 7 + 8 to incr past alignment boundary and diff, 0xfffffff8 // mask to alignment boundary sub diff, edi // subtract from start ==> value ebx at alignment jz davggo // fix alignment // Compute the Raw value for the bytes upto the alignment boundary // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) xor ecx, ecx davglp1: xor eax, eax mov cl, [esi + ebx] // load cl with Prior(x) mov al, [edx + ebx] // load al with Raw(x-bpp) add ax, cx inc ebx shr ax, 1 // divide by 2 add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx cmp ebx, diff // Check if at alignment boundary mov [edi+ebx-1], al // Write back Raw(x); // mov does not affect flags; -1 to offset inc ebx jb davglp1 // Repeat until at alignment boundary davggo: mov eax, FullLength mov ecx, eax sub eax, ebx // subtract alignment fix and eax, 0x00000007 // calc bytes over mult of 8 sub ecx, eax // drop over bytes from original length mov MMXLength, ecx } // end _asm block // Now do the math for the rest of the row switch ( bpp ) { case 3: { ActiveMask.use = 0x0000000000ffffff; ShiftBpp.use = 24; // == 3 * 8 ShiftRem.use = 40; // == 64 - 24 _asm { // Re-init address pointers and offset movq mm7, ActiveMask mov ebx, diff // ebx ==> x = offset to alignment boundary movq mm5, LBCarryMask mov edi, row // edi ==> Avg(x) movq mm4, HBClearMask mov esi, prev_row // esi ==> Prior(x) // PRIME the pump (load the first Raw(x-bpp) data set movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes // (we correct position in loop below) davg3lp: movq mm0, [edi + ebx] // Load mm0 with Avg(x) // Add (Prev_row/2) to Average movq mm3, mm5 psrlq mm2, ShiftRem // Correct position Raw(x-bpp) data movq mm1, [esi + ebx] // Load mm1 with Prior(x) movq mm6, mm7 pand mm3, mm1 // get lsb for each prev_row byte psrlq mm1, 1 // divide prev_row bytes by 2 pand mm1, mm4 // clear invalid bit 7 of each byte paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry movq mm1, mm3 // now use mm1 for getting LBCarrys pand mm1, mm2 // get LBCarrys for each byte where both // lsb's were == 1 (Only valid for active group) psrlq mm2, 1 // divide raw bytes by 2 pand mm2, mm4 // clear invalid bit 7 of each byte paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte pand mm2, mm6 // Leave only Active Group 1 bytes to add to Avg paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active // byte // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 3-5 movq mm2, mm0 // mov updated Raws to mm2 psllq mm2, ShiftBpp // shift data to position correctly movq mm1, mm3 // now use mm1 for getting LBCarrys pand mm1, mm2 // get LBCarrys for each byte where both // lsb's were == 1 (Only valid for active group) psrlq mm2, 1 // divide raw bytes by 2 pand mm2, mm4 // clear invalid bit 7 of each byte paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active // byte // Add 3rd active group (Raw(x-bpp)/2) to Average with LBCarry psllq mm6, ShiftBpp // shift the mm6 mask to cover the last two // bytes movq mm2, mm0 // mov updated Raws to mm2 psllq mm2, ShiftBpp // shift data to position correctly // Data only needs to be shifted once here to // get the correct x-bpp offset. movq mm1, mm3 // now use mm1 for getting LBCarrys pand mm1, mm2 // get LBCarrys for each byte where both // lsb's were == 1 (Only valid for active group) psrlq mm2, 1 // divide raw bytes by 2 pand mm2, mm4 // clear invalid bit 7 of each byte paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg add ebx, 8 paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active // byte // Now ready to write back to memory movq [edi + ebx - 8], mm0 // Move updated Raw(x) to use as Raw(x-bpp) for next loop cmp ebx, MMXLength movq mm2, mm0 // mov updated Raw(x) to mm2 jb davg3lp } // end _asm block } break; case 6: case 4: case 7: case 5: { ActiveMask.use = 0xffffffffffffffff; // use shift below to clear // appropriate inactive bytes ShiftBpp.use = bpp << 3; ShiftRem.use = 64 - ShiftBpp.use; _asm { movq mm4, HBClearMask // Re-init address pointers and offset mov ebx, diff // ebx ==> x = offset to alignment boundary // Load ActiveMask and clear all bytes except for 1st active group movq mm7, ActiveMask mov edi, row // edi ==> Avg(x) psrlq mm7, ShiftRem mov esi, prev_row // esi ==> Prior(x) movq mm6, mm7 movq mm5, LBCarryMask psllq mm6, ShiftBpp // Create mask for 2nd active group // PRIME the pump (load the first Raw(x-bpp) data set movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes // (we correct position in loop below) davg4lp: movq mm0, [edi + ebx] psrlq mm2, ShiftRem // shift data to position correctly movq mm1, [esi + ebx] // Add (Prev_row/2) to Average movq mm3, mm5 pand mm3, mm1 // get lsb for each prev_row byte psrlq mm1, 1 // divide prev_row bytes by 2 pand mm1, mm4 // clear invalid bit 7 of each byte paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry movq mm1, mm3 // now use mm1 for getting LBCarrys pand mm1, mm2 // get LBCarrys for each byte where both // lsb's were == 1 (Only valid for active group) psrlq mm2, 1 // divide raw bytes by 2 pand mm2, mm4 // clear invalid bit 7 of each byte paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte pand mm2, mm7 // Leave only Active Group 1 bytes to add to Avg paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active // byte // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry movq mm2, mm0 // mov updated Raws to mm2 psllq mm2, ShiftBpp // shift data to position correctly add ebx, 8 movq mm1, mm3 // now use mm1 for getting LBCarrys pand mm1, mm2 // get LBCarrys for each byte where both // lsb's were == 1 (Only valid for active group) psrlq mm2, 1 // divide raw bytes by 2 pand mm2, mm4 // clear invalid bit 7 of each byte paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active // byte cmp ebx, MMXLength // Now ready to write back to memory movq [edi + ebx - 8], mm0 // Prep Raw(x-bpp) for next loop movq mm2, mm0 // mov updated Raws to mm2 jb davg4lp } // end _asm block } break; case 2: { ActiveMask.use = 0x000000000000ffff; ShiftBpp.use = 16; // == 2 * 8 [BUGFIX] ShiftRem.use = 48; // == 64 - 16 [BUGFIX] _asm { // Load ActiveMask movq mm7, ActiveMask // Re-init address pointers and offset mov ebx, diff // ebx ==> x = offset to alignment boundary movq mm5, LBCarryMask mov edi, row // edi ==> Avg(x) movq mm4, HBClearMask mov esi, prev_row // esi ==> Prior(x) // PRIME the pump (load the first Raw(x-bpp) data set movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes // (we correct position in loop below) davg2lp: movq mm0, [edi + ebx] psrlq mm2, ShiftRem // shift data to position correctly [BUGFIX] movq mm1, [esi + ebx] // Add (Prev_row/2) to Average movq mm3, mm5 pand mm3, mm1 // get lsb for each prev_row byte psrlq mm1, 1 // divide prev_row bytes by 2 pand mm1, mm4 // clear invalid bit 7 of each byte movq mm6, mm7 paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry movq mm1, mm3 // now use mm1 for getting LBCarrys pand mm1, mm2 // get LBCarrys for each byte where both // lsb's were == 1 (Only valid for active group) psrlq mm2, 1 // divide raw bytes by 2 pand mm2, mm4 // clear invalid bit 7 of each byte paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte pand mm2, mm6 // Leave only Active Group 1 bytes to add to Avg paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 2 & 3 movq mm2, mm0 // mov updated Raws to mm2 psllq mm2, ShiftBpp // shift data to position correctly movq mm1, mm3 // now use mm1 for getting LBCarrys pand mm1, mm2 // get LBCarrys for each byte where both // lsb's were == 1 (Only valid for active group) psrlq mm2, 1 // divide raw bytes by 2 pand mm2, mm4 // clear invalid bit 7 of each byte paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte // Add rdd active group (Raw(x-bpp)/2) to Average with LBCarry psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 4 & 5 movq mm2, mm0 // mov updated Raws to mm2 psllq mm2, ShiftBpp // shift data to position correctly // Data only needs to be shifted once here to // get the correct x-bpp offset. movq mm1, mm3 // now use mm1 for getting LBCarrys pand mm1, mm2 // get LBCarrys for each byte where both // lsb's were == 1 (Only valid for active group) psrlq mm2, 1 // divide raw bytes by 2 pand mm2, mm4 // clear invalid bit 7 of each byte paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte // Add 4th active group (Raw(x-bpp)/2) to Average with LBCarry psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 6 & 7 movq mm2, mm0 // mov updated Raws to mm2 psllq mm2, ShiftBpp // shift data to position correctly // Data only needs to be shifted once here to // get the correct x-bpp offset. add ebx, 8 movq mm1, mm3 // now use mm1 for getting LBCarrys pand mm1, mm2 // get LBCarrys for each byte where both // lsb's were == 1 (Only valid for active group) psrlq mm2, 1 // divide raw bytes by 2 pand mm2, mm4 // clear invalid bit 7 of each byte paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte cmp ebx, MMXLength // Now ready to write back to memory movq [edi + ebx - 8], mm0 // Prep Raw(x-bpp) for next loop movq mm2, mm0 // mov updated Raws to mm2 jb davg2lp } // end _asm block } break; case 1: // bpp == 1 { _asm { // Re-init address pointers and offset mov ebx, diff // ebx ==> x = offset to alignment boundary mov edi, row // edi ==> Avg(x) cmp ebx, FullLength // Test if offset at end of array jnb davg1end // Do Paeth decode for remaining bytes mov esi, prev_row // esi ==> Prior(x) mov edx, edi xor ecx, ecx // zero ecx before using cl & cx in loop below sub edx, bpp // edx ==> Raw(x-bpp) davg1lp: // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) xor eax, eax mov cl, [esi + ebx] // load cl with Prior(x) mov al, [edx + ebx] // load al with Raw(x-bpp) add ax, cx inc ebx shr ax, 1 // divide by 2 add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx cmp ebx, FullLength // Check if at end of array mov [edi+ebx-1], al // Write back Raw(x); // mov does not affect flags; -1 to offset inc ebx jb davg1lp davg1end: } // end _asm block } return; case 8: // bpp == 8 { _asm { // Re-init address pointers and offset mov ebx, diff // ebx ==> x = offset to alignment boundary movq mm5, LBCarryMask mov edi, row // edi ==> Avg(x) movq mm4, HBClearMask mov esi, prev_row // esi ==> Prior(x) // PRIME the pump (load the first Raw(x-bpp) data set movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes // (NO NEED to correct position in loop below) davg8lp: movq mm0, [edi + ebx] movq mm3, mm5 movq mm1, [esi + ebx] add ebx, 8 pand mm3, mm1 // get lsb for each prev_row byte psrlq mm1, 1 // divide prev_row bytes by 2 pand mm3, mm2 // get LBCarrys for each byte where both // lsb's were == 1 psrlq mm2, 1 // divide raw bytes by 2 pand mm1, mm4 // clear invalid bit 7 of each byte paddb mm0, mm3 // add LBCarrys to Avg for each byte pand mm2, mm4 // clear invalid bit 7 of each byte paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte paddb mm0, mm2 // add (Raw/2) to Avg for each byte cmp ebx, MMXLength movq [edi + ebx - 8], mm0 movq mm2, mm0 // reuse as Raw(x-bpp) jb davg8lp } // end _asm block } break; default: // bpp greater than 8 { _asm { movq mm5, LBCarryMask // Re-init address pointers and offset mov ebx, diff // ebx ==> x = offset to alignment boundary mov edi, row // edi ==> Avg(x) movq mm4, HBClearMask mov edx, edi mov esi, prev_row // esi ==> Prior(x) sub edx, bpp // edx ==> Raw(x-bpp) davgAlp: movq mm0, [edi + ebx] movq mm3, mm5 movq mm1, [esi + ebx] pand mm3, mm1 // get lsb for each prev_row byte movq mm2, [edx + ebx] psrlq mm1, 1 // divide prev_row bytes by 2 pand mm3, mm2 // get LBCarrys for each byte where both // lsb's were == 1 psrlq mm2, 1 // divide raw bytes by 2 pand mm1, mm4 // clear invalid bit 7 of each byte paddb mm0, mm3 // add LBCarrys to Avg for each byte pand mm2, mm4 // clear invalid bit 7 of each byte paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte add ebx, 8 paddb mm0, mm2 // add (Raw/2) to Avg for each byte cmp ebx, MMXLength movq [edi + ebx - 8], mm0 jb davgAlp } // end _asm block } break; } // end switch ( bpp ) _asm { // MMX acceleration complete now do clean-up // Check if any remaining bytes left to decode mov ebx, MMXLength // ebx ==> x = offset bytes remaining after MMX mov edi, row // edi ==> Avg(x) cmp ebx, FullLength // Test if offset at end of array jnb davgend // Do Paeth decode for remaining bytes mov esi, prev_row // esi ==> Prior(x) mov edx, edi xor ecx, ecx // zero ecx before using cl & cx in loop below sub edx, bpp // edx ==> Raw(x-bpp) davglp2: // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) xor eax, eax mov cl, [esi + ebx] // load cl with Prior(x) mov al, [edx + ebx] // load al with Raw(x-bpp) add ax, cx inc ebx shr ax, 1 // divide by 2 add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx cmp ebx, FullLength // Check if at end of array mov [edi+ebx-1], al // Write back Raw(x); // mov does not affect flags; -1 to offset inc ebx jb davglp2 davgend: emms // End MMX instructions; prep for possible FP instrs. } // end _asm block } // Optimized code for PNG Paeth filter decoder void /* PRIVATE */ png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, png_bytep prev_row) { png_uint_32 FullLength; png_uint_32 MMXLength; //png_uint_32 len; int bpp; int diff; //int ptemp; int patemp, pbtemp, pctemp; bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel FullLength = row_info->rowbytes; // # of bytes to filter _asm { xor ebx, ebx // ebx ==> x offset mov edi, row xor edx, edx // edx ==> x-bpp offset mov esi, prev_row xor eax, eax // Compute the Raw value for the first bpp bytes // Note: the formula works out to be always // Paeth(x) = Raw(x) + Prior(x) where x < bpp dpthrlp: mov al, [edi + ebx] add al, [esi + ebx] inc ebx cmp ebx, bpp mov [edi + ebx - 1], al jb dpthrlp // get # of bytes to alignment mov diff, edi // take start of row add diff, ebx // add bpp xor ecx, ecx add diff, 0xf // add 7 + 8 to incr past alignment boundary and diff, 0xfffffff8 // mask to alignment boundary sub diff, edi // subtract from start ==> value ebx at alignment jz dpthgo // fix alignment dpthlp1: xor eax, eax // pav = p - a = (a + b - c) - a = b - c mov al, [esi + ebx] // load Prior(x) into al mov cl, [esi + edx] // load Prior(x-bpp) into cl sub eax, ecx // subtract Prior(x-bpp) mov patemp, eax // Save pav for later use xor eax, eax // pbv = p - b = (a + b - c) - b = a - c mov al, [edi + edx] // load Raw(x-bpp) into al sub eax, ecx // subtract Prior(x-bpp) mov ecx, eax // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv add eax, patemp // pcv = pav + pbv // pc = abs(pcv) test eax, 0x80000000 jz dpthpca neg eax // reverse sign of neg values dpthpca: mov pctemp, eax // save pc for later use // pb = abs(pbv) test ecx, 0x80000000 jz dpthpba neg ecx // reverse sign of neg values dpthpba: mov pbtemp, ecx // save pb for later use // pa = abs(pav) mov eax, patemp test eax, 0x80000000 jz dpthpaa neg eax // reverse sign of neg values dpthpaa: mov patemp, eax // save pa for later use // test if pa <= pb cmp eax, ecx jna dpthabb // pa > pb; now test if pb <= pc cmp ecx, pctemp jna dpthbbc // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) mov cl, [esi + edx] // load Prior(x-bpp) into cl jmp dpthpaeth dpthbbc: // pb <= pc; Raw(x) = Paeth(x) + Prior(x) mov cl, [esi + ebx] // load Prior(x) into cl jmp dpthpaeth dpthabb: // pa <= pb; now test if pa <= pc cmp eax, pctemp jna dpthabc // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) mov cl, [esi + edx] // load Prior(x-bpp) into cl jmp dpthpaeth dpthabc: // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) mov cl, [edi + edx] // load Raw(x-bpp) into cl dpthpaeth: inc ebx inc edx // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 add [edi + ebx - 1], cl cmp ebx, diff jb dpthlp1 dpthgo: mov ecx, FullLength mov eax, ecx sub eax, ebx // subtract alignment fix and eax, 0x00000007 // calc bytes over mult of 8 sub ecx, eax // drop over bytes from original length mov MMXLength, ecx } // end _asm block // Now do the math for the rest of the row switch ( bpp ) { case 3: { ActiveMask.use = 0x0000000000ffffff; ActiveMaskEnd.use = 0xffff000000000000; ShiftBpp.use = 24; // == bpp(3) * 8 ShiftRem.use = 40; // == 64 - 24 _asm { mov ebx, diff mov edi, row mov esi, prev_row pxor mm0, mm0 // PRIME the pump (load the first Raw(x-bpp) data set movq mm1, [edi+ebx-8] dpth3lp: psrlq mm1, ShiftRem // shift last 3 bytes to 1st 3 bytes movq mm2, [esi + ebx] // load b=Prior(x) punpcklbw mm1, mm0 // Unpack High bytes of a movq mm3, [esi+ebx-8] // Prep c=Prior(x-bpp) bytes punpcklbw mm2, mm0 // Unpack High bytes of b psrlq mm3, ShiftRem // shift last 3 bytes to 1st 3 bytes // pav = p - a = (a + b - c) - a = b - c movq mm4, mm2 punpcklbw mm3, mm0 // Unpack High bytes of c // pbv = p - b = (a + b - c) - b = a - c movq mm5, mm1 psubw mm4, mm3 pxor mm7, mm7 // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv movq mm6, mm4 psubw mm5, mm3 // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) pcmpgtw mm0, mm4 // Create mask pav bytes < 0 paddw mm6, mm5 pand mm0, mm4 // Only pav bytes < 0 in mm7 pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 psubw mm4, mm0 pand mm7, mm5 // Only pbv bytes < 0 in mm0 psubw mm4, mm0 psubw mm5, mm7 pxor mm0, mm0 pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 pand mm0, mm6 // Only pav bytes < 0 in mm7 psubw mm5, mm7 psubw mm6, mm0 // test pa <= pb movq mm7, mm4 psubw mm6, mm0 pcmpgtw mm7, mm5 // pa > pb? movq mm0, mm7 // use mm7 mask to merge pa & pb pand mm5, mm7 // use mm0 mask copy to merge a & b pand mm2, mm0 pandn mm7, mm4 pandn mm0, mm1 paddw mm7, mm5 paddw mm0, mm2 // test ((pa <= pb)? pa:pb) <= pc pcmpgtw mm7, mm6 // pab > pc? pxor mm1, mm1 pand mm3, mm7 pandn mm7, mm0 paddw mm7, mm3 pxor mm0, mm0 packuswb mm7, mm1 movq mm3, [esi + ebx] // load c=Prior(x-bpp) pand mm7, ActiveMask movq mm2, mm3 // load b=Prior(x) step 1 paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) punpcklbw mm3, mm0 // Unpack High bytes of c movq [edi + ebx], mm7 // write back updated value movq mm1, mm7 // Now mm1 will be used as Raw(x-bpp) // Now do Paeth for 2nd set of bytes (3-5) psrlq mm2, ShiftBpp // load b=Prior(x) step 2 punpcklbw mm1, mm0 // Unpack High bytes of a pxor mm7, mm7 punpcklbw mm2, mm0 // Unpack High bytes of b // pbv = p - b = (a + b - c) - b = a - c movq mm5, mm1 // pav = p - a = (a + b - c) - a = b - c movq mm4, mm2 psubw mm5, mm3 psubw mm4, mm3 // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = // pav + pbv = pbv + pav movq mm6, mm5 paddw mm6, mm4 // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) pcmpgtw mm0, mm5 // Create mask pbv bytes < 0 pcmpgtw mm7, mm4 // Create mask pav bytes < 0 pand mm0, mm5 // Only pbv bytes < 0 in mm0 pand mm7, mm4 // Only pav bytes < 0 in mm7 psubw mm5, mm0 psubw mm4, mm7 psubw mm5, mm0 psubw mm4, mm7 pxor mm0, mm0 pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 pand mm0, mm6 // Only pav bytes < 0 in mm7 psubw mm6, mm0 // test pa <= pb movq mm7, mm4 psubw mm6, mm0 pcmpgtw mm7, mm5 // pa > pb? movq mm0, mm7 // use mm7 mask to merge pa & pb pand mm5, mm7 // use mm0 mask copy to merge a & b pand mm2, mm0 pandn mm7, mm4 pandn mm0, mm1 paddw mm7, mm5 paddw mm0, mm2 // test ((pa <= pb)? pa:pb) <= pc pcmpgtw mm7, mm6 // pab > pc? movq mm2, [esi + ebx] // load b=Prior(x) pand mm3, mm7 pandn mm7, mm0 pxor mm1, mm1 paddw mm7, mm3 pxor mm0, mm0 packuswb mm7, mm1 movq mm3, mm2 // load c=Prior(x-bpp) step 1 pand mm7, ActiveMask punpckhbw mm2, mm0 // Unpack High bytes of b psllq mm7, ShiftBpp // Shift bytes to 2nd group of 3 bytes // pav = p - a = (a + b - c) - a = b - c movq mm4, mm2 paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) psllq mm3, ShiftBpp // load c=Prior(x-bpp) step 2 movq [edi + ebx], mm7 // write back updated value movq mm1, mm7 punpckhbw mm3, mm0 // Unpack High bytes of c psllq mm1, ShiftBpp // Shift bytes // Now mm1 will be used as Raw(x-bpp) // Now do Paeth for 3rd, and final, set of bytes (6-7) pxor mm7, mm7 punpckhbw mm1, mm0 // Unpack High bytes of a psubw mm4, mm3 // pbv = p - b = (a + b - c) - b = a - c movq mm5, mm1 // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv movq mm6, mm4 psubw mm5, mm3 pxor mm0, mm0 paddw mm6, mm5 // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) pcmpgtw mm0, mm4 // Create mask pav bytes < 0 pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 pand mm0, mm4 // Only pav bytes < 0 in mm7 pand mm7, mm5 // Only pbv bytes < 0 in mm0 psubw mm4, mm0 psubw mm5, mm7 psubw mm4, mm0 psubw mm5, mm7 pxor mm0, mm0 pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 pand mm0, mm6 // Only pav bytes < 0 in mm7 psubw mm6, mm0 // test pa <= pb movq mm7, mm4 psubw mm6, mm0 pcmpgtw mm7, mm5 // pa > pb? movq mm0, mm7 // use mm0 mask copy to merge a & b pand mm2, mm0 // use mm7 mask to merge pa & pb pand mm5, mm7 pandn mm0, mm1 pandn mm7, mm4 paddw mm0, mm2 paddw mm7, mm5 // test ((pa <= pb)? pa:pb) <= pc pcmpgtw mm7, mm6 // pab > pc? pand mm3, mm7 pandn mm7, mm0 paddw mm7, mm3 pxor mm1, mm1 packuswb mm1, mm7 // Step ebx to next set of 8 bytes and repeat loop til done add ebx, 8 pand mm1, ActiveMaskEnd paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x) cmp ebx, MMXLength pxor mm0, mm0 // pxor does not affect flags movq [edi + ebx - 8], mm1 // write back updated value // mm1 will be used as Raw(x-bpp) next loop // mm3 ready to be used as Prior(x-bpp) next loop jb dpth3lp } // end _asm block } break; case 6: case 7: case 5: { ActiveMask.use = 0x00000000ffffffff; ActiveMask2.use = 0xffffffff00000000; ShiftBpp.use = bpp << 3; // == bpp * 8 ShiftRem.use = 64 - ShiftBpp.use; _asm { mov ebx, diff mov edi, row mov esi, prev_row // PRIME the pump (load the first Raw(x-bpp) data set movq mm1, [edi+ebx-8] pxor mm0, mm0 dpth6lp: // Must shift to position Raw(x-bpp) data psrlq mm1, ShiftRem // Do first set of 4 bytes movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes punpcklbw mm1, mm0 // Unpack Low bytes of a movq mm2, [esi + ebx] // load b=Prior(x) punpcklbw mm2, mm0 // Unpack Low bytes of b // Must shift to position Prior(x-bpp) data psrlq mm3, ShiftRem // pav = p - a = (a + b - c) - a = b - c movq mm4, mm2 punpcklbw mm3, mm0 // Unpack Low bytes of c // pbv = p - b = (a + b - c) - b = a - c movq mm5, mm1 psubw mm4, mm3 pxor mm7, mm7 // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv movq mm6, mm4 psubw mm5, mm3 // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) pcmpgtw mm0, mm4 // Create mask pav bytes < 0 paddw mm6, mm5 pand mm0, mm4 // Only pav bytes < 0 in mm7 pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 psubw mm4, mm0 pand mm7, mm5 // Only pbv bytes < 0 in mm0 psubw mm4, mm0 psubw mm5, mm7 pxor mm0, mm0 pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 pand mm0, mm6 // Only pav bytes < 0 in mm7 psubw mm5, mm7 psubw mm6, mm0 // test pa <= pb movq mm7, mm4 psubw mm6, mm0 pcmpgtw mm7, mm5 // pa > pb? movq mm0, mm7 // use mm7 mask to merge pa & pb pand mm5, mm7 // use mm0 mask copy to merge a & b pand mm2, mm0 pandn mm7, mm4 pandn mm0, mm1 paddw mm7, mm5 paddw mm0, mm2 // test ((pa <= pb)? pa:pb) <= pc pcmpgtw mm7, mm6 // pab > pc? pxor mm1, mm1 pand mm3, mm7 pandn mm7, mm0 paddw mm7, mm3 pxor mm0, mm0 packuswb mm7, mm1 movq mm3, [esi + ebx - 8] // load c=Prior(x-bpp) pand mm7, ActiveMask psrlq mm3, ShiftRem movq mm2, [esi + ebx] // load b=Prior(x) step 1 paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) movq mm6, mm2 movq [edi + ebx], mm7 // write back updated value movq mm1, [edi+ebx-8] psllq mm6, ShiftBpp movq mm5, mm7 psrlq mm1, ShiftRem por mm3, mm6 psllq mm5, ShiftBpp punpckhbw mm3, mm0 // Unpack High bytes of c por mm1, mm5 // Do second set of 4 bytes punpckhbw mm2, mm0 // Unpack High bytes of b punpckhbw mm1, mm0 // Unpack High bytes of a // pav = p - a = (a + b - c) - a = b - c movq mm4, mm2 // pbv = p - b = (a + b - c) - b = a - c movq mm5, mm1 psubw mm4, mm3 pxor mm7, mm7 // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv movq mm6, mm4 psubw mm5, mm3 // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) pcmpgtw mm0, mm4 // Create mask pav bytes < 0 paddw mm6, mm5 pand mm0, mm4 // Only pav bytes < 0 in mm7 pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 psubw mm4, mm0 pand mm7, mm5 // Only pbv bytes < 0 in mm0 psubw mm4, mm0 psubw mm5, mm7 pxor mm0, mm0 pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 pand mm0, mm6 // Only pav bytes < 0 in mm7 psubw mm5, mm7 psubw mm6, mm0 // test pa <= pb movq mm7, mm4 psubw mm6, mm0 pcmpgtw mm7, mm5 // pa > pb? movq mm0, mm7 // use mm7 mask to merge pa & pb pand mm5, mm7 // use mm0 mask copy to merge a & b pand mm2, mm0 pandn mm7, mm4 pandn mm0, mm1 paddw mm7, mm5 paddw mm0, mm2 // test ((pa <= pb)? pa:pb) <= pc pcmpgtw mm7, mm6 // pab > pc? pxor mm1, mm1 pand mm3, mm7 pandn mm7, mm0 pxor mm1, mm1 paddw mm7, mm3 pxor mm0, mm0 // Step ex to next set of 8 bytes and repeat loop til done add ebx, 8 packuswb mm1, mm7 paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x) cmp ebx, MMXLength movq [edi + ebx - 8], mm1 // write back updated value // mm1 will be used as Raw(x-bpp) next loop jb dpth6lp } // end _asm block } break; case 4: { ActiveMask.use = 0x00000000ffffffff; _asm { mov ebx, diff mov edi, row mov esi, prev_row pxor mm0, mm0 // PRIME the pump (load the first Raw(x-bpp) data set movq mm1, [edi+ebx-8] // Only time should need to read // a=Raw(x-bpp) bytes dpth4lp: // Do first set of 4 bytes movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes punpckhbw mm1, mm0 // Unpack Low bytes of a movq mm2, [esi + ebx] // load b=Prior(x) punpcklbw mm2, mm0 // Unpack High bytes of b // pav = p - a = (a + b - c) - a = b - c movq mm4, mm2 punpckhbw mm3, mm0 // Unpack High bytes of c // pbv = p - b = (a + b - c) - b = a - c movq mm5, mm1 psubw mm4, mm3 pxor mm7, mm7 // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv movq mm6, mm4 psubw mm5, mm3 // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) pcmpgtw mm0, mm4 // Create mask pav bytes < 0 paddw mm6, mm5 pand mm0, mm4 // Only pav bytes < 0 in mm7 pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 psubw mm4, mm0 pand mm7, mm5 // Only pbv bytes < 0 in mm0 psubw mm4, mm0 psubw mm5, mm7 pxor mm0, mm0 pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 pand mm0, mm6 // Only pav bytes < 0 in mm7 psubw mm5, mm7 psubw mm6, mm0 // test pa <= pb movq mm7, mm4 psubw mm6, mm0 pcmpgtw mm7, mm5 // pa > pb? movq mm0, mm7 // use mm7 mask to merge pa & pb pand mm5, mm7 // use mm0 mask copy to merge a & b pand mm2, mm0 pandn mm7, mm4 pandn mm0, mm1 paddw mm7, mm5 paddw mm0, mm2 // test ((pa <= pb)? pa:pb) <= pc pcmpgtw mm7, mm6 // pab > pc? pxor mm1, mm1 pand mm3, mm7 pandn mm7, mm0 paddw mm7, mm3 pxor mm0, mm0 packuswb mm7, mm1 movq mm3, [esi + ebx] // load c=Prior(x-bpp) pand mm7, ActiveMask movq mm2, mm3 // load b=Prior(x) step 1 paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) punpcklbw mm3, mm0 // Unpack High bytes of c movq [edi + ebx], mm7 // write back updated value movq mm1, mm7 // Now mm1 will be used as Raw(x-bpp) // Do second set of 4 bytes punpckhbw mm2, mm0 // Unpack Low bytes of b punpcklbw mm1, mm0 // Unpack Low bytes of a // pav = p - a = (a + b - c) - a = b - c movq mm4, mm2 // pbv = p - b = (a + b - c) - b = a - c movq mm5, mm1 psubw mm4, mm3 pxor mm7, mm7 // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv movq mm6, mm4 psubw mm5, mm3 // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) pcmpgtw mm0, mm4 // Create mask pav bytes < 0 paddw mm6, mm5 pand mm0, mm4 // Only pav bytes < 0 in mm7 pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 psubw mm4, mm0 pand mm7, mm5 // Only pbv bytes < 0 in mm0 psubw mm4, mm0 psubw mm5, mm7 pxor mm0, mm0 pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 pand mm0, mm6 // Only pav bytes < 0 in mm7 psubw mm5, mm7 psubw mm6, mm0 // test pa <= pb movq mm7, mm4 psubw mm6, mm0 pcmpgtw mm7, mm5 // pa > pb? movq mm0, mm7 // use mm7 mask to merge pa & pb pand mm5, mm7 // use mm0 mask copy to merge a & b pand mm2, mm0 pandn mm7, mm4 pandn mm0, mm1 paddw mm7, mm5 paddw mm0, mm2 // test ((pa <= pb)? pa:pb) <= pc pcmpgtw mm7, mm6 // pab > pc? pxor mm1, mm1 pand mm3, mm7 pandn mm7, mm0 pxor mm1, mm1 paddw mm7, mm3 pxor mm0, mm0 // Step ex to next set of 8 bytes and repeat loop til done add ebx, 8 packuswb mm1, mm7 paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x) cmp ebx, MMXLength movq [edi + ebx - 8], mm1 // write back updated value // mm1 will be used as Raw(x-bpp) next loop jb dpth4lp } // end _asm block } break; case 8: // bpp == 8 { ActiveMask.use = 0x00000000ffffffff; _asm { mov ebx, diff mov edi, row mov esi, prev_row pxor mm0, mm0 // PRIME the pump (load the first Raw(x-bpp) data set movq mm1, [edi+ebx-8] // Only time should need to read // a=Raw(x-bpp) bytes dpth8lp: // Do first set of 4 bytes movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes punpcklbw mm1, mm0 // Unpack Low bytes of a movq mm2, [esi + ebx] // load b=Prior(x) punpcklbw mm2, mm0 // Unpack Low bytes of b // pav = p - a = (a + b - c) - a = b - c movq mm4, mm2 punpcklbw mm3, mm0 // Unpack Low bytes of c // pbv = p - b = (a + b - c) - b = a - c movq mm5, mm1 psubw mm4, mm3 pxor mm7, mm7 // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv movq mm6, mm4 psubw mm5, mm3 // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) pcmpgtw mm0, mm4 // Create mask pav bytes < 0 paddw mm6, mm5 pand mm0, mm4 // Only pav bytes < 0 in mm7 pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 psubw mm4, mm0 pand mm7, mm5 // Only pbv bytes < 0 in mm0 psubw mm4, mm0 psubw mm5, mm7 pxor mm0, mm0 pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 pand mm0, mm6 // Only pav bytes < 0 in mm7 psubw mm5, mm7 psubw mm6, mm0 // test pa <= pb movq mm7, mm4 psubw mm6, mm0 pcmpgtw mm7, mm5 // pa > pb? movq mm0, mm7 // use mm7 mask to merge pa & pb pand mm5, mm7 // use mm0 mask copy to merge a & b pand mm2, mm0 pandn mm7, mm4 pandn mm0, mm1 paddw mm7, mm5 paddw mm0, mm2 // test ((pa <= pb)? pa:pb) <= pc pcmpgtw mm7, mm6 // pab > pc? pxor mm1, mm1 pand mm3, mm7 pandn mm7, mm0 paddw mm7, mm3 pxor mm0, mm0 packuswb mm7, mm1 movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes pand mm7, ActiveMask movq mm2, [esi + ebx] // load b=Prior(x) paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x) punpckhbw mm3, mm0 // Unpack High bytes of c movq [edi + ebx], mm7 // write back updated value movq mm1, [edi+ebx-8] // read a=Raw(x-bpp) bytes // Do second set of 4 bytes punpckhbw mm2, mm0 // Unpack High bytes of b punpckhbw mm1, mm0 // Unpack High bytes of a // pav = p - a = (a + b - c) - a = b - c movq mm4, mm2 // pbv = p - b = (a + b - c) - b = a - c movq mm5, mm1 psubw mm4, mm3 pxor mm7, mm7 // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv movq mm6, mm4 psubw mm5, mm3 // pa = abs(p-a) = abs(pav) // pb = abs(p-b) = abs(pbv) // pc = abs(p-c) = abs(pcv) pcmpgtw mm0, mm4 // Create mask pav bytes < 0 paddw mm6, mm5 pand mm0, mm4 // Only pav bytes < 0 in mm7 pcmpgtw mm7, mm5 // Create mask pbv bytes < 0 psubw mm4, mm0 pand mm7, mm5 // Only pbv bytes < 0 in mm0 psubw mm4, mm0 psubw mm5, mm7 pxor mm0, mm0 pcmpgtw mm0, mm6 // Create mask pcv bytes < 0 pand mm0, mm6 // Only pav bytes < 0 in mm7 psubw mm5, mm7 psubw mm6, mm0 // test pa <= pb movq mm7, mm4 psubw mm6, mm0 pcmpgtw mm7, mm5 // pa > pb? movq mm0, mm7 // use mm7 mask to merge pa & pb pand mm5, mm7 // use mm0 mask copy to merge a & b pand mm2, mm0 pandn mm7, mm4 pandn mm0, mm1 paddw mm7, mm5 paddw mm0, mm2 // test ((pa <= pb)? pa:pb) <= pc pcmpgtw mm7, mm6 // pab > pc? pxor mm1, mm1 pand mm3, mm7 pandn mm7, mm0 pxor mm1, mm1 paddw mm7, mm3 pxor mm0, mm0 // Step ex to next set of 8 bytes and repeat loop til done add ebx, 8 packuswb mm1, mm7 paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x) cmp ebx, MMXLength movq [edi + ebx - 8], mm1 // write back updated value // mm1 will be used as Raw(x-bpp) next loop jb dpth8lp } // end _asm block } break; case 1: // bpp = 1 case 2: // bpp = 2 default: // bpp > 8 { _asm { mov ebx, diff cmp ebx, FullLength jnb dpthdend mov edi, row mov esi, prev_row // Do Paeth decode for remaining bytes mov edx, ebx xor ecx, ecx // zero ecx before using cl & cx in loop below sub edx, bpp // Set edx = ebx - bpp dpthdlp: xor eax, eax // pav = p - a = (a + b - c) - a = b - c mov al, [esi + ebx] // load Prior(x) into al mov cl, [esi + edx] // load Prior(x-bpp) into cl sub eax, ecx // subtract Prior(x-bpp) mov patemp, eax // Save pav for later use xor eax, eax // pbv = p - b = (a + b - c) - b = a - c mov al, [edi + edx] // load Raw(x-bpp) into al sub eax, ecx // subtract Prior(x-bpp) mov ecx, eax // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv add eax, patemp // pcv = pav + pbv // pc = abs(pcv) test eax, 0x80000000 jz dpthdpca neg eax // reverse sign of neg values dpthdpca: mov pctemp, eax // save pc for later use // pb = abs(pbv) test ecx, 0x80000000 jz dpthdpba neg ecx // reverse sign of neg values dpthdpba: mov pbtemp, ecx // save pb for later use // pa = abs(pav) mov eax, patemp test eax, 0x80000000 jz dpthdpaa neg eax // reverse sign of neg values dpthdpaa: mov patemp, eax // save pa for later use // test if pa <= pb cmp eax, ecx jna dpthdabb // pa > pb; now test if pb <= pc cmp ecx, pctemp jna dpthdbbc // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) mov cl, [esi + edx] // load Prior(x-bpp) into cl jmp dpthdpaeth dpthdbbc: // pb <= pc; Raw(x) = Paeth(x) + Prior(x) mov cl, [esi + ebx] // load Prior(x) into cl jmp dpthdpaeth dpthdabb: // pa <= pb; now test if pa <= pc cmp eax, pctemp jna dpthdabc // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) mov cl, [esi + edx] // load Prior(x-bpp) into cl jmp dpthdpaeth dpthdabc: // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) mov cl, [edi + edx] // load Raw(x-bpp) into cl dpthdpaeth: inc ebx inc edx // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 add [edi + ebx - 1], cl cmp ebx, FullLength jb dpthdlp dpthdend: } // end _asm block } return; // No need to go further with this one } // end switch ( bpp ) _asm { // MMX acceleration complete now do clean-up // Check if any remaining bytes left to decode mov ebx, MMXLength cmp ebx, FullLength jnb dpthend mov edi, row mov esi, prev_row // Do Paeth decode for remaining bytes mov edx, ebx xor ecx, ecx // zero ecx before using cl & cx in loop below sub edx, bpp // Set edx = ebx - bpp dpthlp2: xor eax, eax // pav = p - a = (a + b - c) - a = b - c mov al, [esi + ebx] // load Prior(x) into al mov cl, [esi + edx] // load Prior(x-bpp) into cl sub eax, ecx // subtract Prior(x-bpp) mov patemp, eax // Save pav for later use xor eax, eax // pbv = p - b = (a + b - c) - b = a - c mov al, [edi + edx] // load Raw(x-bpp) into al sub eax, ecx // subtract Prior(x-bpp) mov ecx, eax // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv add eax, patemp // pcv = pav + pbv // pc = abs(pcv) test eax, 0x80000000 jz dpthpca2 neg eax // reverse sign of neg values dpthpca2: mov pctemp, eax // save pc for later use // pb = abs(pbv) test ecx, 0x80000000 jz dpthpba2 neg ecx // reverse sign of neg values dpthpba2: mov pbtemp, ecx // save pb for later use // pa = abs(pav) mov eax, patemp test eax, 0x80000000 jz dpthpaa2 neg eax // reverse sign of neg values dpthpaa2: mov patemp, eax // save pa for later use // test if pa <= pb cmp eax, ecx jna dpthabb2 // pa > pb; now test if pb <= pc cmp ecx, pctemp jna dpthbbc2 // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) mov cl, [esi + edx] // load Prior(x-bpp) into cl jmp dpthpaeth2 dpthbbc2: // pb <= pc; Raw(x) = Paeth(x) + Prior(x) mov cl, [esi + ebx] // load Prior(x) into cl jmp dpthpaeth2 dpthabb2: // pa <= pb; now test if pa <= pc cmp eax, pctemp jna dpthabc2 // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) mov cl, [esi + edx] // load Prior(x-bpp) into cl jmp dpthpaeth2 dpthabc2: // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) mov cl, [edi + edx] // load Raw(x-bpp) into cl dpthpaeth2: inc ebx inc edx // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 add [edi + ebx - 1], cl cmp ebx, FullLength jb dpthlp2 dpthend: emms // End MMX instructions; prep for possible FP instrs. } // end _asm block } // Optimized code for PNG Sub filter decoder void /* PRIVATE */ png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row) { //int test; int bpp; png_uint_32 FullLength; png_uint_32 MMXLength; int diff; bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel FullLength = row_info->rowbytes - bpp; // # of bytes to filter _asm { mov edi, row mov esi, edi // lp = row add edi, bpp // rp = row + bpp xor eax, eax // get # of bytes to alignment mov diff, edi // take start of row add diff, 0xf // add 7 + 8 to incr past // alignment boundary xor ebx, ebx and diff, 0xfffffff8 // mask to alignment boundary sub diff, edi // subtract from start ==> value // ebx at alignment jz dsubgo // fix alignment dsublp1: mov al, [esi+ebx] add [edi+ebx], al inc ebx cmp ebx, diff jb dsublp1 dsubgo: mov ecx, FullLength mov edx, ecx sub edx, ebx // subtract alignment fix and edx, 0x00000007 // calc bytes over mult of 8 sub ecx, edx // drop over bytes from length mov MMXLength, ecx } // end _asm block // Now do the math for the rest of the row switch ( bpp ) { case 3: { ActiveMask.use = 0x0000ffffff000000; ShiftBpp.use = 24; // == 3 * 8 ShiftRem.use = 40; // == 64 - 24 _asm { mov edi, row movq mm7, ActiveMask // Load ActiveMask for 2nd active byte group mov esi, edi // lp = row add edi, bpp // rp = row + bpp movq mm6, mm7 mov ebx, diff psllq mm6, ShiftBpp // Move mask in mm6 to cover 3rd active // byte group // PRIME the pump (load the first Raw(x-bpp) data set movq mm1, [edi+ebx-8] dsub3lp: psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes // no need for mask; shift clears inactive bytes // Add 1st active group movq mm0, [edi+ebx] paddb mm0, mm1 // Add 2nd active group movq mm1, mm0 // mov updated Raws to mm1 psllq mm1, ShiftBpp // shift data to position correctly pand mm1, mm7 // mask to use only 2nd active group paddb mm0, mm1 // Add 3rd active group movq mm1, mm0 // mov updated Raws to mm1 psllq mm1, ShiftBpp // shift data to position correctly pand mm1, mm6 // mask to use only 3rd active group add ebx, 8 paddb mm0, mm1 cmp ebx, MMXLength movq [edi+ebx-8], mm0 // Write updated Raws back to array // Prep for doing 1st add at top of loop movq mm1, mm0 jb dsub3lp } // end _asm block } break; case 1: { // Placed here just in case this is a duplicate of the // non-MMX code for the SUB filter in png_read_filter_row below // // png_bytep rp; // png_bytep lp; // png_uint_32 i; // bpp = (row_info->pixel_depth + 7) >> 3; // for (i = (png_uint_32)bpp, rp = row + bpp, lp = row; // i < row_info->rowbytes; i++, rp++, lp++) // { // *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff); // } _asm { mov ebx, diff mov edi, row cmp ebx, FullLength jnb dsub1end mov esi, edi // lp = row xor eax, eax add edi, bpp // rp = row + bpp dsub1lp: mov al, [esi+ebx] add [edi+ebx], al inc ebx cmp ebx, FullLength jb dsub1lp dsub1end: } // end _asm block } return; case 6: case 7: case 4: case 5: { ShiftBpp.use = bpp << 3; ShiftRem.use = 64 - ShiftBpp.use; _asm { mov edi, row mov ebx, diff mov esi, edi // lp = row add edi, bpp // rp = row + bpp // PRIME the pump (load the first Raw(x-bpp) data set movq mm1, [edi+ebx-8] dsub4lp: psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes // no need for mask; shift clears inactive bytes movq mm0, [edi+ebx] paddb mm0, mm1 // Add 2nd active group movq mm1, mm0 // mov updated Raws to mm1 psllq mm1, ShiftBpp // shift data to position correctly // there is no need for any mask // since shift clears inactive bits/bytes add ebx, 8 paddb mm0, mm1 cmp ebx, MMXLength movq [edi+ebx-8], mm0 movq mm1, mm0 // Prep for doing 1st add at top of loop jb dsub4lp } // end _asm block } break; case 2: { ActiveMask.use = 0x00000000ffff0000; ShiftBpp.use = 16; // == 2 * 8 ShiftRem.use = 48; // == 64 - 16 _asm { movq mm7, ActiveMask // Load ActiveMask for 2nd active byte group mov ebx, diff movq mm6, mm7 mov edi, row psllq mm6, ShiftBpp // Move mask in mm6 to cover 3rd active // byte group mov esi, edi // lp = row movq mm5, mm6 add edi, bpp // rp = row + bpp psllq mm5, ShiftBpp // Move mask in mm5 to cover 4th active // byte group // PRIME the pump (load the first Raw(x-bpp) data set movq mm1, [edi+ebx-8] dsub2lp: // Add 1st active group psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes // no need for mask; shift clears inactive // bytes movq mm0, [edi+ebx] paddb mm0, mm1 // Add 2nd active group movq mm1, mm0 // mov updated Raws to mm1 psllq mm1, ShiftBpp // shift data to position correctly pand mm1, mm7 // mask to use only 2nd active group paddb mm0, mm1 // Add 3rd active group movq mm1, mm0 // mov updated Raws to mm1 psllq mm1, ShiftBpp // shift data to position correctly pand mm1, mm6 // mask to use only 3rd active group paddb mm0, mm1 // Add 4th active group movq mm1, mm0 // mov updated Raws to mm1 psllq mm1, ShiftBpp // shift data to position correctly pand mm1, mm5 // mask to use only 4th active group add ebx, 8 paddb mm0, mm1 cmp ebx, MMXLength movq [edi+ebx-8], mm0 // Write updated Raws back to array movq mm1, mm0 // Prep for doing 1st add at top of loop jb dsub2lp } // end _asm block } break; case 8: { _asm { mov edi, row mov ebx, diff mov esi, edi // lp = row add edi, bpp // rp = row + bpp mov ecx, MMXLength movq mm7, [edi+ebx-8] // PRIME the pump (load the first // Raw(x-bpp) data set and ecx, 0x0000003f // calc bytes over mult of 64 dsub8lp: movq mm0, [edi+ebx] // Load Sub(x) for 1st 8 bytes paddb mm0, mm7 movq mm1, [edi+ebx+8] // Load Sub(x) for 2nd 8 bytes movq [edi+ebx], mm0 // Write Raw(x) for 1st 8 bytes // Now mm0 will be used as Raw(x-bpp) for // the 2nd group of 8 bytes. This will be // repeated for each group of 8 bytes with // the 8th group being used as the Raw(x-bpp) // for the 1st group of the next loop. paddb mm1, mm0 movq mm2, [edi+ebx+16] // Load Sub(x) for 3rd 8 bytes movq [edi+ebx+8], mm1 // Write Raw(x) for 2nd 8 bytes paddb mm2, mm1 movq mm3, [edi+ebx+24] // Load Sub(x) for 4th 8 bytes movq [edi+ebx+16], mm2 // Write Raw(x) for 3rd 8 bytes paddb mm3, mm2 movq mm4, [edi+ebx+32] // Load Sub(x) for 5th 8 bytes movq [edi+ebx+24], mm3 // Write Raw(x) for 4th 8 bytes paddb mm4, mm3 movq mm5, [edi+ebx+40] // Load Sub(x) for 6th 8 bytes movq [edi+ebx+32], mm4 // Write Raw(x) for 5th 8 bytes paddb mm5, mm4 movq mm6, [edi+ebx+48] // Load Sub(x) for 7th 8 bytes movq [edi+ebx+40], mm5 // Write Raw(x) for 6th 8 bytes paddb mm6, mm5 movq mm7, [edi+ebx+56] // Load Sub(x) for 8th 8 bytes movq [edi+ebx+48], mm6 // Write Raw(x) for 7th 8 bytes add ebx, 64 paddb mm7, mm6 cmp ebx, ecx movq [edi+ebx-8], mm7 // Write Raw(x) for 8th 8 bytes jb dsub8lp cmp ebx, MMXLength jnb dsub8lt8 dsub8lpA: movq mm0, [edi+ebx] add ebx, 8 paddb mm0, mm7 cmp ebx, MMXLength movq [edi+ebx-8], mm0 // use -8 to offset early add to ebx movq mm7, mm0 // Move calculated Raw(x) data to mm1 to // be the new Raw(x-bpp) for the next loop jb dsub8lpA dsub8lt8: } // end _asm block } break; default: // bpp greater than 8 bytes { _asm { mov ebx, diff mov edi, row mov esi, edi // lp = row add edi, bpp // rp = row + bpp dsubAlp: movq mm0, [edi+ebx] movq mm1, [esi+ebx] add ebx, 8 paddb mm0, mm1 cmp ebx, MMXLength movq [edi+ebx-8], mm0 // mov does not affect flags; -8 to offset // add ebx jb dsubAlp } // end _asm block } break; } // end switch ( bpp ) _asm { mov ebx, MMXLength mov edi, row cmp ebx, FullLength jnb dsubend mov esi, edi // lp = row xor eax, eax add edi, bpp // rp = row + bpp dsublp2: mov al, [esi+ebx] add [edi+ebx], al inc ebx cmp ebx, FullLength jb dsublp2 dsubend: emms // End MMX instructions; prep for possible FP instrs. } // end _asm block } // Optimized code for PNG Up filter decoder void /* PRIVATE */ png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row, png_bytep prev_row) { png_uint_32 len; len = row_info->rowbytes; // # of bytes to filter _asm { mov edi, row // get # of bytes to alignment mov ecx, edi xor ebx, ebx add ecx, 0x7 xor eax, eax and ecx, 0xfffffff8 mov esi, prev_row sub ecx, edi jz dupgo // fix alignment duplp1: mov al, [edi+ebx] add al, [esi+ebx] inc ebx cmp ebx, ecx mov [edi + ebx-1], al // mov does not affect flags; -1 to offset inc ebx jb duplp1 dupgo: mov ecx, len mov edx, ecx sub edx, ebx // subtract alignment fix and edx, 0x0000003f // calc bytes over mult of 64 sub ecx, edx // drop over bytes from length // Unrolled loop - use all MMX registers and interleave to reduce // number of branch instructions (loops) and reduce partial stalls duploop: movq mm1, [esi+ebx] movq mm0, [edi+ebx] movq mm3, [esi+ebx+8] paddb mm0, mm1 movq mm2, [edi+ebx+8] movq [edi+ebx], mm0 paddb mm2, mm3 movq mm5, [esi+ebx+16] movq [edi+ebx+8], mm2 movq mm4, [edi+ebx+16] movq mm7, [esi+ebx+24] paddb mm4, mm5 movq mm6, [edi+ebx+24] movq [edi+ebx+16], mm4 paddb mm6, mm7 movq mm1, [esi+ebx+32] movq [edi+ebx+24], mm6 movq mm0, [edi+ebx+32] movq mm3, [esi+ebx+40] paddb mm0, mm1 movq mm2, [edi+ebx+40] movq [edi+ebx+32], mm0 paddb mm2, mm3 movq mm5, [esi+ebx+48] movq [edi+ebx+40], mm2 movq mm4, [edi+ebx+48] movq mm7, [esi+ebx+56] paddb mm4, mm5 movq mm6, [edi+ebx+56] movq [edi+ebx+48], mm4 add ebx, 64 paddb mm6, mm7 cmp ebx, ecx movq [edi+ebx-8], mm6 // (+56)movq does not affect flags; // -8 to offset add ebx jb duploop cmp edx, 0 // Test for bytes over mult of 64 jz dupend // 2 lines added by lcreeve at netins.net // (mail 11 Jul 98 in png-implement list) cmp edx, 8 //test for less than 8 bytes jb duplt8 add ecx, edx and edx, 0x00000007 // calc bytes over mult of 8 sub ecx, edx // drop over bytes from length jz duplt8 // Loop using MMX registers mm0 & mm1 to update 8 bytes simultaneously duplpA: movq mm1, [esi+ebx] movq mm0, [edi+ebx] add ebx, 8 paddb mm0, mm1 cmp ebx, ecx movq [edi+ebx-8], mm0 // movq does not affect flags; -8 to offset add ebx jb duplpA cmp edx, 0 // Test for bytes over mult of 8 jz dupend duplt8: xor eax, eax add ecx, edx // move over byte count into counter // Loop using x86 registers to update remaining bytes duplp2: mov al, [edi + ebx] add al, [esi + ebx] inc ebx cmp ebx, ecx mov [edi + ebx-1], al // mov does not affect flags; -1 to offset inc ebx jb duplp2 dupend: // Conversion of filtered row completed emms // End MMX instructions; prep for possible FP instrs. } // end _asm block } // Optimized png_read_filter_row routines void /* PRIVATE */ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter) { #ifdef PNG_DEBUG char filnm[10]; #endif if (mmx_supported == 2) { #if !defined(PNG_1_0_X) /* this should have happened in png_init_mmx_flags() already */ png_warning(png_ptr, "asm_flags may not have been initialized"); #endif png_mmx_support(); } #ifdef PNG_DEBUG png_debug(1, "in png_read_filter_row\n"); switch (filter) { case 0: sprintf(filnm, "none"); break; #if !defined(PNG_1_0_X) case 1: sprintf(filnm, "sub-%s", (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : "x86"); break; case 2: sprintf(filnm, "up-%s", (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" : "x86"); break; case 3: sprintf(filnm, "avg-%s", (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" : "x86"); break; case 4: sprintf(filnm, "Paeth-%s", (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX":"x86"); break; #else case 1: sprintf(filnm, "sub"); break; case 2: sprintf(filnm, "up"); break; case 3: sprintf(filnm, "avg"); break; case 4: sprintf(filnm, "Paeth"); break; #endif default: sprintf(filnm, "unknw"); break; } png_debug2(0,"row=%5d, %s, ", png_ptr->row_number, filnm); png_debug2(0, "pd=%2d, b=%d, ", (int)row_info->pixel_depth, (int)((row_info->pixel_depth + 7) >> 3)); png_debug1(0,"len=%8d, ", row_info->rowbytes); #endif /* PNG_DEBUG */ switch (filter) { case PNG_FILTER_VALUE_NONE: break; case PNG_FILTER_VALUE_SUB: { #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) #else if (mmx_supported) #endif { png_read_filter_row_mmx_sub(row_info, row); } else { png_uint_32 i; png_uint_32 istop = row_info->rowbytes; png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; png_bytep rp = row + bpp; png_bytep lp = row; for (i = bpp; i < istop; i++) { *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); rp++; } } break; } case PNG_FILTER_VALUE_UP: { #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) #else if (mmx_supported) #endif { png_read_filter_row_mmx_up(row_info, row, prev_row); } else { png_uint_32 i; png_uint_32 istop = row_info->rowbytes; png_bytep rp = row; png_bytep pp = prev_row; for (i = 0; i < istop; ++i) { *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); rp++; } } break; } case PNG_FILTER_VALUE_AVG: { #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) #else if (mmx_supported) #endif { png_read_filter_row_mmx_avg(row_info, row, prev_row); } else { png_uint_32 i; png_bytep rp = row; png_bytep pp = prev_row; png_bytep lp = row; png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; png_uint_32 istop = row_info->rowbytes - bpp; for (i = 0; i < bpp; i++) { *rp = (png_byte)(((int)(*rp) + ((int)(*pp++) >> 1)) & 0xff); rp++; } for (i = 0; i < istop; i++) { *rp = (png_byte)(((int)(*rp) + ((int)(*pp++ + *lp++) >> 1)) & 0xff); rp++; } } break; } case PNG_FILTER_VALUE_PAETH: { #if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) #else if (mmx_supported) #endif { png_read_filter_row_mmx_paeth(row_info, row, prev_row); } else { png_uint_32 i; png_bytep rp = row; png_bytep pp = prev_row; png_bytep lp = row; png_bytep cp = prev_row; png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; png_uint_32 istop=row_info->rowbytes - bpp; for (i = 0; i < bpp; i++) { *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); rp++; } for (i = 0; i < istop; i++) // use leftover rp,pp { int a, b, c, pa, pb, pc, p; a = *lp++; b = *pp++; c = *cp++; p = b - c; pc = a - c; #ifdef PNG_USE_ABS pa = abs(p); pb = abs(pc); pc = abs(p + pc); #else pa = p < 0 ? -p : p; pb = pc < 0 ? -pc : pc; pc = (p + pc) < 0 ? -(p + pc) : p + pc; #endif /* if (pa <= pb && pa <= pc) p = a; else if (pb <= pc) p = b; else p = c; */ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; *rp = (png_byte)(((int)(*rp) + p) & 0xff); rp++; } } break; } default: png_warning(png_ptr, "Ignoring bad row filter type"); *row=0; break; } } #endif /* PNG_ASSEMBLER_CODE_SUPPORTED && PNG_USE_PNGVCRD */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngget.c0000664000175000017500000006263710777447272020625 0ustar evanevan /* pngget.c - retrieval of values from info struct * * libpng 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ #define PNG_INTERNAL #include "png.h" png_uint_32 PNGAPI png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag) { if (png_ptr != NULL && info_ptr != NULL) return(info_ptr->valid & flag); else return(0); } png_uint_32 PNGAPI png_get_rowbytes(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) return(info_ptr->rowbytes); else return(0); } #if defined(PNG_INFO_IMAGE_SUPPORTED) png_bytepp PNGAPI png_get_rows(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) return(info_ptr->row_pointers); else return(0); } #endif #ifdef PNG_EASY_ACCESS_SUPPORTED /* easy access to info, added in libpng-0.99 */ png_uint_32 PNGAPI png_get_image_width(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) { return info_ptr->width; } return (0); } png_uint_32 PNGAPI png_get_image_height(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) { return info_ptr->height; } return (0); } png_byte PNGAPI png_get_bit_depth(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) { return info_ptr->bit_depth; } return (0); } png_byte PNGAPI png_get_color_type(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) { return info_ptr->color_type; } return (0); } png_byte PNGAPI png_get_filter_type(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) { return info_ptr->filter_type; } return (0); } png_byte PNGAPI png_get_interlace_type(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) { return info_ptr->interlace_type; } return (0); } png_byte PNGAPI png_get_compression_type(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) { return info_ptr->compression_type; } return (0); } png_uint_32 PNGAPI png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) #if defined(PNG_pHYs_SUPPORTED) if (info_ptr->valid & PNG_INFO_pHYs) { png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter"); if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER) return (0); else return (info_ptr->x_pixels_per_unit); } #else return (0); #endif return (0); } png_uint_32 PNGAPI png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) #if defined(PNG_pHYs_SUPPORTED) if (info_ptr->valid & PNG_INFO_pHYs) { png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter"); if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER) return (0); else return (info_ptr->y_pixels_per_unit); } #else return (0); #endif return (0); } png_uint_32 PNGAPI png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) #if defined(PNG_pHYs_SUPPORTED) if (info_ptr->valid & PNG_INFO_pHYs) { png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter"); if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER || info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit) return (0); else return (info_ptr->x_pixels_per_unit); } #else return (0); #endif return (0); } #ifdef PNG_FLOATING_POINT_SUPPORTED float PNGAPI png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) #if defined(PNG_pHYs_SUPPORTED) if (info_ptr->valid & PNG_INFO_pHYs) { png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio"); if (info_ptr->x_pixels_per_unit == 0) return ((float)0.0); else return ((float)((float)info_ptr->y_pixels_per_unit /(float)info_ptr->x_pixels_per_unit)); } #else return (0.0); #endif return ((float)0.0); } #endif png_int_32 PNGAPI png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) #if defined(PNG_oFFs_SUPPORTED) if (info_ptr->valid & PNG_INFO_oFFs) { png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns"); if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER) return (0); else return (info_ptr->x_offset); } #else return (0); #endif return (0); } png_int_32 PNGAPI png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) #if defined(PNG_oFFs_SUPPORTED) if (info_ptr->valid & PNG_INFO_oFFs) { png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns"); if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER) return (0); else return (info_ptr->y_offset); } #else return (0); #endif return (0); } png_int_32 PNGAPI png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) #if defined(PNG_oFFs_SUPPORTED) if (info_ptr->valid & PNG_INFO_oFFs) { png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns"); if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) return (0); else return (info_ptr->x_offset); } #else return (0); #endif return (0); } png_int_32 PNGAPI png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) #if defined(PNG_oFFs_SUPPORTED) if (info_ptr->valid & PNG_INFO_oFFs) { png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns"); if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) return (0); else return (info_ptr->y_offset); } #else return (0); #endif return (0); } #if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED) png_uint_32 PNGAPI png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) { return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr) *.0254 +.5)); } png_uint_32 PNGAPI png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) { return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr) *.0254 +.5)); } png_uint_32 PNGAPI png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) { return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr) *.0254 +.5)); } float PNGAPI png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr) { return ((float)png_get_x_offset_microns(png_ptr, info_ptr) *.00003937); } float PNGAPI png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr) { return ((float)png_get_y_offset_microns(png_ptr, info_ptr) *.00003937); } #if defined(PNG_pHYs_SUPPORTED) png_uint_32 PNGAPI png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) { png_uint_32 retval = 0; if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { png_debug1(1, "in %s retrieval function\n", "pHYs"); if (res_x != NULL) { *res_x = info_ptr->x_pixels_per_unit; retval |= PNG_INFO_pHYs; } if (res_y != NULL) { *res_y = info_ptr->y_pixels_per_unit; retval |= PNG_INFO_pHYs; } if (unit_type != NULL) { *unit_type = (int)info_ptr->phys_unit_type; retval |= PNG_INFO_pHYs; if(*unit_type == 1) { if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50); if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50); } } } return (retval); } #endif /* PNG_pHYs_SUPPORTED */ #endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */ /* png_get_channels really belongs in here, too, but it's been around longer */ #endif /* PNG_EASY_ACCESS_SUPPORTED */ png_byte PNGAPI png_get_channels(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) return(info_ptr->channels); else return (0); } png_bytep PNGAPI png_get_signature(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) return(info_ptr->signature); else return (NULL); } #if defined(PNG_bKGD_SUPPORTED) png_uint_32 PNGAPI png_get_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p *background) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) && background != NULL) { png_debug1(1, "in %s retrieval function\n", "bKGD"); *background = &(info_ptr->background); return (PNG_INFO_bKGD); } return (0); } #endif #if defined(PNG_cHRM_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED png_uint_32 PNGAPI png_get_cHRM(png_structp png_ptr, png_infop info_ptr, double *white_x, double *white_y, double *red_x, double *red_y, double *green_x, double *green_y, double *blue_x, double *blue_y) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) { png_debug1(1, "in %s retrieval function\n", "cHRM"); if (white_x != NULL) *white_x = (double)info_ptr->x_white; if (white_y != NULL) *white_y = (double)info_ptr->y_white; if (red_x != NULL) *red_x = (double)info_ptr->x_red; if (red_y != NULL) *red_y = (double)info_ptr->y_red; if (green_x != NULL) *green_x = (double)info_ptr->x_green; if (green_y != NULL) *green_y = (double)info_ptr->y_green; if (blue_x != NULL) *blue_x = (double)info_ptr->x_blue; if (blue_y != NULL) *blue_y = (double)info_ptr->y_blue; return (PNG_INFO_cHRM); } return (0); } #endif #ifdef PNG_FIXED_POINT_SUPPORTED png_uint_32 PNGAPI png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, png_fixed_point *blue_x, png_fixed_point *blue_y) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) { png_debug1(1, "in %s retrieval function\n", "cHRM"); if (white_x != NULL) *white_x = info_ptr->int_x_white; if (white_y != NULL) *white_y = info_ptr->int_y_white; if (red_x != NULL) *red_x = info_ptr->int_x_red; if (red_y != NULL) *red_y = info_ptr->int_y_red; if (green_x != NULL) *green_x = info_ptr->int_x_green; if (green_y != NULL) *green_y = info_ptr->int_y_green; if (blue_x != NULL) *blue_x = info_ptr->int_x_blue; if (blue_y != NULL) *blue_y = info_ptr->int_y_blue; return (PNG_INFO_cHRM); } return (0); } #endif #endif #if defined(PNG_gAMA_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED png_uint_32 PNGAPI png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) && file_gamma != NULL) { png_debug1(1, "in %s retrieval function\n", "gAMA"); *file_gamma = (double)info_ptr->gamma; return (PNG_INFO_gAMA); } return (0); } #endif #ifdef PNG_FIXED_POINT_SUPPORTED png_uint_32 PNGAPI png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point *int_file_gamma) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) && int_file_gamma != NULL) { png_debug1(1, "in %s retrieval function\n", "gAMA"); *int_file_gamma = info_ptr->int_gamma; return (PNG_INFO_gAMA); } return (0); } #endif #endif #if defined(PNG_sRGB_SUPPORTED) png_uint_32 PNGAPI png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB) && file_srgb_intent != NULL) { png_debug1(1, "in %s retrieval function\n", "sRGB"); *file_srgb_intent = (int)info_ptr->srgb_intent; return (PNG_INFO_sRGB); } return (0); } #endif #if defined(PNG_iCCP_SUPPORTED) png_uint_32 PNGAPI png_get_iCCP(png_structp png_ptr, png_infop info_ptr, png_charpp name, int *compression_type, png_charpp profile, png_uint_32 *proflen) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP) && name != NULL && profile != NULL && proflen != NULL) { png_debug1(1, "in %s retrieval function\n", "iCCP"); *name = info_ptr->iccp_name; *profile = info_ptr->iccp_profile; /* compression_type is a dummy so the API won't have to change if we introduce multiple compression types later. */ *proflen = (int)info_ptr->iccp_proflen; *compression_type = (int)info_ptr->iccp_compression; return (PNG_INFO_iCCP); } return (0); } #endif #if defined(PNG_sPLT_SUPPORTED) png_uint_32 PNGAPI png_get_sPLT(png_structp png_ptr, png_infop info_ptr, png_sPLT_tpp spalettes) { if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) *spalettes = info_ptr->splt_palettes; return ((png_uint_32)info_ptr->splt_palettes_num); } #endif #if defined(PNG_hIST_SUPPORTED) png_uint_32 PNGAPI png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) && hist != NULL) { png_debug1(1, "in %s retrieval function\n", "hIST"); *hist = info_ptr->hist; return (PNG_INFO_hIST); } return (0); } #endif png_uint_32 PNGAPI png_get_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 *width, png_uint_32 *height, int *bit_depth, int *color_type, int *interlace_type, int *compression_type, int *filter_type) { if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL && bit_depth != NULL && color_type != NULL) { png_debug1(1, "in %s retrieval function\n", "IHDR"); *width = info_ptr->width; *height = info_ptr->height; *bit_depth = info_ptr->bit_depth; if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16) png_error(png_ptr, "Invalid bit depth"); *color_type = info_ptr->color_type; if (info_ptr->color_type > 6) png_error(png_ptr, "Invalid color type"); if (compression_type != NULL) *compression_type = info_ptr->compression_type; if (filter_type != NULL) *filter_type = info_ptr->filter_type; if (interlace_type != NULL) *interlace_type = info_ptr->interlace_type; /* check for potential overflow of rowbytes */ if (*width == 0 || *width > PNG_UINT_31_MAX) png_error(png_ptr, "Invalid image width"); if (*height == 0 || *height > PNG_UINT_31_MAX) png_error(png_ptr, "Invalid image height"); if (info_ptr->width > (PNG_UINT_32_MAX >> 3) /* 8-byte RGBA pixels */ - 64 /* bigrowbuf hack */ - 1 /* filter byte */ - 7*8 /* rounding of width to multiple of 8 pixels */ - 8) /* extra max_pixel_depth pad */ { png_warning(png_ptr, "Width too large for libpng to process image data."); } return (1); } return (0); } #if defined(PNG_oFFs_SUPPORTED) png_uint_32 PNGAPI png_get_oFFs(png_structp png_ptr, png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) && offset_x != NULL && offset_y != NULL && unit_type != NULL) { png_debug1(1, "in %s retrieval function\n", "oFFs"); *offset_x = info_ptr->x_offset; *offset_y = info_ptr->y_offset; *unit_type = (int)info_ptr->offset_unit_type; return (PNG_INFO_oFFs); } return (0); } #endif #if defined(PNG_pCAL_SUPPORTED) png_uint_32 PNGAPI png_get_pCAL(png_structp png_ptr, png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, png_charp *units, png_charpp *params) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && nparams != NULL && units != NULL && params != NULL) { png_debug1(1, "in %s retrieval function\n", "pCAL"); *purpose = info_ptr->pcal_purpose; *X0 = info_ptr->pcal_X0; *X1 = info_ptr->pcal_X1; *type = (int)info_ptr->pcal_type; *nparams = (int)info_ptr->pcal_nparams; *units = info_ptr->pcal_units; *params = info_ptr->pcal_params; return (PNG_INFO_pCAL); } return (0); } #endif #if defined(PNG_sCAL_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED png_uint_32 PNGAPI png_get_sCAL(png_structp png_ptr, png_infop info_ptr, int *unit, double *width, double *height) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) { *unit = info_ptr->scal_unit; *width = info_ptr->scal_pixel_width; *height = info_ptr->scal_pixel_height; return (PNG_INFO_sCAL); } return(0); } #else #ifdef PNG_FIXED_POINT_SUPPORTED png_uint_32 PNGAPI png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr, int *unit, png_charpp width, png_charpp height) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) { *unit = info_ptr->scal_unit; *width = info_ptr->scal_s_width; *height = info_ptr->scal_s_height; return (PNG_INFO_sCAL); } return(0); } #endif #endif #endif #if defined(PNG_pHYs_SUPPORTED) png_uint_32 PNGAPI png_get_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) { png_uint_32 retval = 0; if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { png_debug1(1, "in %s retrieval function\n", "pHYs"); if (res_x != NULL) { *res_x = info_ptr->x_pixels_per_unit; retval |= PNG_INFO_pHYs; } if (res_y != NULL) { *res_y = info_ptr->y_pixels_per_unit; retval |= PNG_INFO_pHYs; } if (unit_type != NULL) { *unit_type = (int)info_ptr->phys_unit_type; retval |= PNG_INFO_pHYs; } } return (retval); } #endif png_uint_32 PNGAPI png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette, int *num_palette) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE) && palette != NULL) { png_debug1(1, "in %s retrieval function\n", "PLTE"); *palette = info_ptr->palette; *num_palette = info_ptr->num_palette; png_debug1(3, "num_palette = %d\n", *num_palette); return (PNG_INFO_PLTE); } return (0); } #if defined(PNG_sBIT_SUPPORTED) png_uint_32 PNGAPI png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) && sig_bit != NULL) { png_debug1(1, "in %s retrieval function\n", "sBIT"); *sig_bit = &(info_ptr->sig_bit); return (PNG_INFO_sBIT); } return (0); } #endif #if defined(PNG_TEXT_SUPPORTED) png_uint_32 PNGAPI png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr, int *num_text) { if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) { png_debug1(1, "in %s retrieval function\n", (png_ptr->chunk_name[0] == '\0' ? "text" : (png_const_charp)png_ptr->chunk_name)); if (text_ptr != NULL) *text_ptr = info_ptr->text; if (num_text != NULL) *num_text = info_ptr->num_text; return ((png_uint_32)info_ptr->num_text); } if (num_text != NULL) *num_text = 0; return(0); } #endif #if defined(PNG_tIME_SUPPORTED) png_uint_32 PNGAPI png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) && mod_time != NULL) { png_debug1(1, "in %s retrieval function\n", "tIME"); *mod_time = &(info_ptr->mod_time); return (PNG_INFO_tIME); } return (0); } #endif #if defined(PNG_tRNS_SUPPORTED) png_uint_32 PNGAPI png_get_tRNS(png_structp png_ptr, png_infop info_ptr, png_bytep *trans, int *num_trans, png_color_16p *trans_values) { png_uint_32 retval = 0; if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) { png_debug1(1, "in %s retrieval function\n", "tRNS"); if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (trans != NULL) { *trans = info_ptr->trans; retval |= PNG_INFO_tRNS; } if (trans_values != NULL) *trans_values = &(info_ptr->trans_values); } else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */ { if (trans_values != NULL) { *trans_values = &(info_ptr->trans_values); retval |= PNG_INFO_tRNS; } if(trans != NULL) *trans = NULL; } if(num_trans != NULL) { *num_trans = info_ptr->num_trans; retval |= PNG_INFO_tRNS; } } return (retval); } #endif #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) png_uint_32 PNGAPI png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr, png_unknown_chunkpp unknowns) { if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) *unknowns = info_ptr->unknown_chunks; return ((png_uint_32)info_ptr->unknown_chunks_num); } #endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) png_byte PNGAPI png_get_rgb_to_gray_status (png_structp png_ptr) { return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0); } #endif #if defined(PNG_USER_CHUNKS_SUPPORTED) png_voidp PNGAPI png_get_user_chunk_ptr(png_structp png_ptr) { return (png_ptr? png_ptr->user_chunk_ptr : NULL); } #endif #ifdef PNG_WRITE_SUPPORTED png_uint_32 PNGAPI png_get_compression_buffer_size(png_structp png_ptr) { return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L); } #endif #ifndef PNG_1_0_X #ifdef PNG_ASSEMBLER_CODE_SUPPORTED /* this function was added to libpng 1.2.0 and should exist by default */ png_uint_32 PNGAPI png_get_asm_flags (png_structp png_ptr) { return (png_uint_32)(png_ptr? png_ptr->asm_flags : 0L); } /* this function was added to libpng 1.2.0 and should exist by default */ png_uint_32 PNGAPI png_get_asm_flagmask (int flag_select) { png_uint_32 settable_asm_flags = 0; if (flag_select & PNG_SELECT_READ) settable_asm_flags |= PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | PNG_ASM_FLAG_MMX_READ_INTERLACE | PNG_ASM_FLAG_MMX_READ_FILTER_SUB | PNG_ASM_FLAG_MMX_READ_FILTER_UP | PNG_ASM_FLAG_MMX_READ_FILTER_AVG | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; /* no non-MMX flags yet */ #if 0 /* GRR: no write-flags yet, either, but someday... */ if (flag_select & PNG_SELECT_WRITE) settable_asm_flags |= PNG_ASM_FLAG_MMX_WRITE_ [whatever] ; #endif /* 0 */ return settable_asm_flags; /* _theoretically_ settable capabilities only */ } #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */ /* this function was added to libpng 1.2.0 */ png_uint_32 PNGAPI png_get_mmx_flagmask (int flag_select, int *compilerID) { png_uint_32 settable_mmx_flags = 0; if (flag_select & PNG_SELECT_READ) settable_mmx_flags |= PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | PNG_ASM_FLAG_MMX_READ_INTERLACE | PNG_ASM_FLAG_MMX_READ_FILTER_SUB | PNG_ASM_FLAG_MMX_READ_FILTER_UP | PNG_ASM_FLAG_MMX_READ_FILTER_AVG | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; #if 0 /* GRR: no MMX write support yet, but someday... */ if (flag_select & PNG_SELECT_WRITE) settable_mmx_flags |= PNG_ASM_FLAG_MMX_WRITE_ [whatever] ; #endif /* 0 */ if (compilerID != NULL) { #ifdef PNG_USE_PNGVCRD *compilerID = 1; /* MSVC */ #else #ifdef PNG_USE_PNGGCCRD *compilerID = 2; /* gcc/gas */ #else *compilerID = -1; /* unknown (i.e., no asm/MMX code compiled) */ #endif #endif } return settable_mmx_flags; /* _theoretically_ settable capabilities only */ } /* this function was added to libpng 1.2.0 */ png_byte PNGAPI png_get_mmx_bitdepth_threshold (png_structp png_ptr) { return (png_byte)(png_ptr? png_ptr->mmx_bitdepth_threshold : 0); } /* this function was added to libpng 1.2.0 */ png_uint_32 PNGAPI png_get_mmx_rowbytes_threshold (png_structp png_ptr) { return (png_uint_32)(png_ptr? png_ptr->mmx_rowbytes_threshold : 0L); } #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED /* these functions were added to libpng 1.2.6 */ png_uint_32 PNGAPI png_get_user_width_max (png_structp png_ptr) { return (png_ptr? png_ptr->user_width_max : 0); } png_uint_32 PNGAPI png_get_user_height_max (png_structp png_ptr) { return (png_ptr? png_ptr->user_height_max : 0); } #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ #endif /* ?PNG_1_0_X */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/Y2KINFO0000664000175000017500000000442110777447272020164 0ustar evanevan Y2K compliance in libpng: ========================= December 3, 2004 Since the PNG Development group is an ad-hoc body, we can't make an official declaration. This is your unofficial assurance that libpng from version 0.71 and upward through 1.2.8 are Y2K compliant. It is my belief that earlier versions were also Y2K compliant. Libpng only has three year fields. One is a 2-byte unsigned integer that will hold years up to 65535. The other two hold the date in text format, and will hold years up to 9999. The integer is "png_uint_16 year" in png_time_struct. The strings are "png_charp time_buffer" in png_struct and "near_time_buffer", which is a local character string in png.c. There are seven time-related functions: png_convert_to_rfc_1123() in png.c (formerly png_convert_to_rfc_1152() in error) png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c png_convert_from_time_t() in pngwrite.c png_get_tIME() in pngget.c png_handle_tIME() in pngrutil.c, called in pngread.c png_set_tIME() in pngset.c png_write_tIME() in pngwutil.c, called in pngwrite.c All appear to handle dates properly in a Y2K environment. The png_convert_from_time_t() function calls gmtime() to convert from system clock time, which returns (year - 1900), which we properly convert to the full 4-digit year. There is a possibility that applications using libpng are not passing 4-digit years into the png_convert_to_rfc_1123() function, or that they are incorrectly passing only a 2-digit year instead of "year - 1900" into the png_convert_from_struct_tm() function, but this is not under our control. The libpng documentation has always stated that it works with 4-digit years, and the APIs have been documented as such. The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned integer to hold the year, and can hold years as large as 65535. zlib, upon which libpng depends, is also Y2K compliant. It contains no date-related code. Glenn Randers-Pehrson libpng maintainer PNG Development Group syslinux-legacy-3.63+dfsg/com32/lib/libpng/png.50000664000175000017500000000451410777447272020035 0ustar evanevan.TH PNG 5 "December 3, 2004" .SH NAME png \- Portable Network Graphics (PNG) format .SH DESCRIPTION PNG (Portable Network Graphics) is an extensible file format for the lossless, portable, well-compressed storage of raster images. PNG provides a patent-free replacement for GIF and can also replace many common uses of TIFF. Indexed-color, grayscale, and truecolor images are supported, plus an optional alpha channel. Sample depths range from 1 to 16 bits. .br PNG is designed to work well in online viewing applications, such as the World Wide Web, so it is fully streamable with a progressive display option. PNG is robust, providing both full file integrity checking and fast, simple detection of common transmission errors. Also, PNG can store gamma and chromaticity data for improved color matching on heterogeneous platforms. .SH "SEE ALSO" .IR libpng(3), zlib(3), deflate(5), and zlib(5) .LP PNG specification (second edition), November 2003: .IP .br PNG_UINT_31_MAX) png_error(png_ptr, "PNG unsigned integer out of range.\n"); return (i); } #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ png_uint_32 /* PRIVATE */ png_get_uint_32(png_bytep buf) { png_uint_32 i = ((png_uint_32)(*buf) << 24) + ((png_uint_32)(*(buf + 1)) << 16) + ((png_uint_32)(*(buf + 2)) << 8) + (png_uint_32)(*(buf + 3)); return (i); } #if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED) /* Grab a signed 32-bit integer from a buffer in big-endian format. The * data is stored in the PNG file in two's complement format, and it is * assumed that the machine format for signed integers is the same. */ png_int_32 /* PRIVATE */ png_get_int_32(png_bytep buf) { png_int_32 i = ((png_int_32)(*buf) << 24) + ((png_int_32)(*(buf + 1)) << 16) + ((png_int_32)(*(buf + 2)) << 8) + (png_int_32)(*(buf + 3)); return (i); } #endif /* PNG_READ_pCAL_SUPPORTED */ /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ png_uint_16 /* PRIVATE */ png_get_uint_16(png_bytep buf) { png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) + (png_uint_16)(*(buf + 1))); return (i); } #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */ /* Read data, and (optionally) run it through the CRC. */ void /* PRIVATE */ png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) { png_read_data(png_ptr, buf, length); png_calculate_crc(png_ptr, buf, length); } /* Optionally skip data and then check the CRC. Depending on whether we are reading a ancillary or critical chunk, and how the program has set things up, we may calculate the CRC on the data and print a message. Returns '1' if there was a CRC error, '0' otherwise. */ int /* PRIVATE */ png_crc_finish(png_structp png_ptr, png_uint_32 skip) { png_size_t i; png_size_t istop = png_ptr->zbuf_size; for (i = (png_size_t)skip; i > istop; i -= istop) { png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); } if (i) { png_crc_read(png_ptr, png_ptr->zbuf, i); } if (png_crc_error(png_ptr)) { if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) { png_chunk_warning(png_ptr, "CRC error"); } else { png_chunk_error(png_ptr, "CRC error"); } return (1); } return (0); } /* Compare the CRC stored in the PNG file with that calculated by libpng from the data it has read thus far. */ int /* PRIVATE */ png_crc_error(png_structp png_ptr) { png_byte crc_bytes[4]; png_uint_32 crc; int need_crc = 1; if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ { if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) need_crc = 0; } else /* critical */ { if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) need_crc = 0; } png_read_data(png_ptr, crc_bytes, 4); if (need_crc) { crc = png_get_uint_32(crc_bytes); return ((int)(crc != png_ptr->crc)); } else return (0); } #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \ defined(PNG_READ_iCCP_SUPPORTED) /* * Decompress trailing data in a chunk. The assumption is that chunkdata * points at an allocated area holding the contents of a chunk with a * trailing compressed part. What we get back is an allocated area * holding the original prefix part and an uncompressed version of the * trailing part (the malloc area passed in is freed). */ png_charp /* PRIVATE */ png_decompress_chunk(png_structp png_ptr, int comp_type, png_charp chunkdata, png_size_t chunklength, png_size_t prefix_size, png_size_t *newlength) { static char msg[] = "Error decoding compressed text"; png_charp text; png_size_t text_size; if (comp_type == PNG_COMPRESSION_TYPE_BASE) { int ret = Z_OK; png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size); png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; text_size = 0; text = NULL; while (png_ptr->zstream.avail_in) { ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); if (ret != Z_OK && ret != Z_STREAM_END) { if (png_ptr->zstream.msg != NULL) png_warning(png_ptr, png_ptr->zstream.msg); else png_warning(png_ptr, msg); inflateReset(&png_ptr->zstream); png_ptr->zstream.avail_in = 0; if (text == NULL) { text_size = prefix_size + png_sizeof(msg) + 1; text = (png_charp)png_malloc_warn(png_ptr, text_size); if (text == NULL) { png_free(png_ptr,chunkdata); png_error(png_ptr,"Not enough memory to decompress chunk"); } png_memcpy(text, chunkdata, prefix_size); } text[text_size - 1] = 0x00; /* Copy what we can of the error message into the text chunk */ text_size = (png_size_t)(chunklength - (text - chunkdata) - 1); text_size = png_sizeof(msg) > text_size ? text_size : png_sizeof(msg); png_memcpy(text + prefix_size, msg, text_size + 1); break; } if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END) { if (text == NULL) { text_size = prefix_size + png_ptr->zbuf_size - png_ptr->zstream.avail_out; text = (png_charp)png_malloc_warn(png_ptr, text_size + 1); if (text == NULL) { png_free(png_ptr,chunkdata); png_error(png_ptr,"Not enough memory to decompress chunk."); } png_memcpy(text + prefix_size, png_ptr->zbuf, text_size - prefix_size); png_memcpy(text, chunkdata, prefix_size); *(text + text_size) = 0x00; } else { png_charp tmp; tmp = text; text = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(text_size + png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); if (text == NULL) { png_free(png_ptr, tmp); png_free(png_ptr, chunkdata); png_error(png_ptr,"Not enough memory to decompress chunk.."); } png_memcpy(text, tmp, text_size); png_free(png_ptr, tmp); png_memcpy(text + text_size, png_ptr->zbuf, (png_ptr->zbuf_size - png_ptr->zstream.avail_out)); text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; *(text + text_size) = 0x00; } if (ret == Z_STREAM_END) break; else { png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; } } } if (ret != Z_STREAM_END) { #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) char umsg[50]; if (ret == Z_BUF_ERROR) sprintf(umsg,"Buffer error in compressed datastream in %s chunk", png_ptr->chunk_name); else if (ret == Z_DATA_ERROR) sprintf(umsg,"Data error in compressed datastream in %s chunk", png_ptr->chunk_name); else sprintf(umsg,"Incomplete compressed datastream in %s chunk", png_ptr->chunk_name); png_warning(png_ptr, umsg); #else png_warning(png_ptr, "Incomplete compressed datastream in chunk other than IDAT"); #endif text_size=prefix_size; if (text == NULL) { text = (png_charp)png_malloc_warn(png_ptr, text_size+1); if (text == NULL) { png_free(png_ptr, chunkdata); png_error(png_ptr,"Not enough memory for text."); } png_memcpy(text, chunkdata, prefix_size); } *(text + text_size) = 0x00; } inflateReset(&png_ptr->zstream); png_ptr->zstream.avail_in = 0; png_free(png_ptr, chunkdata); chunkdata = text; *newlength=text_size; } else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ { #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) char umsg[50]; sprintf(umsg, "Unknown zTXt compression type %d", comp_type); png_warning(png_ptr, umsg); #else png_warning(png_ptr, "Unknown zTXt compression type"); #endif *(chunkdata + prefix_size) = 0x00; *newlength=prefix_size; } return chunkdata; } #endif /* read and check the IDHR chunk */ void /* PRIVATE */ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_byte buf[13]; png_uint_32 width, height; int bit_depth, color_type, compression_type, filter_type; int interlace_type; png_debug(1, "in png_handle_IHDR\n"); if (png_ptr->mode & PNG_HAVE_IHDR) png_error(png_ptr, "Out of place IHDR"); /* check the length */ if (length != 13) png_error(png_ptr, "Invalid IHDR chunk"); png_ptr->mode |= PNG_HAVE_IHDR; png_crc_read(png_ptr, buf, 13); png_crc_finish(png_ptr, 0); width = png_get_uint_31(png_ptr, buf); height = png_get_uint_31(png_ptr, buf + 4); bit_depth = buf[8]; color_type = buf[9]; compression_type = buf[10]; filter_type = buf[11]; interlace_type = buf[12]; /* set internal variables */ png_ptr->width = width; png_ptr->height = height; png_ptr->bit_depth = (png_byte)bit_depth; png_ptr->interlaced = (png_byte)interlace_type; png_ptr->color_type = (png_byte)color_type; #if defined(PNG_MNG_FEATURES_SUPPORTED) png_ptr->filter_type = (png_byte)filter_type; #endif png_ptr->compression_type = (png_byte)compression_type; /* find number of channels */ switch (png_ptr->color_type) { case PNG_COLOR_TYPE_GRAY: case PNG_COLOR_TYPE_PALETTE: png_ptr->channels = 1; break; case PNG_COLOR_TYPE_RGB: png_ptr->channels = 3; break; case PNG_COLOR_TYPE_GRAY_ALPHA: png_ptr->channels = 2; break; case PNG_COLOR_TYPE_RGB_ALPHA: png_ptr->channels = 4; break; } /* set up other useful info */ png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels); png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width); png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth); png_debug1(3,"channels = %d\n", png_ptr->channels); png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes); png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type, compression_type, filter_type); } /* read and check the palette */ void /* PRIVATE */ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_color palette[PNG_MAX_PALETTE_LENGTH]; int num, i; #ifndef PNG_NO_POINTER_INDEXING png_colorp pal_ptr; #endif png_debug(1, "in png_handle_PLTE\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before PLTE"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid PLTE after IDAT"); png_crc_finish(png_ptr, length); return; } else if (png_ptr->mode & PNG_HAVE_PLTE) png_error(png_ptr, "Duplicate PLTE chunk"); png_ptr->mode |= PNG_HAVE_PLTE; if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) { png_warning(png_ptr, "Ignoring PLTE chunk in grayscale PNG"); png_crc_finish(png_ptr, length); return; } #if !defined(PNG_READ_OPT_PLTE_SUPPORTED) if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) { png_crc_finish(png_ptr, length); return; } #endif if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) { if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) { png_warning(png_ptr, "Invalid palette chunk"); png_crc_finish(png_ptr, length); return; } else { png_error(png_ptr, "Invalid palette chunk"); } } num = (int)length / 3; #ifndef PNG_NO_POINTER_INDEXING for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) { png_byte buf[3]; png_crc_read(png_ptr, buf, 3); pal_ptr->red = buf[0]; pal_ptr->green = buf[1]; pal_ptr->blue = buf[2]; } #else for (i = 0; i < num; i++) { png_byte buf[3]; png_crc_read(png_ptr, buf, 3); /* don't depend upon png_color being any order */ palette[i].red = buf[0]; palette[i].green = buf[1]; palette[i].blue = buf[2]; } #endif /* If we actually NEED the PLTE chunk (ie for a paletted image), we do whatever the normal CRC configuration tells us. However, if we have an RGB image, the PLTE can be considered ancillary, so we will act as though it is. */ #if !defined(PNG_READ_OPT_PLTE_SUPPORTED) if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) #endif { png_crc_finish(png_ptr, 0); } #if !defined(PNG_READ_OPT_PLTE_SUPPORTED) else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ { /* If we don't want to use the data from an ancillary chunk, we have two options: an error abort, or a warning and we ignore the data in this chunk (which should be OK, since it's considered ancillary for a RGB or RGBA image). */ if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) { if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) { png_chunk_error(png_ptr, "CRC error"); } else { png_chunk_warning(png_ptr, "CRC error"); return; } } /* Otherwise, we (optionally) emit a warning and use the chunk. */ else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) { png_chunk_warning(png_ptr, "CRC error"); } } #endif png_set_PLTE(png_ptr, info_ptr, palette, num); #if defined(PNG_READ_tRNS_SUPPORTED) if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) { if (png_ptr->num_trans > (png_uint_16)num) { png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); png_ptr->num_trans = (png_uint_16)num; } if (info_ptr->num_trans > (png_uint_16)num) { png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); info_ptr->num_trans = (png_uint_16)num; } } } #endif } void /* PRIVATE */ png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_debug(1, "in png_handle_IEND\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) { png_error(png_ptr, "No image in file"); } png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); if (length != 0) { png_warning(png_ptr, "Incorrect IEND chunk length"); } png_crc_finish(png_ptr, length); if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */ return; } #if defined(PNG_READ_gAMA_SUPPORTED) void /* PRIVATE */ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_fixed_point igamma; #ifdef PNG_FLOATING_POINT_SUPPORTED float file_gamma; #endif png_byte buf[4]; png_debug(1, "in png_handle_gAMA\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before gAMA"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid gAMA after IDAT"); png_crc_finish(png_ptr, length); return; } else if (png_ptr->mode & PNG_HAVE_PLTE) /* Should be an error, but we can cope with it */ png_warning(png_ptr, "Out of place gAMA chunk"); if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) #if defined(PNG_READ_sRGB_SUPPORTED) && !(info_ptr->valid & PNG_INFO_sRGB) #endif ) { png_warning(png_ptr, "Duplicate gAMA chunk"); png_crc_finish(png_ptr, length); return; } if (length != 4) { png_warning(png_ptr, "Incorrect gAMA chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, 4); if (png_crc_finish(png_ptr, 0)) return; igamma = (png_fixed_point)png_get_uint_32(buf); /* check for zero gamma */ if (igamma == 0) { png_warning(png_ptr, "Ignoring gAMA chunk with gamma=0"); return; } #if defined(PNG_READ_sRGB_SUPPORTED) if (info_ptr->valid & PNG_INFO_sRGB) if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) { png_warning(png_ptr, "Ignoring incorrect gAMA value when sRGB is also present"); #ifndef PNG_NO_CONSOLE_IO fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma); #endif return; } #endif /* PNG_READ_sRGB_SUPPORTED */ #ifdef PNG_FLOATING_POINT_SUPPORTED file_gamma = (float)igamma / (float)100000.0; # ifdef PNG_READ_GAMMA_SUPPORTED png_ptr->gamma = file_gamma; # endif png_set_gAMA(png_ptr, info_ptr, file_gamma); #endif #ifdef PNG_FIXED_POINT_SUPPORTED png_set_gAMA_fixed(png_ptr, info_ptr, igamma); #endif } #endif #if defined(PNG_READ_sBIT_SUPPORTED) void /* PRIVATE */ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_size_t truelen; png_byte buf[4]; png_debug(1, "in png_handle_sBIT\n"); buf[0] = buf[1] = buf[2] = buf[3] = 0; if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before sBIT"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid sBIT after IDAT"); png_crc_finish(png_ptr, length); return; } else if (png_ptr->mode & PNG_HAVE_PLTE) { /* Should be an error, but we can cope with it */ png_warning(png_ptr, "Out of place sBIT chunk"); } if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) { png_warning(png_ptr, "Duplicate sBIT chunk"); png_crc_finish(png_ptr, length); return; } if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) truelen = 3; else truelen = (png_size_t)png_ptr->channels; if (length != truelen || length > 4) { png_warning(png_ptr, "Incorrect sBIT chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, truelen); if (png_crc_finish(png_ptr, 0)) return; if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) { png_ptr->sig_bit.red = buf[0]; png_ptr->sig_bit.green = buf[1]; png_ptr->sig_bit.blue = buf[2]; png_ptr->sig_bit.alpha = buf[3]; } else { png_ptr->sig_bit.gray = buf[0]; png_ptr->sig_bit.red = buf[0]; png_ptr->sig_bit.green = buf[0]; png_ptr->sig_bit.blue = buf[0]; png_ptr->sig_bit.alpha = buf[1]; } png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); } #endif #if defined(PNG_READ_cHRM_SUPPORTED) void /* PRIVATE */ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_byte buf[4]; #ifdef PNG_FLOATING_POINT_SUPPORTED float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; #endif png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, int_y_green, int_x_blue, int_y_blue; png_uint_32 uint_x, uint_y; png_debug(1, "in png_handle_cHRM\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before cHRM"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid cHRM after IDAT"); png_crc_finish(png_ptr, length); return; } else if (png_ptr->mode & PNG_HAVE_PLTE) /* Should be an error, but we can cope with it */ png_warning(png_ptr, "Missing PLTE before cHRM"); if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) #if defined(PNG_READ_sRGB_SUPPORTED) && !(info_ptr->valid & PNG_INFO_sRGB) #endif ) { png_warning(png_ptr, "Duplicate cHRM chunk"); png_crc_finish(png_ptr, length); return; } if (length != 32) { png_warning(png_ptr, "Incorrect cHRM chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, 4); uint_x = png_get_uint_32(buf); png_crc_read(png_ptr, buf, 4); uint_y = png_get_uint_32(buf); if (uint_x > 80000L || uint_y > 80000L || uint_x + uint_y > 100000L) { png_warning(png_ptr, "Invalid cHRM white point"); png_crc_finish(png_ptr, 24); return; } int_x_white = (png_fixed_point)uint_x; int_y_white = (png_fixed_point)uint_y; png_crc_read(png_ptr, buf, 4); uint_x = png_get_uint_32(buf); png_crc_read(png_ptr, buf, 4); uint_y = png_get_uint_32(buf); if (uint_x > 80000L || uint_y > 80000L || uint_x + uint_y > 100000L) { png_warning(png_ptr, "Invalid cHRM red point"); png_crc_finish(png_ptr, 16); return; } int_x_red = (png_fixed_point)uint_x; int_y_red = (png_fixed_point)uint_y; png_crc_read(png_ptr, buf, 4); uint_x = png_get_uint_32(buf); png_crc_read(png_ptr, buf, 4); uint_y = png_get_uint_32(buf); if (uint_x > 80000L || uint_y > 80000L || uint_x + uint_y > 100000L) { png_warning(png_ptr, "Invalid cHRM green point"); png_crc_finish(png_ptr, 8); return; } int_x_green = (png_fixed_point)uint_x; int_y_green = (png_fixed_point)uint_y; png_crc_read(png_ptr, buf, 4); uint_x = png_get_uint_32(buf); png_crc_read(png_ptr, buf, 4); uint_y = png_get_uint_32(buf); if (uint_x > 80000L || uint_y > 80000L || uint_x + uint_y > 100000L) { png_warning(png_ptr, "Invalid cHRM blue point"); png_crc_finish(png_ptr, 0); return; } int_x_blue = (png_fixed_point)uint_x; int_y_blue = (png_fixed_point)uint_y; #ifdef PNG_FLOATING_POINT_SUPPORTED white_x = (float)int_x_white / (float)100000.0; white_y = (float)int_y_white / (float)100000.0; red_x = (float)int_x_red / (float)100000.0; red_y = (float)int_y_red / (float)100000.0; green_x = (float)int_x_green / (float)100000.0; green_y = (float)int_y_green / (float)100000.0; blue_x = (float)int_x_blue / (float)100000.0; blue_y = (float)int_y_blue / (float)100000.0; #endif #if defined(PNG_READ_sRGB_SUPPORTED) if (info_ptr->valid & PNG_INFO_sRGB) { if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) || PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) || PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) || PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) || PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) || PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000)) { png_warning(png_ptr, "Ignoring incorrect cHRM value when sRGB is also present"); #ifndef PNG_NO_CONSOLE_IO #ifdef PNG_FLOATING_POINT_SUPPORTED fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n", white_x, white_y, red_x, red_y); fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n", green_x, green_y, blue_x, blue_y); #else fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", int_x_white, int_y_white, int_x_red, int_y_red); fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n", int_x_green, int_y_green, int_x_blue, int_y_blue); #endif #endif /* PNG_NO_CONSOLE_IO */ } png_crc_finish(png_ptr, 0); return; } #endif /* PNG_READ_sRGB_SUPPORTED */ #ifdef PNG_FLOATING_POINT_SUPPORTED png_set_cHRM(png_ptr, info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); #endif #ifdef PNG_FIXED_POINT_SUPPORTED png_set_cHRM_fixed(png_ptr, info_ptr, int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, int_y_green, int_x_blue, int_y_blue); #endif if (png_crc_finish(png_ptr, 0)) return; } #endif #if defined(PNG_READ_sRGB_SUPPORTED) void /* PRIVATE */ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { int intent; png_byte buf[1]; png_debug(1, "in png_handle_sRGB\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before sRGB"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid sRGB after IDAT"); png_crc_finish(png_ptr, length); return; } else if (png_ptr->mode & PNG_HAVE_PLTE) /* Should be an error, but we can cope with it */ png_warning(png_ptr, "Out of place sRGB chunk"); if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) { png_warning(png_ptr, "Duplicate sRGB chunk"); png_crc_finish(png_ptr, length); return; } if (length != 1) { png_warning(png_ptr, "Incorrect sRGB chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, 1); if (png_crc_finish(png_ptr, 0)) return; intent = buf[0]; /* check for bad intent */ if (intent >= PNG_sRGB_INTENT_LAST) { png_warning(png_ptr, "Unknown sRGB intent"); return; } #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) if ((info_ptr->valid & PNG_INFO_gAMA)) { png_fixed_point igamma; #ifdef PNG_FIXED_POINT_SUPPORTED igamma=info_ptr->int_gamma; #else # ifdef PNG_FLOATING_POINT_SUPPORTED igamma=(png_fixed_point)(info_ptr->gamma * 100000.); # endif #endif if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) { png_warning(png_ptr, "Ignoring incorrect gAMA value when sRGB is also present"); #ifndef PNG_NO_CONSOLE_IO # ifdef PNG_FIXED_POINT_SUPPORTED fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma); # else # ifdef PNG_FLOATING_POINT_SUPPORTED fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma); # endif # endif #endif } } #endif /* PNG_READ_gAMA_SUPPORTED */ #ifdef PNG_READ_cHRM_SUPPORTED #ifdef PNG_FIXED_POINT_SUPPORTED if (info_ptr->valid & PNG_INFO_cHRM) if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) || PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) || PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) || PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) || PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) || PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) || PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) || PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000)) { png_warning(png_ptr, "Ignoring incorrect cHRM value when sRGB is also present"); } #endif /* PNG_FIXED_POINT_SUPPORTED */ #endif /* PNG_READ_cHRM_SUPPORTED */ png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); } #endif /* PNG_READ_sRGB_SUPPORTED */ #if defined(PNG_READ_iCCP_SUPPORTED) void /* PRIVATE */ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Note: this does not properly handle chunks that are > 64K under DOS */ { png_charp chunkdata; png_byte compression_type; png_bytep pC; png_charp profile; png_uint_32 skip = 0; png_uint_32 profile_size, profile_length; png_size_t slength, prefix_length, data_length; png_debug(1, "in png_handle_iCCP\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before iCCP"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid iCCP after IDAT"); png_crc_finish(png_ptr, length); return; } else if (png_ptr->mode & PNG_HAVE_PLTE) /* Should be an error, but we can cope with it */ png_warning(png_ptr, "Out of place iCCP chunk"); if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) { png_warning(png_ptr, "Duplicate iCCP chunk"); png_crc_finish(png_ptr, length); return; } #ifdef PNG_MAX_MALLOC_64K if (length > (png_uint_32)65535L) { png_warning(png_ptr, "iCCP chunk too large to fit in memory"); skip = length - (png_uint_32)65535L; length = (png_uint_32)65535L; } #endif chunkdata = (png_charp)png_malloc(png_ptr, length + 1); slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunkdata, slength); if (png_crc_finish(png_ptr, skip)) { png_free(png_ptr, chunkdata); return; } chunkdata[slength] = 0x00; for (profile = chunkdata; *profile; profile++) /* empty loop to find end of name */ ; ++profile; /* there should be at least one zero (the compression type byte) following the separator, and we should be on it */ if ( profile >= chunkdata + slength) { png_free(png_ptr, chunkdata); png_warning(png_ptr, "Malformed iCCP chunk"); return; } /* compression_type should always be zero */ compression_type = *profile++; if (compression_type) { png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 wrote nonzero) */ } prefix_length = profile - chunkdata; chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata, slength, prefix_length, &data_length); profile_length = data_length - prefix_length; if ( prefix_length > data_length || profile_length < 4) { png_free(png_ptr, chunkdata); png_warning(png_ptr, "Profile size field missing from iCCP chunk"); return; } /* Check the profile_size recorded in the first 32 bits of the ICC profile */ pC = (png_bytep)(chunkdata+prefix_length); profile_size = ((*(pC ))<<24) | ((*(pC+1))<<16) | ((*(pC+2))<< 8) | ((*(pC+3)) ); if(profile_size < profile_length) profile_length = profile_size; if(profile_size > profile_length) { png_free(png_ptr, chunkdata); png_warning(png_ptr, "Ignoring truncated iCCP profile.\n"); return; } png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type, chunkdata + prefix_length, profile_length); png_free(png_ptr, chunkdata); } #endif /* PNG_READ_iCCP_SUPPORTED */ #if defined(PNG_READ_sPLT_SUPPORTED) void /* PRIVATE */ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Note: this does not properly handle chunks that are > 64K under DOS */ { png_bytep chunkdata; png_bytep entry_start; png_sPLT_t new_palette; #ifdef PNG_NO_POINTER_INDEXING png_sPLT_entryp pp; #endif int data_length, entry_size, i; png_uint_32 skip = 0; png_size_t slength; png_debug(1, "in png_handle_sPLT\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before sPLT"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid sPLT after IDAT"); png_crc_finish(png_ptr, length); return; } #ifdef PNG_MAX_MALLOC_64K if (length > (png_uint_32)65535L) { png_warning(png_ptr, "sPLT chunk too large to fit in memory"); skip = length - (png_uint_32)65535L; length = (png_uint_32)65535L; } #endif chunkdata = (png_bytep)png_malloc(png_ptr, length + 1); slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunkdata, slength); if (png_crc_finish(png_ptr, skip)) { png_free(png_ptr, chunkdata); return; } chunkdata[slength] = 0x00; for (entry_start = chunkdata; *entry_start; entry_start++) /* empty loop to find end of name */ ; ++entry_start; /* a sample depth should follow the separator, and we should be on it */ if (entry_start > chunkdata + slength) { png_free(png_ptr, chunkdata); png_warning(png_ptr, "malformed sPLT chunk"); return; } new_palette.depth = *entry_start++; entry_size = (new_palette.depth == 8 ? 6 : 10); data_length = (slength - (entry_start - chunkdata)); /* integrity-check the data length */ if (data_length % entry_size) { png_free(png_ptr, chunkdata); png_warning(png_ptr, "sPLT chunk has bad length"); return; } new_palette.nentries = (png_uint_32) (data_length / entry_size); if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry))) { png_warning(png_ptr, "sPLT chunk too long"); return; } new_palette.entries = (png_sPLT_entryp)png_malloc_warn( png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); if (new_palette.entries == NULL) { png_warning(png_ptr, "sPLT chunk requires too much memory"); return; } #ifndef PNG_NO_POINTER_INDEXING for (i = 0; i < new_palette.nentries; i++) { png_sPLT_entryp pp = new_palette.entries + i; if (new_palette.depth == 8) { pp->red = *entry_start++; pp->green = *entry_start++; pp->blue = *entry_start++; pp->alpha = *entry_start++; } else { pp->red = png_get_uint_16(entry_start); entry_start += 2; pp->green = png_get_uint_16(entry_start); entry_start += 2; pp->blue = png_get_uint_16(entry_start); entry_start += 2; pp->alpha = png_get_uint_16(entry_start); entry_start += 2; } pp->frequency = png_get_uint_16(entry_start); entry_start += 2; } #else pp = new_palette.entries; for (i = 0; i < new_palette.nentries; i++) { if (new_palette.depth == 8) { pp[i].red = *entry_start++; pp[i].green = *entry_start++; pp[i].blue = *entry_start++; pp[i].alpha = *entry_start++; } else { pp[i].red = png_get_uint_16(entry_start); entry_start += 2; pp[i].green = png_get_uint_16(entry_start); entry_start += 2; pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; } pp->frequency = png_get_uint_16(entry_start); entry_start += 2; } #endif /* discard all chunk data except the name and stash that */ new_palette.name = (png_charp)chunkdata; png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); png_free(png_ptr, chunkdata); png_free(png_ptr, new_palette.entries); } #endif /* PNG_READ_sPLT_SUPPORTED */ #if defined(PNG_READ_tRNS_SUPPORTED) void /* PRIVATE */ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; png_debug(1, "in png_handle_tRNS\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before tRNS"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid tRNS after IDAT"); png_crc_finish(png_ptr, length); return; } else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) { png_warning(png_ptr, "Duplicate tRNS chunk"); png_crc_finish(png_ptr, length); return; } if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) { png_byte buf[2]; if (length != 2) { png_warning(png_ptr, "Incorrect tRNS chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, 2); png_ptr->num_trans = 1; png_ptr->trans_values.gray = png_get_uint_16(buf); } else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) { png_byte buf[6]; if (length != 6) { png_warning(png_ptr, "Incorrect tRNS chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, (png_size_t)length); png_ptr->num_trans = 1; png_ptr->trans_values.red = png_get_uint_16(buf); png_ptr->trans_values.green = png_get_uint_16(buf + 2); png_ptr->trans_values.blue = png_get_uint_16(buf + 4); } else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (!(png_ptr->mode & PNG_HAVE_PLTE)) { /* Should be an error, but we can cope with it. */ png_warning(png_ptr, "Missing PLTE before tRNS"); } if (length > (png_uint_32)png_ptr->num_palette || length > PNG_MAX_PALETTE_LENGTH) { png_warning(png_ptr, "Incorrect tRNS chunk length"); png_crc_finish(png_ptr, length); return; } if (length == 0) { png_warning(png_ptr, "Zero length tRNS chunk"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, readbuf, (png_size_t)length); png_ptr->num_trans = (png_uint_16)length; } else { png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); png_crc_finish(png_ptr, length); return; } if (png_crc_finish(png_ptr, 0)) return; png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, &(png_ptr->trans_values)); } #endif #if defined(PNG_READ_bKGD_SUPPORTED) void /* PRIVATE */ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_size_t truelen; png_byte buf[6]; png_debug(1, "in png_handle_bKGD\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before bKGD"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid bKGD after IDAT"); png_crc_finish(png_ptr, length); return; } else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && !(png_ptr->mode & PNG_HAVE_PLTE)) { png_warning(png_ptr, "Missing PLTE before bKGD"); png_crc_finish(png_ptr, length); return; } else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) { png_warning(png_ptr, "Duplicate bKGD chunk"); png_crc_finish(png_ptr, length); return; } if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) truelen = 1; else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) truelen = 6; else truelen = 2; if (length != truelen) { png_warning(png_ptr, "Incorrect bKGD chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, truelen); if (png_crc_finish(png_ptr, 0)) return; /* We convert the index value into RGB components so that we can allow * arbitrary RGB values for background when we have transparency, and * so it is easy to determine the RGB values of the background color * from the info_ptr struct. */ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { png_ptr->background.index = buf[0]; if(info_ptr->num_palette) { if(buf[0] > info_ptr->num_palette) { png_warning(png_ptr, "Incorrect bKGD chunk index value"); return; } png_ptr->background.red = (png_uint_16)png_ptr->palette[buf[0]].red; png_ptr->background.green = (png_uint_16)png_ptr->palette[buf[0]].green; png_ptr->background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue; } } else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ { png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = png_ptr->background.gray = png_get_uint_16(buf); } else { png_ptr->background.red = png_get_uint_16(buf); png_ptr->background.green = png_get_uint_16(buf + 2); png_ptr->background.blue = png_get_uint_16(buf + 4); } png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background)); } #endif #if defined(PNG_READ_hIST_SUPPORTED) void /* PRIVATE */ png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { unsigned int num, i; png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; png_debug(1, "in png_handle_hIST\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before hIST"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid hIST after IDAT"); png_crc_finish(png_ptr, length); return; } else if (!(png_ptr->mode & PNG_HAVE_PLTE)) { png_warning(png_ptr, "Missing PLTE before hIST"); png_crc_finish(png_ptr, length); return; } else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) { png_warning(png_ptr, "Duplicate hIST chunk"); png_crc_finish(png_ptr, length); return; } num = length / 2 ; if (num != (unsigned int) png_ptr->num_palette || num > (unsigned int) PNG_MAX_PALETTE_LENGTH) { png_warning(png_ptr, "Incorrect hIST chunk length"); png_crc_finish(png_ptr, length); return; } for (i = 0; i < num; i++) { png_byte buf[2]; png_crc_read(png_ptr, buf, 2); readbuf[i] = png_get_uint_16(buf); } if (png_crc_finish(png_ptr, 0)) return; png_set_hIST(png_ptr, info_ptr, readbuf); } #endif #if defined(PNG_READ_pHYs_SUPPORTED) void /* PRIVATE */ png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_byte buf[9]; png_uint_32 res_x, res_y; int unit_type; png_debug(1, "in png_handle_pHYs\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before pHYs"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid pHYs after IDAT"); png_crc_finish(png_ptr, length); return; } else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { png_warning(png_ptr, "Duplicate pHYs chunk"); png_crc_finish(png_ptr, length); return; } if (length != 9) { png_warning(png_ptr, "Incorrect pHYs chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, 9); if (png_crc_finish(png_ptr, 0)) return; res_x = png_get_uint_32(buf); res_y = png_get_uint_32(buf + 4); unit_type = buf[8]; png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); } #endif #if defined(PNG_READ_oFFs_SUPPORTED) void /* PRIVATE */ png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_byte buf[9]; png_int_32 offset_x, offset_y; int unit_type; png_debug(1, "in png_handle_oFFs\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before oFFs"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid oFFs after IDAT"); png_crc_finish(png_ptr, length); return; } else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) { png_warning(png_ptr, "Duplicate oFFs chunk"); png_crc_finish(png_ptr, length); return; } if (length != 9) { png_warning(png_ptr, "Incorrect oFFs chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, 9); if (png_crc_finish(png_ptr, 0)) return; offset_x = png_get_int_32(buf); offset_y = png_get_int_32(buf + 4); unit_type = buf[8]; png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); } #endif #if defined(PNG_READ_pCAL_SUPPORTED) /* read the pCAL chunk (described in the PNG Extensions document) */ void /* PRIVATE */ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_charp purpose; png_int_32 X0, X1; png_byte type, nparams; png_charp buf, units, endptr; png_charpp params; png_size_t slength; int i; png_debug(1, "in png_handle_pCAL\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before pCAL"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid pCAL after IDAT"); png_crc_finish(png_ptr, length); return; } else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) { png_warning(png_ptr, "Duplicate pCAL chunk"); png_crc_finish(png_ptr, length); return; } png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n", length + 1); purpose = (png_charp)png_malloc_warn(png_ptr, length + 1); if (purpose == NULL) { png_warning(png_ptr, "No memory for pCAL purpose."); return; } slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)purpose, slength); if (png_crc_finish(png_ptr, 0)) { png_free(png_ptr, purpose); return; } purpose[slength] = 0x00; /* null terminate the last string */ png_debug(3, "Finding end of pCAL purpose string\n"); for (buf = purpose; *buf; buf++) /* empty loop */ ; endptr = purpose + slength; /* We need to have at least 12 bytes after the purpose string in order to get the parameter information. */ if (endptr <= buf + 12) { png_warning(png_ptr, "Invalid pCAL data"); png_free(png_ptr, purpose); return; } png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n"); X0 = png_get_int_32((png_bytep)buf+1); X1 = png_get_int_32((png_bytep)buf+5); type = buf[9]; nparams = buf[10]; units = buf + 11; png_debug(3, "Checking pCAL equation type and number of parameters\n"); /* Check that we have the right number of parameters for known equation types. */ if ((type == PNG_EQUATION_LINEAR && nparams != 2) || (type == PNG_EQUATION_BASE_E && nparams != 3) || (type == PNG_EQUATION_ARBITRARY && nparams != 3) || (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) { png_warning(png_ptr, "Invalid pCAL parameters for equation type"); png_free(png_ptr, purpose); return; } else if (type >= PNG_EQUATION_LAST) { png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); } for (buf = units; *buf; buf++) /* Empty loop to move past the units string. */ ; png_debug(3, "Allocating pCAL parameters array\n"); params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams *png_sizeof(png_charp))) ; if (params == NULL) { png_free(png_ptr, purpose); png_warning(png_ptr, "No memory for pCAL params."); return; } /* Get pointers to the start of each parameter string. */ for (i = 0; i < (int)nparams; i++) { buf++; /* Skip the null string terminator from previous parameter. */ png_debug1(3, "Reading pCAL parameter %d\n", i); for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++) /* Empty loop to move past each parameter string */ ; /* Make sure we haven't run out of data yet */ if (buf > endptr) { png_warning(png_ptr, "Invalid pCAL data"); png_free(png_ptr, purpose); png_free(png_ptr, params); return; } } png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams, units, params); png_free(png_ptr, purpose); png_free(png_ptr, params); } #endif #if defined(PNG_READ_sCAL_SUPPORTED) /* read the sCAL chunk */ void /* PRIVATE */ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_charp buffer, ep; #ifdef PNG_FLOATING_POINT_SUPPORTED double width, height; png_charp vp; #else #ifdef PNG_FIXED_POINT_SUPPORTED png_charp swidth, sheight; #endif #endif png_size_t slength; png_debug(1, "in png_handle_sCAL\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before sCAL"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid sCAL after IDAT"); png_crc_finish(png_ptr, length); return; } else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) { png_warning(png_ptr, "Duplicate sCAL chunk"); png_crc_finish(png_ptr, length); return; } png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n", length + 1); buffer = (png_charp)png_malloc_warn(png_ptr, length + 1); if (buffer == NULL) { png_warning(png_ptr, "Out of memory while processing sCAL chunk"); return; } slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)buffer, slength); if (png_crc_finish(png_ptr, 0)) { png_free(png_ptr, buffer); return; } buffer[slength] = 0x00; /* null terminate the last string */ ep = buffer + 1; /* skip unit byte */ #ifdef PNG_FLOATING_POINT_SUPPORTED width = strtod(ep, &vp); if (*vp) { png_warning(png_ptr, "malformed width string in sCAL chunk"); return; } #else #ifdef PNG_FIXED_POINT_SUPPORTED swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); if (swidth == NULL) { png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); return; } png_memcpy(swidth, ep, (png_size_t)png_strlen(ep)); #endif #endif for (ep = buffer; *ep; ep++) /* empty loop */ ; ep++; #ifdef PNG_FLOATING_POINT_SUPPORTED height = strtod(ep, &vp); if (*vp) { png_warning(png_ptr, "malformed height string in sCAL chunk"); return; } #else #ifdef PNG_FIXED_POINT_SUPPORTED sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); if (swidth == NULL) { png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); return; } png_memcpy(sheight, ep, (png_size_t)png_strlen(ep)); #endif #endif if (buffer + slength < ep #ifdef PNG_FLOATING_POINT_SUPPORTED || width <= 0. || height <= 0. #endif ) { png_warning(png_ptr, "Invalid sCAL data"); png_free(png_ptr, buffer); #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) png_free(png_ptr, swidth); png_free(png_ptr, sheight); #endif return; } #ifdef PNG_FLOATING_POINT_SUPPORTED png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height); #else #ifdef PNG_FIXED_POINT_SUPPORTED png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight); #endif #endif png_free(png_ptr, buffer); #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) png_free(png_ptr, swidth); png_free(png_ptr, sheight); #endif } #endif #if defined(PNG_READ_tIME_SUPPORTED) void /* PRIVATE */ png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_byte buf[7]; png_time mod_time; png_debug(1, "in png_handle_tIME\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Out of place tIME chunk"); else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) { png_warning(png_ptr, "Duplicate tIME chunk"); png_crc_finish(png_ptr, length); return; } if (png_ptr->mode & PNG_HAVE_IDAT) png_ptr->mode |= PNG_AFTER_IDAT; if (length != 7) { png_warning(png_ptr, "Incorrect tIME chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, 7); if (png_crc_finish(png_ptr, 0)) return; mod_time.second = buf[6]; mod_time.minute = buf[5]; mod_time.hour = buf[4]; mod_time.day = buf[3]; mod_time.month = buf[2]; mod_time.year = png_get_uint_16(buf); png_set_tIME(png_ptr, info_ptr, &mod_time); } #endif #if defined(PNG_READ_tEXt_SUPPORTED) /* Note: this does not properly handle chunks that are > 64K under DOS */ void /* PRIVATE */ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_textp text_ptr; png_charp key; png_charp text; png_uint_32 skip = 0; png_size_t slength; int ret; png_debug(1, "in png_handle_tEXt\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before tEXt"); if (png_ptr->mode & PNG_HAVE_IDAT) png_ptr->mode |= PNG_AFTER_IDAT; #ifdef PNG_MAX_MALLOC_64K if (length > (png_uint_32)65535L) { png_warning(png_ptr, "tEXt chunk too large to fit in memory"); skip = length - (png_uint_32)65535L; length = (png_uint_32)65535L; } #endif key = (png_charp)png_malloc_warn(png_ptr, length + 1); if (key == NULL) { png_warning(png_ptr, "No memory to process text chunk."); return; } slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)key, slength); if (png_crc_finish(png_ptr, skip)) { png_free(png_ptr, key); return; } key[slength] = 0x00; for (text = key; *text; text++) /* empty loop to find end of key */ ; if (text != key + slength) text++; text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)png_sizeof(png_text)); if (text_ptr == NULL) { png_warning(png_ptr, "Not enough memory to process text chunk."); png_free(png_ptr, key); return; } text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; text_ptr->key = key; #ifdef PNG_iTXt_SUPPORTED text_ptr->lang = NULL; text_ptr->lang_key = NULL; text_ptr->itxt_length = 0; #endif text_ptr->text = text; text_ptr->text_length = png_strlen(text); ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, key); png_free(png_ptr, text_ptr); if (ret) png_warning(png_ptr, "Insufficient memory to process text chunk."); } #endif #if defined(PNG_READ_zTXt_SUPPORTED) /* note: this does not correctly handle chunks that are > 64K under DOS */ void /* PRIVATE */ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_textp text_ptr; png_charp chunkdata; png_charp text; int comp_type; int ret; png_size_t slength, prefix_len, data_len; png_debug(1, "in png_handle_zTXt\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before zTXt"); if (png_ptr->mode & PNG_HAVE_IDAT) png_ptr->mode |= PNG_AFTER_IDAT; #ifdef PNG_MAX_MALLOC_64K /* We will no doubt have problems with chunks even half this size, but there is no hard and fast rule to tell us where to stop. */ if (length > (png_uint_32)65535L) { png_warning(png_ptr,"zTXt chunk too large to fit in memory"); png_crc_finish(png_ptr, length); return; } #endif chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); if (chunkdata == NULL) { png_warning(png_ptr,"Out of memory processing zTXt chunk."); return; } slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunkdata, slength); if (png_crc_finish(png_ptr, 0)) { png_free(png_ptr, chunkdata); return; } chunkdata[slength] = 0x00; for (text = chunkdata; *text; text++) /* empty loop */ ; /* zTXt must have some text after the chunkdataword */ if (text == chunkdata + slength) { comp_type = PNG_TEXT_COMPRESSION_NONE; png_warning(png_ptr, "Zero length zTXt chunk"); } else { comp_type = *(++text); if (comp_type != PNG_TEXT_COMPRESSION_zTXt) { png_warning(png_ptr, "Unknown compression type in zTXt chunk"); comp_type = PNG_TEXT_COMPRESSION_zTXt; } text++; /* skip the compression_method byte */ } prefix_len = text - chunkdata; chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata, (png_size_t)length, prefix_len, &data_len); text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)png_sizeof(png_text)); if (text_ptr == NULL) { png_warning(png_ptr,"Not enough memory to process zTXt chunk."); png_free(png_ptr, chunkdata); return; } text_ptr->compression = comp_type; text_ptr->key = chunkdata; #ifdef PNG_iTXt_SUPPORTED text_ptr->lang = NULL; text_ptr->lang_key = NULL; text_ptr->itxt_length = 0; #endif text_ptr->text = chunkdata + prefix_len; text_ptr->text_length = data_len; ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, text_ptr); png_free(png_ptr, chunkdata); if (ret) png_error(png_ptr, "Insufficient memory to store zTXt chunk."); } #endif #if defined(PNG_READ_iTXt_SUPPORTED) /* note: this does not correctly handle chunks that are > 64K under DOS */ void /* PRIVATE */ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_textp text_ptr; png_charp chunkdata; png_charp key, lang, text, lang_key; int comp_flag; int comp_type = 0; int ret; png_size_t slength, prefix_len, data_len; png_debug(1, "in png_handle_iTXt\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before iTXt"); if (png_ptr->mode & PNG_HAVE_IDAT) png_ptr->mode |= PNG_AFTER_IDAT; #ifdef PNG_MAX_MALLOC_64K /* We will no doubt have problems with chunks even half this size, but there is no hard and fast rule to tell us where to stop. */ if (length > (png_uint_32)65535L) { png_warning(png_ptr,"iTXt chunk too large to fit in memory"); png_crc_finish(png_ptr, length); return; } #endif chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); if (chunkdata == NULL) { png_warning(png_ptr, "No memory to process iTXt chunk."); return; } slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunkdata, slength); if (png_crc_finish(png_ptr, 0)) { png_free(png_ptr, chunkdata); return; } chunkdata[slength] = 0x00; for (lang = chunkdata; *lang; lang++) /* empty loop */ ; lang++; /* skip NUL separator */ /* iTXt must have a language tag (possibly empty), two compression bytes, translated keyword (possibly empty), and possibly some text after the keyword */ if (lang >= chunkdata + slength) { comp_flag = PNG_TEXT_COMPRESSION_NONE; png_warning(png_ptr, "Zero length iTXt chunk"); } else { comp_flag = *lang++; comp_type = *lang++; } for (lang_key = lang; *lang_key; lang_key++) /* empty loop */ ; lang_key++; /* skip NUL separator */ for (text = lang_key; *text; text++) /* empty loop */ ; text++; /* skip NUL separator */ prefix_len = text - chunkdata; key=chunkdata; if (comp_flag) chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata, (size_t)length, prefix_len, &data_len); else data_len=png_strlen(chunkdata + prefix_len); text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)png_sizeof(png_text)); if (text_ptr == NULL) { png_warning(png_ptr,"Not enough memory to process iTXt chunk."); png_free(png_ptr, chunkdata); return; } text_ptr->compression = (int)comp_flag + 1; text_ptr->lang_key = chunkdata+(lang_key-key); text_ptr->lang = chunkdata+(lang-key); text_ptr->itxt_length = data_len; text_ptr->text_length = 0; text_ptr->key = chunkdata; text_ptr->text = chunkdata + prefix_len; ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, text_ptr); png_free(png_ptr, chunkdata); if (ret) png_error(png_ptr, "Insufficient memory to store iTXt chunk."); } #endif /* This function is called when we haven't found a handler for a chunk. If there isn't a problem with the chunk itself (ie bad chunk name, CRC, or a critical chunk), the chunk is silently ignored -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which case it will be saved away to be written out later. */ void /* PRIVATE */ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_uint_32 skip = 0; png_debug(1, "in png_handle_unknown\n"); if (png_ptr->mode & PNG_HAVE_IDAT) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_IDAT; #endif if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */ png_ptr->mode |= PNG_AFTER_IDAT; } png_check_chunk_name(png_ptr, png_ptr->chunk_name); if (!(png_ptr->chunk_name[0] & 0x20)) { #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != PNG_HANDLE_CHUNK_ALWAYS #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) && png_ptr->read_user_chunk_fn == NULL #endif ) #endif png_chunk_error(png_ptr, "unknown critical chunk"); } #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) { png_unknown_chunk chunk; #ifdef PNG_MAX_MALLOC_64K if (length > (png_uint_32)65535L) { png_warning(png_ptr, "unknown chunk too large to fit in memory"); skip = length - (png_uint_32)65535L; length = (png_uint_32)65535L; } #endif png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name); chunk.data = (png_bytep)png_malloc(png_ptr, length); chunk.size = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunk.data, length); #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) if(png_ptr->read_user_chunk_fn != NULL) { /* callback to user unknown chunk handler */ if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0) { if (!(png_ptr->chunk_name[0] & 0x20)) if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != PNG_HANDLE_CHUNK_ALWAYS) { png_free(png_ptr, chunk.data); png_chunk_error(png_ptr, "unknown critical chunk"); } png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); } } else #endif png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); png_free(png_ptr, chunk.data); } else #endif skip = length; png_crc_finish(png_ptr, skip); #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED) if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */ return; #endif } /* This function is called to verify that a chunk name is valid. This function can't have the "critical chunk check" incorporated into it, since in the future we will need to be able to call user functions to handle unknown critical chunks after we check that the chunk name itself is valid. */ #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) void /* PRIVATE */ png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) { png_debug(1, "in png_check_chunk_name\n"); if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) { png_chunk_error(png_ptr, "invalid chunk type"); } } /* Combines the row recently read in with the existing pixels in the row. This routine takes care of alpha and transparency if requested. This routine also handles the two methods of progressive display of interlaced images, depending on the mask value. The mask value describes which pixels are to be combined with the row. The pattern always repeats every 8 pixels, so just 8 bits are needed. A one indicates the pixel is to be combined, a zero indicates the pixel is to be skipped. This is in addition to any alpha or transparency value associated with the pixel. If you want all pixels to be combined, pass 0xff (255) in mask. */ #ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW void /* PRIVATE */ png_combine_row(png_structp png_ptr, png_bytep row, int mask) { png_debug(1,"in png_combine_row\n"); if (mask == 0xff) { png_memcpy(row, png_ptr->row_buf + 1, PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); } else { switch (png_ptr->row_info.pixel_depth) { case 1: { png_bytep sp = png_ptr->row_buf + 1; png_bytep dp = row; int s_inc, s_start, s_end; int m = 0x80; int shift; png_uint_32 i; png_uint_32 row_width = png_ptr->width; #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; s_end = 7; s_inc = 1; } else #endif { s_start = 7; s_end = 0; s_inc = -1; } shift = s_start; for (i = 0; i < row_width; i++) { if (m & mask) { int value; value = (*sp >> shift) & 0x01; *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); *dp |= (png_byte)(value << shift); } if (shift == s_end) { shift = s_start; sp++; dp++; } else shift += s_inc; if (m == 1) m = 0x80; else m >>= 1; } break; } case 2: { png_bytep sp = png_ptr->row_buf + 1; png_bytep dp = row; int s_start, s_end, s_inc; int m = 0x80; int shift; png_uint_32 i; png_uint_32 row_width = png_ptr->width; int value; #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; s_end = 6; s_inc = 2; } else #endif { s_start = 6; s_end = 0; s_inc = -2; } shift = s_start; for (i = 0; i < row_width; i++) { if (m & mask) { value = (*sp >> shift) & 0x03; *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); *dp |= (png_byte)(value << shift); } if (shift == s_end) { shift = s_start; sp++; dp++; } else shift += s_inc; if (m == 1) m = 0x80; else m >>= 1; } break; } case 4: { png_bytep sp = png_ptr->row_buf + 1; png_bytep dp = row; int s_start, s_end, s_inc; int m = 0x80; int shift; png_uint_32 i; png_uint_32 row_width = png_ptr->width; int value; #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; s_end = 4; s_inc = 4; } else #endif { s_start = 4; s_end = 0; s_inc = -4; } shift = s_start; for (i = 0; i < row_width; i++) { if (m & mask) { value = (*sp >> shift) & 0xf; *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); *dp |= (png_byte)(value << shift); } if (shift == s_end) { shift = s_start; sp++; dp++; } else shift += s_inc; if (m == 1) m = 0x80; else m >>= 1; } break; } default: { png_bytep sp = png_ptr->row_buf + 1; png_bytep dp = row; png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); png_uint_32 i; png_uint_32 row_width = png_ptr->width; png_byte m = 0x80; for (i = 0; i < row_width; i++) { if (m & mask) { png_memcpy(dp, sp, pixel_bytes); } sp += pixel_bytes; dp += pixel_bytes; if (m == 1) m = 0x80; else m >>= 1; } break; } } } } #endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */ #ifdef PNG_READ_INTERLACING_SUPPORTED #ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */ /* OLD pre-1.0.9 interface: void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, png_uint_32 transformations) */ void /* PRIVATE */ png_do_read_interlace(png_structp png_ptr) { png_row_infop row_info = &(png_ptr->row_info); png_bytep row = png_ptr->row_buf + 1; int pass = png_ptr->pass; png_uint_32 transformations = png_ptr->transformations; #ifdef PNG_USE_LOCAL_ARRAYS /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* offset to next interlace block */ const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; #endif png_debug(1,"in png_do_read_interlace (stock C version)\n"); if (row != NULL && row_info != NULL) { png_uint_32 final_width; final_width = row_info->width * png_pass_inc[pass]; switch (row_info->pixel_depth) { case 1: { png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); int sshift, dshift; int s_start, s_end, s_inc; int jstop = png_pass_inc[pass]; png_byte v; png_uint_32 i; int j; #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (transformations & PNG_PACKSWAP) { sshift = (int)((row_info->width + 7) & 0x07); dshift = (int)((final_width + 7) & 0x07); s_start = 7; s_end = 0; s_inc = -1; } else #endif { sshift = 7 - (int)((row_info->width + 7) & 0x07); dshift = 7 - (int)((final_width + 7) & 0x07); s_start = 0; s_end = 7; s_inc = 1; } for (i = 0; i < row_info->width; i++) { v = (png_byte)((*sp >> sshift) & 0x01); for (j = 0; j < jstop; j++) { *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); if (dshift == s_end) { dshift = s_start; dp--; } else dshift += s_inc; } if (sshift == s_end) { sshift = s_start; sp--; } else sshift += s_inc; } break; } case 2: { png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); int sshift, dshift; int s_start, s_end, s_inc; int jstop = png_pass_inc[pass]; png_uint_32 i; #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (transformations & PNG_PACKSWAP) { sshift = (int)(((row_info->width + 3) & 0x03) << 1); dshift = (int)(((final_width + 3) & 0x03) << 1); s_start = 6; s_end = 0; s_inc = -2; } else #endif { sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); s_start = 0; s_end = 6; s_inc = 2; } for (i = 0; i < row_info->width; i++) { png_byte v; int j; v = (png_byte)((*sp >> sshift) & 0x03); for (j = 0; j < jstop; j++) { *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); if (dshift == s_end) { dshift = s_start; dp--; } else dshift += s_inc; } if (sshift == s_end) { sshift = s_start; sp--; } else sshift += s_inc; } break; } case 4: { png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); int sshift, dshift; int s_start, s_end, s_inc; png_uint_32 i; int jstop = png_pass_inc[pass]; #if defined(PNG_READ_PACKSWAP_SUPPORTED) if (transformations & PNG_PACKSWAP) { sshift = (int)(((row_info->width + 1) & 0x01) << 2); dshift = (int)(((final_width + 1) & 0x01) << 2); s_start = 4; s_end = 0; s_inc = -4; } else #endif { sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); s_start = 0; s_end = 4; s_inc = 4; } for (i = 0; i < row_info->width; i++) { png_byte v = (png_byte)((*sp >> sshift) & 0xf); int j; for (j = 0; j < jstop; j++) { *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); if (dshift == s_end) { dshift = s_start; dp--; } else dshift += s_inc; } if (sshift == s_end) { sshift = s_start; sp--; } else sshift += s_inc; } break; } default: { png_size_t pixel_bytes = (row_info->pixel_depth >> 3); png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes; png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; int jstop = png_pass_inc[pass]; png_uint_32 i; for (i = 0; i < row_info->width; i++) { png_byte v[8]; int j; png_memcpy(v, sp, pixel_bytes); for (j = 0; j < jstop; j++) { png_memcpy(dp, v, pixel_bytes); dp -= pixel_bytes; } sp -= pixel_bytes; } break; } } row_info->width = final_width; row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); } #if !defined(PNG_READ_PACKSWAP_SUPPORTED) if (&transformations == NULL) /* silence compiler warning */ return; #endif } #endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */ #endif /* PNG_READ_INTERLACING_SUPPORTED */ #ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW void /* PRIVATE */ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter) { png_debug(1, "in png_read_filter_row\n"); png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter); switch (filter) { case PNG_FILTER_VALUE_NONE: break; case PNG_FILTER_VALUE_SUB: { png_uint_32 i; png_uint_32 istop = row_info->rowbytes; png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; png_bytep rp = row + bpp; png_bytep lp = row; for (i = bpp; i < istop; i++) { *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); rp++; } break; } case PNG_FILTER_VALUE_UP: { png_uint_32 i; png_uint_32 istop = row_info->rowbytes; png_bytep rp = row; png_bytep pp = prev_row; for (i = 0; i < istop; i++) { *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); rp++; } break; } case PNG_FILTER_VALUE_AVG: { png_uint_32 i; png_bytep rp = row; png_bytep pp = prev_row; png_bytep lp = row; png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; png_uint_32 istop = row_info->rowbytes - bpp; for (i = 0; i < bpp; i++) { *rp = (png_byte)(((int)(*rp) + ((int)(*pp++) / 2 )) & 0xff); rp++; } for (i = 0; i < istop; i++) { *rp = (png_byte)(((int)(*rp) + (int)(*pp++ + *lp++) / 2 ) & 0xff); rp++; } break; } case PNG_FILTER_VALUE_PAETH: { png_uint_32 i; png_bytep rp = row; png_bytep pp = prev_row; png_bytep lp = row; png_bytep cp = prev_row; png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; png_uint_32 istop=row_info->rowbytes - bpp; for (i = 0; i < bpp; i++) { *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); rp++; } for (i = 0; i < istop; i++) /* use leftover rp,pp */ { int a, b, c, pa, pb, pc, p; a = *lp++; b = *pp++; c = *cp++; p = b - c; pc = a - c; #ifdef PNG_USE_ABS pa = abs(p); pb = abs(pc); pc = abs(p + pc); #else pa = p < 0 ? -p : p; pb = pc < 0 ? -pc : pc; pc = (p + pc) < 0 ? -(p + pc) : p + pc; #endif /* if (pa <= pb && pa <= pc) p = a; else if (pb <= pc) p = b; else p = c; */ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; *rp = (png_byte)(((int)(*rp) + p) & 0xff); rp++; } break; } default: png_warning(png_ptr, "Ignoring bad adaptive filter type"); *row=0; break; } } #endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */ void /* PRIVATE */ png_read_finish_row(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* start of interlace block */ const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* offset to next interlace block */ const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* start of interlace block in the y direction */ const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* offset to next interlace block in the y direction */ const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif png_debug(1, "in png_read_finish_row\n"); png_ptr->row_number++; if (png_ptr->row_number < png_ptr->num_rows) return; if (png_ptr->interlaced) { png_ptr->row_number = 0; png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1); do { png_ptr->pass++; if (png_ptr->pass >= 7) break; png_ptr->iwidth = (png_ptr->width + png_pass_inc[png_ptr->pass] - 1 - png_pass_start[png_ptr->pass]) / png_pass_inc[png_ptr->pass]; png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1; if (!(png_ptr->transformations & PNG_INTERLACE)) { png_ptr->num_rows = (png_ptr->height + png_pass_yinc[png_ptr->pass] - 1 - png_pass_ystart[png_ptr->pass]) / png_pass_yinc[png_ptr->pass]; if (!(png_ptr->num_rows)) continue; } else /* if (png_ptr->transformations & PNG_INTERLACE) */ break; } while (png_ptr->iwidth == 0); if (png_ptr->pass < 7) return; } if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_IDAT; #endif char extra; int ret; png_ptr->zstream.next_out = (Byte *)&extra; png_ptr->zstream.avail_out = (uInt)1; for(;;) { if (!(png_ptr->zstream.avail_in)) { while (!png_ptr->idat_size) { png_byte chunk_length[4]; png_crc_finish(png_ptr, 0); png_read_data(png_ptr, chunk_length, 4); png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) png_error(png_ptr, "Not enough image data"); } png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; png_ptr->zstream.next_in = png_ptr->zbuf; if (png_ptr->zbuf_size > png_ptr->idat_size) png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); png_ptr->idat_size -= png_ptr->zstream.avail_in; } ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); if (ret == Z_STREAM_END) { if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || png_ptr->idat_size) png_warning(png_ptr, "Extra compressed data"); png_ptr->mode |= PNG_AFTER_IDAT; png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; break; } if (ret != Z_OK) png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : "Decompression Error"); if (!(png_ptr->zstream.avail_out)) { png_warning(png_ptr, "Extra compressed data."); png_ptr->mode |= PNG_AFTER_IDAT; png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; break; } } png_ptr->zstream.avail_out = 0; } if (png_ptr->idat_size || png_ptr->zstream.avail_in) png_warning(png_ptr, "Extra compression data"); inflateReset(&png_ptr->zstream); png_ptr->mode |= PNG_AFTER_IDAT; } void /* PRIVATE */ png_read_start_row(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* start of interlace block */ const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* offset to next interlace block */ const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* start of interlace block in the y direction */ const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* offset to next interlace block in the y direction */ const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif int max_pixel_depth; png_uint_32 row_bytes; png_debug(1, "in png_read_start_row\n"); png_ptr->zstream.avail_in = 0; png_init_read_transformations(png_ptr); if (png_ptr->interlaced) { if (!(png_ptr->transformations & PNG_INTERLACE)) png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - png_pass_ystart[0]) / png_pass_yinc[0]; else png_ptr->num_rows = png_ptr->height; png_ptr->iwidth = (png_ptr->width + png_pass_inc[png_ptr->pass] - 1 - png_pass_start[png_ptr->pass]) / png_pass_inc[png_ptr->pass]; row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1; png_ptr->irowbytes = (png_size_t)row_bytes; if((png_uint_32)png_ptr->irowbytes != row_bytes) png_error(png_ptr, "Rowbytes overflow in png_read_start_row"); } else { png_ptr->num_rows = png_ptr->height; png_ptr->iwidth = png_ptr->width; png_ptr->irowbytes = png_ptr->rowbytes + 1; } max_pixel_depth = png_ptr->pixel_depth; #if defined(PNG_READ_PACK_SUPPORTED) if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) max_pixel_depth = 8; #endif #if defined(PNG_READ_EXPAND_SUPPORTED) if (png_ptr->transformations & PNG_EXPAND) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (png_ptr->num_trans) max_pixel_depth = 32; else max_pixel_depth = 24; } else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) { if (max_pixel_depth < 8) max_pixel_depth = 8; if (png_ptr->num_trans) max_pixel_depth *= 2; } else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) { if (png_ptr->num_trans) { max_pixel_depth *= 4; max_pixel_depth /= 3; } } } #endif #if defined(PNG_READ_FILLER_SUPPORTED) if (png_ptr->transformations & (PNG_FILLER)) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) max_pixel_depth = 32; else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) { if (max_pixel_depth <= 8) max_pixel_depth = 16; else max_pixel_depth = 32; } else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) { if (max_pixel_depth <= 32) max_pixel_depth = 32; else max_pixel_depth = 64; } } #endif #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) if (png_ptr->transformations & PNG_GRAY_TO_RGB) { if ( #if defined(PNG_READ_EXPAND_SUPPORTED) (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || #endif #if defined(PNG_READ_FILLER_SUPPORTED) (png_ptr->transformations & (PNG_FILLER)) || #endif png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { if (max_pixel_depth <= 16) max_pixel_depth = 32; else max_pixel_depth = 64; } else { if (max_pixel_depth <= 8) { if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) max_pixel_depth = 32; else max_pixel_depth = 24; } else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) max_pixel_depth = 64; else max_pixel_depth = 48; } } #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) if(png_ptr->transformations & PNG_USER_TRANSFORM) { int user_pixel_depth=png_ptr->user_transform_depth* png_ptr->user_transform_channels; if(user_pixel_depth > max_pixel_depth) max_pixel_depth=user_pixel_depth; } #endif /* align the width on the next larger 8 pixels. Mainly used for interlacing */ row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); /* calculate the maximum bytes needed, adding a byte and a pixel for safety's sake */ row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) + 1 + ((max_pixel_depth + 7) >> 3); #ifdef PNG_MAX_MALLOC_64K if (row_bytes > (png_uint_32)65536L) png_error(png_ptr, "This image requires a row greater than 64KB"); #endif png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64); png_ptr->row_buf = png_ptr->big_row_buf+32; #if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD) png_ptr->row_buf_size = row_bytes; #endif #ifdef PNG_MAX_MALLOC_64K if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L) png_error(png_ptr, "This image requires a row greater than 64KB"); #endif if ((png_uint_32)png_ptr->rowbytes > PNG_SIZE_MAX - 1) png_error(png_ptr, "Row has too many bytes to allocate in memory."); png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( png_ptr->rowbytes + 1)); png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1); png_debug1(3, "width = %lu,\n", png_ptr->width); png_debug1(3, "height = %lu,\n", png_ptr->height); png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth); png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows); png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes); png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes); png_ptr->flags |= PNG_FLAG_ROW_INIT; } syslinux-legacy-3.63+dfsg/com32/lib/libpng/libpng.txt0000664000175000017500000037143210777447272021205 0ustar evanevanlibpng.txt - A description on how to use and modify libpng libpng version 1.2.8 - December 3, 2004 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2004 Glenn Randers-Pehrson For conditions of distribution and use, see copyright notice in png.h. based on: libpng 1.0 beta 6 version 0.96 May 28, 1997 Updated and distributed by Andreas Dilger Copyright (c) 1996, 1997 Andreas Dilger libpng 1.0 beta 2 - version 0.88 January 26, 1996 For conditions of distribution and use, see copyright notice in png.h. Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. Updated/rewritten per request in the libpng FAQ Copyright (c) 1995, 1996 Frank J. T. Wojcik December 18, 1995 & January 20, 1996 I. Introduction This file describes how to use and modify the PNG reference library (known as libpng) for your own use. There are five sections to this file: introduction, structures, reading, writing, and modification and configuration notes for various special platforms. In addition to this file, example.c is a good starting point for using the library, as it is heavily commented and should include everything most people will need. We assume that libpng is already installed; see the INSTALL file for instructions on how to install libpng. Libpng was written as a companion to the PNG specification, as a way of reducing the amount of time and effort it takes to support the PNG file format in application programs. The PNG specification (second edition), November 2003, is available as a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at The PNG-1.0 specification is available as RFC 2083 and as a W3C Recommendation . Some additional chunks are described in the special-purpose public chunks documents at . Other information about PNG, and the latest version of libpng, can be found at the PNG home page, . Most users will not have to modify the library significantly; advanced users may want to modify it more. All attempts were made to make it as complete as possible, while keeping the code easy to understand. Currently, this library only supports C. Support for other languages is being considered. Libpng has been designed to handle multiple sessions at one time, to be easily modifiable, to be portable to the vast majority of machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy to use. The ultimate goal of libpng is to promote the acceptance of the PNG file format in whatever way possible. While there is still work to be done (see the TODO file), libpng should cover the majority of the needs of its users. Libpng uses zlib for its compression and decompression of PNG files. Further information about zlib, and the latest version of zlib, can be found at the zlib home page, . The zlib compression utility is a general purpose utility that is useful for more than PNG files, and can be used without libpng. See the documentation delivered with zlib for more details. You can usually find the source files for the zlib utility wherever you find the libpng source files. Libpng is thread safe, provided the threads are using different instances of the structures. Each thread should have its own png_struct and png_info instances, and thus its own image. Libpng does not protect itself against two threads using the same instance of a structure. Note: thread safety may be defeated by use of some of the MMX assembler code in pnggccrd.c, which is only compiled when the user defines PNG_THREAD_UNSAFE_OK. II. Structures There are two main structures that are important to libpng, png_struct and png_info. The first, png_struct, is an internal structure that will not, for the most part, be used by a user except as the first variable passed to every libpng function call. The png_info structure is designed to provide information about the PNG file. At one time, the fields of png_info were intended to be directly accessible to the user. However, this tended to cause problems with applications using dynamically loaded libraries, and as a result a set of interface functions for png_info (the png_get_*() and png_set_*() functions) was developed. The fields of png_info are still available for older applications, but it is suggested that applications use the new interfaces if at all possible. Applications that do make direct access to the members of png_struct (except for png_ptr->jmpbuf) must be recompiled whenever the library is updated, and applications that make direct access to the members of png_info must be recompiled if they were compiled or loaded with libpng version 1.0.6, in which the members were in a different order. In version 1.0.7, the members of the png_info structure reverted to the old order, as they were in versions 0.97c through 1.0.5. Starting with version 2.0.0, both structures are going to be hidden, and the contents of the structures will only be accessible through the png_get/png_set functions. The png.h header file is an invaluable reference for programming with libpng. And while I'm on the topic, make sure you include the libpng header file: #include III. Reading We'll now walk you through the possible functions to call when reading in a PNG file sequentially, briefly explaining the syntax and purpose of each one. See example.c and png.h for more detail. While progressive reading is covered in the next section, you will still need some of the functions discussed in this section to read a PNG file. Setup You will want to do the I/O initialization(*) before you get into libpng, so if it doesn't work, you don't have much to undo. Of course, you will also want to insure that you are, in fact, dealing with a PNG file. Libpng provides a simple check to see if a file is a PNG file. To use it, pass in the first 1 to 8 bytes of the file to the function png_sig_cmp(), and it will return 0 if the bytes match the corresponding bytes of the PNG signature, or nonzero otherwise. Of course, the more bytes you pass in, the greater the accuracy of the prediction. If you are intending to keep the file pointer open for use in libpng, you must ensure you don't read more than 8 bytes from the beginning of the file, and you also have to make a call to png_set_sig_bytes_read() with the number of bytes you read from the beginning. Libpng will then only check the bytes (if any) that your program didn't read. (*): If you are not using the standard I/O functions, you will need to replace them with custom functions. See the discussion under Customizing libpng. FILE *fp = fopen(file_name, "rb"); if (!fp) { return (ERROR); } fread(header, 1, number, fp); is_png = !png_sig_cmp(header, 0, number); if (!is_png) { return (NOT_PNG); } Next, png_struct and png_info need to be allocated and initialized. In order to ensure that the size of these structures is correct even with a dynamically linked libpng, there are functions to initialize and allocate the structures. We also pass the library version, optional pointers to error handling functions, and a pointer to a data struct for use by the error functions, if necessary (the pointer and functions can be NULL if the default error handlers are to be used). See the section on Changes to Libpng below regarding the old initialization functions. The structure allocation functions quietly return NULL if they fail to create the structure, so your application should check for that. png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn); if (!png_ptr) return (ERROR); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return (ERROR); } png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return (ERROR); } If you want to use your own memory allocation routines, define PNG_USER_MEM_SUPPORTED and use png_create_read_struct_2() instead of png_create_read_struct(): png_structp png_ptr = png_create_read_struct_2 (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn, (png_voidp) user_mem_ptr, user_malloc_fn, user_free_fn); The error handling routines passed to png_create_read_struct() and the memory alloc/free routines passed to png_create_struct_2() are only necessary if you are not using the libpng supplied error handling and memory alloc/free functions. When libpng encounters an error, it expects to longjmp back to your routine. Therefore, you will need to call setjmp and pass your png_jmpbuf(png_ptr). If you read the file from different routines, you will need to update the jmpbuf field every time you enter a new routine that will call a png_*() function. See your documentation of setjmp/longjmp for your compiler for more information on setjmp/longjmp. See the discussion on libpng error handling in the Customizing Libpng section below for more information on the libpng error handling. If an error occurs, and libpng longjmp's back to your setjmp, you will want to call png_destroy_read_struct() to free any memory. if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return (ERROR); } If you would rather avoid the complexity of setjmp/longjmp issues, you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case errors will result in a call to PNG_ABORT() which defaults to abort(). Now you need to set up the input code. The default for libpng is to use the C function fread(). If you use this, you will need to pass a valid FILE * in the function png_init_io(). Be sure that the file is opened in binary mode. If you wish to handle reading data in another way, you need not call the png_init_io() function, but you must then implement the libpng I/O methods discussed in the Customizing Libpng section below. png_init_io(png_ptr, fp); If you had previously opened the file and read any of the signature from the beginning in order to see if this was a PNG file, you need to let libpng know that there are some bytes missing from the start of the file. png_set_sig_bytes(png_ptr, number); Setting up callback code You can set up a callback function to handle any unknown chunks in the input stream. You must supply the function read_chunk_callback(png_ptr ptr, png_unknown_chunkp chunk); { /* The unknown chunk structure contains your chunk data: */ png_byte name[5]; png_byte *data; png_size_t size; /* Note that libpng has already taken care of the CRC handling */ /* put your code here. Return one of the following: */ return (-n); /* chunk had an error */ return (0); /* did not recognize */ return (n); /* success */ } (You can give your function another name that you like instead of "read_chunk_callback") To inform libpng about your function, use png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, read_chunk_callback); This names not only the callback function, but also a user pointer that you can retrieve with png_get_user_chunk_ptr(png_ptr); At this point, you can set up a callback function that will be called after each row has been read, which you can use to control a progress meter or the like. It's demonstrated in pngtest.c. You must supply a function void read_row_callback(png_ptr ptr, png_uint_32 row, int pass); { /* put your code here */ } (You can give it another name that you like instead of "read_row_callback") To inform libpng about your function, use png_set_read_status_fn(png_ptr, read_row_callback); Width and height limits The PNG specification allows the width and height of an image to be as large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns. Since very few applications really need to process such large images, we have imposed an arbitrary 1-million limit on rows and columns. Larger images will be rejected immediately with a png_error() call. If you wish to override this limit, you can use png_set_user_limits(png_ptr, width_max, height_max); to set your own limits, or use width_max = height_max = 0x7fffffffL to allow all valid dimensions (libpng may reject some very large images anyway because of potential buffer overflow conditions). You should put this statement after you create the PNG structure and before calling png_read_info(), png_read_png(), or png_process_data(). If you need to retrieve the limits that are being applied, use width_max = png_get_user_width_max(png_ptr); height_max = png_get_user_height_max(png_ptr); Unknown-chunk handling Now you get to set the way the library processes unknown chunks in the input PNG stream. Both known and unknown chunks will be read. Normal behavior is that known chunks will be parsed into information in various info_ptr members; unknown chunks will be discarded. To change this, you can call: png_set_keep_unknown_chunks(png_ptr, keep, chunk_list, num_chunks); keep - 0: do not handle as unknown 1: do not keep 2: keep only if safe-to-copy 3: keep even if unsafe-to-copy You can use these definitions: PNG_HANDLE_CHUNK_AS_DEFAULT 0 PNG_HANDLE_CHUNK_NEVER 1 PNG_HANDLE_CHUNK_IF_SAFE 2 PNG_HANDLE_CHUNK_ALWAYS 3 chunk_list - list of chunks affected (a byte string, five bytes per chunk, NULL or '\0' if num_chunks is 0) num_chunks - number of chunks affected; if 0, all unknown chunks are affected. If nonzero, only the chunks in the list are affected Unknown chunks declared in this way will be saved as raw data onto a list of png_unknown_chunk structures. If a chunk that is normally known to libpng is named in the list, it will be handled as unknown, according to the "keep" directive. If a chunk is named in successive instances of png_set_keep_unknown_chunks(), the final instance will take precedence. The IHDR and IEND chunks should not be named in chunk_list; if they are, libpng will process them normally anyway. The high-level read interface At this point there are two ways to proceed; through the high-level read interface, or through a sequence of low-level read operations. You can use the high-level interface if (a) you are willing to read the entire image into memory, and (b) the input transformations you want to do are limited to the following set: PNG_TRANSFORM_IDENTITY No transformation PNG_TRANSFORM_STRIP_16 Strip 16-bit samples to 8 bits PNG_TRANSFORM_STRIP_ALPHA Discard the alpha channel PNG_TRANSFORM_PACKING Expand 1, 2 and 4-bit samples to bytes PNG_TRANSFORM_PACKSWAP Change order of packed pixels to LSB first PNG_TRANSFORM_EXPAND Perform set_expand() PNG_TRANSFORM_INVERT_MONO Invert monochrome images PNG_TRANSFORM_SHIFT Normalize pixels to the sBIT depth PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA to BGRA PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA to AG PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity to transparency PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples (This excludes setting a background color, doing gamma transformation, dithering, and setting filler.) If this is the case, simply do this: png_read_png(png_ptr, info_ptr, png_transforms, NULL) where png_transforms is an integer containing the logical OR of some set of transformation flags. This call is equivalent to png_read_info(), followed the set of transformations indicated by the transform mask, then png_read_image(), and finally png_read_end(). (The final parameter of this call is not yet used. Someday it might point to transformation parameters required by some future input transform.) You must use png_transforms and not call any png_set_transform() functions when you use png_read_png(). After you have called png_read_png(), you can retrieve the image data with row_pointers = png_get_rows(png_ptr, info_ptr); where row_pointers is an array of pointers to the pixel data for each row: png_bytep row_pointers[height]; If you know your image size and pixel size ahead of time, you can allocate row_pointers prior to calling png_read_png() with if (height > PNG_UINT_32_MAX/png_sizeof(png_byte)) png_error (png_ptr, "Image is too tall to process in memory"); if (width > PNG_UINT_32_MAX/pixel_size) png_error (png_ptr, "Image is too wide to process in memory"); row_pointers = png_malloc(png_ptr, height*png_sizeof(png_bytep)); for (int i=0; i) and png_get_(png_ptr, info_ptr, ...) functions return non-zero if the data has been read, or zero if it is missing. The parameters to the png_get_ are set directly if they are simple data types, or a pointer into the info_ptr is returned for any complex types. png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); palette - the palette for the file (array of png_color) num_palette - number of entries in the palette png_get_gAMA(png_ptr, info_ptr, &gamma); gamma - the gamma the file is written at (PNG_INFO_gAMA) png_get_sRGB(png_ptr, info_ptr, &srgb_intent); srgb_intent - the rendering intent (PNG_INFO_sRGB) The presence of the sRGB chunk means that the pixel data is in the sRGB color space. This chunk also implies specific values of gAMA and cHRM. png_get_iCCP(png_ptr, info_ptr, &name, &compression_type, &profile, &proflen); name - The profile name. compression - The compression type; always PNG_COMPRESSION_TYPE_BASE for PNG 1.0. You may give NULL to this argument to ignore it. profile - International Color Consortium color profile data. May contain NULs. proflen - length of profile data in bytes. png_get_sBIT(png_ptr, info_ptr, &sig_bit); sig_bit - the number of significant bits for (PNG_INFO_sBIT) each of the gray, red, green, and blue channels, whichever are appropriate for the given color type (png_color_16) png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values); trans - array of transparent entries for palette (PNG_INFO_tRNS) trans_values - graylevel or color sample values of the single transparent color for non-paletted images (PNG_INFO_tRNS) num_trans - number of transparent entries (PNG_INFO_tRNS) png_get_hIST(png_ptr, info_ptr, &hist); (PNG_INFO_hIST) hist - histogram of palette (array of png_uint_16) png_get_tIME(png_ptr, info_ptr, &mod_time); mod_time - time image was last modified (PNG_VALID_tIME) png_get_bKGD(png_ptr, info_ptr, &background); background - background color (PNG_VALID_bKGD) valid 16-bit red, green and blue values, regardless of color_type num_comments = png_get_text(png_ptr, info_ptr, &text_ptr, &num_text); num_comments - number of comments text_ptr - array of png_text holding image comments text_ptr[i].compression - type of compression used on "text" PNG_TEXT_COMPRESSION_NONE PNG_TEXT_COMPRESSION_zTXt PNG_ITXT_COMPRESSION_NONE PNG_ITXT_COMPRESSION_zTXt text_ptr[i].key - keyword for comment. Must contain 1-79 characters. text_ptr[i].text - text comments for current keyword. Can be empty. text_ptr[i].text_length - length of text string, after decompression, 0 for iTXt text_ptr[i].itxt_length - length of itxt string, after decompression, 0 for tEXt/zTXt text_ptr[i].lang - language of comment (empty string for unknown). text_ptr[i].lang_key - keyword in UTF-8 (empty string for unknown). num_text - number of comments (same as num_comments; you can put NULL here to avoid the duplication) Note while png_set_text() will accept text, language, and translated keywords that can be NULL pointers, the structure returned by png_get_text will always contain regular zero-terminated C strings. They might be empty strings but they will never be NULL pointers. num_spalettes = png_get_sPLT(png_ptr, info_ptr, &palette_ptr); palette_ptr - array of palette structures holding contents of one or more sPLT chunks read. num_spalettes - number of sPLT chunks read. png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, &unit_type); offset_x - positive offset from the left edge of the screen offset_y - positive offset from the top edge of the screen unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type); res_x - pixels/unit physical resolution in x direction res_y - pixels/unit physical resolution in x direction unit_type - PNG_RESOLUTION_UNKNOWN, PNG_RESOLUTION_METER png_get_sCAL(png_ptr, info_ptr, &unit, &width, &height) unit - physical scale units (an integer) width - width of a pixel in physical scale units height - height of a pixel in physical scale units (width and height are doubles) png_get_sCAL_s(png_ptr, info_ptr, &unit, &width, &height) unit - physical scale units (an integer) width - width of a pixel in physical scale units height - height of a pixel in physical scale units (width and height are strings like "2.54") num_unknown_chunks = png_get_unknown_chunks(png_ptr, info_ptr, &unknowns) unknowns - array of png_unknown_chunk structures holding unknown chunks unknowns[i].name - name of unknown chunk unknowns[i].data - data of unknown chunk unknowns[i].size - size of unknown chunk's data unknowns[i].location - position of chunk in file The value of "i" corresponds to the order in which the chunks were read from the PNG file or inserted with the png_set_unknown_chunks() function. The data from the pHYs chunk can be retrieved in several convenient forms: res_x = png_get_x_pixels_per_meter(png_ptr, info_ptr) res_y = png_get_y_pixels_per_meter(png_ptr, info_ptr) res_x_and_y = png_get_pixels_per_meter(png_ptr, info_ptr) res_x = png_get_x_pixels_per_inch(png_ptr, info_ptr) res_y = png_get_y_pixels_per_inch(png_ptr, info_ptr) res_x_and_y = png_get_pixels_per_inch(png_ptr, info_ptr) aspect_ratio = png_get_pixel_aspect_ratio(png_ptr, info_ptr) (Each of these returns 0 [signifying "unknown"] if the data is not present or if res_x is 0; res_x_and_y is 0 if res_x != res_y) The data from the oFFs chunk can be retrieved in several convenient forms: x_offset = png_get_x_offset_microns(png_ptr, info_ptr); y_offset = png_get_y_offset_microns(png_ptr, info_ptr); x_offset = png_get_x_offset_inches(png_ptr, info_ptr); y_offset = png_get_y_offset_inches(png_ptr, info_ptr); (Each of these returns 0 [signifying "unknown" if both x and y are 0] if the data is not present or if the chunk is present but the unit is the pixel) For more information, see the png_info definition in png.h and the PNG specification for chunk contents. Be careful with trusting rowbytes, as some of the transformations could increase the space needed to hold a row (expand, filler, gray_to_rgb, etc.). See png_read_update_info(), below. A quick word about text_ptr and num_text. PNG stores comments in keyword/text pairs, one pair per chunk, with no limit on the number of text chunks, and a 2^31 byte limit on their size. While there are suggested keywords, there is no requirement to restrict the use to these strings. It is strongly suggested that keywords and text be sensible to humans (that's the point), so don't use abbreviations. Non-printing symbols are not allowed. See the PNG specification for more details. There is also no requirement to have text after the keyword. Keywords should be limited to 79 Latin-1 characters without leading or trailing spaces, but non-consecutive spaces are allowed within the keyword. It is possible to have the same keyword any number of times. The text_ptr is an array of png_text structures, each holding a pointer to a language string, a pointer to a keyword and a pointer to a text string. The text string, language code, and translated keyword may be empty or NULL pointers. The keyword/text pairs are put into the array in the order that they are received. However, some or all of the text chunks may be after the image, so, to make sure you have read all the text chunks, don't mess with these until after you read the stuff after the image. This will be mentioned again below in the discussion that goes with png_read_end(). Input transformations After you've read the header information, you can set up the library to handle any special transformations of the image data. The various ways to transform the data will be described in the order that they should occur. This is important, as some of these change the color type and/or bit depth of the data, and some others only work on certain color types and bit depths. Even though each transformation checks to see if it has data that it can do something with, you should make sure to only enable a transformation if it will be valid for the data. For example, don't swap red and blue on grayscale data. The colors used for the background and transparency values should be supplied in the same format/depth as the current image data. They are stored in the same format/depth as the image data in a bKGD or tRNS chunk, so this is what libpng expects for this data. The colors are transformed to keep in sync with the image data when an application calls the png_read_update_info() routine (see below). Data will be decoded into the supplied row buffers packed into bytes unless the library has been told to transform it into another format. For example, 4 bit/pixel paletted or grayscale data will be returned 2 pixels/byte with the leftmost pixel in the high-order bits of the byte, unless png_set_packing() is called. 8-bit RGB data will be stored in RGB RGB RGB format unless png_set_filler() or png_set_add_alpha() is called to insert filler bytes, either before or after each RGB triplet. 16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant byte of the color value first, unless png_set_strip_16() is called to transform it to regular RGB RGB triplets, or png_set_filler() or png_set_add alpha() is called to insert filler bytes, either before or after each RRGGBB triplet. Similarly, 8-bit or 16-bit grayscale data can be modified with png_set_filler(), png_set_add_alpha(), or png_set_strip_16(). The following code transforms grayscale images of less than 8 to 8 bits, changes paletted images to RGB, and adds a full alpha channel if there is transparency information in a tRNS chunk. This is most useful on grayscale images with bit depths of 2 or 4 or if there is a multiple-image viewing application that wishes to treat all images in the same way. if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); These three functions are actually aliases for png_set_expand(), added in libpng version 1.0.4, with the function names expanded to improve code readability. In some future version they may actually do different things. PNG can have files with 16 bits per channel. If you only can handle 8 bits per channel, this will strip the pixels down to 8 bit. if (bit_depth == 16) png_set_strip_16(png_ptr); If, for some reason, you don't need the alpha channel on an image, and you want to remove it rather than combining it with the background (but the image author certainly had in mind that you *would* combine it with the background, so that's what you should probably do): if (color_type & PNG_COLOR_MASK_ALPHA) png_set_strip_alpha(png_ptr); In PNG files, the alpha channel in an image is the level of opacity. If you need the alpha channel in an image to be the level of transparency instead of opacity, you can invert the alpha channel (or the tRNS chunk data) after it's read, so that 0 is fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit images) is fully transparent, with png_set_invert_alpha(png_ptr); PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as they can, resulting in, for example, 8 pixels per byte for 1 bit files. This code expands to 1 pixel per byte without changing the values of the pixels: if (bit_depth < 8) png_set_packing(png_ptr); PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixels stored in a PNG image have been "scaled" or "shifted" up to the next higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to 8 bits/sample in the range [0, 255]). However, it is also possible to convert the PNG pixel data back to the original bit depth of the image. This call reduces the pixels back down to the original bit depth: png_color_8p sig_bit; if (png_get_sBIT(png_ptr, info_ptr, &sig_bit)) png_set_shift(png_ptr, sig_bit); PNG files store 3-color pixels in red, green, blue order. This code changes the storage of the pixels to blue, green, red: if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_bgr(png_ptr); PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them into 4 or 8 bytes for windowing systems that need them in this format: if (color_type == PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE); where "filler" is the 8 or 16-bit number to fill with, and the location is either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether you want the filler before the RGB or after. This transformation does not affect images that already have full alpha channels. To add an opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which will generate RGBA pixels. Note that png_set_filler() does not change the color type. If you want to do that, you can add a true alpha channel with if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY) png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER); where "filler" contains the alpha value to assign to each pixel. This function was added in libpng-1.2.7. If you are reading an image with an alpha channel, and you need the data as ARGB instead of the normal PNG format RGBA: if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_swap_alpha(png_ptr); For some uses, you may want a grayscale image to be represented as RGB. This code will do that conversion: if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); Conversely, you can convert an RGB or RGBA image to grayscale or grayscale with alpha. if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_rgb_to_gray_fixed(png_ptr, error_action, int red_weight, int green_weight); error_action = 1: silently do the conversion error_action = 2: issue a warning if the original image has any pixel where red != green or red != blue error_action = 3: issue an error and abort the conversion if the original image has any pixel where red != green or red != blue red_weight: weight of red component times 100000 green_weight: weight of green component times 100000 If either weight is negative, default weights (21268, 71514) are used. If you have set error_action = 1 or 2, you can later check whether the image really was gray, after processing the image rows, with the png_get_rgb_to_gray_status(png_ptr) function. It will return a png_byte that is zero if the image was gray or 1 if there were any non-gray pixels. bKGD and sBIT data will be silently converted to grayscale, using the green channel data, regardless of the error_action setting. With red_weight+green_weight<=100000, the normalized graylevel is computed: int rw = red_weight * 65536; int gw = green_weight * 65536; int bw = 65536 - (rw + gw); gray = (rw*red + gw*green + bw*blue)/65536; The default values approximate those recommended in the Charles Poynton's Color FAQ, Copyright (c) 1998-01-04 Charles Poynton Y = 0.212671 * R + 0.715160 * G + 0.072169 * B Libpng approximates this with Y = 0.21268 * R + 0.7151 * G + 0.07217 * B which can be expressed with integers as Y = (6969 * R + 23434 * G + 2365 * B)/32768 The calculation is done in a linear colorspace, if the image gamma is known. If you have a grayscale and you are using png_set_expand_depth(), png_set_expand(), or png_set_gray_to_rgb to change to truecolor or to a higher bit-depth, you must either supply the background color as a gray value at the original file bit-depth (need_expand = 1) or else supply the background color as an RGB triplet at the final, expanded bit depth (need_expand = 0). Similarly, if you are reading a paletted image, you must either supply the background color as a palette index (need_expand = 1) or as an RGB triplet that may or may not be in the palette (need_expand = 0). png_color_16 my_background; png_color_16p image_background; if (png_get_bKGD(png_ptr, info_ptr, &image_background)) png_set_background(png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); else png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); The png_set_background() function tells libpng to composite images with alpha or simple transparency against the supplied background color. If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid), you may use this color, or supply another color more suitable for the current display (e.g., the background color from a web page). You need to tell libpng whether the color is in the gamma space of the display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file (PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't know why anyone would use this, but it's here). To properly display PNG images on any kind of system, the application needs to know what the display gamma is. Ideally, the user will know this, and the application will allow them to set it. One method of allowing the user to set the display gamma separately for each system is to check for a SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be correctly set. Note that display_gamma is the overall gamma correction required to produce pleasing results, which depends on the lighting conditions in the surrounding environment. In a dim or brightly lit room, no compensation other than the physical gamma exponent of the monitor is needed, while in a dark room a slightly smaller exponent is better. double gamma, screen_gamma; if (/* We have a user-defined screen gamma value */) { screen_gamma = user_defined_screen_gamma; } /* One way that applications can share the same screen gamma value */ else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL) { screen_gamma = (double)atof(gamma_str); } /* If we don't have another value */ else { screen_gamma = 2.2; /* A good guess for a PC monitor in a bright office or a dim room */ screen_gamma = 2.0; /* A good guess for a PC monitor in a dark room */ screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */ } The png_set_gamma() function handles gamma transformations of the data. Pass both the file gamma and the current screen_gamma. If the file does not have a gamma value, you can pass one anyway if you have an idea what it is (usually 0.45455 is a good guess for GIF images on PCs). Note that file gammas are inverted from screen gammas. See the discussions on gamma in the PNG specification for an excellent description of what gamma is, and why all applications should support it. It is strongly recommended that PNG viewers support gamma correction. if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, screen_gamma, gamma); else png_set_gamma(png_ptr, screen_gamma, 0.45455); If you need to reduce an RGB file to a paletted file, or if a paletted file has more entries then will fit on your screen, png_set_dither() will do that. Note that this is a simple match dither that merely finds the closest color available. This should work fairly well with optimized palettes, and fairly badly with linear color cubes. If you pass a palette that is larger then maximum_colors, the file will reduce the number of colors in the palette so it will fit into maximum_colors. If there is a histogram, it will use it to make more intelligent choices when reducing the palette. If there is no histogram, it may not do as good a job. if (color_type & PNG_COLOR_MASK_COLOR) { if (png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) { png_uint_16p histogram = NULL; png_get_hIST(png_ptr, info_ptr, &histogram); png_set_dither(png_ptr, palette, num_palette, max_screen_colors, histogram, 1); } else { png_color std_color_cube[MAX_SCREEN_COLORS] = { ... colors ... }; png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS, MAX_SCREEN_COLORS, NULL,0); } } PNG files describe monochrome as black being zero and white being one. The following code will reverse this (make black be one and white be zero): if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY) png_set_invert_mono(png_ptr); This function can also be used to invert grayscale and gray-alpha images: if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_invert_mono(png_ptr); PNG files store 16 bit pixels in network byte order (big-endian, ie. most significant bits first). This code changes the storage to the other way (little-endian, i.e. least significant bits first, the way PCs store them): if (bit_depth == 16) png_set_swap(png_ptr); If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you need to change the order the pixels are packed into bytes, you can use: if (bit_depth < 8) png_set_packswap(png_ptr); Finally, you can write your own transformation function if none of the existing ones meets your needs. This is done by setting a callback with png_set_read_user_transform_fn(png_ptr, read_transform_fn); You must supply the function void read_transform_fn(png_ptr ptr, row_info_ptr row_info, png_bytep data) See pngtest.c for a working example. Your function will be called after all of the other transformations have been processed. You can also set up a pointer to a user structure for use by your callback function, and you can inform libpng that your transform function will change the number of channels or bit depth with the function png_set_user_transform_info(png_ptr, user_ptr, user_depth, user_channels); The user's application, not libpng, is responsible for allocating and freeing any memory required for the user structure. You can retrieve the pointer via the function png_get_user_transform_ptr(). For example: voidp read_user_transform_ptr = png_get_user_transform_ptr(png_ptr); The last thing to handle is interlacing; this is covered in detail below, but you must call the function here if you want libpng to handle expansion of the interlaced image. number_of_passes = png_set_interlace_handling(png_ptr); After setting the transformations, libpng can update your png_info structure to reflect any transformations you've requested with this call. This is most useful to update the info structure's rowbytes field so you can use it to allocate your image memory. This function will also update your palette with the correct screen_gamma and background if these have been given with the calls above. png_read_update_info(png_ptr, info_ptr); After you call png_read_update_info(), you can allocate any memory you need to hold the image. The row data is simply raw byte data for all forms of images. As the actual allocation varies among applications, no example will be given. If you are allocating one large chunk, you will need to build an array of pointers to each row, as it will be needed for some of the functions below. Reading image data After you've allocated memory, you can read the image data. The simplest way to do this is in one function call. If you are allocating enough memory to hold the whole image, you can just call png_read_image() and libpng will read in all the image data and put it in the memory area supplied. You will need to pass in an array of pointers to each row. This function automatically handles interlacing, so you don't need to call png_set_interlace_handling() or call this function multiple times, or any of that other stuff necessary with png_read_rows(). png_read_image(png_ptr, row_pointers); where row_pointers is: png_bytep row_pointers[height]; You can point to void or char or whatever you use for pixels. If you don't want to read in the whole image at once, you can use png_read_rows() instead. If there is no interlacing (check interlace_type == PNG_INTERLACE_NONE), this is simple: png_read_rows(png_ptr, row_pointers, NULL, number_of_rows); where row_pointers is the same as in the png_read_image() call. If you are doing this just one row at a time, you can do this with a single row_pointer instead of an array of row_pointers: png_bytep row_pointer = row; png_read_row(png_ptr, row_pointer, NULL); If the file is interlaced (interlace_type != 0 in the IHDR chunk), things get somewhat harder. The only current (PNG Specification version 1.2) interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7) is a somewhat complicated 2D interlace scheme, known as Adam7, that breaks down an image into seven smaller images of varying size, based on an 8x8 grid. libpng can fill out those images or it can give them to you "as is". If you want them filled out, there are two ways to do that. The one mentioned in the PNG specification is to expand each pixel to cover those pixels that have not been read yet (the "rectangle" method). This results in a blocky image for the first pass, which gradually smooths out as more pixels are read. The other method is the "sparkle" method, where pixels are drawn only in their final locations, with the rest of the image remaining whatever colors they were initialized to before the start of the read. The first method usually looks better, but tends to be slower, as there are more pixels to put in the rows. If you don't want libpng to handle the interlacing details, just call png_read_rows() seven times to read in all seven images. Each of the images is a valid image by itself, or they can all be combined on an 8x8 grid to form a single image (although if you intend to combine them you would be far better off using the libpng interlace handling). The first pass will return an image 1/8 as wide as the entire image (every 8th column starting in column 0) and 1/8 as high as the original (every 8th row starting in row 0), the second will be 1/8 as wide (starting in column 4) and 1/8 as high (also starting in row 0). The third pass will be 1/4 as wide (every 4th pixel starting in column 0) and 1/8 as high (every 8th row starting in row 4), and the fourth pass will be 1/4 as wide and 1/4 as high (every 4th column starting in column 2, and every 4th row starting in row 0). The fifth pass will return an image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2), while the sixth pass will be 1/2 as wide and 1/2 as high as the original (starting in column 1 and row 0). The seventh and final pass will be as wide as the original, and 1/2 as high, containing all of the odd numbered scanlines. Phew! If you want libpng to expand the images, call this before calling png_start_read_image() or png_read_update_info(): if (interlace_type == PNG_INTERLACE_ADAM7) number_of_passes = png_set_interlace_handling(png_ptr); This will return the number of passes needed. Currently, this is seven, but may change if another interlace type is added. This function can be called even if the file is not interlaced, where it will return one pass. If you are not going to display the image after each pass, but are going to wait until the entire image is read in, use the sparkle effect. This effect is faster and the end result of either method is exactly the same. If you are planning on displaying the image after each pass, the "rectangle" effect is generally considered the better looking one. If you only want the "sparkle" effect, just call png_read_rows() as normal, with the third parameter NULL. Make sure you make pass over the image number_of_passes times, and you don't change the data in the rows between calls. You can change the locations of the data, just not the data. Each pass only writes the pixels appropriate for that pass, and assumes the data from previous passes is still valid. png_read_rows(png_ptr, row_pointers, NULL, number_of_rows); If you only want the first effect (the rectangles), do the same as before except pass the row buffer in the third parameter, and leave the second parameter NULL. png_read_rows(png_ptr, NULL, row_pointers, number_of_rows); Finishing a sequential read After you are finished reading the image through either the high- or low-level interfaces, you can finish reading the file. If you are interested in comments or time, which may be stored either before or after the image data, you should pass the separate png_info struct if you want to keep the comments from before and after the image separate. If you are not interested, you can pass NULL. png_read_end(png_ptr, end_info); When you are done, you can free all memory allocated by libpng like this: png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); It is also possible to individually free the info_ptr members that point to libpng-allocated storage with the following function: png_free_data(png_ptr, info_ptr, mask, seq) mask - identifies data to be freed, a mask containing the logical OR of one or more of PNG_FREE_PLTE, PNG_FREE_TRNS, PNG_FREE_HIST, PNG_FREE_ICCP, PNG_FREE_PCAL, PNG_FREE_ROWS, PNG_FREE_SCAL, PNG_FREE_SPLT, PNG_FREE_TEXT, PNG_FREE_UNKN, or simply PNG_FREE_ALL seq - sequence number of item to be freed (-1 for all items) This function may be safely called when the relevant storage has already been freed, or has not yet been allocated, or was allocated by the user and not by libpng, and will in those cases do nothing. The "seq" parameter is ignored if only one item of the selected data type, such as PLTE, is allowed. If "seq" is not -1, and multiple items are allowed for the data type identified in the mask, such as text or sPLT, only the n'th item in the structure is freed, where n is "seq". The default behavior is only to free data that was allocated internally by libpng. This can be changed, so that libpng will not free the data, or so that it will free data that was allocated by the user with png_malloc() or png_zalloc() and passed in via a png_set_*() function, with png_data_freer(png_ptr, info_ptr, freer, mask) mask - which data elements are affected same choices as in png_free_data() freer - one of PNG_DESTROY_WILL_FREE_DATA PNG_SET_WILL_FREE_DATA PNG_USER_WILL_FREE_DATA This function only affects data that has already been allocated. You can call this function after reading the PNG data but before calling any png_set_*() functions, to control whether the user or the png_set_*() function is responsible for freeing any existing data that might be present, and again after the png_set_*() functions to control whether the user or png_destroy_*() is supposed to free the data. When the user assumes responsibility for libpng-allocated data, the application must use png_free() to free it, and when the user transfers responsibility to libpng for data that the user has allocated, the user must have used png_malloc() or png_zalloc() to allocate it. If you allocated your row_pointers in a single block, as suggested above in the description of the high level read interface, you must not transfer responsibility for freeing it to the png_set_rows or png_read_destroy function, because they would also try to free the individual row_pointers[i]. If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword separately, do not transfer responsibility for freeing text_ptr to libpng, because when libpng fills a png_text structure it combines these members with the key member, and png_free_data() will free only text_ptr.key. Similarly, if you transfer responsibility for free'ing text_ptr from libpng to your application, your application must not separately free those members. The png_free_data() function will turn off the "valid" flag for anything it frees. If you need to turn the flag off for a chunk that was freed by your application instead of by libpng, you can use png_set_invalid(png_ptr, info_ptr, mask); mask - identifies the chunks to be made invalid, containing the logical OR of one or more of PNG_INFO_gAMA, PNG_INFO_sBIT, PNG_INFO_cHRM, PNG_INFO_PLTE, PNG_INFO_tRNS, PNG_INFO_bKGD, PNG_INFO_hIST, PNG_INFO_pHYs, PNG_INFO_oFFs, PNG_INFO_tIME, PNG_INFO_pCAL, PNG_INFO_sRGB, PNG_INFO_iCCP, PNG_INFO_sPLT, PNG_INFO_sCAL, PNG_INFO_IDAT For a more compact example of reading a PNG image, see the file example.c. Reading PNG files progressively The progressive reader is slightly different then the non-progressive reader. Instead of calling png_read_info(), png_read_rows(), and png_read_end(), you make one call to png_process_data(), which calls callbacks when it has the info, a row, or the end of the image. You set up these callbacks with png_set_progressive_read_fn(). You don't have to worry about the input/output functions of libpng, as you are giving the library the data directly in png_process_data(). I will assume that you have read the section on reading PNG files above, so I will only highlight the differences (although I will show all of the code). png_structp png_ptr; png_infop info_ptr; /* An example code fragment of how you would initialize the progressive reader in your application. */ int initialize_png_reader() { png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn); if (!png_ptr) return (ERROR); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return (ERROR); } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return (ERROR); } /* This one's new. You can provide functions to be called when the header info is valid, when each row is completed, and when the image is finished. If you aren't using all functions, you can specify NULL parameters. Even when all three functions are NULL, you need to call png_set_progressive_read_fn(). You can use any struct as the user_ptr (cast to a void pointer for the function call), and retrieve the pointer from inside the callbacks using the function png_get_progressive_ptr(png_ptr); which will return a void pointer, which you have to cast appropriately. */ png_set_progressive_read_fn(png_ptr, (void *)user_ptr, info_callback, row_callback, end_callback); return 0; } /* A code fragment that you call as you receive blocks of data */ int process_data(png_bytep buffer, png_uint_32 length) { if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return (ERROR); } /* This one's new also. Simply give it a chunk of data from the file stream (in order, of course). On machines with segmented memory models machines, don't give it any more than 64K. The library seems to run fine with sizes of 4K. Although you can give it much less if necessary (I assume you can give it chunks of 1 byte, I haven't tried less then 256 bytes yet). When this function returns, you may want to display any rows that were generated in the row callback if you don't already do so there. */ png_process_data(png_ptr, info_ptr, buffer, length); return 0; } /* This function is called (as set by png_set_progressive_read_fn() above) when enough data has been supplied so all of the header has been read. */ void info_callback(png_structp png_ptr, png_infop info) { /* Do any setup here, including setting any of the transformations mentioned in the Reading PNG files section. For now, you _must_ call either png_start_read_image() or png_read_update_info() after all the transformations are set (even if you don't set any). You may start getting rows before png_process_data() returns, so this is your last chance to prepare for that. */ } /* This function is called when each row of image data is complete */ void row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass) { /* If the image is interlaced, and you turned on the interlace handler, this function will be called for every row in every pass. Some of these rows will not be changed from the previous pass. When the row is not changed, the new_row variable will be NULL. The rows and passes are called in order, so you don't really need the row_num and pass, but I'm supplying them because it may make your life easier. For the non-NULL rows of interlaced images, you must call png_progressive_combine_row() passing in the row and the old row. You can call this function for NULL rows (it will just return) and for non-interlaced images (it just does the memcpy for you) if it will make the code easier. Thus, you can just do this for all cases: */ png_progressive_combine_row(png_ptr, old_row, new_row); /* where old_row is what was displayed for previously for the row. Note that the first pass (pass == 0, really) will completely cover the old row, so the rows do not have to be initialized. After the first pass (and only for interlaced images), you will have to pass the current row, and the function will combine the old row and the new row. */ } void end_callback(png_structp png_ptr, png_infop info) { /* This function is called after the whole image has been read, including any chunks after the image (up to and including the IEND). You will usually have the same info chunk as you had in the header, although some data may have been added to the comments and time fields. Most people won't do much here, perhaps setting a flag that marks the image as finished. */ } IV. Writing Much of this is very similar to reading. However, everything of importance is repeated here, so you won't have to constantly look back up in the reading section to understand writing. Setup You will want to do the I/O initialization before you get into libpng, so if it doesn't work, you don't have anything to undo. If you are not using the standard I/O functions, you will need to replace them with custom writing functions. See the discussion under Customizing libpng. FILE *fp = fopen(file_name, "wb"); if (!fp) { return (ERROR); } Next, png_struct and png_info need to be allocated and initialized. As these can be both relatively large, you may not want to store these on the stack, unless you have stack space to spare. Of course, you will want to check if they return NULL. If you are also reading, you won't want to name your read structure and your write structure both "png_ptr"; you can call them anything you like, such as "read_ptr" and "write_ptr". Look at pngtest.c, for example. png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn); if (!png_ptr) return (ERROR); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return (ERROR); } If you want to use your own memory allocation routines, define PNG_USER_MEM_SUPPORTED and use png_create_write_struct_2() instead of png_create_write_struct(): png_structp png_ptr = png_create_write_struct_2 (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn, (png_voidp) user_mem_ptr, user_malloc_fn, user_free_fn); After you have these structures, you will need to set up the error handling. When libpng encounters an error, it expects to longjmp() back to your routine. Therefore, you will need to call setjmp() and pass the png_jmpbuf(png_ptr). If you write the file from different routines, you will need to update the png_jmpbuf(png_ptr) every time you enter a new routine that will call a png_*() function. See your documentation of setjmp/longjmp for your compiler for more information on setjmp/longjmp. See the discussion on libpng error handling in the Customizing Libpng section below for more information on the libpng error handling. if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return (ERROR); } ... return; If you would rather avoid the complexity of setjmp/longjmp issues, you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case errors will result in a call to PNG_ABORT() which defaults to abort(). Now you need to set up the output code. The default for libpng is to use the C function fwrite(). If you use this, you will need to pass a valid FILE * in the function png_init_io(). Be sure that the file is opened in binary mode. Again, if you wish to handle writing data in another way, see the discussion on libpng I/O handling in the Customizing Libpng section below. png_init_io(png_ptr, fp); Write callbacks At this point, you can set up a callback function that will be called after each row has been written, which you can use to control a progress meter or the like. It's demonstrated in pngtest.c. You must supply a function void write_row_callback(png_ptr, png_uint_32 row, int pass); { /* put your code here */ } (You can give it another name that you like instead of "write_row_callback") To inform libpng about your function, use png_set_write_status_fn(png_ptr, write_row_callback); You now have the option of modifying how the compression library will run. The following functions are mainly for testing, but may be useful in some cases, like if you need to write PNG files extremely fast and are willing to give up some compression, or if you want to get the maximum possible compression at the expense of slower writing. If you have no special needs in this area, let the library do what it wants by not calling this function at all, as it has been tuned to deliver a good speed/compression ratio. The second parameter to png_set_filter() is the filter method, for which the only valid values are 0 (as of the July 1999 PNG specification, version 1.2) or 64 (if you are writing a PNG datastream that is to be embedded in a MNG datastream). The third parameter is a flag that indicates which filter type(s) are to be tested for each scanline. See the PNG specification for details on the specific filter types. /* turn on or off filtering, and/or choose specific filters. You can use either a single PNG_FILTER_VALUE_NAME or the logical OR of one or more PNG_FILTER_NAME masks. */ png_set_filter(png_ptr, 0, PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | PNG_FILTER_UP | PNG_FILTER_VALUE_UP | PNG_FILTER_AVE | PNG_FILTER_VALUE_AVE | PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH| PNG_ALL_FILTERS); If an application wants to start and stop using particular filters during compression, it should start out with all of the filters (to ensure that the previous row of pixels will be stored in case it's needed later), and then add and remove them after the start of compression. If you are writing a PNG datastream that is to be embedded in a MNG datastream, the second parameter can be either 0 or 64. The png_set_compression_*() functions interface to the zlib compression library, and should mostly be ignored unless you really know what you are doing. The only generally useful call is png_set_compression_level() which changes how much time zlib spends on trying to compress the image data. See the Compression Library (zlib.h and algorithm.txt, distributed with zlib) for details on the compression levels. /* set the zlib compression level */ png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); /* set other zlib parameters */ png_set_compression_mem_level(png_ptr, 8); png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY); png_set_compression_window_bits(png_ptr, 15); png_set_compression_method(png_ptr, 8); png_set_compression_buffer_size(png_ptr, 8192) extern PNG_EXPORT(void,png_set_zbuf_size) Setting the contents of info for output You now need to fill in the png_info structure with all the data you wish to write before the actual image. Note that the only thing you are allowed to write after the image is the text chunks and the time chunk (as of PNG Specification 1.2, anyway). See png_write_end() and the latest PNG specification for more information on that. If you wish to write them before the image, fill them in now, and flag that data as being valid. If you want to wait until after the data, don't fill them until png_write_end(). For all the fields in png_info and their data types, see png.h. For explanations of what the fields contain, see the PNG specification. Some of the more important parts of the png_info are: png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type, compression_type, filter_method) width - holds the width of the image in pixels (up to 2^31). height - holds the height of the image in pixels (up to 2^31). bit_depth - holds the bit depth of one of the image channels. (valid values are 1, 2, 4, 8, 16 and depend also on the color_type. See also significant bits (sBIT) below). color_type - describes which color/alpha channels are present. PNG_COLOR_TYPE_GRAY (bit depths 1, 2, 4, 8, 16) PNG_COLOR_TYPE_GRAY_ALPHA (bit depths 8, 16) PNG_COLOR_TYPE_PALETTE (bit depths 1, 2, 4, 8) PNG_COLOR_TYPE_RGB (bit_depths 8, 16) PNG_COLOR_TYPE_RGB_ALPHA (bit_depths 8, 16) PNG_COLOR_MASK_PALETTE PNG_COLOR_MASK_COLOR PNG_COLOR_MASK_ALPHA interlace_type - PNG_INTERLACE_NONE or PNG_INTERLACE_ADAM7 compression_type - (must be PNG_COMPRESSION_TYPE_DEFAULT) filter_method - (must be PNG_FILTER_TYPE_DEFAULT or, if you are writing a PNG to be embedded in a MNG datastream, can also be PNG_INTRAPIXEL_DIFFERENCING) png_set_PLTE(png_ptr, info_ptr, palette, num_palette); palette - the palette for the file (array of png_color) num_palette - number of entries in the palette png_set_gAMA(png_ptr, info_ptr, gamma); gamma - the gamma the image was created at (PNG_INFO_gAMA) png_set_sRGB(png_ptr, info_ptr, srgb_intent); srgb_intent - the rendering intent (PNG_INFO_sRGB) The presence of the sRGB chunk means that the pixel data is in the sRGB color space. This chunk also implies specific values of gAMA and cHRM. Rendering intent is the CSS-1 property that has been defined by the International Color Consortium (http://www.color.org). It can be one of PNG_sRGB_INTENT_SATURATION, PNG_sRGB_INTENT_PERCEPTUAL, PNG_sRGB_INTENT_ABSOLUTE, or PNG_sRGB_INTENT_RELATIVE. png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, srgb_intent); srgb_intent - the rendering intent (PNG_INFO_sRGB) The presence of the sRGB chunk means that the pixel data is in the sRGB color space. This function also causes gAMA and cHRM chunks with the specific values that are consistent with sRGB to be written. png_set_iCCP(png_ptr, info_ptr, name, compression_type, profile, proflen); name - The profile name. compression - The compression type; always PNG_COMPRESSION_TYPE_BASE for PNG 1.0. You may give NULL to this argument to ignore it. profile - International Color Consortium color profile data. May contain NULs. proflen - length of profile data in bytes. png_set_sBIT(png_ptr, info_ptr, sig_bit); sig_bit - the number of significant bits for (PNG_INFO_sBIT) each of the gray, red, green, and blue channels, whichever are appropriate for the given color type (png_color_16) png_set_tRNS(png_ptr, info_ptr, trans, num_trans, trans_values); trans - array of transparent entries for palette (PNG_INFO_tRNS) trans_values - graylevel or color sample values of the single transparent color for non-paletted images (PNG_INFO_tRNS) num_trans - number of transparent entries (PNG_INFO_tRNS) png_set_hIST(png_ptr, info_ptr, hist); (PNG_INFO_hIST) hist - histogram of palette (array of png_uint_16) png_set_tIME(png_ptr, info_ptr, mod_time); mod_time - time image was last modified (PNG_VALID_tIME) png_set_bKGD(png_ptr, info_ptr, background); background - background color (PNG_VALID_bKGD) png_set_text(png_ptr, info_ptr, text_ptr, num_text); text_ptr - array of png_text holding image comments text_ptr[i].compression - type of compression used on "text" PNG_TEXT_COMPRESSION_NONE PNG_TEXT_COMPRESSION_zTXt PNG_ITXT_COMPRESSION_NONE PNG_ITXT_COMPRESSION_zTXt text_ptr[i].key - keyword for comment. Must contain 1-79 characters. text_ptr[i].text - text comments for current keyword. Can be NULL or empty. text_ptr[i].text_length - length of text string, after decompression, 0 for iTXt text_ptr[i].itxt_length - length of itxt string, after decompression, 0 for tEXt/zTXt text_ptr[i].lang - language of comment (NULL or empty for unknown). text_ptr[i].translated_keyword - keyword in UTF-8 (NULL or empty for unknown). num_text - number of comments png_set_sPLT(png_ptr, info_ptr, &palette_ptr, num_spalettes); palette_ptr - array of png_sPLT_struct structures to be added to the list of palettes in the info structure. num_spalettes - number of palette structures to be added. png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); offset_x - positive offset from the left edge of the screen offset_y - positive offset from the top edge of the screen unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); res_x - pixels/unit physical resolution in x direction res_y - pixels/unit physical resolution in y direction unit_type - PNG_RESOLUTION_UNKNOWN, PNG_RESOLUTION_METER png_set_sCAL(png_ptr, info_ptr, unit, width, height) unit - physical scale units (an integer) width - width of a pixel in physical scale units height - height of a pixel in physical scale units (width and height are doubles) png_set_sCAL_s(png_ptr, info_ptr, unit, width, height) unit - physical scale units (an integer) width - width of a pixel in physical scale units height - height of a pixel in physical scale units (width and height are strings like "2.54") png_set_unknown_chunks(png_ptr, info_ptr, &unknowns, num_unknowns) unknowns - array of png_unknown_chunk structures holding unknown chunks unknowns[i].name - name of unknown chunk unknowns[i].data - data of unknown chunk unknowns[i].size - size of unknown chunk's data unknowns[i].location - position to write chunk in file 0: do not write chunk PNG_HAVE_IHDR: before PLTE PNG_HAVE_PLTE: before IDAT PNG_AFTER_IDAT: after IDAT The "location" member is set automatically according to what part of the output file has already been written. You can change its value after calling png_set_unknown_chunks() as demonstrated in pngtest.c. Within each of the "locations", the chunks are sequenced according to their position in the structure (that is, the value of "i", which is the order in which the chunk was either read from the input file or defined with png_set_unknown_chunks). A quick word about text and num_text. text is an array of png_text structures. num_text is the number of valid structures in the array. Each png_text structure holds a language code, a keyword, a text value, and a compression type. The compression types have the same valid numbers as the compression types of the image data. Currently, the only valid number is zero. However, you can store text either compressed or uncompressed, unlike images, which always have to be compressed. So if you don't want the text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE. Because tEXt and zTXt chunks don't have a language field, if you specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt any language code or translated keyword will not be written out. Until text gets around 1000 bytes, it is not worth compressing it. After the text has been written out to the file, the compression type is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR, so that it isn't written out again at the end (in case you are calling png_write_end() with the same struct. The keywords that are given in the PNG Specification are: Title Short (one line) title or caption for image Author Name of image's creator Description Description of image (possibly long) Copyright Copyright notice Creation Time Time of original image creation (usually RFC 1123 format, see below) Software Software used to create the image Disclaimer Legal disclaimer Warning Warning of nature of content Source Device used to create the image Comment Miscellaneous comment; conversion from other image format The keyword-text pairs work like this. Keywords should be short simple descriptions of what the comment is about. Some typical keywords are found in the PNG specification, as is some recommendations on keywords. You can repeat keywords in a file. You can even write some text before the image and some after. For example, you may want to put a description of the image before the image, but leave the disclaimer until after, so viewers working over modem connections don't have to wait for the disclaimer to go over the modem before they start seeing the image. Finally, keywords should be full words, not abbreviations. Keywords and text are in the ISO 8859-1 (Latin-1) character set (a superset of regular ASCII) and can not contain NUL characters, and should not contain control or other unprintable characters. To make the comments widely readable, stick with basic ASCII, and avoid machine specific character set extensions like the IBM-PC character set. The keyword must be present, but you can leave off the text string on non-compressed pairs. Compressed pairs must have a text string, as only the text string is compressed anyway, so the compression would be meaningless. PNG supports modification time via the png_time structure. Two conversion routines are provided, png_convert_from_time_t() for time_t and png_convert_from_struct_tm() for struct tm. The time_t routine uses gmtime(). You don't have to use either of these, but if you wish to fill in the png_time structure directly, you should provide the time in universal time (GMT) if possible instead of your local time. Note that the year number is the full year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and that months start with 1. If you want to store the time of the original image creation, you should use a plain tEXt chunk with the "Creation Time" keyword. This is necessary because the "creation time" of a PNG image is somewhat vague, depending on whether you mean the PNG file, the time the image was created in a non-PNG format, a still photo from which the image was scanned, or possibly the subject matter itself. In order to facilitate machine-readable dates, it is recommended that the "Creation Time" tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"), although this isn't a requirement. Unlike the tIME chunk, the "Creation Time" tEXt chunk is not expected to be automatically changed by the software. To facilitate the use of RFC 1123 dates, a function png_convert_to_rfc1123(png_timep) is provided to convert from PNG time to an RFC 1123 format string. Writing unknown chunks You can use the png_set_unknown_chunks function to queue up chunks for writing. You give it a chunk name, raw data, and a size; that's all there is to it. The chunks will be written by the next following png_write_info_before_PLTE, png_write_info, or png_write_end function. Any chunks previously read into the info structure's unknown-chunk list will also be written out in a sequence that satisfies the PNG specification's ordering rules. The high-level write interface At this point there are two ways to proceed; through the high-level write interface, or through a sequence of low-level write operations. You can use the high-level interface if your image data is present in the info structure. All defined output transformations are permitted, enabled by the following masks. PNG_TRANSFORM_IDENTITY No transformation PNG_TRANSFORM_PACKING Pack 1, 2 and 4-bit samples PNG_TRANSFORM_PACKSWAP Change order of packed pixels to LSB first PNG_TRANSFORM_INVERT_MONO Invert monochrome images PNG_TRANSFORM_SHIFT Normalize pixels to the sBIT depth PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA to BGRA PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA to AG PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity to transparency PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples PNG_TRANSFORM_STRIP_FILLER Strip out filler bytes. If you have valid image data in the info structure (you can use png_set_rows() to put image data in the info structure), simply do this: png_write_png(png_ptr, info_ptr, png_transforms, NULL) where png_transforms is an integer containing the logical OR of some set of transformation flags. This call is equivalent to png_write_info(), followed the set of transformations indicated by the transform mask, then png_write_image(), and finally png_write_end(). (The final parameter of this call is not yet used. Someday it might point to transformation parameters required by some future output transform.) You must use png_transforms and not call any png_set_transform() functions when you use png_write_png(). The low-level write interface If you are going the low-level route instead, you are now ready to write all the file information up to the actual image data. You do this with a call to png_write_info(). png_write_info(png_ptr, info_ptr); Note that there is one transformation you may need to do before png_write_info(). In PNG files, the alpha channel in an image is the level of opacity. If your data is supplied as a level of transparency, you can invert the alpha channel before you write it, so that 0 is fully transparent and 255 (in 8-bit or paletted images) or 65535 (in 16-bit images) is fully opaque, with png_set_invert_alpha(png_ptr); This must appear before png_write_info() instead of later with the other transformations because in the case of paletted images the tRNS chunk data has to be inverted before the tRNS chunk is written. If your image is not a paletted image, the tRNS data (which in such cases represents a single color to be rendered as transparent) won't need to be changed, and you can safely do this transformation after your png_write_info() call. If you need to write a private chunk that you want to appear before the PLTE chunk when PLTE is present, you can write the PNG info in two steps, and insert code to write your own chunk between them: png_write_info_before_PLTE(png_ptr, info_ptr); png_set_unknown_chunks(png_ptr, info_ptr, ...); png_write_info(png_ptr, info_ptr); After you've written the file information, you can set up the library to handle any special transformations of the image data. The various ways to transform the data will be described in the order that they should occur. This is important, as some of these change the color type and/or bit depth of the data, and some others only work on certain color types and bit depths. Even though each transformation checks to see if it has data that it can do something with, you should make sure to only enable a transformation if it will be valid for the data. For example, don't swap red and blue on grayscale data. PNG files store RGB pixels packed into 3 or 6 bytes. This code tells the library to strip input data that has 4 or 8 bytes per pixel down to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2 bytes per pixel). png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); where the 0 is unused, and the location is either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel is stored XRGB or RGBX. PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as they can, resulting in, for example, 8 pixels per byte for 1 bit files. If the data is supplied at 1 pixel per byte, use this code, which will correctly pack the pixels into a single byte: png_set_packing(png_ptr); PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If your data is of another bit depth, you can write an sBIT chunk into the file so that decoders can recover the original data if desired. /* Set the true bit depth of the image data */ if (color_type & PNG_COLOR_MASK_COLOR) { sig_bit.red = true_bit_depth; sig_bit.green = true_bit_depth; sig_bit.blue = true_bit_depth; } else { sig_bit.gray = true_bit_depth; } if (color_type & PNG_COLOR_MASK_ALPHA) { sig_bit.alpha = true_bit_depth; } png_set_sBIT(png_ptr, info_ptr, &sig_bit); If the data is stored in the row buffer in a bit depth other than one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG), this will scale the values to appear to be the correct bit depth as is required by PNG. png_set_shift(png_ptr, &sig_bit); PNG files store 16 bit pixels in network byte order (big-endian, ie. most significant bits first). This code would be used if they are supplied the other way (little-endian, i.e. least significant bits first, the way PCs store them): if (bit_depth > 8) png_set_swap(png_ptr); If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you need to change the order the pixels are packed into bytes, you can use: if (bit_depth < 8) png_set_packswap(png_ptr); PNG files store 3 color pixels in red, green, blue order. This code would be used if they are supplied as blue, green, red: png_set_bgr(png_ptr); PNG files describe monochrome as black being zero and white being one. This code would be used if the pixels are supplied with this reversed (black being one and white being zero): png_set_invert_mono(png_ptr); Finally, you can write your own transformation function if none of the existing ones meets your needs. This is done by setting a callback with png_set_write_user_transform_fn(png_ptr, write_transform_fn); You must supply the function void write_transform_fn(png_ptr ptr, row_info_ptr row_info, png_bytep data) See pngtest.c for a working example. Your function will be called before any of the other transformations are processed. You can also set up a pointer to a user structure for use by your callback function. png_set_user_transform_info(png_ptr, user_ptr, 0, 0); The user_channels and user_depth parameters of this function are ignored when writing; you can set them to zero as shown. You can retrieve the pointer via the function png_get_user_transform_ptr(). For example: voidp write_user_transform_ptr = png_get_user_transform_ptr(png_ptr); It is possible to have libpng flush any pending output, either manually, or automatically after a certain number of lines have been written. To flush the output stream a single time call: png_write_flush(png_ptr); and to have libpng flush the output stream periodically after a certain number of scanlines have been written, call: png_set_flush(png_ptr, nrows); Note that the distance between rows is from the last time png_write_flush() was called, or the first row of the image if it has never been called. So if you write 50 lines, and then png_set_flush 25, it will flush the output on the next scanline, and every 25 lines thereafter, unless png_write_flush() is called before 25 more lines have been written. If nrows is too small (less than about 10 lines for a 640 pixel wide RGB image) the image compression may decrease noticeably (although this may be acceptable for real-time applications). Infrequent flushing will only degrade the compression performance by a few percent over images that do not use flushing. Writing the image data That's it for the transformations. Now you can write the image data. The simplest way to do this is in one function call. If you have the whole image in memory, you can just call png_write_image() and libpng will write the image. You will need to pass in an array of pointers to each row. This function automatically handles interlacing, so you don't need to call png_set_interlace_handling() or call this function multiple times, or any of that other stuff necessary with png_write_rows(). png_write_image(png_ptr, row_pointers); where row_pointers is: png_byte *row_pointers[height]; You can point to void or char or whatever you use for pixels. If you don't want to write the whole image at once, you can use png_write_rows() instead. If the file is not interlaced, this is simple: png_write_rows(png_ptr, row_pointers, number_of_rows); row_pointers is the same as in the png_write_image() call. If you are just writing one row at a time, you can do this with a single row_pointer instead of an array of row_pointers: png_bytep row_pointer = row; png_write_row(png_ptr, row_pointer); When the file is interlaced, things can get a good deal more complicated. The only currently (as of the PNG Specification version 1.2, dated July 1999) defined interlacing scheme for PNG files is the "Adam7" interlace scheme, that breaks down an image into seven smaller images of varying size. libpng will build these images for you, or you can do them yourself. If you want to build them yourself, see the PNG specification for details of which pixels to write when. If you don't want libpng to handle the interlacing details, just use png_set_interlace_handling() and call png_write_rows() the correct number of times to write all seven sub-images. If you want libpng to build the sub-images, call this before you start writing any rows: number_of_passes = png_set_interlace_handling(png_ptr); This will return the number of passes needed. Currently, this is seven, but may change if another interlace type is added. Then write the complete image number_of_passes times. png_write_rows(png_ptr, row_pointers, number_of_rows); As some of these rows are not used, and thus return immediately, you may want to read about interlacing in the PNG specification, and only update the rows that are actually used. Finishing a sequential write After you are finished writing the image, you should finish writing the file. If you are interested in writing comments or time, you should pass an appropriately filled png_info pointer. If you are not interested, you can pass NULL. png_write_end(png_ptr, info_ptr); When you are done, you can free all memory used by libpng like this: png_destroy_write_struct(&png_ptr, &info_ptr); It is also possible to individually free the info_ptr members that point to libpng-allocated storage with the following function: png_free_data(png_ptr, info_ptr, mask, seq) mask - identifies data to be freed, a mask containing the logical OR of one or more of PNG_FREE_PLTE, PNG_FREE_TRNS, PNG_FREE_HIST, PNG_FREE_ICCP, PNG_FREE_PCAL, PNG_FREE_ROWS, PNG_FREE_SCAL, PNG_FREE_SPLT, PNG_FREE_TEXT, PNG_FREE_UNKN, or simply PNG_FREE_ALL seq - sequence number of item to be freed (-1 for all items) This function may be safely called when the relevant storage has already been freed, or has not yet been allocated, or was allocated by the user and not by libpng, and will in those cases do nothing. The "seq" parameter is ignored if only one item of the selected data type, such as PLTE, is allowed. If "seq" is not -1, and multiple items are allowed for the data type identified in the mask, such as text or sPLT, only the n'th item in the structure is freed, where n is "seq". If you allocated data such as a palette that you passed in to libpng with png_set_*, you must not free it until just before the call to png_destroy_write_struct(). The default behavior is only to free data that was allocated internally by libpng. This can be changed, so that libpng will not free the data, or so that it will free data that was allocated by the user with png_malloc() or png_zalloc() and passed in via a png_set_*() function, with png_data_freer(png_ptr, info_ptr, freer, mask) mask - which data elements are affected same choices as in png_free_data() freer - one of PNG_DESTROY_WILL_FREE_DATA PNG_SET_WILL_FREE_DATA PNG_USER_WILL_FREE_DATA For example, to transfer responsibility for some data from a read structure to a write structure, you could use png_data_freer(read_ptr, read_info_ptr, PNG_USER_WILL_FREE_DATA, PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) png_data_freer(write_ptr, write_info_ptr, PNG_DESTROY_WILL_FREE_DATA, PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) thereby briefly reassigning responsibility for freeing to the user but immediately afterwards reassigning it once more to the write_destroy function. Having done this, it would then be safe to destroy the read structure and continue to use the PLTE, tRNS, and hIST data in the write structure. This function only affects data that has already been allocated. You can call this function before calling after the png_set_*() functions to control whether the user or png_destroy_*() is supposed to free the data. When the user assumes responsibility for libpng-allocated data, the application must use png_free() to free it, and when the user transfers responsibility to libpng for data that the user has allocated, the user must have used png_malloc() or png_zalloc() to allocate it. If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword separately, do not transfer responsibility for freeing text_ptr to libpng, because when libpng fills a png_text structure it combines these members with the key member, and png_free_data() will free only text_ptr.key. Similarly, if you transfer responsibility for free'ing text_ptr from libpng to your application, your application must not separately free those members. For a more compact example of writing a PNG image, see the file example.c. V. Modifying/Customizing libpng: There are three issues here. The first is changing how libpng does standard things like memory allocation, input/output, and error handling. The second deals with more complicated things like adding new chunks, adding new transformations, and generally changing how libpng works. Both of those are compile-time issues; that is, they are generally determined at the time the code is written, and there is rarely a need to provide the user with a means of changing them. The third is a run-time issue: choosing between and/or tuning one or more alternate versions of computationally intensive routines; specifically, optimized assembly-language (and therefore compiler- and platform-dependent) versions. Memory allocation, input/output, and error handling All of the memory allocation, input/output, and error handling in libpng goes through callbacks that are user-settable. The default routines are in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively. To change these functions, call the appropriate png_set_*_fn() function. Memory allocation is done through the functions png_malloc() and png_free(). These currently just call the standard C functions. If your pointers can't access more then 64K at a time, you will want to set MAXSEG_64K in zlib.h. Since it is unlikely that the method of handling memory allocation on a platform will change between applications, these functions must be modified in the library at compile time. If you prefer to use a different method of allocating and freeing data, you can use png_create_read_struct_2() or png_create_write_struct_2() to register your own functions as described above. These functions also provide a void pointer that can be retrieved via mem_ptr=png_get_mem_ptr(png_ptr); Your replacement memory functions must have prototypes as follows: png_voidp malloc_fn(png_structp png_ptr, png_size_t size); void free_fn(png_structp png_ptr, png_voidp ptr); Your malloc_fn() must return NULL in case of failure. The png_malloc() function will normally call png_error() if it receives a NULL from the system memory allocator or from your replacement malloc_fn(). Input/Output in libpng is done through png_read() and png_write(), which currently just call fread() and fwrite(). The FILE * is stored in png_struct and is initialized via png_init_io(). If you wish to change the method of I/O, the library supplies callbacks that you can set through the function png_set_read_fn() and png_set_write_fn() at run time, instead of calling the png_init_io() function. These functions also provide a void pointer that can be retrieved via the function png_get_io_ptr(). For example: png_set_read_fn(png_structp read_ptr, voidp read_io_ptr, png_rw_ptr read_data_fn) png_set_write_fn(png_structp write_ptr, voidp write_io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn); voidp read_io_ptr = png_get_io_ptr(read_ptr); voidp write_io_ptr = png_get_io_ptr(write_ptr); The replacement I/O functions must have prototypes as follows: void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length); void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length); void user_flush_data(png_structp png_ptr); Supplying NULL for the read, write, or flush functions sets them back to using the default C stream functions. It is an error to read from a write stream, and vice versa. Error handling in libpng is done through png_error() and png_warning(). Errors handled through png_error() are fatal, meaning that png_error() should never return to its caller. Currently, this is handled via setjmp() and longjmp() (unless you have compiled libpng with PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()), but you could change this to do things like exit() if you should wish. On non-fatal errors, png_warning() is called to print a warning message, and then control returns to the calling code. By default png_error() and png_warning() print a message on stderr via fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined (because you don't want the messages) or PNG_NO_STDIO defined (because fprintf() isn't available). If you wish to change the behavior of the error functions, you will need to set up your own message callbacks. These functions are normally supplied at the time that the png_struct is created. It is also possible to redirect errors and warnings to your own replacement functions after png_create_*_struct() has been called by calling: png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn); png_voidp error_ptr = png_get_error_ptr(png_ptr); If NULL is supplied for either error_fn or warning_fn, then the libpng default function will be used, calling fprintf() and/or longjmp() if a problem is encountered. The replacement error functions should have parameters as follows: void user_error_fn(png_structp png_ptr, png_const_charp error_msg); void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg); The motivation behind using setjmp() and longjmp() is the C++ throw and catch exception handling methods. This makes the code much easier to write, as there is no need to check every return code of every function call. However, there are some uncertainties about the status of local variables after a longjmp, so the user may want to be careful about doing anything after setjmp returns non-zero besides returning itself. Consult your compiler documentation for more details. For an alternative approach, you may wish to use the "cexcept" facility (see http://cexcept.sourceforge.net). Custom chunks If you need to read or write custom chunks, you may need to get deeper into the libpng code. The library now has mechanisms for storing and writing chunks of unknown type; you can even declare callbacks for custom chunks. Hoewver, this may not be good enough if the library code itself needs to know about interactions between your chunk and existing `intrinsic' chunks. If you need to write a new intrinsic chunk, first read the PNG specification. Acquire a first level of understanding of how it works. Pay particular attention to the sections that describe chunk names, and look at how other chunks were designed, so you can do things similarly. Second, check out the sections of libpng that read and write chunks. Try to find a chunk that is similar to yours and use it as a template. More details can be found in the comments inside the code. It is best to handle unknown chunks in a generic method, via callback functions, instead of by modifying libpng functions. If you wish to write your own transformation for the data, look through the part of the code that does the transformations, and check out some of the simpler ones to get an idea of how they work. Try to find a similar transformation to the one you want to add and copy off of it. More details can be found in the comments inside the code itself. Configuring for 16 bit platforms You will want to look into zconf.h to tell zlib (and thus libpng) that it cannot allocate more then 64K at a time. Even if you can, the memory won't be accessible. So limit zlib and libpng to 64K by defining MAXSEG_64K. Configuring for DOS For DOS users who only have access to the lower 640K, you will have to limit zlib's memory usage via a png_set_compression_mem_level() call. See zlib.h or zconf.h in the zlib library for more information. Configuring for Medium Model Libpng's support for medium model has been tested on most of the popular compilers. Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets defined, and FAR gets defined to far in pngconf.h, and you should be all set. Everything in the library (except for zlib's structure) is expecting far data. You must use the typedefs with the p or pp on the end for pointers (or at least look at them and be careful). Make note that the rows of data are defined as png_bytepp, which is an unsigned char far * far *. Configuring for gui/windowing platforms: You will need to write new error and warning functions that use the GUI interface, as described previously, and set them to be the error and warning functions at the time that png_create_*_struct() is called, in order to have them available during the structure initialization. They can be changed later via png_set_error_fn(). On some compilers, you may also have to change the memory allocators (png_malloc, etc.). Configuring for compiler xxx: All includes for libpng are in pngconf.h. If you need to add/change/delete an include, this is the place to do it. The includes that are not needed outside libpng are protected by the PNG_INTERNAL definition, which is only defined for those routines inside libpng itself. The files in libpng proper only include png.h, which includes pngconf.h. Configuring zlib: There are special functions to configure the compression. Perhaps the most useful one changes the compression level, which currently uses input compression values in the range 0 - 9. The library normally uses the default compression level (Z_DEFAULT_COMPRESSION = 6). Tests have shown that for a large majority of images, compression values in the range 3-6 compress nearly as well as higher levels, and do so much faster. For online applications it may be desirable to have maximum speed (Z_BEST_SPEED = 1). With versions of zlib after v0.99, you can also specify no compression (Z_NO_COMPRESSION = 0), but this would create files larger than just storing the raw bitmap. You can specify the compression level by calling: png_set_compression_level(png_ptr, level); Another useful one is to reduce the memory level used by the library. The memory level defaults to 8, but it can be lowered if you are short on memory (running DOS, for example, where you only have 640K). Note that the memory level does have an effect on compression; among other things, lower levels will result in sections of incompressible data being emitted in smaller stored blocks, with a correspondingly larger relative overhead of up to 15% in the worst case. png_set_compression_mem_level(png_ptr, level); The other functions are for configuring zlib. They are not recommended for normal use and may result in writing an invalid PNG file. See zlib.h for more information on what these mean. png_set_compression_strategy(png_ptr, strategy); png_set_compression_window_bits(png_ptr, window_bits); png_set_compression_method(png_ptr, method); png_set_compression_buffer_size(png_ptr, size); Controlling row filtering If you want to control whether libpng uses filtering or not, which filters are used, and how it goes about picking row filters, you can call one of these functions. The selection and configuration of row filters can have a significant impact on the size and encoding speed and a somewhat lesser impact on the decoding speed of an image. Filtering is enabled by default for RGB and grayscale images (with and without alpha), but not for paletted images nor for any images with bit depths less than 8 bits/pixel. The 'method' parameter sets the main filtering method, which is currently only '0' in the PNG 1.2 specification. The 'filters' parameter sets which filter(s), if any, should be used for each scanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS to turn filtering on and off, respectively. Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB, PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise ORed together with '|' to specify one or more filters to use. These filters are described in more detail in the PNG specification. If you intend to change the filter type during the course of writing the image, you should start with flags set for all of the filters you intend to use so that libpng can initialize its internal structures appropriately for all of the filter types. (Note that this means the first row must always be adaptively filtered, because libpng currently does not allocate the filter buffers until png_write_row() is called for the first time.) filters = PNG_FILTER_NONE | PNG_FILTER_SUB PNG_FILTER_UP | PNG_FILTER_AVE | PNG_FILTER_PAETH | PNG_ALL_FILTERS; png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, filters); The second parameter can also be PNG_INTRAPIXEL_DIFFERENCING if you are writing a PNG to be embedded in a MNG datastream. This parameter must be the same as the value of filter_method used in png_set_IHDR(). It is also possible to influence how libpng chooses from among the available filters. This is done in one or both of two ways - by telling it how important it is to keep the same filter for successive rows, and by telling it the relative computational costs of the filters. double weights[3] = {1.5, 1.3, 1.1}, costs[PNG_FILTER_VALUE_LAST] = {1.0, 1.3, 1.3, 1.5, 1.7}; png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_WEIGHTED, 3, weights, costs); The weights are multiplying factors that indicate to libpng that the row filter should be the same for successive rows unless another row filter is that many times better than the previous filter. In the above example, if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a "sum of absolute differences" 1.5 x 1.3 times higher than other filters and still be chosen, while the NONE filter could have a sum 1.1 times higher than other filters and still be chosen. Unspecified weights are taken to be 1.0, and the specified weights should probably be declining like those above in order to emphasize recent filters over older filters. The filter costs specify for each filter type a relative decoding cost to be considered when selecting row filters. This means that filters with higher costs are less likely to be chosen over filters with lower costs, unless their "sum of absolute differences" is that much smaller. The costs do not necessarily reflect the exact computational speeds of the various filters, since this would unduly influence the final image size. Note that the numbers above were invented purely for this example and are given only to help explain the function usage. Little testing has been done to find optimum values for either the costs or the weights. Removing unwanted object code There are a bunch of #define's in pngconf.h that control what parts of libpng are compiled. All the defines end in _SUPPORTED. If you are never going to use a capability, you can change the #define to #undef before recompiling libpng and save yourself code and data space, or you can turn off individual capabilities with defines that begin with PNG_NO_. You can also turn all of the transforms and ancillary chunk capabilities off en masse with compiler directives that define PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS, or all four, along with directives to turn on any of the capabilities that you do want. The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable the extra transformations but still leave the library fully capable of reading and writing PNG files with all known public chunks Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive produces a library that is incapable of reading or writing ancillary chunks. If you are not using the progressive reading capability, you can turn that off with PNG_NO_PROGRESSIVE_READ (don't confuse this with the INTERLACING capability, which you'll still have). All the reading and writing specific code are in separate files, so the linker should only grab the files it needs. However, if you want to make sure, or if you are building a stand alone library, all the reading files start with pngr and all the writing files start with pngw. The files that don't match either (like png.c, pngtrans.c, etc.) are used for both reading and writing, and always need to be included. The progressive reader is in pngpread.c If you are creating or distributing a dynamically linked library (a .so or DLL file), you should not remove or disable any parts of the library, as this will cause applications linked with different versions of the library to fail if they call functions not available in your library. The size of the library itself should not be an issue, because only those sections that are actually used will be loaded into memory. Requesting debug printout The macro definition PNG_DEBUG can be used to request debugging printout. Set it to an integer value in the range 0 to 3. Higher numbers result in increasing amounts of debugging information. The information is printed to the "stderr" file, unless another file name is specified in the PNG_DEBUG_FILE macro definition. When PNG_DEBUG > 0, the following functions (macros) become available: png_debug(level, message) png_debug1(level, message, p1) png_debug2(level, message, p1, p2) in which "level" is compared to PNG_DEBUG to decide whether to print the message, "message" is the formatted string to be printed, and p1 and p2 are parameters that are to be embedded in the string according to printf-style formatting directives. For example, png_debug1(2, "foo=%d\n", foo); is expanded to if(PNG_DEBUG > 2) fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo); When PNG_DEBUG is defined but is zero, the macros aren't defined, but you can still use PNG_DEBUG to control your own debugging: #ifdef PNG_DEBUG fprintf(stderr, ... #endif When PNG_DEBUG = 1, the macros are defined, but only png_debug statements having level = 0 will be printed. There aren't any such statements in this version of libpng, but if you insert some they will be printed. VI. Runtime optimization A new feature in libpng 1.2.0 is the ability to dynamically switch between standard and optimized versions of some routines. Currently these are limited to three computationally intensive tasks when reading PNG files: decoding row filters, expanding interlacing, and combining interlaced or transparent row data with previous row data. Currently the optimized versions are available only for x86 (Intel, AMD, etc.) platforms with MMX support, though this may change in future versions. (For example, the non-MMX assembler optimizations for zlib might become similarly runtime-selectable in future releases, in which case libpng could be extended to support them. Alternatively, the compile-time choice of floating-point versus integer routines for gamma correction might become runtime-selectable.) Because such optimizations tend to be very platform- and compiler-dependent, both in how they are written and in how they perform, the new runtime code in libpng has been written to allow programs to query, enable, and disable either specific optimizations or all such optimizations. For example, to enable all possible optimizations (bearing in mind that some "optimizations" may actually run more slowly in rare cases): #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) png_uint_32 mask, flags; flags = png_get_asm_flags(png_ptr); mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); png_set_asm_flags(png_ptr, flags | mask); #endif To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ by itself when calling png_get_asm_flagmask(); similarly for optimizing only writing. To disable all optimizations: #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) flags = png_get_asm_flags(png_ptr); mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); png_set_asm_flags(png_ptr, flags & ~mask); #endif To enable or disable only MMX-related features, use png_get_mmx_flagmask() in place of png_get_asm_flagmask(). The mmx version takes one additional parameter: #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) int selection = PNG_SELECT_READ | PNG_SELECT_WRITE; int compilerID; mask = png_get_mmx_flagmask(selection, &compilerID); #endif On return, compilerID will indicate which version of the MMX assembler optimizations was compiled. Currently two flavors exist: Microsoft Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2). On non-x86 platforms or on systems compiled without MMX optimizations, a value of -1 is used. Note that both png_get_asm_flagmask() and png_get_mmx_flagmask() return all valid, settable optimization bits for the version of the library that's currently in use. In the case of shared (dynamically linked) libraries, this may include optimizations that did not exist at the time the code was written and compiled. It is also possible, of course, to enable only known, specific optimizations; for example: #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ | PNG_ASM_FLAG_MMX_READ_INTERLACE \ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; png_set_asm_flags(png_ptr, flags); #endif This method would enable only the MMX read-optimizations available at the time of libpng 1.2.0's release, regardless of whether a later version of the DLL were actually being used. (Also note that these functions did not exist in versions older than 1.2.0, so any attempt to run a dynamically linked app on such an older version would fail.) To determine whether the processor supports MMX instructions at all, use the png_mmx_support() function: #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) mmxsupport = png_mmx_support(); #endif It returns -1 if MMX support is not compiled into libpng, 0 if MMX code is compiled but MMX is not supported by the processor, or 1 if MMX support is fully available. Note that png_mmx_support(), png_get_mmx_flagmask(), and png_get_asm_flagmask() all may be called without allocating and ini- tializing any PNG structures (for example, as part of a usage screen or "about" box). The following code can be used to prevent an application from using the thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK defined: #if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \ && defined(PNG_THREAD_UNSAFE_OK) /* Disable thread-unsafe features of pnggccrd */ if (png_access_version() >= 10200) { png_uint_32 mmx_disable_mask = 0; png_uint_32 asm_flags; mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ); asm_flags = png_get_asm_flags(png_ptr); png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask); } #endif For more extensive examples of runtime querying, enabling and disabling of optimized features, see contrib/gregbook/readpng2.c in the libpng source-code distribution. VII. MNG support The MNG specification (available at http://www.libpng.org/pub/mng) allows certain extensions to PNG for PNG images that are embedded in MNG datastreams. Libpng can support some of these extensions. To enable them, use the png_permit_mng_features() function: feature_set = png_permit_mng_features(png_ptr, mask) mask is a png_uint_32 containing the logical OR of the features you want to enable. These include PNG_FLAG_MNG_EMPTY_PLTE PNG_FLAG_MNG_FILTER_64 PNG_ALL_MNG_FEATURES feature_set is a png_uint_32 that is the logical AND of your mask with the set of MNG features that is supported by the version of libpng that you are using. It is an error to use this function when reading or writing a standalone PNG file with the PNG 8-byte signature. The PNG datastream must be wrapped in a MNG datastream. As a minimum, it must have the MNG 8-byte signature and the MHDR and MEND chunks. Libpng does not provide support for these or any other MNG chunks; your application must provide its own support for them. You may wish to consider using libmng (available at http://www.libmng.com) instead. VIII. Changes to Libpng from version 0.88 It should be noted that versions of libpng later than 0.96 are not distributed by the original libpng author, Guy Schalnat, nor by Andreas Dilger, who had taken over from Guy during 1996 and 1997, and distributed versions 0.89 through 0.96, but rather by another member of the original PNG Group, Glenn Randers-Pehrson. Guy and Andreas are still alive and well, but they have moved on to other things. The old libpng functions png_read_init(), png_write_init(), png_info_init(), png_read_destroy(), and png_write_destroy() have been moved to PNG_INTERNAL in version 0.95 to discourage their use. These functions will be removed from libpng version 2.0.0. The preferred method of creating and initializing the libpng structures is via the png_create_read_struct(), png_create_write_struct(), and png_create_info_struct() because they isolate the size of the structures from the application, allow version error checking, and also allow the use of custom error handling routines during the initialization, which the old functions do not. The functions png_read_destroy() and png_write_destroy() do not actually free the memory that libpng allocated for these structs, but just reset the data structures, so they can be used instead of png_destroy_read_struct() and png_destroy_write_struct() if you feel there is too much system overhead allocating and freeing the png_struct for each image read. Setting the error callbacks via png_set_message_fn() before png_read_init() as was suggested in libpng-0.88 is no longer supported because this caused applications that do not use custom error functions to fail if the png_ptr was not initialized to zero. It is still possible to set the error callbacks AFTER png_read_init(), or to change them with png_set_error_fn(), which is essentially the same function, but with a new name to force compilation errors with applications that try to use the old method. Starting with version 1.0.7, you can find out which version of the library you are using at run-time: png_uint_32 libpng_vn = png_access_version_number(); The number libpng_vn is constructed from the major version, minor version with leading zero, and release number with leading zero, (e.g., libpng_vn for version 1.0.7 is 10007). You can also check which version of png.h you used when compiling your application: png_uint_32 application_vn = PNG_LIBPNG_VER; IX. Y2K Compliance in libpng December 3, 2004 Since the PNG Development group is an ad-hoc body, we can't make an official declaration. This is your unofficial assurance that libpng from version 0.71 and upward through 1.2.8 are Y2K compliant. It is my belief that earlier versions were also Y2K compliant. Libpng only has three year fields. One is a 2-byte unsigned integer that will hold years up to 65535. The other two hold the date in text format, and will hold years up to 9999. The integer is "png_uint_16 year" in png_time_struct. The strings are "png_charp time_buffer" in png_struct and "near_time_buffer", which is a local character string in png.c. There are seven time-related functions: png_convert_to_rfc_1123() in png.c (formerly png_convert_to_rfc_1152() in error) png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c png_convert_from_time_t() in pngwrite.c png_get_tIME() in pngget.c png_handle_tIME() in pngrutil.c, called in pngread.c png_set_tIME() in pngset.c png_write_tIME() in pngwutil.c, called in pngwrite.c All appear to handle dates properly in a Y2K environment. The png_convert_from_time_t() function calls gmtime() to convert from system clock time, which returns (year - 1900), which we properly convert to the full 4-digit year. There is a possibility that applications using libpng are not passing 4-digit years into the png_convert_to_rfc_1123() function, or that they are incorrectly passing only a 2-digit year instead of "year - 1900" into the png_convert_from_struct_tm() function, but this is not under our control. The libpng documentation has always stated that it works with 4-digit years, and the APIs have been documented as such. The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned integer to hold the year, and can hold years as large as 65535. zlib, upon which libpng depends, is also Y2K compliant. It contains no date-related code. Glenn Randers-Pehrson libpng maintainer PNG Development Group syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngwutil.c0000664000175000017500000024344610777447272021211 0ustar evanevan /* pngwutil.c - utilities to write a PNG file * * libpng version 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ #define PNG_INTERNAL #include "png.h" #ifdef PNG_WRITE_SUPPORTED /* Place a 32-bit number into a buffer in PNG byte order. We work * with unsigned numbers for convenience, although one supported * ancillary chunk uses signed (two's complement) numbers. */ void /* PRIVATE */ png_save_uint_32(png_bytep buf, png_uint_32 i) { buf[0] = (png_byte)((i >> 24) & 0xff); buf[1] = (png_byte)((i >> 16) & 0xff); buf[2] = (png_byte)((i >> 8) & 0xff); buf[3] = (png_byte)(i & 0xff); } #if defined(PNG_WRITE_pCAL_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) /* The png_save_int_32 function assumes integers are stored in two's * complement format. If this isn't the case, then this routine needs to * be modified to write data in two's complement format. */ void /* PRIVATE */ png_save_int_32(png_bytep buf, png_int_32 i) { buf[0] = (png_byte)((i >> 24) & 0xff); buf[1] = (png_byte)((i >> 16) & 0xff); buf[2] = (png_byte)((i >> 8) & 0xff); buf[3] = (png_byte)(i & 0xff); } #endif /* Place a 16-bit number into a buffer in PNG byte order. * The parameter is declared unsigned int, not png_uint_16, * just to avoid potential problems on pre-ANSI C compilers. */ void /* PRIVATE */ png_save_uint_16(png_bytep buf, unsigned int i) { buf[0] = (png_byte)((i >> 8) & 0xff); buf[1] = (png_byte)(i & 0xff); } /* Write a PNG chunk all at once. The type is an array of ASCII characters * representing the chunk name. The array must be at least 4 bytes in * length, and does not need to be null terminated. To be safe, pass the * pre-defined chunk names here, and if you need a new one, define it * where the others are defined. The length is the length of the data. * All the data must be present. If that is not possible, use the * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() * functions instead. */ void PNGAPI png_write_chunk(png_structp png_ptr, png_bytep chunk_name, png_bytep data, png_size_t length) { png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length); png_write_chunk_data(png_ptr, data, length); png_write_chunk_end(png_ptr); } /* Write the start of a PNG chunk. The type is the chunk type. * The total_length is the sum of the lengths of all the data you will be * passing in png_write_chunk_data(). */ void PNGAPI png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name, png_uint_32 length) { png_byte buf[4]; png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length); /* write the length */ png_save_uint_32(buf, length); png_write_data(png_ptr, buf, (png_size_t)4); /* write the chunk name */ png_write_data(png_ptr, chunk_name, (png_size_t)4); /* reset the crc and run it over the chunk name */ png_reset_crc(png_ptr); png_calculate_crc(png_ptr, chunk_name, (png_size_t)4); } /* Write the data of a PNG chunk started with png_write_chunk_start(). * Note that multiple calls to this function are allowed, and that the * sum of the lengths from these calls *must* add up to the total_length * given to png_write_chunk_start(). */ void PNGAPI png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length) { /* write the data, and run the CRC over it */ if (data != NULL && length > 0) { png_calculate_crc(png_ptr, data, length); png_write_data(png_ptr, data, length); } } /* Finish a chunk started with png_write_chunk_start(). */ void PNGAPI png_write_chunk_end(png_structp png_ptr) { png_byte buf[4]; /* write the crc */ png_save_uint_32(buf, png_ptr->crc); png_write_data(png_ptr, buf, (png_size_t)4); } /* Simple function to write the signature. If we have already written * the magic bytes of the signature, or more likely, the PNG stream is * being embedded into another stream and doesn't need its own signature, * we should call png_set_sig_bytes() to tell libpng how many of the * bytes have already been written. */ void /* PRIVATE */ png_write_sig(png_structp png_ptr) { png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; /* write the rest of the 8 byte signature */ png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], (png_size_t)8 - png_ptr->sig_bytes); if(png_ptr->sig_bytes < 3) png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; } #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED) /* * This pair of functions encapsulates the operation of (a) compressing a * text string, and (b) issuing it later as a series of chunk data writes. * The compression_state structure is shared context for these functions * set up by the caller in order to make the whole mess thread-safe. */ typedef struct { char *input; /* the uncompressed input data */ int input_len; /* its length */ int num_output_ptr; /* number of output pointers used */ int max_output_ptr; /* size of output_ptr */ png_charpp output_ptr; /* array of pointers to output */ } compression_state; /* compress given text into storage in the png_ptr structure */ static int /* PRIVATE */ png_text_compress(png_structp png_ptr, png_charp text, png_size_t text_len, int compression, compression_state *comp) { int ret; comp->num_output_ptr = comp->max_output_ptr = 0; comp->output_ptr = NULL; comp->input = NULL; /* we may just want to pass the text right through */ if (compression == PNG_TEXT_COMPRESSION_NONE) { comp->input = text; comp->input_len = text_len; return((int)text_len); } if (compression >= PNG_TEXT_COMPRESSION_LAST) { #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) char msg[50]; sprintf(msg, "Unknown compression type %d", compression); png_warning(png_ptr, msg); #else png_warning(png_ptr, "Unknown compression type"); #endif } /* We can't write the chunk until we find out how much data we have, * which means we need to run the compressor first and save the * output. This shouldn't be a problem, as the vast majority of * comments should be reasonable, but we will set up an array of * malloc'd pointers to be sure. * * If we knew the application was well behaved, we could simplify this * greatly by assuming we can always malloc an output buffer large * enough to hold the compressed text ((1001 * text_len / 1000) + 12) * and malloc this directly. The only time this would be a bad idea is * if we can't malloc more than 64K and we have 64K of random input * data, or if the input string is incredibly large (although this * wouldn't cause a failure, just a slowdown due to swapping). */ /* set up the compression buffers */ png_ptr->zstream.avail_in = (uInt)text_len; png_ptr->zstream.next_in = (Bytef *)text; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf; /* this is the same compression loop as in png_write_row() */ do { /* compress the data */ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); if (ret != Z_OK) { /* error */ if (png_ptr->zstream.msg != NULL) png_error(png_ptr, png_ptr->zstream.msg); else png_error(png_ptr, "zlib error"); } /* check to see if we need more room */ if (!(png_ptr->zstream.avail_out)) { /* make sure the output array has room */ if (comp->num_output_ptr >= comp->max_output_ptr) { int old_max; old_max = comp->max_output_ptr; comp->max_output_ptr = comp->num_output_ptr + 4; if (comp->output_ptr != NULL) { png_charpp old_ptr; old_ptr = comp->output_ptr; comp->output_ptr = (png_charpp)png_malloc(png_ptr, (png_uint_32)(comp->max_output_ptr * png_sizeof (png_charpp))); png_memcpy(comp->output_ptr, old_ptr, old_max * png_sizeof (png_charp)); png_free(png_ptr, old_ptr); } else comp->output_ptr = (png_charpp)png_malloc(png_ptr, (png_uint_32)(comp->max_output_ptr * png_sizeof (png_charp))); } /* save the data */ comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, png_ptr->zbuf_size); comp->num_output_ptr++; /* and reset the buffer */ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_ptr->zstream.next_out = png_ptr->zbuf; } /* continue until we don't have any more to compress */ } while (png_ptr->zstream.avail_in); /* finish the compression */ do { /* tell zlib we are finished */ ret = deflate(&png_ptr->zstream, Z_FINISH); if (ret == Z_OK) { /* check to see if we need more room */ if (!(png_ptr->zstream.avail_out)) { /* check to make sure our output array has room */ if (comp->num_output_ptr >= comp->max_output_ptr) { int old_max; old_max = comp->max_output_ptr; comp->max_output_ptr = comp->num_output_ptr + 4; if (comp->output_ptr != NULL) { png_charpp old_ptr; old_ptr = comp->output_ptr; /* This could be optimized to realloc() */ comp->output_ptr = (png_charpp)png_malloc(png_ptr, (png_uint_32)(comp->max_output_ptr * png_sizeof (png_charpp))); png_memcpy(comp->output_ptr, old_ptr, old_max * png_sizeof (png_charp)); png_free(png_ptr, old_ptr); } else comp->output_ptr = (png_charpp)png_malloc(png_ptr, (png_uint_32)(comp->max_output_ptr * png_sizeof (png_charp))); } /* save off the data */ comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, png_ptr->zbuf_size); comp->num_output_ptr++; /* and reset the buffer pointers */ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_ptr->zstream.next_out = png_ptr->zbuf; } } else if (ret != Z_STREAM_END) { /* we got an error */ if (png_ptr->zstream.msg != NULL) png_error(png_ptr, png_ptr->zstream.msg); else png_error(png_ptr, "zlib error"); } } while (ret != Z_STREAM_END); /* text length is number of buffers plus last buffer */ text_len = png_ptr->zbuf_size * comp->num_output_ptr; if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out; return((int)text_len); } /* ship the compressed text out via chunk writes */ static void /* PRIVATE */ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) { int i; /* handle the no-compression case */ if (comp->input) { png_write_chunk_data(png_ptr, (png_bytep)comp->input, (png_size_t)comp->input_len); return; } /* write saved output buffers, if any */ for (i = 0; i < comp->num_output_ptr; i++) { png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i], png_ptr->zbuf_size); png_free(png_ptr, comp->output_ptr[i]); comp->output_ptr[i]=NULL; } if (comp->max_output_ptr != 0) png_free(png_ptr, comp->output_ptr); comp->output_ptr=NULL; /* write anything left in zbuf */ if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) png_write_chunk_data(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - png_ptr->zstream.avail_out); /* reset zlib for another zTXt/iTXt or image data */ deflateReset(&png_ptr->zstream); png_ptr->zstream.data_type = Z_BINARY; } #endif /* Write the IHDR chunk, and update the png_struct with the necessary * information. Note that the rest of this code depends upon this * information being correct. */ void /* PRIVATE */ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, int compression_type, int filter_type, int interlace_type) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_IHDR; #endif png_byte buf[13]; /* buffer to store the IHDR info */ png_debug(1, "in png_write_IHDR\n"); /* Check that we have valid input data from the application info */ switch (color_type) { case PNG_COLOR_TYPE_GRAY: switch (bit_depth) { case 1: case 2: case 4: case 8: case 16: png_ptr->channels = 1; break; default: png_error(png_ptr,"Invalid bit depth for grayscale image"); } break; case PNG_COLOR_TYPE_RGB: if (bit_depth != 8 && bit_depth != 16) png_error(png_ptr, "Invalid bit depth for RGB image"); png_ptr->channels = 3; break; case PNG_COLOR_TYPE_PALETTE: switch (bit_depth) { case 1: case 2: case 4: case 8: png_ptr->channels = 1; break; default: png_error(png_ptr, "Invalid bit depth for paletted image"); } break; case PNG_COLOR_TYPE_GRAY_ALPHA: if (bit_depth != 8 && bit_depth != 16) png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); png_ptr->channels = 2; break; case PNG_COLOR_TYPE_RGB_ALPHA: if (bit_depth != 8 && bit_depth != 16) png_error(png_ptr, "Invalid bit depth for RGBA image"); png_ptr->channels = 4; break; default: png_error(png_ptr, "Invalid image color type specified"); } if (compression_type != PNG_COMPRESSION_TYPE_BASE) { png_warning(png_ptr, "Invalid compression type specified"); compression_type = PNG_COMPRESSION_TYPE_BASE; } /* Write filter_method 64 (intrapixel differencing) only if * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and * 2. Libpng did not write a PNG signature (this filter_method is only * used in PNG datastreams that are embedded in MNG datastreams) and * 3. The application called png_permit_mng_features with a mask that * included PNG_FLAG_MNG_FILTER_64 and * 4. The filter_method is 64 and * 5. The color_type is RGB or RGBA */ if ( #if defined(PNG_MNG_FEATURES_SUPPORTED) !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) && (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && #endif filter_type != PNG_FILTER_TYPE_BASE) { png_warning(png_ptr, "Invalid filter type specified"); filter_type = PNG_FILTER_TYPE_BASE; } #ifdef PNG_WRITE_INTERLACING_SUPPORTED if (interlace_type != PNG_INTERLACE_NONE && interlace_type != PNG_INTERLACE_ADAM7) { png_warning(png_ptr, "Invalid interlace type specified"); interlace_type = PNG_INTERLACE_ADAM7; } #else interlace_type=PNG_INTERLACE_NONE; #endif /* save off the relevent information */ png_ptr->bit_depth = (png_byte)bit_depth; png_ptr->color_type = (png_byte)color_type; png_ptr->interlaced = (png_byte)interlace_type; #if defined(PNG_MNG_FEATURES_SUPPORTED) png_ptr->filter_type = (png_byte)filter_type; #endif png_ptr->compression_type = (png_byte)compression_type; png_ptr->width = width; png_ptr->height = height; png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); /* set the usr info, so any transformations can modify it */ png_ptr->usr_width = png_ptr->width; png_ptr->usr_bit_depth = png_ptr->bit_depth; png_ptr->usr_channels = png_ptr->channels; /* pack the header information into the buffer */ png_save_uint_32(buf, width); png_save_uint_32(buf + 4, height); buf[8] = (png_byte)bit_depth; buf[9] = (png_byte)color_type; buf[10] = (png_byte)compression_type; buf[11] = (png_byte)filter_type; buf[12] = (png_byte)interlace_type; /* write the chunk */ png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13); /* initialize zlib with PNG info */ png_ptr->zstream.zalloc = png_zalloc; png_ptr->zstream.zfree = png_zfree; png_ptr->zstream.opaque = (voidpf)png_ptr; if (!(png_ptr->do_filter)) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || png_ptr->bit_depth < 8) png_ptr->do_filter = PNG_FILTER_NONE; else png_ptr->do_filter = PNG_ALL_FILTERS; } if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)) { if (png_ptr->do_filter != PNG_FILTER_NONE) png_ptr->zlib_strategy = Z_FILTERED; else png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY; } if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL)) png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL)) png_ptr->zlib_mem_level = 8; if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS)) png_ptr->zlib_window_bits = 15; if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD)) png_ptr->zlib_method = 8; deflateInit2(&png_ptr->zstream, png_ptr->zlib_level, png_ptr->zlib_method, png_ptr->zlib_window_bits, png_ptr->zlib_mem_level, png_ptr->zlib_strategy); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; /* libpng is not interested in zstream.data_type */ /* set it to a predefined value, to avoid its evaluation inside zlib */ png_ptr->zstream.data_type = Z_BINARY; png_ptr->mode = PNG_HAVE_IHDR; } /* write the palette. We are careful not to trust png_color to be in the * correct order for PNG, so people can redefine it to any convenient * structure. */ void /* PRIVATE */ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_PLTE; #endif png_uint_32 i; png_colorp pal_ptr; png_byte buf[3]; png_debug(1, "in png_write_PLTE\n"); if (( #if defined(PNG_MNG_FEATURES_SUPPORTED) !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && #endif num_pal == 0) || num_pal > 256) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { png_error(png_ptr, "Invalid number of colors in palette"); } else { png_warning(png_ptr, "Invalid number of colors in palette"); return; } } if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) { png_warning(png_ptr, "Ignoring request to write a PLTE chunk in grayscale PNG"); return; } png_ptr->num_palette = (png_uint_16)num_pal; png_debug1(3, "num_palette = %d\n", png_ptr->num_palette); png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, num_pal * 3); #ifndef PNG_NO_POINTER_INDEXING for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) { buf[0] = pal_ptr->red; buf[1] = pal_ptr->green; buf[2] = pal_ptr->blue; png_write_chunk_data(png_ptr, buf, (png_size_t)3); } #else /* This is a little slower but some buggy compilers need to do this instead */ pal_ptr=palette; for (i = 0; i < num_pal; i++) { buf[0] = pal_ptr[i].red; buf[1] = pal_ptr[i].green; buf[2] = pal_ptr[i].blue; png_write_chunk_data(png_ptr, buf, (png_size_t)3); } #endif png_write_chunk_end(png_ptr); png_ptr->mode |= PNG_HAVE_PLTE; } /* write an IDAT chunk */ void /* PRIVATE */ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_IDAT; #endif png_debug(1, "in png_write_IDAT\n"); /* Optimize the CMF field in the zlib stream. */ /* This hack of the zlib stream is compliant to the stream specification. */ if (!(png_ptr->mode & PNG_HAVE_IDAT) && png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) { unsigned int z_cmf = data[0]; /* zlib compression method and flags */ if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) { /* Avoid memory underflows and multiplication overflows. */ /* The conditions below are practically always satisfied; however, they still must be checked. */ if (length >= 2 && png_ptr->height < 16384 && png_ptr->width < 16384) { png_uint_32 uncompressed_idat_size = png_ptr->height * ((png_ptr->width * png_ptr->channels * png_ptr->bit_depth + 15) >> 3); unsigned int z_cinfo = z_cmf >> 4; unsigned int half_z_window_size = 1 << (z_cinfo + 7); while (uncompressed_idat_size <= half_z_window_size && half_z_window_size >= 256) { z_cinfo--; half_z_window_size >>= 1; } z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); if (data[0] != (png_byte)z_cmf) { data[0] = (png_byte)z_cmf; data[1] &= 0xe0; data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f); } } } else png_error(png_ptr, "Invalid zlib compression method or flags in IDAT"); } png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length); png_ptr->mode |= PNG_HAVE_IDAT; } /* write an IEND chunk */ void /* PRIVATE */ png_write_IEND(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_IEND; #endif png_debug(1, "in png_write_IEND\n"); png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL, (png_size_t)0); png_ptr->mode |= PNG_HAVE_IEND; } #if defined(PNG_WRITE_gAMA_SUPPORTED) /* write a gAMA chunk */ #ifdef PNG_FLOATING_POINT_SUPPORTED void /* PRIVATE */ png_write_gAMA(png_structp png_ptr, double file_gamma) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_gAMA; #endif png_uint_32 igamma; png_byte buf[4]; png_debug(1, "in png_write_gAMA\n"); /* file_gamma is saved in 1/100,000ths */ igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5); png_save_uint_32(buf, igamma); png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); } #endif #ifdef PNG_FIXED_POINT_SUPPORTED void /* PRIVATE */ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_gAMA; #endif png_byte buf[4]; png_debug(1, "in png_write_gAMA\n"); /* file_gamma is saved in 1/100,000ths */ png_save_uint_32(buf, (png_uint_32)file_gamma); png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); } #endif #endif #if defined(PNG_WRITE_sRGB_SUPPORTED) /* write a sRGB chunk */ void /* PRIVATE */ png_write_sRGB(png_structp png_ptr, int srgb_intent) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_sRGB; #endif png_byte buf[1]; png_debug(1, "in png_write_sRGB\n"); if(srgb_intent >= PNG_sRGB_INTENT_LAST) png_warning(png_ptr, "Invalid sRGB rendering intent specified"); buf[0]=(png_byte)srgb_intent; png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1); } #endif #if defined(PNG_WRITE_iCCP_SUPPORTED) /* write an iCCP chunk */ void /* PRIVATE */ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, png_charp profile, int profile_len) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_iCCP; #endif png_size_t name_len; png_charp new_name; compression_state comp; png_debug(1, "in png_write_iCCP\n"); if (name == NULL || (name_len = png_check_keyword(png_ptr, name, &new_name)) == 0) { png_warning(png_ptr, "Empty keyword in iCCP chunk"); return; } if (compression_type != PNG_COMPRESSION_TYPE_BASE) png_warning(png_ptr, "Unknown compression type in iCCP chunk"); if (profile == NULL) profile_len = 0; if (profile_len) profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp); /* make sure we include the NULL after the name and the compression type */ png_write_chunk_start(png_ptr, (png_bytep)png_iCCP, (png_uint_32)name_len+profile_len+2); new_name[name_len+1]=0x00; png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2); if (profile_len) png_write_compressed_data_out(png_ptr, &comp); png_write_chunk_end(png_ptr); png_free(png_ptr, new_name); } #endif #if defined(PNG_WRITE_sPLT_SUPPORTED) /* write a sPLT chunk */ void /* PRIVATE */ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_sPLT; #endif png_size_t name_len; png_charp new_name; png_byte entrybuf[10]; int entry_size = (spalette->depth == 8 ? 6 : 10); int palette_size = entry_size * spalette->nentries; png_sPLT_entryp ep; #ifdef PNG_NO_POINTER_INDEXING int i; #endif png_debug(1, "in png_write_sPLT\n"); if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr, spalette->name, &new_name))==0) { png_warning(png_ptr, "Empty keyword in sPLT chunk"); return; } /* make sure we include the NULL after the name */ png_write_chunk_start(png_ptr, (png_bytep)png_sPLT, (png_uint_32)(name_len + 2 + palette_size)); png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1); png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1); /* loop through each palette entry, writing appropriately */ #ifndef PNG_NO_POINTER_INDEXING for (ep = spalette->entries; epentries+spalette->nentries; ep++) { if (spalette->depth == 8) { entrybuf[0] = (png_byte)ep->red; entrybuf[1] = (png_byte)ep->green; entrybuf[2] = (png_byte)ep->blue; entrybuf[3] = (png_byte)ep->alpha; png_save_uint_16(entrybuf + 4, ep->frequency); } else { png_save_uint_16(entrybuf + 0, ep->red); png_save_uint_16(entrybuf + 2, ep->green); png_save_uint_16(entrybuf + 4, ep->blue); png_save_uint_16(entrybuf + 6, ep->alpha); png_save_uint_16(entrybuf + 8, ep->frequency); } png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); } #else ep=spalette->entries; for (i=0; i>spalette->nentries; i++) { if (spalette->depth == 8) { entrybuf[0] = (png_byte)ep[i].red; entrybuf[1] = (png_byte)ep[i].green; entrybuf[2] = (png_byte)ep[i].blue; entrybuf[3] = (png_byte)ep[i].alpha; png_save_uint_16(entrybuf + 4, ep[i].frequency); } else { png_save_uint_16(entrybuf + 0, ep[i].red); png_save_uint_16(entrybuf + 2, ep[i].green); png_save_uint_16(entrybuf + 4, ep[i].blue); png_save_uint_16(entrybuf + 6, ep[i].alpha); png_save_uint_16(entrybuf + 8, ep[i].frequency); } png_write_chunk_data(png_ptr, entrybuf, entry_size); } #endif png_write_chunk_end(png_ptr); png_free(png_ptr, new_name); } #endif #if defined(PNG_WRITE_sBIT_SUPPORTED) /* write the sBIT chunk */ void /* PRIVATE */ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_sBIT; #endif png_byte buf[4]; png_size_t size; png_debug(1, "in png_write_sBIT\n"); /* make sure we don't depend upon the order of PNG_COLOR_8 */ if (color_type & PNG_COLOR_MASK_COLOR) { png_byte maxbits; maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 : png_ptr->usr_bit_depth); if (sbit->red == 0 || sbit->red > maxbits || sbit->green == 0 || sbit->green > maxbits || sbit->blue == 0 || sbit->blue > maxbits) { png_warning(png_ptr, "Invalid sBIT depth specified"); return; } buf[0] = sbit->red; buf[1] = sbit->green; buf[2] = sbit->blue; size = 3; } else { if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth) { png_warning(png_ptr, "Invalid sBIT depth specified"); return; } buf[0] = sbit->gray; size = 1; } if (color_type & PNG_COLOR_MASK_ALPHA) { if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) { png_warning(png_ptr, "Invalid sBIT depth specified"); return; } buf[size++] = sbit->alpha; } png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size); } #endif #if defined(PNG_WRITE_cHRM_SUPPORTED) /* write the cHRM chunk */ #ifdef PNG_FLOATING_POINT_SUPPORTED void /* PRIVATE */ png_write_cHRM(png_structp png_ptr, double white_x, double white_y, double red_x, double red_y, double green_x, double green_y, double blue_x, double blue_y) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_cHRM; #endif png_byte buf[32]; png_uint_32 itemp; png_debug(1, "in png_write_cHRM\n"); /* each value is saved in 1/100,000ths */ if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 || white_x + white_y > 1.0) { png_warning(png_ptr, "Invalid cHRM white point specified"); #if !defined(PNG_NO_CONSOLE_IO) fprintf(stderr,"white_x=%f, white_y=%f\n",white_x, white_y); #endif return; } itemp = (png_uint_32)(white_x * 100000.0 + 0.5); png_save_uint_32(buf, itemp); itemp = (png_uint_32)(white_y * 100000.0 + 0.5); png_save_uint_32(buf + 4, itemp); if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 || red_x + red_y > 1.0) { png_warning(png_ptr, "Invalid cHRM red point specified"); return; } itemp = (png_uint_32)(red_x * 100000.0 + 0.5); png_save_uint_32(buf + 8, itemp); itemp = (png_uint_32)(red_y * 100000.0 + 0.5); png_save_uint_32(buf + 12, itemp); if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 || green_x + green_y > 1.0) { png_warning(png_ptr, "Invalid cHRM green point specified"); return; } itemp = (png_uint_32)(green_x * 100000.0 + 0.5); png_save_uint_32(buf + 16, itemp); itemp = (png_uint_32)(green_y * 100000.0 + 0.5); png_save_uint_32(buf + 20, itemp); if (blue_x < 0 || blue_x > 0.8 || blue_y < 0 || blue_y > 0.8 || blue_x + blue_y > 1.0) { png_warning(png_ptr, "Invalid cHRM blue point specified"); return; } itemp = (png_uint_32)(blue_x * 100000.0 + 0.5); png_save_uint_32(buf + 24, itemp); itemp = (png_uint_32)(blue_y * 100000.0 + 0.5); png_save_uint_32(buf + 28, itemp); png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); } #endif #ifdef PNG_FIXED_POINT_SUPPORTED void /* PRIVATE */ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, png_fixed_point blue_y) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_cHRM; #endif png_byte buf[32]; png_debug(1, "in png_write_cHRM\n"); /* each value is saved in 1/100,000ths */ if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L) { png_warning(png_ptr, "Invalid fixed cHRM white point specified"); #if !defined(PNG_NO_CONSOLE_IO) fprintf(stderr,"white_x=%ld, white_y=%ld\n",white_x, white_y); #endif return; } png_save_uint_32(buf, (png_uint_32)white_x); png_save_uint_32(buf + 4, (png_uint_32)white_y); if (red_x > 80000L || red_y > 80000L || red_x + red_y > 100000L) { png_warning(png_ptr, "Invalid cHRM fixed red point specified"); return; } png_save_uint_32(buf + 8, (png_uint_32)red_x); png_save_uint_32(buf + 12, (png_uint_32)red_y); if (green_x > 80000L || green_y > 80000L || green_x + green_y > 100000L) { png_warning(png_ptr, "Invalid fixed cHRM green point specified"); return; } png_save_uint_32(buf + 16, (png_uint_32)green_x); png_save_uint_32(buf + 20, (png_uint_32)green_y); if (blue_x > 80000L || blue_y > 80000L || blue_x + blue_y > 100000L) { png_warning(png_ptr, "Invalid fixed cHRM blue point specified"); return; } png_save_uint_32(buf + 24, (png_uint_32)blue_x); png_save_uint_32(buf + 28, (png_uint_32)blue_y); png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); } #endif #endif #if defined(PNG_WRITE_tRNS_SUPPORTED) /* write the tRNS chunk */ void /* PRIVATE */ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, int num_trans, int color_type) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_tRNS; #endif png_byte buf[6]; png_debug(1, "in png_write_tRNS\n"); if (color_type == PNG_COLOR_TYPE_PALETTE) { if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) { png_warning(png_ptr,"Invalid number of transparent colors specified"); return; } /* write the chunk out as it is */ png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans, (png_size_t)num_trans); } else if (color_type == PNG_COLOR_TYPE_GRAY) { /* one 16 bit value */ if(tran->gray >= (1 << png_ptr->bit_depth)) { png_warning(png_ptr, "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); return; } png_save_uint_16(buf, tran->gray); png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2); } else if (color_type == PNG_COLOR_TYPE_RGB) { /* three 16 bit values */ png_save_uint_16(buf, tran->red); png_save_uint_16(buf + 2, tran->green); png_save_uint_16(buf + 4, tran->blue); if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) { png_warning(png_ptr, "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); return; } png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6); } else { png_warning(png_ptr, "Can't write tRNS with an alpha channel"); } } #endif #if defined(PNG_WRITE_bKGD_SUPPORTED) /* write the background chunk */ void /* PRIVATE */ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_bKGD; #endif png_byte buf[6]; png_debug(1, "in png_write_bKGD\n"); if (color_type == PNG_COLOR_TYPE_PALETTE) { if ( #if defined(PNG_MNG_FEATURES_SUPPORTED) (png_ptr->num_palette || (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && #endif back->index > png_ptr->num_palette) { png_warning(png_ptr, "Invalid background palette index"); return; } buf[0] = back->index; png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1); } else if (color_type & PNG_COLOR_MASK_COLOR) { png_save_uint_16(buf, back->red); png_save_uint_16(buf + 2, back->green); png_save_uint_16(buf + 4, back->blue); if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) { png_warning(png_ptr, "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); return; } png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6); } else { if(back->gray >= (1 << png_ptr->bit_depth)) { png_warning(png_ptr, "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); return; } png_save_uint_16(buf, back->gray); png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2); } } #endif #if defined(PNG_WRITE_hIST_SUPPORTED) /* write the histogram */ void /* PRIVATE */ png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_hIST; #endif int i; png_byte buf[3]; png_debug(1, "in png_write_hIST\n"); if (num_hist > (int)png_ptr->num_palette) { png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist, png_ptr->num_palette); png_warning(png_ptr, "Invalid number of histogram entries specified"); return; } png_write_chunk_start(png_ptr, (png_bytep)png_hIST, (png_uint_32)(num_hist * 2)); for (i = 0; i < num_hist; i++) { png_save_uint_16(buf, hist[i]); png_write_chunk_data(png_ptr, buf, (png_size_t)2); } png_write_chunk_end(png_ptr); } #endif #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) /* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, * and if invalid, correct the keyword rather than discarding the entire * chunk. The PNG 1.0 specification requires keywords 1-79 characters in * length, forbids leading or trailing whitespace, multiple internal spaces, * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. * * The new_key is allocated to hold the corrected keyword and must be freed * by the calling routine. This avoids problems with trying to write to * static keywords without having to have duplicate copies of the strings. */ png_size_t /* PRIVATE */ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) { png_size_t key_len; png_charp kp, dp; int kflag; int kwarn=0; png_debug(1, "in png_check_keyword\n"); *new_key = NULL; if (key == NULL || (key_len = png_strlen(key)) == 0) { png_warning(png_ptr, "zero length keyword"); return ((png_size_t)0); } png_debug1(2, "Keyword to be checked is '%s'\n", key); *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2)); if (*new_key == NULL) { png_warning(png_ptr, "Out of memory while procesing keyword"); return ((png_size_t)0); } /* Replace non-printing characters with a blank and print a warning */ for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++) { if (*kp < 0x20 || (*kp > 0x7E && (png_byte)*kp < 0xA1)) { #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) char msg[40]; sprintf(msg, "invalid keyword character 0x%02X", *kp); png_warning(png_ptr, msg); #else png_warning(png_ptr, "invalid character in keyword"); #endif *dp = ' '; } else { *dp = *kp; } } *dp = '\0'; /* Remove any trailing white space. */ kp = *new_key + key_len - 1; if (*kp == ' ') { png_warning(png_ptr, "trailing spaces removed from keyword"); while (*kp == ' ') { *(kp--) = '\0'; key_len--; } } /* Remove any leading white space. */ kp = *new_key; if (*kp == ' ') { png_warning(png_ptr, "leading spaces removed from keyword"); while (*kp == ' ') { kp++; key_len--; } } png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp); /* Remove multiple internal spaces. */ for (kflag = 0, dp = *new_key; *kp != '\0'; kp++) { if (*kp == ' ' && kflag == 0) { *(dp++) = *kp; kflag = 1; } else if (*kp == ' ') { key_len--; kwarn=1; } else { *(dp++) = *kp; kflag = 0; } } *dp = '\0'; if(kwarn) png_warning(png_ptr, "extra interior spaces removed from keyword"); if (key_len == 0) { png_free(png_ptr, *new_key); *new_key=NULL; png_warning(png_ptr, "Zero length keyword"); } if (key_len > 79) { png_warning(png_ptr, "keyword length must be 1 - 79 characters"); new_key[79] = '\0'; key_len = 79; } return (key_len); } #endif #if defined(PNG_WRITE_tEXt_SUPPORTED) /* write a tEXt chunk */ void /* PRIVATE */ png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, png_size_t text_len) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_tEXt; #endif png_size_t key_len; png_charp new_key; png_debug(1, "in png_write_tEXt\n"); if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) { png_warning(png_ptr, "Empty keyword in tEXt chunk"); return; } if (text == NULL || *text == '\0') text_len = 0; else text_len = png_strlen(text); /* make sure we include the 0 after the key */ png_write_chunk_start(png_ptr, (png_bytep)png_tEXt, (png_uint_32)key_len+text_len+1); /* * We leave it to the application to meet PNG-1.0 requirements on the * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. */ png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1); if (text_len) png_write_chunk_data(png_ptr, (png_bytep)text, text_len); png_write_chunk_end(png_ptr); png_free(png_ptr, new_key); } #endif #if defined(PNG_WRITE_zTXt_SUPPORTED) /* write a compressed text chunk */ void /* PRIVATE */ png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, png_size_t text_len, int compression) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_zTXt; #endif png_size_t key_len; char buf[1]; png_charp new_key; compression_state comp; png_debug(1, "in png_write_zTXt\n"); if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) { png_warning(png_ptr, "Empty keyword in zTXt chunk"); return; } if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE) { png_write_tEXt(png_ptr, new_key, text, (png_size_t)0); png_free(png_ptr, new_key); return; } text_len = png_strlen(text); png_free(png_ptr, new_key); /* compute the compressed data; do it now for the length */ text_len = png_text_compress(png_ptr, text, text_len, compression, &comp); /* write start of chunk */ png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, (png_uint_32) (key_len+text_len+2)); /* write key */ png_write_chunk_data(png_ptr, (png_bytep)key, key_len + 1); buf[0] = (png_byte)compression; /* write compression */ png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1); /* write the compressed data */ png_write_compressed_data_out(png_ptr, &comp); /* close the chunk */ png_write_chunk_end(png_ptr); } #endif #if defined(PNG_WRITE_iTXt_SUPPORTED) /* write an iTXt chunk */ void /* PRIVATE */ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, png_charp lang, png_charp lang_key, png_charp text) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_iTXt; #endif png_size_t lang_len, key_len, lang_key_len, text_len; png_charp new_lang, new_key; png_byte cbuf[2]; compression_state comp; png_debug(1, "in png_write_iTXt\n"); if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) { png_warning(png_ptr, "Empty keyword in iTXt chunk"); return; } if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0) { png_warning(png_ptr, "Empty language field in iTXt chunk"); new_lang = NULL; lang_len = 0; } if (lang_key == NULL) lang_key_len = 0; else lang_key_len = png_strlen(lang_key); if (text == NULL) text_len = 0; else text_len = png_strlen(text); /* compute the compressed data; do it now for the length */ text_len = png_text_compress(png_ptr, text, text_len, compression-2, &comp); /* make sure we include the compression flag, the compression byte, * and the NULs after the key, lang, and lang_key parts */ png_write_chunk_start(png_ptr, (png_bytep)png_iTXt, (png_uint_32)( 5 /* comp byte, comp flag, terminators for key, lang and lang_key */ + key_len + lang_len + lang_key_len + text_len)); /* * We leave it to the application to meet PNG-1.0 requirements on the * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. */ png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1); /* set the compression flag */ if (compression == PNG_ITXT_COMPRESSION_NONE || \ compression == PNG_TEXT_COMPRESSION_NONE) cbuf[0] = 0; else /* compression == PNG_ITXT_COMPRESSION_zTXt */ cbuf[0] = 1; /* set the compression method */ cbuf[1] = 0; png_write_chunk_data(png_ptr, cbuf, 2); cbuf[0] = 0; png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf), lang_len + 1); png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), lang_key_len + 1); png_write_compressed_data_out(png_ptr, &comp); png_write_chunk_end(png_ptr); png_free(png_ptr, new_key); if (new_lang) png_free(png_ptr, new_lang); } #endif #if defined(PNG_WRITE_oFFs_SUPPORTED) /* write the oFFs chunk */ void /* PRIVATE */ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, int unit_type) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_oFFs; #endif png_byte buf[9]; png_debug(1, "in png_write_oFFs\n"); if (unit_type >= PNG_OFFSET_LAST) png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); png_save_int_32(buf, x_offset); png_save_int_32(buf + 4, y_offset); buf[8] = (png_byte)unit_type; png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9); } #endif #if defined(PNG_WRITE_pCAL_SUPPORTED) /* write the pCAL chunk (described in the PNG extensions document) */ void /* PRIVATE */ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, png_charp units, png_charpp params) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_pCAL; #endif png_size_t purpose_len, units_len, total_len; png_uint_32p params_len; png_byte buf[10]; png_charp new_purpose; int i; png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams); if (type >= PNG_EQUATION_LAST) png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1; png_debug1(3, "pCAL purpose length = %d\n", (int)purpose_len); units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); png_debug1(3, "pCAL units length = %d\n", (int)units_len); total_len = purpose_len + units_len + 10; params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams *png_sizeof(png_uint_32))); /* Find the length of each parameter, making sure we don't count the null terminator for the last parameter. */ for (i = 0; i < nparams; i++) { params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1); png_debug2(3, "pCAL parameter %d length = %lu\n", i, params_len[i]); total_len += (png_size_t)params_len[i]; } png_debug1(3, "pCAL total length = %d\n", (int)total_len); png_write_chunk_start(png_ptr, (png_bytep)png_pCAL, (png_uint_32)total_len); png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len); png_save_int_32(buf, X0); png_save_int_32(buf + 4, X1); buf[8] = (png_byte)type; buf[9] = (png_byte)nparams; png_write_chunk_data(png_ptr, buf, (png_size_t)10); png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len); png_free(png_ptr, new_purpose); for (i = 0; i < nparams; i++) { png_write_chunk_data(png_ptr, (png_bytep)params[i], (png_size_t)params_len[i]); } png_free(png_ptr, params_len); png_write_chunk_end(png_ptr); } #endif #if defined(PNG_WRITE_sCAL_SUPPORTED) /* write the sCAL chunk */ #if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) void /* PRIVATE */ png_write_sCAL(png_structp png_ptr, int unit, double width,double height) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_sCAL; #endif png_size_t total_len; char wbuf[32], hbuf[32]; png_byte bunit = unit; png_debug(1, "in png_write_sCAL\n"); #if defined(_WIN32_WCE) /* sprintf() function is not supported on WindowsCE */ { wchar_t wc_buf[32]; swprintf(wc_buf, TEXT("%12.12e"), width); WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, wbuf, 32, NULL, NULL); swprintf(wc_buf, TEXT("%12.12e"), height); WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, hbuf, 32, NULL, NULL); } #else sprintf(wbuf, "%12.12e", width); sprintf(hbuf, "%12.12e", height); #endif total_len = 1 + png_strlen(wbuf)+1 + png_strlen(hbuf); png_debug1(3, "sCAL total length = %d\n", (int)total_len); png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len); png_write_chunk_data(png_ptr, (png_bytep)&bunit, 1); png_write_chunk_data(png_ptr, (png_bytep)wbuf, png_strlen(wbuf)+1); png_write_chunk_data(png_ptr, (png_bytep)hbuf, png_strlen(hbuf)); png_write_chunk_end(png_ptr); } #else #ifdef PNG_FIXED_POINT_SUPPORTED void /* PRIVATE */ png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, png_charp height) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_sCAL; #endif png_size_t total_len; char wbuf[32], hbuf[32]; png_byte bunit = unit; png_debug(1, "in png_write_sCAL_s\n"); png_strcpy(wbuf,(const char *)width); png_strcpy(hbuf,(const char *)height); total_len = 1 + png_strlen(wbuf)+1 + png_strlen(hbuf); png_debug1(3, "sCAL total length = %d\n", total_len); png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len); png_write_chunk_data(png_ptr, (png_bytep)&bunit, 1); png_write_chunk_data(png_ptr, (png_bytep)wbuf, png_strlen(wbuf)+1); png_write_chunk_data(png_ptr, (png_bytep)hbuf, png_strlen(hbuf)); png_write_chunk_end(png_ptr); } #endif #endif #endif #if defined(PNG_WRITE_pHYs_SUPPORTED) /* write the pHYs chunk */ void /* PRIVATE */ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, int unit_type) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_pHYs; #endif png_byte buf[9]; png_debug(1, "in png_write_pHYs\n"); if (unit_type >= PNG_RESOLUTION_LAST) png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); png_save_uint_32(buf, x_pixels_per_unit); png_save_uint_32(buf + 4, y_pixels_per_unit); buf[8] = (png_byte)unit_type; png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9); } #endif #if defined(PNG_WRITE_tIME_SUPPORTED) /* Write the tIME chunk. Use either png_convert_from_struct_tm() * or png_convert_from_time_t(), or fill in the structure yourself. */ void /* PRIVATE */ png_write_tIME(png_structp png_ptr, png_timep mod_time) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_tIME; #endif png_byte buf[7]; png_debug(1, "in png_write_tIME\n"); if (mod_time->month > 12 || mod_time->month < 1 || mod_time->day > 31 || mod_time->day < 1 || mod_time->hour > 23 || mod_time->second > 60) { png_warning(png_ptr, "Invalid time specified for tIME chunk"); return; } png_save_uint_16(buf, mod_time->year); buf[2] = mod_time->month; buf[3] = mod_time->day; buf[4] = mod_time->hour; buf[5] = mod_time->minute; buf[6] = mod_time->second; png_write_chunk(png_ptr, (png_bytep)png_tIME, buf, (png_size_t)7); } #endif /* initializes the row writing capability of libpng */ void /* PRIVATE */ png_write_start_row(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* start of interlace block */ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* offset to next interlace block */ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* start of interlace block in the y direction */ int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* offset to next interlace block in the y direction */ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif png_size_t buf_size; png_debug(1, "in png_write_start_row\n"); buf_size = (png_size_t)(PNG_ROWBYTES( png_ptr->usr_channels*png_ptr->usr_bit_depth,png_ptr->width)+1); /* set up row buffer */ png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size); png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; /* set up filtering buffer, if using this filter */ if (png_ptr->do_filter & PNG_FILTER_SUB) { png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, (png_ptr->rowbytes + 1)); png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; } /* We only need to keep the previous row if we are using one of these. */ if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) { /* set up previous row buffer */ png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size); png_memset(png_ptr->prev_row, 0, buf_size); if (png_ptr->do_filter & PNG_FILTER_UP) { png_ptr->up_row = (png_bytep )png_malloc(png_ptr, (png_ptr->rowbytes + 1)); png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; } if (png_ptr->do_filter & PNG_FILTER_AVG) { png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, (png_ptr->rowbytes + 1)); png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; } if (png_ptr->do_filter & PNG_FILTER_PAETH) { png_ptr->paeth_row = (png_bytep )png_malloc(png_ptr, (png_ptr->rowbytes + 1)); png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; } } #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* if interlaced, we need to set up width and height of pass */ if (png_ptr->interlaced) { if (!(png_ptr->transformations & PNG_INTERLACE)) { png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - png_pass_ystart[0]) / png_pass_yinc[0]; png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 - png_pass_start[0]) / png_pass_inc[0]; } else { png_ptr->num_rows = png_ptr->height; png_ptr->usr_width = png_ptr->width; } } else #endif { png_ptr->num_rows = png_ptr->height; png_ptr->usr_width = png_ptr->width; } png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_ptr->zstream.next_out = png_ptr->zbuf; } /* Internal use only. Called when finished processing a row of data. */ void /* PRIVATE */ png_write_finish_row(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* start of interlace block */ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* offset to next interlace block */ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* start of interlace block in the y direction */ int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* offset to next interlace block in the y direction */ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif int ret; png_debug(1, "in png_write_finish_row\n"); /* next row */ png_ptr->row_number++; /* see if we are done */ if (png_ptr->row_number < png_ptr->num_rows) return; #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* if interlaced, go to next pass */ if (png_ptr->interlaced) { png_ptr->row_number = 0; if (png_ptr->transformations & PNG_INTERLACE) { png_ptr->pass++; } else { /* loop until we find a non-zero width or height pass */ do { png_ptr->pass++; if (png_ptr->pass >= 7) break; png_ptr->usr_width = (png_ptr->width + png_pass_inc[png_ptr->pass] - 1 - png_pass_start[png_ptr->pass]) / png_pass_inc[png_ptr->pass]; png_ptr->num_rows = (png_ptr->height + png_pass_yinc[png_ptr->pass] - 1 - png_pass_ystart[png_ptr->pass]) / png_pass_yinc[png_ptr->pass]; if (png_ptr->transformations & PNG_INTERLACE) break; } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); } /* reset the row above the image for the next pass */ if (png_ptr->pass < 7) { if (png_ptr->prev_row != NULL) png_memset(png_ptr->prev_row, 0, (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* png_ptr->usr_bit_depth,png_ptr->width))+1); return; } } #endif /* if we get here, we've just written the last row, so we need to flush the compressor */ do { /* tell the compressor we are done */ ret = deflate(&png_ptr->zstream, Z_FINISH); /* check for an error */ if (ret == Z_OK) { /* check to see if we need more room */ if (!(png_ptr->zstream.avail_out)) { png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; } } else if (ret != Z_STREAM_END) { if (png_ptr->zstream.msg != NULL) png_error(png_ptr, png_ptr->zstream.msg); else png_error(png_ptr, "zlib error"); } } while (ret != Z_STREAM_END); /* write any extra space */ if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) { png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - png_ptr->zstream.avail_out); } deflateReset(&png_ptr->zstream); png_ptr->zstream.data_type = Z_BINARY; } #if defined(PNG_WRITE_INTERLACING_SUPPORTED) /* Pick out the correct pixels for the interlace pass. * The basic idea here is to go through the row with a source * pointer and a destination pointer (sp and dp), and copy the * correct pixels for the pass. As the row gets compacted, * sp will always be >= dp, so we should never overwrite anything. * See the default: case for the easiest code to understand. */ void /* PRIVATE */ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) { #ifdef PNG_USE_LOCAL_ARRAYS /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* start of interlace block */ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* offset to next interlace block */ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; #endif png_debug(1, "in png_do_write_interlace\n"); /* we don't have to do anything on the last pass (6) */ #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL && pass < 6) #else if (pass < 6) #endif { /* each pixel depth is handled separately */ switch (row_info->pixel_depth) { case 1: { png_bytep sp; png_bytep dp; int shift; int d; int value; png_uint_32 i; png_uint_32 row_width = row_info->width; dp = row; d = 0; shift = 7; for (i = png_pass_start[pass]; i < row_width; i += png_pass_inc[pass]) { sp = row + (png_size_t)(i >> 3); value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; d |= (value << shift); if (shift == 0) { shift = 7; *dp++ = (png_byte)d; d = 0; } else shift--; } if (shift != 7) *dp = (png_byte)d; break; } case 2: { png_bytep sp; png_bytep dp; int shift; int d; int value; png_uint_32 i; png_uint_32 row_width = row_info->width; dp = row; shift = 6; d = 0; for (i = png_pass_start[pass]; i < row_width; i += png_pass_inc[pass]) { sp = row + (png_size_t)(i >> 2); value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; d |= (value << shift); if (shift == 0) { shift = 6; *dp++ = (png_byte)d; d = 0; } else shift -= 2; } if (shift != 6) *dp = (png_byte)d; break; } case 4: { png_bytep sp; png_bytep dp; int shift; int d; int value; png_uint_32 i; png_uint_32 row_width = row_info->width; dp = row; shift = 4; d = 0; for (i = png_pass_start[pass]; i < row_width; i += png_pass_inc[pass]) { sp = row + (png_size_t)(i >> 1); value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; d |= (value << shift); if (shift == 0) { shift = 4; *dp++ = (png_byte)d; d = 0; } else shift -= 4; } if (shift != 4) *dp = (png_byte)d; break; } default: { png_bytep sp; png_bytep dp; png_uint_32 i; png_uint_32 row_width = row_info->width; png_size_t pixel_bytes; /* start at the beginning */ dp = row; /* find out how many bytes each pixel takes up */ pixel_bytes = (row_info->pixel_depth >> 3); /* loop through the row, only looking at the pixels that matter */ for (i = png_pass_start[pass]; i < row_width; i += png_pass_inc[pass]) { /* find out where the original pixel is */ sp = row + (png_size_t)i * pixel_bytes; /* move the pixel */ if (dp != sp) png_memcpy(dp, sp, pixel_bytes); /* next pixel */ dp += pixel_bytes; } break; } } /* set new row width */ row_info->width = (row_info->width + png_pass_inc[pass] - 1 - png_pass_start[pass]) / png_pass_inc[pass]; row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); } } #endif /* This filters the row, chooses which filter to use, if it has not already * been specified by the application, and then writes the row out with the * chosen filter. */ #define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) #define PNG_HISHIFT 10 #define PNG_LOMASK ((png_uint_32)0xffffL) #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) void /* PRIVATE */ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) { png_bytep prev_row, best_row, row_buf; png_uint_32 mins, bpp; png_byte filter_to_do = png_ptr->do_filter; png_uint_32 row_bytes = row_info->rowbytes; #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) int num_p_filters = (int)png_ptr->num_prev_filters; #endif png_debug(1, "in png_write_find_filter\n"); /* find out how many bytes offset each pixel is */ bpp = (row_info->pixel_depth + 7) >> 3; prev_row = png_ptr->prev_row; best_row = row_buf = png_ptr->row_buf; mins = PNG_MAXSUM; /* The prediction method we use is to find which method provides the * smallest value when summing the absolute values of the distances * from zero, using anything >= 128 as negative numbers. This is known * as the "minimum sum of absolute differences" heuristic. Other * heuristics are the "weighted minimum sum of absolute differences" * (experimental and can in theory improve compression), and the "zlib * predictive" method (not implemented yet), which does test compressions * of lines using different filter methods, and then chooses the * (series of) filter(s) that give minimum compressed data size (VERY * computationally expensive). * * GRR 980525: consider also * (1) minimum sum of absolute differences from running average (i.e., * keep running sum of non-absolute differences & count of bytes) * [track dispersion, too? restart average if dispersion too large?] * (1b) minimum sum of absolute differences from sliding average, probably * with window size <= deflate window (usually 32K) * (2) minimum sum of squared differences from zero or running average * (i.e., ~ root-mean-square approach) */ /* We don't need to test the 'no filter' case if this is the only filter * that has been chosen, as it doesn't actually do anything to the data. */ if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE) { png_bytep rp; png_uint_32 sum = 0; png_uint_32 i; int v; for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) { v = *rp; sum += (v < 128) ? v : 256 - v; } #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { png_uint_32 sumhi, sumlo; int j; sumlo = sum & PNG_LOMASK; sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */ /* Reduce the sum if we match any of the previous rows */ for (j = 0; j < num_p_filters; j++) { if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) { sumlo = (sumlo * png_ptr->filter_weights[j]) >> PNG_WEIGHT_SHIFT; sumhi = (sumhi * png_ptr->filter_weights[j]) >> PNG_WEIGHT_SHIFT; } } /* Factor in the cost of this filter (this is here for completeness, * but it makes no sense to have a "cost" for the NONE filter, as * it has the minimum possible computational cost - none). */ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> PNG_COST_SHIFT; sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> PNG_COST_SHIFT; if (sumhi > PNG_HIMASK) sum = PNG_MAXSUM; else sum = (sumhi << PNG_HISHIFT) + sumlo; } #endif mins = sum; } /* sub filter */ if (filter_to_do == PNG_FILTER_SUB) /* it's the only filter so no testing is needed */ { png_bytep rp, lp, dp; png_uint_32 i; for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; i++, rp++, dp++) { *dp = *rp; } for (lp = row_buf + 1; i < row_bytes; i++, rp++, lp++, dp++) { *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); } best_row = png_ptr->sub_row; } else if (filter_to_do & PNG_FILTER_SUB) { png_bytep rp, dp, lp; png_uint_32 sum = 0, lmins = mins; png_uint_32 i; int v; #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* We temporarily increase the "minimum sum" by the factor we * would reduce the sum of this filter, so that we can do the * early exit comparison without scaling the sum each time. */ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; png_uint_32 lmhi, lmlo; lmlo = lmins & PNG_LOMASK; lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; for (j = 0; j < num_p_filters; j++) { if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) { lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> PNG_WEIGHT_SHIFT; lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> PNG_WEIGHT_SHIFT; } } lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> PNG_COST_SHIFT; lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> PNG_COST_SHIFT; if (lmhi > PNG_HIMASK) lmins = PNG_MAXSUM; else lmins = (lmhi << PNG_HISHIFT) + lmlo; } #endif for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; i++, rp++, dp++) { v = *dp = *rp; sum += (v < 128) ? v : 256 - v; } for (lp = row_buf + 1; i < row_bytes; i++, rp++, lp++, dp++) { v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); sum += (v < 128) ? v : 256 - v; if (sum > lmins) /* We are already worse, don't continue. */ break; } #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; png_uint_32 sumhi, sumlo; sumlo = sum & PNG_LOMASK; sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; for (j = 0; j < num_p_filters; j++) { if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) { sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >> PNG_WEIGHT_SHIFT; sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >> PNG_WEIGHT_SHIFT; } } sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> PNG_COST_SHIFT; sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> PNG_COST_SHIFT; if (sumhi > PNG_HIMASK) sum = PNG_MAXSUM; else sum = (sumhi << PNG_HISHIFT) + sumlo; } #endif if (sum < mins) { mins = sum; best_row = png_ptr->sub_row; } } /* up filter */ if (filter_to_do == PNG_FILTER_UP) { png_bytep rp, dp, pp; png_uint_32 i; for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, pp = prev_row + 1; i < row_bytes; i++, rp++, pp++, dp++) { *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); } best_row = png_ptr->up_row; } else if (filter_to_do & PNG_FILTER_UP) { png_bytep rp, dp, pp; png_uint_32 sum = 0, lmins = mins; png_uint_32 i; int v; #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; png_uint_32 lmhi, lmlo; lmlo = lmins & PNG_LOMASK; lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; for (j = 0; j < num_p_filters; j++) { if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) { lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> PNG_WEIGHT_SHIFT; lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> PNG_WEIGHT_SHIFT; } } lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> PNG_COST_SHIFT; lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> PNG_COST_SHIFT; if (lmhi > PNG_HIMASK) lmins = PNG_MAXSUM; else lmins = (lmhi << PNG_HISHIFT) + lmlo; } #endif for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, pp = prev_row + 1; i < row_bytes; i++) { v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); sum += (v < 128) ? v : 256 - v; if (sum > lmins) /* We are already worse, don't continue. */ break; } #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; png_uint_32 sumhi, sumlo; sumlo = sum & PNG_LOMASK; sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; for (j = 0; j < num_p_filters; j++) { if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) { sumlo = (sumlo * png_ptr->filter_weights[j]) >> PNG_WEIGHT_SHIFT; sumhi = (sumhi * png_ptr->filter_weights[j]) >> PNG_WEIGHT_SHIFT; } } sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> PNG_COST_SHIFT; sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> PNG_COST_SHIFT; if (sumhi > PNG_HIMASK) sum = PNG_MAXSUM; else sum = (sumhi << PNG_HISHIFT) + sumlo; } #endif if (sum < mins) { mins = sum; best_row = png_ptr->up_row; } } /* avg filter */ if (filter_to_do == PNG_FILTER_AVG) { png_bytep rp, dp, pp, lp; png_uint_32 i; for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, pp = prev_row + 1; i < bpp; i++) { *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); } for (lp = row_buf + 1; i < row_bytes; i++) { *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff); } best_row = png_ptr->avg_row; } else if (filter_to_do & PNG_FILTER_AVG) { png_bytep rp, dp, pp, lp; png_uint_32 sum = 0, lmins = mins; png_uint_32 i; int v; #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; png_uint_32 lmhi, lmlo; lmlo = lmins & PNG_LOMASK; lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; for (j = 0; j < num_p_filters; j++) { if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG) { lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> PNG_WEIGHT_SHIFT; lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> PNG_WEIGHT_SHIFT; } } lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> PNG_COST_SHIFT; lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> PNG_COST_SHIFT; if (lmhi > PNG_HIMASK) lmins = PNG_MAXSUM; else lmins = (lmhi << PNG_HISHIFT) + lmlo; } #endif for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, pp = prev_row + 1; i < bpp; i++) { v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); sum += (v < 128) ? v : 256 - v; } for (lp = row_buf + 1; i < row_bytes; i++) { v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff); sum += (v < 128) ? v : 256 - v; if (sum > lmins) /* We are already worse, don't continue. */ break; } #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; png_uint_32 sumhi, sumlo; sumlo = sum & PNG_LOMASK; sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; for (j = 0; j < num_p_filters; j++) { if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) { sumlo = (sumlo * png_ptr->filter_weights[j]) >> PNG_WEIGHT_SHIFT; sumhi = (sumhi * png_ptr->filter_weights[j]) >> PNG_WEIGHT_SHIFT; } } sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> PNG_COST_SHIFT; sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> PNG_COST_SHIFT; if (sumhi > PNG_HIMASK) sum = PNG_MAXSUM; else sum = (sumhi << PNG_HISHIFT) + sumlo; } #endif if (sum < mins) { mins = sum; best_row = png_ptr->avg_row; } } /* Paeth filter */ if (filter_to_do == PNG_FILTER_PAETH) { png_bytep rp, dp, pp, cp, lp; png_uint_32 i; for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, pp = prev_row + 1; i < bpp; i++) { *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); } for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) { int a, b, c, pa, pb, pc, p; b = *pp++; c = *cp++; a = *lp++; p = b - c; pc = a - c; #ifdef PNG_USE_ABS pa = abs(p); pb = abs(pc); pc = abs(p + pc); #else pa = p < 0 ? -p : p; pb = pc < 0 ? -pc : pc; pc = (p + pc) < 0 ? -(p + pc) : p + pc; #endif p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); } best_row = png_ptr->paeth_row; } else if (filter_to_do & PNG_FILTER_PAETH) { png_bytep rp, dp, pp, cp, lp; png_uint_32 sum = 0, lmins = mins; png_uint_32 i; int v; #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; png_uint_32 lmhi, lmlo; lmlo = lmins & PNG_LOMASK; lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; for (j = 0; j < num_p_filters; j++) { if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) { lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> PNG_WEIGHT_SHIFT; lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> PNG_WEIGHT_SHIFT; } } lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> PNG_COST_SHIFT; lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> PNG_COST_SHIFT; if (lmhi > PNG_HIMASK) lmins = PNG_MAXSUM; else lmins = (lmhi << PNG_HISHIFT) + lmlo; } #endif for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, pp = prev_row + 1; i < bpp; i++) { v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); sum += (v < 128) ? v : 256 - v; } for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) { int a, b, c, pa, pb, pc, p; b = *pp++; c = *cp++; a = *lp++; #ifndef PNG_SLOW_PAETH p = b - c; pc = a - c; #ifdef PNG_USE_ABS pa = abs(p); pb = abs(pc); pc = abs(p + pc); #else pa = p < 0 ? -p : p; pb = pc < 0 ? -pc : pc; pc = (p + pc) < 0 ? -(p + pc) : p + pc; #endif p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; #else /* PNG_SLOW_PAETH */ p = a + b - c; pa = abs(p - a); pb = abs(p - b); pc = abs(p - c); if (pa <= pb && pa <= pc) p = a; else if (pb <= pc) p = b; else p = c; #endif /* PNG_SLOW_PAETH */ v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); sum += (v < 128) ? v : 256 - v; if (sum > lmins) /* We are already worse, don't continue. */ break; } #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; png_uint_32 sumhi, sumlo; sumlo = sum & PNG_LOMASK; sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; for (j = 0; j < num_p_filters; j++) { if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) { sumlo = (sumlo * png_ptr->filter_weights[j]) >> PNG_WEIGHT_SHIFT; sumhi = (sumhi * png_ptr->filter_weights[j]) >> PNG_WEIGHT_SHIFT; } } sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> PNG_COST_SHIFT; sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> PNG_COST_SHIFT; if (sumhi > PNG_HIMASK) sum = PNG_MAXSUM; else sum = (sumhi << PNG_HISHIFT) + sumlo; } #endif if (sum < mins) { best_row = png_ptr->paeth_row; } } /* Do the actual writing of the filtered row data from the chosen filter. */ png_write_filtered_row(png_ptr, best_row); #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* Save the type of filter we picked this time for future calculations */ if (png_ptr->num_prev_filters > 0) { int j; for (j = 1; j < num_p_filters; j++) { png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1]; } png_ptr->prev_filters[j] = best_row[0]; } #endif } /* Do the actual writing of a previously filtered row. */ void /* PRIVATE */ png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) { png_debug(1, "in png_write_filtered_row\n"); png_debug1(2, "filter = %d\n", filtered_row[0]); /* set up the zlib input buffer */ png_ptr->zstream.next_in = filtered_row; png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1; /* repeat until we have compressed all the data */ do { int ret; /* return of zlib */ /* compress the data */ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); /* check for compression errors */ if (ret != Z_OK) { if (png_ptr->zstream.msg != NULL) png_error(png_ptr, png_ptr->zstream.msg); else png_error(png_ptr, "zlib error"); } /* see if it is time to write another IDAT */ if (!(png_ptr->zstream.avail_out)) { /* write the IDAT and reset the zlib output buffer */ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; } /* repeat until all data has been compressed */ } while (png_ptr->zstream.avail_in); /* swap the current and previous rows */ if (png_ptr->prev_row != NULL) { png_bytep tptr; tptr = png_ptr->prev_row; png_ptr->prev_row = png_ptr->row_buf; png_ptr->row_buf = tptr; } /* finish row - updates counters and flushes zlib if last row */ png_write_finish_row(png_ptr); #if defined(PNG_WRITE_FLUSH_SUPPORTED) png_ptr->flush_rows++; if (png_ptr->flush_dist > 0 && png_ptr->flush_rows >= png_ptr->flush_dist) { png_write_flush(png_ptr); } #endif } #endif /* PNG_WRITE_SUPPORTED */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/LICENSE0000664000175000017500000001026510777447272020170 0ustar evanevan This copy of the libpng notices is provided for your convenience. In case of any discrepancy between this copy and the notices in the file png.h that is included in the libpng distribution, the latter shall prevail. COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: If you modify libpng you may insert additional notices immediately following this sentence. *** This version of libpng has been slightly modified to fit into the libcom32 framework. In particular, it uses the libcom32 Makefile system instead of its own. libpng version 1.2.6, December 3, 2004, is Copyright (c) 2004 Glenn Randers-Pehrson, and is distributed according to the same disclaimer and license as libpng-1.2.5 with the following individual added to the list of Contributing Authors Cosmin Truta libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals added to the list of Contributing Authors Simon-Pierre Cadieux Eric S. Raymond Gilles Vollant and with the following additions to the disclaimer: There is no warranty against interference with your enjoyment of the library or against infringement. There is no warranty that our efforts or the library will fulfill any of your particular purposes or needs. This library is provided with all faults, and the entire risk of satisfactory quality, performance, accuracy, and effort is with the user. libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-0.96, with the following individuals added to the list of Contributing Authors: Tom Lane Glenn Randers-Pehrson Willem van Schaik libpng versions 0.89, June 1996, through 0.96, May 1997, are Copyright (c) 1996, 1997 Andreas Dilger Distributed according to the same disclaimer and license as libpng-0.88, with the following individuals added to the list of Contributing Authors: John Bowler Kevin Bracey Sam Bushell Magnus Holmgren Greg Roelofs Tom Tanner libpng versions 0.5, May 1995, through 0.88, January 1996, are Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. For the purposes of this copyright and license, "Contributing Authors" is defined as the following set of individuals: Andreas Dilger Dave Martindale Guy Eric Schalnat Paul Schmidt Tim Wegner The PNG Reference Library is supplied "AS IS". The Contributing Authors and Group 42, Inc. disclaim all warranties, expressed or implied, including, without limitation, the warranties of merchantability and of fitness for any purpose. The Contributing Authors and Group 42, Inc. assume no liability for direct, indirect, incidental, special, exemplary, or consequential damages, which may result from the use of the PNG Reference Library, even if advised of the possibility of such damage. Permission is hereby granted to use, copy, modify, and distribute this source code, or portions hereof, for any purpose, without fee, subject to the following restrictions: 1. The origin of this source code must not be misrepresented. 2. Altered versions must be plainly marked as such and must not be misrepresented as being the original source. 3. This Copyright notice may not be removed or altered from any source or altered source distribution. The Contributing Authors and Group 42, Inc. specifically permit, without fee, and encourage the use of this source code as a component to supporting the PNG file format in commercial products. If you use this source code in a product, acknowledgment is not required but would be appreciated. A "png_get_copyright" function is available, for convenient use in "about" boxes and the like: printf("%s",png_get_copyright(NULL)); Also, the PNG logo (in PNG format, of course) is supplied in the files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a certification mark of the Open Source Initiative. Glenn Randers-Pehrson glennrp at users.sourceforge.net December 3, 2004 syslinux-legacy-3.63+dfsg/com32/lib/libpng/CHANGES0000664000175000017500000023311710777447272020161 0ustar evanevan CHANGES - changes for libpng version 0.2 added reader into png.h fixed small problems in stub file version 0.3 added pull reader split up pngwrite.c to several files added pnglib.txt added example.c cleaned up writer, adding a few new tranformations fixed some bugs in writer interfaced with zlib 0.5 added K&R support added check for 64 KB blocks for 16 bit machines version 0.4 cleaned up code and commented code simplified time handling into png_time created png_color_16 and png_color_8 to handle color needs cleaned up color type defines fixed various bugs made various names more consistant interfaced with zlib 0.71 cleaned up zTXt reader and writer (using zlib's Reset functions) split transformations into pngrtran.c and pngwtran.c version 0.5 interfaced with zlib 0.8 fixed many reading and writing bugs saved using 3 spaces instead of tabs version 0.6 added png_large_malloc() and png_large_free() added png_size_t cleaned up some compiler warnings added png_start_read_image() version 0.7 cleaned up lots of bugs finished dithering and other stuff added test program changed name from pnglib to libpng version 0.71 [June, 1995] changed pngtest.png for zlib 0.93 fixed error in libpng.txt and example.c version 0.8 cleaned up some bugs added png_set_filler() split up pngstub.c into pngmem.c, pngio.c, and pngerror.c added #define's to remove unwanted code moved png_info_init() to png.c added old_size into png_realloc() added functions to manually set filtering and compression info changed compression parameters based on image type optimized filter selection code added version info changed external functions passing floats to doubles (k&r problems?) put all the configurable stuff in pngconf.h enabled png_set_shift to work with paletted images on read added png_read_update_info() - updates info structure with transformations version 0.81 [August, 1995] incorporated Tim Wegner's medium model code (thanks, Tim) version 0.82 [September, 1995] [unspecified changes] version 0.85 [December, 1995] added more medium model code (almost everything's a far) added i/o, error, and memory callback functions fixed some bugs (16 bit, 4 bit interlaced, etc.) added first run progressive reader (barely tested) version 0.86 [January, 1996] fixed bugs improved documentation version 0.87 [January, 1996] fixed medium model bugs fixed other bugs introduced in 0.85 and 0.86 added some minor documentation version 0.88 [January, 1996] fixed progressive bugs replaced tabs with spaces cleaned up documentation added callbacks for read/write and warning/error functions version 0.89 [July, 1996] added new initialization API to make libpng work better with shared libs we now have png_create_read_struct(), png_create_write_struct(), png_create_info_struct(), png_destroy_read_struct(), and png_destroy_write_struct() instead of the separate calls to malloc and png_read_init(), png_info_init(), and png_write_init() changed warning/error callback functions to fix bug - this means you should use the new initialization API if you were using the old png_set_message_fn() calls, and that the old API no longer exists so that people are aware that they need to change their code changed filter selection API to allow selection of multiple filters since it didn't work in previous versions of libpng anyways optimized filter selection code fixed png_set_background() to allow using an arbitrary RGB color for paletted images fixed gamma and background correction for paletted images, so png_correct_palette is not needed unless you are correcting an external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED in pngconf.h) - if nobody uses this, it may disappear in the future. fixed bug with Borland 64K memory allocation (Alexander Lehmann) fixed bug in interlace handling (Smarasderagd, I think) added more error checking for writing and image to reduce invalid files separated read and write functions so that they won't both be linked into a binary when only reading or writing functionality is used new pngtest image also has interlacing and zTXt updated documentation to reflect new API version 0.90 [January, 1997] made CRC errors/warnings on critical and ancillary chunks configurable libpng will use the zlib CRC routines by (compile-time) default changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner) added external C++ wrapper statements to png.h (Gilles Dauphin) allow PNG file to be read when some or all of file signature has already been read from the beginning of the stream. ****This affects the size of info_struct and invalidates all programs that use a shared libpng**** fixed png_filler() declarations fixed? background color conversions fixed order of error function pointers to match documentation current chunk name is now available in png_struct to reduce the number of nearly identical error messages (will simplify multi-lingual support when available) try to get ready for unknown-chunk callback functions: - previously read critical chunks are flagged, so the chunk handling routines can determine if the chunk is in the right place - all chunk handling routines have the same prototypes, so we will be able to handle all chunks via a callback mechanism try to fix Linux "setjmp" buffer size problems removed png_large_malloc, png_large_free, and png_realloc functions. version 0.95 [March, 1997] fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never fixed bug in PNG file signature compares when start != 0 changed parameter type of png_set_filler(...filler...) from png_byte to png_uint_32 added test for MACOS to ensure that both math.h and fp.h are not #included added macros for libpng to be compiled as a Windows DLL (Andreas Kupries) added "packswap" transformation, which changes the endianness of packed-pixel bytes (Kevin Bracey) added "strip_alpha" transformation, which removes the alpha channel of input images without using it (not neccesarily a good idea) added "swap_alpha" transformation, which puts the alpha channel in front of the color bytes instead of after removed all implicit variable tests which assume NULL == 0 (I think) changed several variables to "png_size_t" to show 16/32-bit limitations added new pCAL chunk read/write support added experimental filter selection weighting (Greg Roelofs) removed old png_set_rgbx() and png_set_xrgb() functions that have been obsolete for about 2 years now (use png_set_filler() instead) added macros to read 16- and 32-bit ints directly from buffer, to be used only on those systems that support it (namely PowerPC and 680x0) With some testing, this may become the default for MACOS/PPC systems. only calculate CRC on data if we are going to use it added macros for zTXt compression type PNG_zTXt_COMPRESSION_??? added macros for simple libpng debugging output selectable at compile time removed PNG_READ_END_MODE in progressive reader (Smarasderagd) more description of info_struct in libpng.txt and png.h more instructions in example.c more chunk types tested in pngtest.c renamed pngrcb.c to pngset.c, and all png_read_ functions to be png_set_. We now have corresponding png_get_ functions in pngget.c to get infomation in info_ptr. This isolates the application from the internal organization of png_info_struct (good for shared library implementations). version 0.96 [May, 1997] fixed serious bug with < 8bpp images introduced in 0.95 fixed 256-color transparency bug (Greg Roelofs) fixed up documentation (Greg Roelofs, Laszlo Nyul) fixed "error" in pngconf.h for Linux setjmp() behaviour fixed DOS medium model support (Tim Wegner) fixed png_check_keyword() for case with error in static string text added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul) added typecasts to quiet compiler errors added more debugging info version 0.97 [January, 1998] removed PNG_USE_OWN_CRC capability relocated png_set_crc_action from pngrutil.c to pngrtran.c fixed typecasts of "new_key", etc. (Andreas Dilger) added RFC 1152 [sic] date support fixed bug in gamma handling of 4-bit grayscale added 2-bit grayscale gamma handling (Glenn R-P) added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P) minor corrections in libpng.txt added simple sRGB support (Glenn R-P) easier conditional compiling, e.g. define PNG_READ/WRITE_NOT_FULLY_SUPPORTED; all configurable options can be selected from command-line instead of having to edit pngconf.h (Glenn R-P) fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P) added more conditions for png_do_background, to avoid changing black pixels to background when a background is supplied and no pixels are transparent repaired PNG_NO_STDIO behaviour tested NODIV support and made it default behaviour (Greg Roelofs) added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler) regularized version numbering scheme and bumped shared-library major version number to 2 to avoid problems with libpng 0.89 apps (Greg Roelofs) version 0.98 [January, 1998] cleaned up some typos in libpng.txt and in code documentation fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler) cosmetic change "display_gamma" to "screen_gamma" in pngrtran.c changed recommendation about file_gamma for PC images to .51 from .45, in example.c and libpng.txt, added comments to distinguish between screen_gamma, viewing_gamma, and display_gamma. changed all references to RFC1152 to read RFC1123 and changed the PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent) changed srgb_intent from png_byte to int to avoid compiler bugs version 0.99 [January 30, 1998] free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler) fixed a longstanding "packswap" bug in pngtrans.c fixed some inconsistencies in pngconf.h that prevented compiling with PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined fixed some typos and made other minor rearrangement of libpng.txt (Andreas) changed recommendation about file_gamma for PC images to .50 from .51 in example.c and libpng.txt, and changed file_gamma for sRGB images to .45 added a number of functions to access information from the png structure png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit) added TARGET_MACOS similar to zlib-1.0.8 define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined added type casting to all png_malloc() function calls version 0.99a [January 31, 1998] Added type casts and parentheses to all returns that return a value.(Tim W.) version 0.99b [February 4, 1998] Added type cast png_uint_32 on malloc function calls where needed. Changed type of num_hist from png_uint_32 to int (same as num_palette). Added checks for rowbytes overflow, in case png_size_t is less than 32 bits. Renamed makefile.elf to makefile.lnx. version 0.99c [February 7, 1998] More type casting. Removed erroneous overflow test in pngmem.c. Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes. Added UNIX manual pages libpng.3 (incorporating libpng.txt) and png.5. version 0.99d [February 11, 1998] Renamed "far_to_near()" "png_far_to_near()" Revised libpng.3 Version 99c "buffered" operations didn't work as intended. Replaced them with png_memcpy_check() and png_memset_check(). Added many "if (png_ptr == NULL) return" to quell compiler warnings about unused png_ptr, mostly in pngget.c and pngset.c. Check for overlength tRNS chunk present when indexed-color PLTE is read. Cleaned up spelling errors in libpng.3/libpng.txt Corrected a problem with png_get_tRNS() which returned undefined trans array version 0.99e [February 28, 1998] Corrected png_get_tRNS() again. Add parentheses for easier reading of pngget.c, fixed "||" should be "&&". Touched up example.c to make more of it compileable, although the entire file still can't be compiled (Willem van Schaik) Fixed a bug in png_do_shift() (Bryan Tsai) Added a space in png.h prototype for png_write_chunk_start() Replaced pngtest.png with one created with zlib 1.1.1 Changed pngtest to report PASS even when file size is different (Jean-loup G.) Corrected some logic errors in png_do_invert_alpha() (Chris Patterson) version 0.99f [March 5, 1998] Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey) Moved makefiles into a "scripts" directory, and added INSTALL instruction file Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok) Added pointers to "note on libpng versions" in makefile.lnx and README Added row callback feature when reading and writing nonprogressive rows and added a test of this feature in pngtest.c Added user transform callbacks, with test of the feature in pngtest.c version 0.99g [March 6, 1998, morning] Minor changes to pngtest.c to suppress compiler warnings. Removed "beta" language from documentation. version 0.99h [March 6, 1998, evening] Minor changes to previous minor changes to pngtest.c Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro Added user transform capability version 1.00 [March 7, 1998] Changed several typedefs in pngrutil.c Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik) replaced "while(1)" with "for(;;)" added PNGARG() to prototypes in pngtest.c and removed some prototypes updated some of the makefiles (Tom Lane) changed some typedefs (s_start, etc.) in pngrutil.c fixed dimensions of "short_months" array in pngwrite.c Replaced ansi2knr.c with the one from jpeg-v6 version 1.0.0 [March 8, 1998] Changed name from 1.00 to 1.0.0 (Adam Costello) Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert) version 1.0.0a [March 9, 1998] Fixed three bugs in pngrtran.c to make gamma+background handling consistent (Greg Roelofs) Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz for major, minor, and bugfix releases. This is 10001. (Adam Costello, Tom Lane) Make months range from 1-12 in png_convert_to_rfc1123 version 1.0.0b [March 13, 1998] Quieted compiler complaints about two empty "for" loops in pngrutil.c Minor changes to makefile.s2x Removed #ifdef/#endif around a png_free() in pngread.c version 1.0.1 [March 14, 1998] Changed makefile.s2x to reduce security risk of using a relative pathname Fixed some typos in the documentation (Greg). Fixed a problem with value of "channels" returned by png_read_update_info() version 1.0.1a [April 21, 1998] Optimized Paeth calculations by replacing abs() function calls with intrinsics plus other loop optimizations. Improves avg decoding speed by about 20%. Commented out i386istic "align" compiler flags in makefile.lnx. Reduced the default warning level in some makefiles, to make them consistent. Removed references to IJG and JPEG in the ansi2knr.c copyright statement. Fixed a bug in png_do_strip_filler with XXRRGGBB => RRGGBB transformation. Added grayscale and 16-bit capability to png_do_read_filler(). Fixed a bug in pngset.c, introduced in version 0.99c, that sets rowbytes too large when writing an image with bit_depth < 8 (Bob Dellaca). Corrected some bugs in the experimental weighted filtering heuristics. Moved a misplaced pngrutil code block that truncates tRNS if it has more than num_palette entries -- test was done before num_palette was defined. Fixed a png_convert_to_rfc1123() bug that converts day 31 to 0 (Steve Eddins). Changed compiler flags in makefile.wat for better optimization (Pawel Mrochen). version 1.0.1b [May 2, 1998] Relocated png_do_gray_to_rgb() within png_do_read_transformations() (Greg). Relocated the png_composite macros from pngrtran.c to png.h (Greg). Added makefile.sco (contributed by Mike Hopkirk). Fixed two bugs (missing definitions of "istop") introduced in libpng-1.0.1a. Fixed a bug in pngrtran.c that would set channels=5 under some circumstances. More work on the Paeth-filtering, achieving imperceptible speedup (A Kleinert). More work on loop optimization which may help when compiled with C++ compilers. Added warnings when people try to use transforms they've defined out. Collapsed 4 "i" and "c" loops into single "i" loops in pngrtran and pngwtran. Revised paragraph about png_set_expand() in libpng.txt and libpng.3 (Greg) version 1.0.1c [May 11, 1998] Fixed a bug in pngrtran.c (introduced in libpng-1.0.1a) where the masks for filler bytes should have been 0xff instead of 0xf. Added max_pixel_depth=32 in pngrutil.c when using FILLER with palette images. Moved PNG_WRITE_WEIGHTED_FILTER_SUPPORTED and PNG_WRITE_FLUSH_SUPPORTED out of the PNG_WRITE_TRANSFORMS_NOT_SUPPORTED block of pngconf.h Added "PNG_NO_WRITE_TRANSFORMS" etc., as alternatives for *_NOT_SUPPORTED, for consistency, in pngconf.h Added individual "ifndef PNG_NO_[CAPABILITY]" in pngconf.h to make it easier to remove unwanted capabilities via the compile line Made some corrections to grammar (which, it's) in documentation (Greg). Corrected example.c, use of row_pointers in png_write_image(). version 1.0.1d [May 24, 1998] Corrected several statements that used side effects illegally in pngrutil.c and pngtrans.c, that were introduced in version 1.0.1b Revised png_read_rows() to avoid repeated if-testing for NULL (A Kleinert) More corrections to example.c, use of row_pointers in png_write_image() and png_read_rows(). Added pngdll.mak and pngdef.pas to scripts directory, contributed by Bob Dellaca, to make a png32bd.dll with Borland C++ 4.5 Fixed error in example.c with png_set_text: num_text is 3, not 2 (Guido V.) Changed several loops from count-down to count-up, for consistency. version 1.0.1e [June 6, 1998] Revised libpng.txt and libpng.3 description of png_set_read|write_fn(), and added warnings when people try to set png_read_fn and png_write_fn in the same structure. Added a test such that png_do_gamma will be done when num_trans==0 for truecolor images that have defined a background. This corrects an error that was introduced in libpng-0.90 that can cause gamma processing to be skipped. Added tests in png.h to include "trans" and "trans_values" in structures when PNG_READ_BACKGROUND_SUPPORTED or PNG_READ_EXPAND_SUPPORTED is defined. Add png_free(png_ptr->time_buffer) in png_destroy_read_struct() Moved png_convert_to_rfc_1123() from pngwrite.c to png.c Added capability for user-provided malloc_fn() and free_fn() functions, and revised pngtest.c to demonstrate their use, replacing the PNGTEST_DEBUG_MEM feature. Added makefile.w32, for Microsoft C++ 4.0 and later (Tim Wegner). version 1.0.2 [June 14, 1998] Fixed two bugs in makefile.bor . version 1.0.2a [December 30, 1998] Replaced and extended code that was removed from png_set_filler() in 1.0.1a. Fixed a bug in png_do_filler() that made it fail to write filler bytes in the left-most pixel of each row (Kevin Bracey). Changed "static pngcharp tIME_string" to "static char tIME_string[30]" in pngtest.c (Duncan Simpson). Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk even when no tIME chunk was present in the source file. Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit. Fixed a problem in png_read_push_finish_row(), which would not skip some passes that it should skip, for images that are less than 3 pixels high. Interchanged the order of calls to png_do_swap() and png_do_shift() in pngwtran.c (John Cromer). Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h . Changed "bad adaptive filter type" from error to warning in pngrutil.c . Fixed a documentation error about default filtering with 8-bit indexed-color. Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO (L. Peter Deutsch). Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions. Added png_get_copyright() and png_get_header_version() functions. Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c Added information about debugging in libpng.txt and libpng.3 . Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and makefile.sco. Removed lines after Dynamic Dependencies" in makefile.aco . Revised makefile.dec to make a shared library (Jeremie Petit). Removed trailing blanks from all files. version 1.0.2a [January 6, 1999] Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h Added "if" tests to silence complaints about unused png_ptr in png.h and png.c Changed "check_if_png" function in example.c to return true (nonzero) if PNG. Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig() which is obsolete. version 1.0.3 [January 14, 1999] Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice) Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO. version 1.0.3a [August 12, 1999] Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning if an attempt is made to read an interlaced image when it's not supported. Added check if png_ptr->trans is defined before freeing it in pngread.c Modified the Y2K statement to include versions back to version 0.71 Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments) Replaced leading blanks with tab characters in makefile.hux Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents. Changed (float)red and (float)green to (double)red, (double)green in png_set_rgb_to_gray() to avoid "promotion" problems in AIX. Fixed a bug in pngconf.h that omitted when PNG_DEBUG==0 (K Bracey). Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt). Updated documentation to refer to the PNG-1.2 specification. Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c in makefile.knr, INSTALL, and README (L. Peter Deutsch) Fixed bugs in calculation of the length of rowbytes when adding alpha channels to 16-bit images, in pngrtran.c (Chris Nokleberg) Added function png_set_user_transform_info() to store user_transform_ptr, user_depth, and user_channels into the png_struct, and a function png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg) Added function png_set_empty_plte_permitted() to make libpng useable in MNG applications. Corrected the typedef for png_free_ptr in png.h (Jesse Jones). Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be consistent with PNG-1.2, and allow variance of 500 before complaining. Added assembler code contributed by Intel in file pngvcrd.c and modified makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation, Gilles Vollant) Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy. Added some aliases for png_set_expand() in pngrtran.c, namely png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS() (Greg Roelofs, in "PNG: The Definitive Guide"). Added makefile.beo for BEOS on X86, contributed by Sander Stok. version 1.0.3b [August 26, 1999] Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h Changed leading blanks to tabs in all makefiles. Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code. Made alternate versions of png_set_expand() in pngrtran.c, namely png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha (Greg Roelofs, in "PNG: The Definitive Guide"). Deleted the 1.0.3a aliases. Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h Revised calculation of num_blocks in pngmem.c to avoid a potentially negative shift distance, whose results are undefined in the C language. Added a check in pngset.c to prevent writing multiple tIME chunks. Added a check in pngwrite.c to detect invalid small window_bits sizes. version 1.0.3d [September 4, 1999] Fixed type casting of igamma in pngrutil.c Added new png_expand functions to scripts/pngdef.pas and pngos2.def Added a demo read_user_transform_fn that examines the row filters in pngtest.c version 1.0.4 [September 24, 1999] Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h Made several minor corrections to pngtest.c Renamed the makefiles with longer but more user friendly extensions. Copied the PNG copyright and license to a separate LICENSE file. Revised documentation, png.h, and example.c to remove reference to "viewing_gamma" which no longer appears in the PNG specification. Revised pngvcrd.c to use MMX code for interlacing only on the final pass. Updated pngvcrd.c to use the faster C filter algorithms from libpng-1.0.1a Split makefile.win32vc into two versions, makefile.vcawin32 (uses MMX assembler code) and makefile.vcwin32 (doesn't). Added a CPU timing report to pngtest.c (enabled by defining PNGTEST_TIMING) Added a copy of pngnow.png to the distribution. version 1.0.4a [September 25, 1999] Increase max_pixel_depth in pngrutil.c if a user transform needs it. Changed several division operations to right-shifts in pngvcrd.c version 1.0.4b [September 30, 1999] Added parentheses in line 3732 of pngvcrd.c Added a comment in makefile.linux warning about buggy -O3 in pgcc 2.95.1 version 1.0.4c [October 1, 1999] Added a "png_check_version" function in png.c and pngtest.c that will generate a helpful compiler error if an old png.h is found in the search path. Changed type of png_user_transform_depth|channels from int to png_byte. version 1.0.4d [October 6, 1999] Changed 0.45 to 0.45455 in png_set_sRGB() Removed unused PLTE entries from pngnow.png Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly. version 1.0.4e [October 10, 1999] Fixed sign error in pngvcrd.c (Greg Roelofs) Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P) version 1.0.4f [October 15, 1999] Surrounded example.c code with #if 0 .. #endif to prevent people from inadvertently trying to compile it. Changed png_get_header_version() from a function to a macro in png.h Added type casting mostly in pngrtran.c and pngwtran.c Removed some pointless "ptr = NULL" in pngmem.c Added a "contrib" directory containing the source code from Greg's book. version 1.0.5 [October 15, 1999] Minor editing of the INSTALL and README files. version 1.0.5a [October 23, 1999] Added contrib/pngsuite and contrib/pngminus (Willem van Schaik) Fixed a typo in the png_set_sRGB() function call in example.c (Jan Nijtmans) Further optimization and bugfix of pngvcrd.c Revised pngset.c so that it does not allocate or free memory in the user's text_ptr structure. Instead, it makes its own copy. Created separate write_end_info_struct in pngtest.c for a more severe test. Added code in pngwrite.c to free info_ptr->text[i].key to stop a memory leak. version 1.0.5b [November 23, 1999] Moved PNG_FLAG_HAVE_CHUNK_HEADER, PNG_FLAG_BACKGROUND_IS_GRAY and PNG_FLAG_WROTE_tIME from flags to mode. Added png_write_info_before_PLTE() function. Fixed some typecasting in contrib/gregbook/*.c Updated scripts/makevms.com and added makevms.com to contrib/gregbook and contrib/pngminus (Martin Zinser) version 1.0.5c [November 26, 1999] Moved png_get_header_version from png.h to png.c, to accomodate ansi2knr. Removed all global arrays (according to PNG_NO_GLOBAL_ARRAYS macro), to accomodate making DLL's: Moved usr_png_ver from global variable to function png_get_header_ver() in png.c. Moved png_sig to png_sig_bytes in png.c and eliminated use of png_sig in pngwutil.c. Moved the various png_CHNK arrays into pngtypes.h. Eliminated use of global png_pass arrays. Declared the png_CHNK and png_pass arrays to be "const". Made the global arrays available to applications (although none are used in libpng itself) when PNG_NO_GLOBAL_ARRAYS is not defined or when PNG_GLOBAL_ARRAYS is defined. Removed some extraneous "-I" from contrib/pngminus/makefile.std Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2. Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3 version 1.0.5d [November 29, 1999] Add type cast (png_const_charp) two places in png.c Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays. Renamed "PNG_GLOBAL_ARRAYS" to "PNG_USE_GLOBAL_ARRAYS" and made available to applications a macro "PNG_USE_LOCAL_ARRAYS". #ifdef out all the new declarations when PNG_USE_GLOBAL_ARRAYS is defined. Added PNG_EXPORT_VAR macro to accommodate making DLL's. version 1.0.5e [November 30, 1999] Added iCCP, iTXt, and sPLT support; added "lang" member to the png_text structure; refactored the inflate/deflate support to make adding new chunks with trailing compressed parts easier in the future, and added new functions png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP, png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond). NOTE: Applications that write text chunks MUST define png_text->lang before calling png_set_text(). It must be set to NULL if you want to write tEXt or zTXt chunks. If you want your application to be able to run with older versions of libpng, use #ifdef PNG_iTXt_SUPPORTED png_text[i].lang = NULL; #endif Changed png_get_oFFs() and png_set_oFFs() to use signed rather than unsigned offsets (Eric S. Raymond). Combined PNG_READ_cHNK_SUPPORTED and PNG_WRITE_cHNK_SUPPORTED macros into PNG_cHNK_SUPPORTED and combined the three types of PNG_text_SUPPORTED macros, leaving the separate macros also available. Removed comments on #endifs at the end of many short, non-nested #if-blocks. version 1.0.5f [December 6, 1999] Changed makefile.solaris to issue a warning about potential problems when the ucb "ld" is in the path ahead of the ccs "ld". Removed "- [date]" from the "synopsis" line in libpng.3 and libpngpf.3. Added sCAL chunk support (Eric S. Raymond). version 1.0.5g [December 7, 1999] Fixed "png_free_spallettes" typo in png.h Added code to handle new chunks in pngpread.c Moved PNG_CHNK string macro definitions outside of PNG_NO_EXTERN block Added "translated_key" to png_text structure and png_write_iTXt(). Added code in pngwrite.c to work around a newly discovered zlib bug. version 1.0.5h [December 10, 1999] NOTE: regarding the note for version 1.0.5e, the following must also be included in your code: png_text[i].translated_key = NULL; Unknown chunk handling is now supported. Option to eliminate all floating point support was added. Some new fixed-point functions such as png_set_gAMA_fixed() were added. Expanded tabs and removed trailing blanks in source files. version 1.0.5i [December 13, 1999] Added some type casts to silence compiler warnings. Renamed "png_free_spalette" to "png_free_spalettes" for consistency. Removed leading blanks from a #define in pngvcrd.c Added some parameters to the new png_set_keep_unknown_chunks() function. Added a test for up->location != 0 in the first instance of writing unknown chunks in pngwrite.c Changed "num" to "i" in png_free_spalettes() and png_free_unknowns() to prevent recursion. Added png_free_hIST() function. Various patches to fix bugs in the sCAL and integer cHRM processing, and to add some convenience macros for use with sCAL. version 1.0.5j [December 21, 1999] Changed "unit" parameter of png_write_sCAL from png_byte to int, to work around buggy compilers. Added new type "png_fixed_point" for integers that hold float*100000 values Restored backward compatibility of tEXt/zTXt chunk processing: Restored the first four members of png_text to the same order as v.1.0.5d. Added members "lang_key" and "itxt_length" to png_text struct. Set text_length=0 when "text" contains iTXt data. Use the "compression" member to distinguish among tEXt/zTXt/iTXt types. Added PNG_ITXT_COMPRESSION_NONE (1) and PNG_ITXT_COMPRESSION_zTXt(2) macros. The "Note" above, about backward incompatibility of libpng-1.0.5e, no longer applies. Fixed png_read|write_iTXt() to read|write parameters in the right order, and to write the iTXt chunk after IDAT if it appears in the end_ptr. Added pnggccrd.c, version of pngvcrd.c Intel assembler for gcc (Greg Roelofs) Reversed the order of trying to write floating-point and fixed-point gAMA. version 1.0.5k [December 27, 1999] Added many parentheses, e.g., "if (a && b & c)" becomes "if (a && (b & c))" Added png_handle_as_unknown() function (Glenn) Added png_free_chunk_list() function and chunk_list and num_chunk_list members of png_ptr. Eliminated erroneous warnings about multiple sPLT chunks and sPLT-after-PLTE. Fixed a libpng-1.0.5h bug in pngrutil.c that was issuing erroneous warnings about ignoring incorrect gAMA with sRGB (gAMA was in fact not ignored) Added png_free_tRNS(); png_set_tRNS() now malloc's its own trans array (ESR). Define png_get_int_32 when oFFs chunk is supported as well as when pCAL is. Changed type of proflen from png_int_32 to png_uint_32 in png_get_iCCP(). version 1.0.5l [January 1, 2000] Added functions png_set_read_user_chunk_fn() and png_get_user_chunk_ptr() for setting a callback function to handle unknown chunks and for retrieving the associated user pointer (Glenn). version 1.0.5m [January 7, 2000] Added high-level functions png_read_png(), png_write_png(), png_free_pixels(). version 1.0.5n [January 9, 2000] Added png_free_PLTE() function, and modified png_set_PLTE() to malloc its own memory for info_ptr->palette. This makes it safe for the calling application to free its copy of the palette any time after it calls png_set_PLTE(). version 1.0.5o [January 20, 2000] Cosmetic changes only (removed some trailing blanks and TABs) version 1.0.5p [January 31, 2000] Renamed pngdll.mak to makefile.bd32 Cosmetic changes in pngtest.c version 1.0.5q [February 5, 2000] Relocated the makefile.solaris warning about PATH problems. Fixed pngvcrd.c bug by pushing/popping registers in mmxsupport (Bruce Oberg) Revised makefile.gcmmx Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros version 1.0.5r [February 7, 2000] Removed superfluous prototype for png_get_itxt from png.h Fixed a bug in pngrtran.c that improperly expanded the background color. Return *num_text=0 from png_get_text() when appropriate, and fix documentation of png_get_text() in libpng.txt/libpng.3. version 1.0.5s [February 18, 2000] Added "png_jmp_env()" macro to pngconf.h, to help people migrate to the new error handler that's planned for the next libpng release, and changed example.c, pngtest.c, and contrib programs to use this macro. Revised some of the DLL-export macros in pngconf.h (Greg Roelofs) Fixed a bug in png_read_png() that caused it to fail to expand some images that it should have expanded. Fixed some mistakes in the unused and undocumented INCH_CONVERSIONS functions in pngget.c Changed the allocation of palette, history, and trans arrays back to the version 1.0.5 method (linking instead of copying) which restores backward compatibility with version 1.0.5. Added some remarks about that in example.c. Added "free_me" member to info_ptr and png_ptr and added png_free_data() function. Updated makefile.linux and makefile.gccmmx to make directories conditionally. Made cosmetic changes to pngasmrd.h Added png_set_rows() and png_get_rows(), for use with png_read|write_png(). Modified png_read_png() to allocate info_ptr->row_pointers only if it hasn't already been allocated. version 1.0.5t [March 4, 2000] Changed png_jmp_env() migration aiding macro to png_jmpbuf(). Fixed "interlace" typo (should be "interlaced") in contrib/gregbook/read2-x.c Fixed bug with use of PNG_BEFORE_IHDR bit in png_ptr->mode, introduced when PNG_FLAG_HAVE_CHUNK_HEADER was moved into png_ptr->mode in version 1.0.5b Files in contrib/gregbook were revised to use png_jmpbuf() and to select a 24-bit visual if one is available, and to allow abbreviated options. Files in contrib/pngminus were revised to use the png_jmpbuf() macro. Removed spaces in makefile.linux and makefile.gcmmx, introduced in 1.0.5s version 1.0.5u [March 5, 2000] Simplified the code that detects old png.h in png.c and pngtest.c Renamed png_spalette (_p, _pp) to png_sPLT_t (_tp, _tpp) Increased precision of rgb_to_gray calculations from 8 to 15 bits and added png_set_rgb_to_gray_fixed() function. Added makefile.bc32 (32-bit Borland C++, C mode) version 1.0.5v [March 11, 2000] Added some parentheses to the png_jmpbuf macro definition. Updated references to the zlib home page, which has moved to freesoftware.com. Corrected bugs in documentation regarding png_read_row() and png_write_row(). Updated documentation of png_rgb_to_gray calculations in libpng.3/libpng.txt. Renamed makefile.borland,turboc3 back to makefile.bor,tc3 as in version 1.0.3, revised borland makefiles; added makefile.ibmvac3 and makefile.gcc (Cosmin) version 1.0.6 [March 20, 2000] Minor revisions of makefile.bor, libpng.txt, and gregbook/rpng2-win.c Added makefile.sggcc (SGI IRIX with gcc) version 1.0.6d [April 7, 2000] Changed sprintf() to strcpy() in png_write_sCAL_s() to work without STDIO Added data_length parameter to png_decompress_chunk() function Revised documentation to remove reference to abandoned png_free_chnk functions Fixed an error in png_rgb_to_gray_fixed() Revised example.c, usage of png_destroy_write_struct(). Renamed makefile.ibmvac3 to makefile.ibmc, added libpng.icc IBM project file Added a check for info_ptr->free_me&PNG_FREE_TEXT when freeing text in png.c Simplify png_sig_bytes() function to remove use of non-ISO-C strdup(). version 1.0.6e [April 9, 2000] Added png_data_freer() function. In the code that checks for over-length tRNS chunks, added check of info_ptr->num_trans as well as png_ptr->num_trans (Matthias Benckmann) Minor revisions of libpng.txt/libpng.3. Check for existing data and free it if the free_me flag is set, in png_set_*() and png_handle_*(). Only define PNG_WEIGHTED_FILTERS_SUPPORTED when PNG_FLOATING_POINT_SUPPORTED is defined. Changed several instances of PNG_NO_CONSOLE_ID to PNG_NO_STDIO in pngrutil.c and mentioned the purposes of the two macros in libpng.txt/libpng.3. version 1.0.6f [April 14, 2000] Revised png_set_iCCP() and png_set_rows() to avoid prematurely freeing data. Add checks in png_set_text() for NULL members of the input text structure. Revised libpng.txt/libpng.3. Removed superfluous prototype for png_set_itxt from png.h Removed "else" from pngread.c, after png_error(), and changed "0" to "length". Changed several png_errors about malformed ancillary chunks to png_warnings. version 1.0.6g [April 24, 2000] Added png_pass-* arrays to pnggccrd.c when PNG_USE_LOCAL_ARRAYS is defined. Relocated paragraph about png_set_background() in libpng.3/libpng.txt and other revisions (Matthias Benckmann) Relocated info_ptr->free_me, png_ptr->free_me, and other info_ptr and png_ptr members to restore binary compatibility with libpng-1.0.5 (breaks compatibility with libpng-1.0.6). version 1.0.6h [April 24, 2000] Changed shared library so-number pattern from 2.x.y.z to xy.z (this builds libpng.so.10 & libpng.so.10.6h instead of libpng.so.2 & libpng.so.2.1.0.6h) This is a temporary change for test purposes. version 1.0.6i [May 2, 2000] Rearranged some members at the end of png_info and png_struct, to put unknown_chunks_num and free_me within the original size of the png_structs and free_me, png_read_user_fn, and png_free_fn within the original png_info, because some old applications allocate the structs directly instead of using png_create_*(). Added documentation of user memory functions in libpng.txt/libpng.3 Modified png_read_png so that it will use user_allocated row_pointers if present, unless free_me directs that it be freed, and added description of the use of png_set_rows() and png_get_rows() in libpng.txt/libpng.3. Added PNG_LEGACY_SUPPORTED macro, and #ifdef out all new (since version 1.00) members of png_struct and png_info, to regain binary compatibility when you define this macro. Capabilities lost in this event are user transforms (new in version 1.0.0),the user transform pointer (new in version 1.0.2), rgb_to_gray (new in 1.0.5), iCCP, sCAL, sPLT, the high-level interface, and unknown chunks support (all new in 1.0.6). This was necessary because of old applications that allocate the structs directly as authors were instructed to do in libpng-0.88 and earlier, instead of using png_create_*(). Added modes PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT which can be used to detect codes that directly allocate the structs, and code to check these modes in png_read_init() and png_write_init() and generate a libpng error if the modes aren't set and PNG_LEGACY_SUPPORTED was not defined. Added makefile.intel and updated makefile.watcom (Pawel Mrochen) version 1.0.6j [May 3, 2000] Overloaded png_read_init() and png_write_init() with macros that convert calls to png_read_init_2() or png_write_init_2() that check the version and structure sizes. version 1.0.7beta11 [May 7, 2000] Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes which are no longer used. Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXT_SUPPORTED is defined. Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory overrun when old applications fill the info_ptr->text structure directly. Added PNGAPI macro, and added it to the definitions of all exported functions. Relocated version macro definitions ahead of the includes of zlib.h and pngconf.h in png.h. version 1.0.7beta12 [May 12, 2000] Revised pngset.c to avoid a problem with expanding the png_debug macro. Deleted some extraneous defines from pngconf.h Made PNG_NO_CONSOLE_IO the default condition when PNG_BUILD_DLL is defined. Use MSC _RPTn debugging instead of fprintf if _MSC_VER is defined. Added png_access_version_number() function. Check for mask&PNG_FREE_CHNK (for TEXT, SCAL, PCAL) in png_free_data(). Expanded libpng.3/libpng.txt information about png_data_freer(). version 1.0.7beta14 [May 17, 2000] (beta13 was not published) Changed pnggccrd.c and pngvcrd.c to handle bad adaptive filter types as warnings instead of errors, as pngrutil.c does. Set the PNG_INFO_IDAT valid flag in png_set_rows() so png_write_png() will actually write IDATs. Made the default PNG_USE_LOCAL_ARRAYS depend on PNG_DLL instead of WIN32. Make png_free_data() ignore its final parameter except when freeing data that can have multiple instances (text, sPLT, unknowns). Fixed a new bug in png_set_rows(). Removed info_ptr->valid tests from png_free_data(), as in version 1.0.5. Added png_set_invalid() function. Fixed incorrect illustrations of png_destroy_write_struct() in example.c. version 1.0.7beta15 [May 30, 2000] Revised the deliberately erroneous Linux setjmp code in pngconf.h to produce fewer error messages. Rearranged checks for Z_OK to check the most likely path first in pngpread.c and pngwutil.c. Added checks in pngtest.c for png_create_*() returning NULL, and mentioned in libpng.txt/libpng.3 the need for applications to check this. Changed names of png_default_*() functions in pngtest to pngtest_*(). Changed return type of png_get_x|y_offset_*() from png_uint_32 to png_int_32. Fixed some bugs in the unused PNG_INCH_CONVERSIONS functions in pngget.c Set each pointer to NULL after freeing it in png_free_data(). Worked around a problem in pngconf.h; AIX's strings.h defines an "index" macro that conflicts with libpng's png_color_16.index. (Dimitri Papadapoulos) Added "msvc" directory with MSVC++ project files (Simon-Pierre Cadieux). version 1.0.7beta16 [June 4, 2000] Revised the workaround of AIX string.h "index" bug. Added a check for overlength PLTE chunk in pngrutil.c. Added PNG_NO_POINTER_INDEXING macro to use array-indexing instead of pointer indexing in pngrutil.c and pngwutil.c to accommodate a buggy compiler. Added a warning in png_decompress_chunk() when it runs out of data, e.g. when it tries to read an erroneous PhotoShop iCCP chunk. Added PNG_USE_DLL macro. Revised the copyright/disclaimer/license notice. Added contrib/msvctest directory version 1.0.7rc1 [June 9, 2000] Corrected the definition of PNG_TRANSFORM_INVERT_ALPHA (0x0400 not 0x0200) Added contrib/visupng directory (Willem van Schaik) version 1.0.7beta18 [June 23, 2000] Revised PNGAPI definition, and pngvcrd.c to work with __GCC__ and do not redefine PNGAPI if it is passed in via a compiler directive. Revised visupng/PngFile.c to remove returns from within the Try block. Removed leading underscores from "_PNG_H" and "_PNG_SAVE_BSD_SOURCE" macros. Updated contrib/visupng/cexcept.h to version 1.0.0. Fixed bugs in pngwrite.c and pngwutil.c that prevented writing iCCP chunks. version 1.0.7rc2 [June 28, 2000] Updated license to include disclaimers required by UCITA. Fixed "DJBPP" typo in pnggccrd.c introduced in beta18. version 1.0.7 [July 1, 2000] Revised the definition of "trans_values" in libpng.3/libpng.txt version 1.0.8beta1 [July 8, 2000] Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks. Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and pngwutil.c. Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h. Removed unused "#include " from png.c Added WindowsCE support. Revised pnggccrd.c to work with gcc-2.95.2 and in the Cygwin environment. version 1.0.8beta2 [July 10, 2000] Added project files to the wince directory and made further revisions of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE. version 1.0.8beta3 [July 11, 2000] Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS() for indexed-color input files to avoid potential double-freeing trans array under some unusual conditions; problem was introduced in version 1.0.6f. Further revisions to pngtest.c and files in the wince subdirectory. version 1.0.8beta4 [July 14, 2000] Added the files pngbar.png and pngbar.jpg to the distribution. Added makefile.cygwin, and cygwin support in pngconf.h Added PNG_NO_ZALLOC_ZERO macro (makes png_zalloc skip zeroing memory) version 1.0.8rc1 [July 16, 2000] Revised png_debug() macros and statements to eliminate compiler warnings. version 1.0.8 [July 24, 2000] Added png_flush() in pngwrite.c, after png_write_IEND(). Updated makefile.hpux to build a shared library. version 1.0.9beta1 [November 10, 2000] Fixed typo in scripts/makefile.hpux Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser) Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser) Changed "cdrom.com" in documentation to "libpng.org" Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg). Changed type of "params" from voidp to png_voidp in png_read|write_png(). Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h. Revised the 3 instances of WRITEFILE in pngtest.c. Relocated "msvc" and "wince" project subdirectories into "dll" subdirectory. Updated png.rc in dll/msvc project Revised makefile.dec to define and use LIBPATH and INCPATH Increased size of global png_libpng_ver[] array from 12 to 18 chars. Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const. Removed duplicate png_crc_finish() from png_handle_bKGD() function. Added a warning when application calls png_read_update_info() multiple times. Revised makefile.cygwin Fixed bugs in iCCP support in pngrutil.c and pngwutil.c. Replaced png_set_empty_plte_permitted() with png_permit_mng_features(). version 1.0.9beta2 [November 19, 2000] Renamed the "dll" subdirectory "projects". Added borland project files to "projects" subdirectory. Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate. Add error message in png_set_compression_buffer_size() when malloc fails. version 1.0.9beta3 [November 23, 2000] Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project. Removed the png_flush() in pngwrite.c that crashes some applications that don't set png_output_flush_fn. Added makefile.macosx and makefile.aix to scripts directory. version 1.0.9beta4 [December 1, 2000] Change png_chunk_warning to png_warning in png_check_keyword(). Increased the first part of msg buffer from 16 to 18 in png_chunk_error(). version 1.0.9beta5 [December 15, 2000] Added support for filter method 64 (for PNG datastreams embedded in MNG). version 1.0.9beta6 [December 18, 2000] Revised png_set_filter() to accept filter method 64 when appropriate. Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to help prevent applications from using MNG features in PNG datastreams. Added png_permit_mng_features() function. Revised libpng.3/libpng.txt. Changed "filter type" to "filter method". version 1.0.9rc1 [December 23, 2000] Revised test for PNG_HAVE_PNG_SIGNATURE in pngrutil.c Fixed error handling of unknown compression type in png_decompress_chunk(). In pngconf.h, define __cdecl when _MSC_VER is defined. version 1.0.9beta7 [December 28, 2000] Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places. Revised memory management in png_set_hIST and png_handle_hIST in a backward compatible manner. PLTE and tRNS were revised similarly. Revised the iCCP chunk reader to ignore trailing garbage. version 1.0.9beta8 [January 12, 2001] Moved pngasmrd.h into pngconf.h. Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop. version 1.0.9beta9 [January 15, 2001] Added png_set_invalid, png_permit_mng_features, and png_mmx_supported to wince and msvc project module definition files. Minor revision of makefile.cygwin. Fixed bug with progressive reading of narrow interlaced images in pngpread.c version 1.0.9beta10 [January 16, 2001] Do not typedef png_FILE_p in pngconf.h when PNG_NO_STDIO is defined. Fixed "png_mmx_supported" typo in project definition files. version 1.0.9beta11 [January 19, 2001] Updated makefile.sgi to make shared library. Removed png_mmx_support() function and disabled PNG_MNG_FEATURES_SUPPORTED by default, for the benefit of DLL forward compatibility. These will be re-enabled in version 1.2.0. version 1.0.9rc2 [January 22, 2001] Revised cygwin support. version 1.0.9 [January 31, 2001] Added check of cygwin's ALL_STATIC in pngconf.h Added "-nommx" parameter to contrib/gregbook/rpng2-win and rpng2-x demos. version 1.0.10beta1 [March 14, 2001] Revised makefile.dec, makefile.sgi, and makefile.sggcc; added makefile.hpgcc. Reformatted libpng.3 to eliminate bad line breaks. Added checks for _mmx_supported in the read_filter_row function of pnggccrd.c Added prototype for png_mmx_support() near the top of pnggccrd.c Moved some error checking from png_handle_IHDR to png_set_IHDR. Added PNG_NO_READ_SUPPORTED and PNG_NO_WRITE_SUPPORTED macros. Revised png_mmx_support() function in pnggccrd.c Restored version 1.0.8 PNG_WRITE_EMPTY_PLTE_SUPPORTED behavior in pngwutil.c Fixed memory leak in contrib/visupng/PngFile.c Fixed bugs in png_combine_row() in pnggccrd.c and pngvcrd.c (C version) Added warnings when retrieving or setting gamma=0. Increased the first part of msg buffer from 16 to 18 in png_chunk_warning(). version 1.0.10rc1 [March 23, 2001] Changed all instances of memcpy, strcpy, and strlen to png_memcpy, png_strcpy, and png_strlen. Revised png_mmx_supported() function in pnggccrd.c to return proper value. Fixed bug in progressive reading (pngpread.c) with small images (height < 8). version 1.0.10 [March 30, 2001] Deleted extraneous space (introduced in 1.0.9) from line 42 of makefile.cygwin Added beos project files (Chris Herborth) version 1.0.11beta1 [April 3, 2001] Added type casts on several png_malloc() calls (Dimitri Papadapoulos). Removed a no-longer needed AIX work-around from pngconf.h Changed several "//" single-line comments to C-style in pnggccrd.c version 1.0.11beta2 [April 11, 2001] Removed PNGAPI from several functions whose prototypes did not have PNGAPI. Updated scripts/pngos2.def version 1.0.11beta3 [April 14, 2001] Added checking the results of many instances of png_malloc() for NULL version 1.0.11beta4 [April 20, 2001] Undid the changes from version 1.0.11beta3. Added a check for NULL return from user's malloc_fn(). Removed some useless type casts of the NULL pointer. Added makefile.netbsd version 1.0.11 [April 27, 2001] Revised makefile.netbsd version 1.0.12beta1 [May 14, 2001] Test for Windows platform in pngconf.h when including malloc.h (Emmanuel Blot) Updated makefile.cygwin and handling of Cygwin's ALL_STATIC in pngconf.h Added some never-to-be-executed code in pnggccrd.c to quiet compiler warnings. Eliminated the png_error about apps using png_read|write_init(). Instead, libpng will reallocate the png_struct and info_struct if they are too small. This retains future binary compatibility for old applications written for libpng-0.88 and earlier. version 1.2.0beta1 [May 6, 2001] Bumped DLLNUM to 2. Re-enabled PNG_MNG_FEATURES_SUPPORTED and enabled PNG_ASSEMBLER_CODE_SUPPORTED by default. Added runtime selection of MMX features. Added png_set_strip_error_numbers function and related macros. version 1.2.0beta2 [May 7, 2001] Finished merging 1.2.0beta1 with version 1.0.11 Added a check for attempts to read or write PLTE in grayscale PNG datastreams. version 1.2.0beta3 [May 17, 2001] Enabled user memory function by default. Modified png_create_struct so it passes user mem_ptr to user memory allocator. Increased png_mng_features flag from png_byte to png_uint_32. Bumped shared-library (so-number) and dll-number to 3. version 1.2.0beta4 [June 23, 2001] Check for missing profile length field in iCCP chunk and free chunk_data in case of truncated iCCP chunk. Bumped shared-library number to 3 in makefile.sgi and makefile.sggcc Bumped dll-number from 2 to 3 in makefile.cygwin Revised contrib/gregbook/rpng*-x.c to avoid a memory leak and to exit cleanly if user attempts to run it on an 8-bit display. Updated contrib/gregbook Use png_malloc instead of png_zalloc to allocate palette in pngset.c Updated makefile.ibmc Added some typecasts to eliminate gcc 3.0 warnings. Changed prototypes of png_write_oFFS width and height from png_uint_32 to png_int_32. Updated example.c Revised prototypes for png_debug_malloc and png_debug_free in pngtest.c version 1.2.0beta5 [August 8, 2001] Revised contrib/gregbook Revised makefile.gcmmx Revised pnggccrd.c to conditionally compile some thread-unsafe code only when PNG_THREAD_UNSAFE_OK is defined. Added tests to prevent pngwutil.c from writing a bKGD or tRNS chunk with value exceeding 2^bit_depth-1 Revised makefile.sgi and makefile.sggcc Replaced calls to fprintf(stderr,...) with png_warning() in pnggccrd.c Removed restriction that do_invert_mono only operate on 1-bit opaque files version 1.2.0 [September 1, 2001] Changed a png_warning() to png_debug() in pnggccrd.c Fixed contrib/gregbook/rpng-x.c, rpng2-x.c to avoid crash with XFreeGC(). version 1.2.1beta1 [October 19, 2001] Revised makefile.std in contrib/pngminus Include background_1 in png_struct regardless of gamma support. Revised makefile.netbsd and makefile.macosx, added makefile.darwin. Revised example.c to provide more details about using row_callback(). version 1.2.1beta2 [October 25, 2001] Added type cast to each NULL appearing in a function call, except for WINCE functions. Added makefile.so9. version 1.2.1beta3 [October 27, 2001] Removed type casts from all NULLs. Simplified png_create_struct_2(). version 1.2.1beta4 [November 7, 2001] Revised png_create_info_struct() and png_creat_struct_2(). Added error message if png_write_info() was omitted. Type cast NULLs appearing in function calls when _NO_PROTO or PNG_TYPECAST_NULL is defined. version 1.2.1rc1 [November 24, 2001] Type cast NULLs appearing in function calls except when PNG_NO_TYPECAST_NULL is defined. Changed typecast of "size" argument to png_size_t in pngmem.c calls to the user malloc_fn, to agree with the prototype in png.h Added a pop/push operation to pnggccrd.c, to preserve Eflag (Maxim Sobolev) Updated makefile.sgi to recognize LIBPATH and INCPATH. Updated various makefiles so "make clean" does not remove previous major version of the shared library. version 1.2.1rc2 [December 4, 2001] Always allocate 256-entry internal palette, hist, and trans arrays, to avoid out-of-bounds memory reference caused by invalid PNG datastreams. Added a check for prefix_length > data_length in iCCP chunk handler. version 1.2.1 [December 7, 2001] None. version 1.2.2beta1 [February 22, 2002] Fixed a bug with reading the length of iCCP profiles (Larry Reeves). Revised makefile.linux, makefile.gcmmx, and makefile.sgi to generate libpng.a, libpng12.so (not libpng.so.3), and libpng12/png.h Revised makefile.darwin to remove "-undefined suppress" option. Added checks for gamma and chromaticity values over 21474.83, which exceed the limit for PNG unsigned 32-bit integers when encoded. Revised calls to png_create_read_struct() and png_create_write_struct() for simpler debugging. Revised png_zalloc() so zlib handles errors (uses PNG_FLAG_MALLOC_NULL_MEM_OK) version 1.2.2beta2 [February 23, 2002] Check chunk_length and idat_size for invalid (over PNG_MAX_UINT) lengths. Check for invalid image dimensions in png_get_IHDR. Added missing "fi;" in the install target of the SGI makefiles. Added install-static to all makefiles that make shared libraries. Always do gamma compensation when image is partially transparent. version 1.2.2beta3 [March 7, 2002] Compute background.gray and background_1.gray even when color_type is RGB in case image gets reduced to gray later. Modified shared-library makefiles to install pkgconfig/libpngNN.pc. Export (with PNGAPI) png_zalloc, png_zfree, and png_handle_as_unknown Removed unused png_write_destroy_info prototype from png.h Eliminated incorrect use of width_mmx from pnggccrd.c in pixel_bytes == 8 case Added install-shared target to all makefiles that make shared libraries. Stopped a double free of palette, hist, and trans when not using free_me. Added makefile.32sunu for Sun Ultra 32 and makefile.64sunu for Sun Ultra 64. version 1.2.2beta4 [March 8, 2002] Compute background.gray and background_1.gray even when color_type is RGB in case image gets reduced to gray later (Jason Summers). Relocated a misplaced /bin/rm in the "install-shared" makefile targets Added PNG_1_0_X macro which can be used to build a 1.0.x-compatible library. version 1.2.2beta5 [March 26, 2002] Added missing PNGAPI to several function definitions. Check for invalid bit_depth or color_type in png_get_IHDR(), and check for missing PLTE or IHDR in png_push_read_chunk() (Matthias Clasen). Revised iTXt support to accept NULL for lang and lang_key. Compute gamma for color components of background even when color_type is gray. Changed "()" to "{}" in scripts/libpng.pc.in. Revised makefiles to put png.h and pngconf.h only in $prefix/include/libpngNN Revised makefiles to make symlink to libpng.so.NN in addition to libpngNN.so version 1.2.2beta6 [March 31, 2002] version 1.0.13beta1 [March 31, 2002] Prevent png_zalloc() from trying to memset memory that it failed to acquire. Add typecasts of PNG_MAX_UINT in pngset_cHRM_fixed() (Matt Holgate). Ensure that the right function (user or default) is used to free the png_struct after an error in png_create_read_struct_2(). version 1.2.2rc1 [April 7, 2002] version 1.0.13rc1 [April 7, 2002] Save the ebx register in pnggccrd.c (Sami Farin) Add "mem_ptr = png_ptr->mem_ptr" in png_destroy_write_struct() (Paul Gardner). Updated makefiles to put headers in include/libpng and remove old include/*.h. version 1.2.2 [April 15, 2002] version 1.0.13 [April 15, 2002] Revised description of png_set_filter() in libpng.3/libpng.txt. Revised makefile.netbsd and added makefile.neNNbsd and makefile.freebsd version 1.0.13patch01 [April 17, 2002] version 1.2.2patch01 [April 17, 2002] Changed ${PNGMAJ}.${PNGVER} bug to ${PNGVER} in makefile.sgi and makefile.sggcc Fixed VER -> PNGVER typo in makefile.macosx and added install-static to install Added install: target to makefile.32sunu and makefile.64sunu version 1.0.13patch03 [April 18, 2002] version 1.2.2patch03 [April 18, 2002] Revised 15 makefiles to link libpng.a to libpngNN.a and the include libpng subdirectory to libpngNN subdirectory without the full pathname. Moved generation of libpng.pc from "install" to "all" in 15 makefiles. version 1.2.3rc1 [April 28, 2002] Added install-man target to 15 makefiles (Dimitri Papadopolous-Orfanos). Added $(DESTDIR) feature to 24 makefiles (Tim Mooney) Fixed bug with $prefix, should be $(prefix) in makefile.hpux. Updated cygwin-specific portion of pngconf.h and revised makefile.cygwin Added a link from libpngNN.pc to libpng.pc in 15 makefiles. Added links from include/libpngNN/*.h to include/*.h in 24 makefiles. Revised makefile.darwin to make relative links without full pathname. Added setjmp() at the end of png_create_*_struct_2() in case user forgets to put one in their application. Restored png_zalloc() and png_zfree() prototypes to version 1.2.1 and removed them from module definition files. version 1.2.3rc2 [May 1, 2002] Fixed bug in reporting number of channels in pngget.c and pngset.c, that was introduced in version 1.2.2beta5. Exported png_zalloc(), png_zfree(), png_default_read(), png_default_write(), png_default_flush(), and png_push_fill_buffer() and included them in module definition files. Added "libpng.pc" dependency to the "install-shared" target in 15 makefiles. version 1.2.3rc3 [May 1, 2002] Revised prototype for png_default_flush() Remove old libpng.pc and libpngNN.pc before installing new ones. version 1.2.3rc4 [May 2, 2002] Typos in *.def files (png_default_read|write -> png_default_read|write_data) In makefiles, changed rm libpng.NN.pc to rm libpngNN.pc Added libpng-config and libpngNN-config and modified makefiles to install them. Changed $(MANPATH) to $(DESTDIR)$(MANPATH) in makefiles Added "Win32 DLL VB" configuration to projects/msvc/libpng.dsp version 1.2.3rc5 [May 11, 2002] Changed "error" and "message" in prototypes to "error_message" and "warning_message" to avoid namespace conflict. Revised 15 makefiles to build libpng-config from libpng-config-*.in Once more restored png_zalloc and png_zfree to regular nonexported form. Restored png_default_read|write_data, png_default_flush, png_read_fill_buffer to nonexported form, but with PNGAPI, and removed them from module def files. version 1.2.3rc6 [May 14, 2002] Removed "PNGAPI" from png_zalloc() and png_zfree() in png.c Changed "Gz" to "Gd" in projects/msvc/libpng.dsp and zlib.dsp. Removed leftover libpng-config "sed" script from four makefiles. Revised libpng-config creating script in 16 makefiles. version 1.2.3 [May 22, 2002] Revised libpng-config target in makefile.cygwin. Removed description of png_set_mem_fn() from documentation. Revised makefile.freebsd. Minor cosmetic changes to 15 makefiles, e.g., $(DI) = $(DESTDIR)/$(INCDIR). Revised projects/msvc/README.txt Changed -lpng to -lpngNN in LDFLAGS in several makefiles. version 1.2.4beta1 [May 24, 2002] Added libpng.pc and libpng-config to "all:" target in 16 makefiles. Fixed bug in 16 makefiles: $(DESTDIR)/$(LIBPATH) to $(DESTDIR)$(LIBPATH) Added missing "\" before closing double quote in makefile.gcmmx. Plugged various memory leaks; added png_malloc_warn() and png_set_text_2() functions. version 1.2.4beta2 [June 25, 2002] Plugged memory leak of png_ptr->current_text (Matt Holgate). Check for buffer overflow before reading CRC in pngpread.c (Warwick Allison) Added -soname to the loader flags in makefile.dec, makefile.sgi, and makefile.sggcc. Added "test-installed" target to makefile.linux, makefile.gcmmx, makefile.sgi, and makefile.sggcc. version 1.2.4beta3 [June 28, 2002] Plugged memory leak of row_buf in pngtest.c when there is a png_error(). Detect buffer overflow in pngpread.c when IDAT is corrupted with extra data. Added "test-installed" target to makefile.32sunu, makefile.64sunu, makefile.beos, makefile.darwin, makefile.dec, makefile.macosx, makefile.solaris, makefile.hpux, makefile.hpgcc, and makefile.so9. version 1.2.4rc1 and 1.0.14rc1 [July 2, 2002] Added "test-installed" target to makefile.cygwin and makefile.sco. Revised pnggccrd.c to be able to back out version 1.0.x via PNG_1_0_X macro. version 1.2.4 and 1.0.14 [July 8, 2002] Changed png_warning() to png_error() when width is too large to process. version 1.2.4patch01 [July 20, 2002] Revised makefile.cygwin to use DLL number 12 instead of 13. version 1.2.5beta1 [August 6, 2002] Added code to contrib/gregbook/readpng2.c to ignore unused chunks. Replaced toucan.png in contrib/gregbook (it has been corrupt since 1.0.11) Removed some stray *.o files from contrib/gregbook. Changed png_error() to png_warning() about "Too much data" in pngpread.c and about "Extra compressed data" in pngrutil.c. Prevent png_ptr->pass from exceeding 7 in png_push_finish_row(). Updated makefile.hpgcc Updated png.c and pnggccrd.c handling of return from png_mmx_support() version 1.2.5beta2 [August 15, 2002] Only issue png_warning() about "Too much data" in pngpread.c when avail_in is nonzero. Updated makefiles to install a separate libpng.so.3 with its own rpath. version 1.2.5rc1 and 1.0.15rc1 [August 24, 2002] Revised makefiles to not remove previous minor versions of shared libraries. version 1.2.5rc2 and 1.0.15rc2 [September 16, 2002] Revised 13 makefiles to remove "-lz" and "-L$(ZLIBLIB)", etc., from shared library loader directive. Added missing "$OBJSDLL" line to makefile.gcmmx. Added missing "; fi" to makefile.32sunu. version 1.2.5rc3 and 1.0.15rc3 [September 18, 2002] Revised libpng-config script. version 1.2.5 and 1.0.15 [October 3, 2002] Revised makefile.macosx, makefile.darwin, makefile.hpgcc, and makefile.hpux, and makefile.aix. Relocated two misplaced PNGAPI lines in pngtest.c version 1.2.6beta1 [October 22, 2002] Commented out warning about uninitialized mmx_support in pnggccrd.c. Changed "IBMCPP__" flag to "__IBMCPP__" in pngconf.h. Relocated two more misplaced PNGAPI lines in pngtest.c Fixed memory overrun bug in png_do_read_filler() with 16-bit datastreams, introduced in version 1.0.2. Revised makefile.macosx, makefile.dec, makefile.aix, and makefile.32sunu. version 1.2.6beta2 [November 1, 2002] Added libpng-config "--ldopts" output. Added "AR=ar" and "ARFLAGS=rc" and changed "ar rc" to "$(AR) $(ARFLAGS)" in makefiles. version 1.2.6beta3 [July 18, 2004] Reverted makefile changes from version 1.2.6beta2 and some of the changes from version 1.2.6beta1; these will be postponed until version 1.2.7. Version 1.2.6 is going to be a simple bugfix release. Changed the one instance of "ln -sf" to "ln -f -s" in each Sun makefile. Fixed potential overrun in pngerror.c by using strncpy instead of memcpy. Added "#!/bin/sh" at the top of configure, for recognition of the 'x' flag under Cygwin (Cosmin). Optimized vacuous tests that silence compiler warnings, in png.c (Cosmin). Added support for PNG_USER_CONFIG, in pngconf.h (Cosmin). Fixed the special memory handler for Borland C under DOS, in pngmem.c (Cosmin). Removed some spurious assignments in pngrutil.c (Cosmin). Replaced 65536 with 65536L, and 0xffff with 0xffffL, to silence warnings on 16-bit platforms (Cosmin). Enclosed shift op expressions in parentheses, to silence warnings (Cosmin). Used proper type png_fixed_point, to avoid problems on 16-bit platforms, in png_handle_sRGB() (Cosmin). Added compression_type to png_struct, and optimized the window size inside the deflate stream (Cosmin). Fixed definition of isnonalpha(), in pngerror.c and pngrutil.c (Cosmin). Fixed handling of unknown chunks that come after IDAT (Cosmin). Allowed png_error() and png_warning() to work even if png_ptr == NULL (Cosmin). Replaced row_info->rowbytes with row_bytes in png_write_find_filter() (Cosmin). Fixed definition of PNG_LIBPNG_VER_DLLNUM (Simon-Pierre). Used PNG_LIBPNG_VER and PNG_LIBPNG_VER_STRING instead of the hardcoded values in png.c (Simon-Pierre, Cosmin). Initialized png_libpng_ver[] with PNG_LIBPNG_VER_STRING (Simon-Pierre). Replaced PNG_LIBPNG_VER_MAJOR with PNG_LIBPNG_VER_DLLNUM in png.rc (Simon-Pierre). Moved the definition of PNG_HEADER_VERSION_STRING near the definitions of the other PNG_LIBPNG_VER_... symbols in png.h (Cosmin). Relocated #ifndef PNGAPI guards in pngconf.h (Simon-Pierre, Cosmin). Updated scripts/makefile.vc(a)win32 (Cosmin). Updated the MSVC project (Simon-Pierre, Cosmin). Updated the Borland C++ Builder project (Cosmin). Avoided access to asm_flags in pngvcrd.c, if PNG_1_0_X is defined (Cosmin). Commented out warning about uninitialized mmx_support in pngvcrd.c (Cosmin). Removed scripts/makefile.bd32 and scripts/pngdef.pas (Cosmin). Added extra guard around inclusion of Turbo C memory headers, in pngconf.h (Cosmin). Renamed projects/msvc/ to projects/visualc6/, and projects/borland/ to projects/cbuilder5/ (Cosmin). Moved projects/visualc6/png32ms.def to scripts/pngw32.def, and projects/visualc6/png.rc to scripts/pngw32.rc (Cosmin). Added projects/visualc6/pngtest.dsp; removed contrib/msvctest/ (Cosmin). Changed line endings to DOS style in cbuilder5 and visualc6 files, even in the tar.* distributions (Cosmin). Updated contrib/visupng/VisualPng.dsp (Cosmin). Updated contrib/visupng/cexcept.h to version 2.0.0 (Cosmin). Added a separate distribution with "configure" and supporting files (Junichi). version 1.2.6beta4 [July 28, 2004] Added user ability to change png_size_t via a PNG_SIZE_T macro. Added png_sizeof() and png_convert_size() functions. Added PNG_SIZE_MAX (maximum value of a png_size_t variable. Added check in png_malloc_default() for (size_t)size != (png_uint_32)size which would indicate an overflow. Changed sPLT failure action from png_error to png_warning and abandon chunk. Changed sCAL and iCCP failures from png_error to png_warning and abandon. Added png_get_uint_31(png_ptr, buf) function. Added PNG_UINT_32_MAX macro. Renamed PNG_MAX_UINT to PNG_UINT_31_MAX. Made png_zalloc() issue a png_warning and return NULL on potential overflow. Turn on PNG_NO_ZALLOC_ZERO by default in version 1.2.x Revised "clobber list" in pnggccrd.c so it will compile under gcc-3.4. Revised Borland portion of png_malloc() to return NULL or issue png_error() according to setting of PNG_FLAG_MALLOC_NULL_MEM_OK. Added PNG_NO_SEQUENTIAL_READ_SUPPORTED macro to conditionally remove sequential read support. Added some "#if PNG_WRITE_SUPPORTED" blocks. #ifdef'ed out some redundancy in png_malloc_default(). Use png_malloc instead of png_zalloc to allocate the pallete. version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004] Fixed buffer overflow vulnerability in png_handle_tRNS() Fixed integer arithmetic overflow vulnerability in png_read_png(). Fixed some harmless bugs in png_handle_sBIT, etc, that would cause duplicate chunk types to go undetected. Fixed some timestamps in the -config version Rearranged order of processing of color types in png_handle_tRNS(). Added ROWBYTES macro to calculate rowbytes without integer overflow. Updated makefile.darwin and removed makefile.macosx from scripts directory. Imposed default one million column, one-million row limits on the image dimensions, and added png_set_user_limits() function to override them. Revised use of PNG_SET_USER_LIMITS_SUPPORTED macro. Fixed wrong cast of returns from png_get_user_width|height_max(). Changed some "keep the compiler happy" from empty statements to returns, Revised libpng.txt to remove 1.2.x stuff from the 1.0.x distribution version 1.0.16rc2 and 1.2.6rc2 [August 7, 2004] Revised makefile.darwin and makefile.solaris. Removed makefile.macosx. Revised pngtest's png_debug_malloc() to use png_malloc() instead of png_malloc_default() which is not supposed to be exported. Fixed off-by-one error in one of the conversions to PNG_ROWBYTES() in pngpread.c. Bug was introduced in 1.2.6rc1. Fixed bug in RGB to RGBX transformation introduced in 1.2.6rc1. Fixed old bug in RGB to Gray transformation. Fixed problem with 64-bit compilers by casting arguments to abs() to png_int_32. Changed "ln -sf" to "ln -f -s" in three makefiles (solaris, sco, so9). Changed "HANDLE_CHUNK_*" to "PNG_HANDLE_CHUNK_*" (Cosmin) Added "-@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGMAJ)" to 15 *NIX makefiles. Added code to update the row_info->colortype in png_do_read_filler() (MSB). version 1.0.16rc3 and 1.2.6rc3 [August 9, 2004] Eliminated use of "abs()" in testing cHRM and gAMA values, to avoid trouble with some 64-bit compilers. Created PNG_OUT_OF_RANGE() macro. Revised documentation of png_set_keep_unknown_chunks(). Check handle_as_unknown status in pngpread.c, as in pngread.c previously. Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_INTERNAL section of png.h Added "rim" definitions for CONST4 and CONST6 in pnggccrd.c version 1.0.16rc4 and 1.2.6rc4 [August 10, 2004] Fixed mistake in pngtest.c introduced in 1.2.6rc2 (declaration of "pinfo" was out of place). version 1.0.16rc5 and 1.2.6rc5 [August 10, 2004] Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_ASSEMBLER_CODE_SUPPORTED section of png.h where they were inadvertently placed in version rc3. version 1.0.16 and 1.2.6 [August 15, 2004] Revised pngtest so memory allocation testing is only done when PNG_DEBUG==1. version 1.2.7beta1 [August 26, 2004] Removed unused pngasmrd.h file. Removed references to uu.net for archived files. Added references to PNG Spec (second edition) and the PNG ISO/IEC Standard. Added "test-dd" target in 15 makefiles, to run pngtest in DESTDIR. Fixed bug with "optimized window size" in the IDAT datastream, that causes libpng to write PNG files with incorrect zlib header bytes. version 1.2.7beta2 [August 28, 2004] Fixed bug with sCAL chunk and big-endian machines (David Munro). Undid new code added in 1.2.6rc2 to update the color_type in png_set_filler(). Added png_set_add_alpha() that updates color type. version 1.0.17rc1 and 1.2.7rc1 [September 4, 2004] Revised png_set_strip_filler() to not remove alpha if color_type has alpha. version 1.0.17 and 1.2.7 [September 12, 2004] Added makefile.hp64 Changed projects/msvc/png32ms.def to scripts/png32ms.def in makefile.cygwin version 1.2.8beta1 [November 1, 2004] Fixed bug in png_text_compress() that would fail to complete a large block. Fixed bug, introduced in libpng-1.2.7, that overruns a buffer during strip alpha operation in png_do_strip_filler(). Added PNG_1_2_X definition in pngconf.h #ifdef out png_info_init in png.c and png_read_init in pngread.c (as of 1.3.0) version 1.2.8beta2 [November 2, 2004] Reduce color_type to a nonalpha type after strip alpha operation in png_do_strip_filler(). version 1.2.8beta3 [November 3, 2004] Revised definitions of PNG_MAX_UINT_32, PNG_MAX_SIZE, and PNG_MAXSUM version 1.2.8beta4 [November 12, 2004] Fixed (again) definition of PNG_LIBPNG_VER_DLLNUM in png.h (Cosmin). Added PNG_LIBPNG_BUILD_PRIVATE in png.h (Cosmin). Set png_ptr->zstream.data_type to Z_BINARY, to avoid unnecessary detection of data type in deflate (Cosmin). Deprecated but continue to support SPECIALBUILD and PRIVATEBUILD in favor of PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. version 1.2.8beta5 [November 20, 2004] Use png_ptr->flags instead of png_ptr->transformations to pass PNG_STRIP_ALPHA info to png_do_strip_filler(), to preserve ABI compatibility. Revised handling of SPECIALBUILD, PRIVATEBUILD, PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. version 1.2.8rc1 [November 24, 2004] Moved handling of BUILD macros from pngconf.h to png.h Added definition of PNG_LIBPNG_BASE_TYPE in png.h, inadvertently omitted from beta5. Revised scripts/pngw32.rc Despammed mailing addresses by masking "@" with "at". Inadvertently installed a supposedly faster test version of pngrutil.c version 1.2.8rc2 [November 26, 2004] Added two missing "\" in png.h Change tests in pngread.c and pngpread.c to if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) png_do_read_transformations(png_ptr); version 1.2.8rc3 [November 28, 2004] Reverted pngrutil.c to version libpng-1.2.8beta5. Added scripts/makefile.elf with supporting code in pngconf.h for symbol versioning (John Bowler). version 1.2.8rc4 [November 29, 2004] Added projects/visualc7 (Simon-pierre). version 1.2.8rc5 [November 29, 2004] Fixed new typo in scripts/pngw32.rc version 1.2.8 [December 3, 2004] Removed projects/visualc7, added projects/visualc71. Send comments/corrections/commendations to png-implement at ccrc.wustl.edu (subscription required; write to majordomo at ccrc.wustl.edu with "subscribe png-implement" in the message) or to glennrp at users.sourceforge.net Glenn R-P syslinux-legacy-3.63+dfsg/com32/lib/libpng/README0000664000175000017500000003324410777447272020045 0ustar evanevanREADME for libpng version 1.2.8 - December 3, 2004 (shared library 12.0) See the note about version numbers near the top of png.h See INSTALL for instructions on how to install libpng. Libpng comes in several distribution formats. Get libpng-*.tar.gz or libpng-*.tar.bz2 if you want UNIX-style line endings in the text files, or lpng*.zip if you want DOS-style line endings. Version 0.89 was the first official release of libpng. Don't let the fact that it's the first release fool you. The libpng library has been in extensive use and testing since mid-1995. By late 1997 it had finally gotten to the stage where there hadn't been significant changes to the API in some time, and people have a bad feeling about libraries with versions < 1.0. Version 1.0.0 was released in March 1998. **** Note that some of the changes to the png_info structure render this version of the library binary incompatible with libpng-0.89 or earlier versions if you are using a shared library. The type of the "filler" parameter for png_set_filler() has changed from png_byte to png_uint_32, which will affect shared-library applications that use this function. To avoid problems with changes to the internals of png_info_struct, new APIs have been made available in 0.95 to avoid direct application access to info_ptr. These functions are the png_set_ and png_get_ functions. These functions should be used when accessing/storing the info_struct data, rather than manipulating it directly, to avoid such problems in the future. It is important to note that the APIs do not make current programs that access the info struct directly incompatible with the new library. However, it is strongly suggested that new programs use the new APIs (as shown in example.c and pngtest.c), and older programs be converted to the new format, to facilitate upgrades in the future. **** Additions since 0.90 include the ability to compile libpng as a Windows DLL, and new APIs for accessing data in the info struct. Experimental functions include the ability to set weighting and cost factors for row filter selection, direct reads of integers from buffers on big-endian processors that support misaligned data access, faster methods of doing alpha composition, and more accurate 16->8 bit color conversion. The additions since 0.89 include the ability to read from a PNG stream which has had some (or all) of the signature bytes read by the calling application. This also allows the reading of embedded PNG streams that do not have the PNG file signature. As well, it is now possible to set the library action on the detection of chunk CRC errors. It is possible to set different actions based on whether the CRC error occurred in a critical or an ancillary chunk. The changes made to the library, and bugs fixed are based on discussions on the PNG-implement mailing list and not on material submitted privately to Guy, Andreas, or Glenn. They will forward any good suggestions to the list. For a detailed description on using libpng, read libpng.txt. For examples of libpng in a program, see example.c and pngtest.c. For usage information and restrictions (what little they are) on libpng, see png.h. For a description on using zlib (the compression library used by libpng) and zlib's restrictions, see zlib.h I have included a general makefile, as well as several machine and compiler specific ones, but you may have to modify one for your own needs. You should use zlib 1.0.4 or later to run this, but it MAY work with versions as old as zlib 0.95. Even so, there are bugs in older zlib versions which can cause the output of invalid compression streams for some images. You will definitely need zlib 1.0.4 or later if you are taking advantage of the MS-DOS "far" structure allocation for the small and medium memory models. You should also note that zlib is a compression library that is useful for more things than just PNG files. You can use zlib as a drop-in replacement for fread() and fwrite() if you are so inclined. zlib should be available at the same place that libpng is, or at. ftp://ftp.info-zip.org/pub/infozip/zlib You may also want a copy of the PNG specification. It is available as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find these at http://www.libpng.org/pub/png/documents/ This code is currently being archived at libpng.sf.net in the [DOWNLOAD] area, and on CompuServe, Lib 20 (PNG SUPPORT) at GO GRAPHSUP. If you can't find it in any of those places, e-mail me, and I'll help you find it. If you have any code changes, requests, problems, etc., please e-mail them to me. Also, I'd appreciate any make files or project files, and any modifications you needed to make to get libpng to compile, along with a #define variable to tell what compiler/system you are on. If you needed to add transformations to libpng, or wish libpng would provide the image in a different way, drop me a note (and code, if possible), so I can consider supporting the transformation. Finally, if you get any warning messages when compiling libpng (note: not zlib), and they are easy to fix, I'd appreciate the fix. Please mention "libpng" somewhere in the subject line. Thanks. This release was created and will be supported by myself (of course based in a large way on Guy's and Andreas' earlier work), and the PNG group. glennrp at users.sourceforge.net png-implement at ccrc.wustl.edu (subscription required; write to majordomo at ccrc.wustl.edu with "subscribe png-implement" in the message). You can't reach Guy, the original libpng author, at the addresses given in previous versions of this document. He and Andreas will read mail addressed to the png-implement list, however. Please do not send general questions about PNG. Send them to the (png-list at ccrc.wustl.edu, subscription required, write to majordomo at ccrc.wustl.edu with "subscribe png-list" in your message). On the other hand, please do not send libpng questions to that address, send them to me or to the png-implement list. I'll get them in the end anyway. If you have a question about something in the PNG specification that is related to using libpng, send it to me. Send me any questions that start with "I was using libpng, and ...". If in doubt, send questions to me. I'll bounce them to others, if necessary. Please do not send suggestions on how to change PNG. We have been discussing PNG for nine years now, and it is official and finished. If you have suggestions for libpng, however, I'll gladly listen. Even if your suggestion is not used immediately, it may be used later. Files in this distribution: ANNOUNCE => Announcement of this version, with recent changes CHANGES => Description of changes between libpng versions KNOWNBUG => List of known bugs and deficiencies LICENSE => License to use and redistribute libpng README => This file TODO => Things not implemented in the current library Y2KINFO => Statement of Y2K compliance example.c => Example code for using libpng functions libpng.3 => manual page for libpng (includes libpng.txt) libpng.txt => Description of libpng and its functions libpngpf.3 => manual page for libpng's private functions png.5 => manual page for the PNG format png.c => Basic interface functions common to library png.h => Library function and interface declarations pngconf.h => System specific library configuration pngasmrd.h => Header file for assembler-coded functions pngerror.c => Error/warning message I/O functions pngget.c => Functions for retrieving info from struct pngmem.c => Memory handling functions pngbar.png => PNG logo, 88x31 pngnow.png => PNG logo, 98x31 pngpread.c => Progressive reading functions pngread.c => Read data/helper high-level functions pngrio.c => Lowest-level data read I/O functions pngrtran.c => Read data transformation functions pngrutil.c => Read data utility functions pngset.c => Functions for storing data into the info_struct pngtest.c => Library test program pngtest.png => Library test sample image pngtrans.c => Common data transformation functions pngwio.c => Lowest-level write I/O functions pngwrite.c => High-level write functions pngwtran.c => Write data transformations pngwutil.c => Write utility functions contrib => Contributions gregbook => source code for PNG reading and writing, from Greg Roelofs' "PNG: The Definitive Guide", O'Reilly, 1999 msvctest => Builds and runs pngtest using a MSVC workspace pngminus => Simple pnm2png and png2pnm programs pngsuite => Test images visupng => Contains a MSVC workspace for VisualPng projects => Contains project files and workspaces for building DLL beos => Contains a Beos workspace for building libpng c5builder => Contains a Borland workspace for building libpng and zlib visualc6 => Contains a Microsoft Visual C++ (MSVC) workspace for building libpng and zlib netware.txt => Contains instructions for downloading a set of project files for building libpng and zlib on Netware. wince.txt => Contains instructions for downloading a Microsoft Visual C++ (Windows CD Toolkit) workspace for building libpng and zlib on WindowsCE scripts => Directory containing scripts for building libpng: descrip.mms => VMS makefile for MMS or MMK makefile.std => Generic UNIX makefile (cc, creates static libpng.a) makefile.elf => Linux/ELF makefile symbol versioning, gcc, creates libpng12.so.0.1.2.8) makefile.linux => Linux/ELF makefile (gcc, creates libpng12.so.0.1.2.8) makefile.gcmmx => Linux/ELF makefile (gcc, creates libpng12.so.0.1.2.8, uses assembler code tuned for Intel MMX platform) makefile.gcc => Generic makefile (gcc, creates static libpng.a) makefile.knr => Archaic UNIX Makefile that converts files with ansi2knr (Requires ansi2knr.c from ftp://ftp.cs.wisc.edu/ghost) makefile.aix => AIX makefile makefile.cygwin => Cygwin/gcc makefile makefile.darwin => Darwin makefile makefile.dec => DEC Alpha UNIX makefile makefile.freebsd => FreeBSD makefile makefile.hpgcc => HPUX makefile using gcc makefile.hpux => HPUX (10.20 and 11.00) makefile makefile.hp64 => HPUX (10.20 and 11.00) makefile, 64 bit makefile.ibmc => IBM C/C++ version 3.x for Win32 and OS/2 (static) makefile.intel => Intel C/C++ version 4.0 and later libpng.icc => Project file, IBM VisualAge/C++ 4.0 or later makefile.netbsd => NetBSD/cc makefile, PNGGCCRD, makes libpng.so. makefile.ne12bsd => NetBSD/cc makefile, PNGGCCRD, makes libpng12.so makefile.openbsd => OpenBSD makefile makefile.sgi => Silicon Graphics IRIX (cc, creates static lib) makefile.sggcc => Silicon Graphics (gcc, creates libpng12.so.0.1.2.8) makefile.sunos => Sun makefile makefile.solaris => Solaris 2.X makefile (gcc, creates libpng12.so.0.1.2.8) makefile.so9 => Solaris 9 makefile (gcc, creates libpng12.so.0.1.2.8) makefile.32sunu => Sun Ultra 32-bit makefile makefile.64sunu => Sun Ultra 64-bit makefile makefile.sco => For SCO OSr5 ELF and Unixware 7 with Native cc makefile.mips => MIPS makefile makefile.acorn => Acorn makefile makefile.amiga => Amiga makefile smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC compiler (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc) makefile.atari => Atari makefile makefile.beos => BEOS makefile for X86 makefile.bor => Borland makefile (uses bcc) makefile.bc32 => 32-bit Borland C++ (all modules compiled in C mode) makefile.tc3 => Turbo C 3.0 makefile makefile.dj2 => DJGPP 2 makefile makefile.msc => Microsoft C makefile makefile.vcawin32=> makefile for Microsoft Visual C++ 5.0 and later (uses assembler code tuned for Intel MMX platform) makefile.vcwin32 => makefile for Microsoft Visual C++ 4.0 and later (does not use assembler code) makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def) pngos2.def => OS/2 module definition file used by makefile.os2 makefile.watcom => Watcom 10a+ Makefile, 32-bit flat memory model makevms.com => VMS build script SCOPTIONS.ppc => Used with smakefile.ppc Good luck, and happy coding. -Glenn Randers-Pehrson (current maintainer) Internet: glennrp at users.sourceforge.net -Andreas Eric Dilger (former maintainer, 1996-1997) Internet: adilger at enel.ucalgary.ca Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/ -Guy Eric Schalnat (original author and former maintainer, 1995-1996) (formerly of Group 42, Inc) Internet: gschal at infinet.com syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngerror.c0000664000175000017500000002063010777447272021162 0ustar evanevan /* pngerror.c - stub functions for i/o and memory allocation * * libpng version 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * * This file provides a location for all error handling. Users who * need special error handling are expected to write replacement functions * and use png_set_error_fn() to use those functions. See the instructions * at each function. */ #define PNG_INTERNAL #include "png.h" static void /* PRIVATE */ png_default_error PNGARG((png_structp png_ptr, png_const_charp error_message)); static void /* PRIVATE */ png_default_warning PNGARG((png_structp png_ptr, png_const_charp warning_message)); /* This function is called whenever there is a fatal error. This function * should not be changed. If there is a need to handle errors differently, * you should supply a replacement error function and use png_set_error_fn() * to replace the error function at run-time. */ void PNGAPI png_error(png_structp png_ptr, png_const_charp error_message) { #ifdef PNG_ERROR_NUMBERS_SUPPORTED char msg[16]; if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) { if (*error_message == '#') { int offset; for (offset=1; offset<15; offset++) if (*(error_message+offset) == ' ') break; if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) { int i; for (i=0; iflags&PNG_FLAG_STRIP_ERROR_TEXT) { msg[0]='0'; msg[1]='\0'; error_message=msg; } } } #endif if (png_ptr != NULL && png_ptr->error_fn != NULL) (*(png_ptr->error_fn))(png_ptr, error_message); /* If the custom handler doesn't exist, or if it returns, use the default handler, which will not return. */ png_default_error(png_ptr, error_message); } /* This function is called whenever there is a non-fatal error. This function * should not be changed. If there is a need to handle warnings differently, * you should supply a replacement warning function and use * png_set_error_fn() to replace the warning function at run-time. */ void PNGAPI png_warning(png_structp png_ptr, png_const_charp warning_message) { int offset = 0; #ifdef PNG_ERROR_NUMBERS_SUPPORTED if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) #endif { if (*warning_message == '#') { for (offset=1; offset<15; offset++) if (*(warning_message+offset) == ' ') break; } } if (png_ptr != NULL && png_ptr->warning_fn != NULL) (*(png_ptr->warning_fn))(png_ptr, warning_message+offset); else png_default_warning(png_ptr, warning_message+offset); } /* These utilities are used internally to build an error message that relates * to the current chunk. The chunk name comes from png_ptr->chunk_name, * this is used to prefix the message. The message is limited in length * to 63 bytes, the name characters are output as hex digits wrapped in [] * if the character is invalid. */ #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) static PNG_CONST char png_digit[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; static void /* PRIVATE */ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp error_message) { int iout = 0, iin = 0; while (iin < 4) { int c = png_ptr->chunk_name[iin++]; if (isnonalpha(c)) { buffer[iout++] = '['; buffer[iout++] = png_digit[(c & 0xf0) >> 4]; buffer[iout++] = png_digit[c & 0x0f]; buffer[iout++] = ']'; } else { buffer[iout++] = (png_byte)c; } } if (error_message == NULL) buffer[iout] = 0; else { buffer[iout++] = ':'; buffer[iout++] = ' '; png_strncpy(buffer+iout, error_message, 63); buffer[iout+63] = 0; } } void PNGAPI png_chunk_error(png_structp png_ptr, png_const_charp error_message) { char msg[18+64]; png_format_buffer(png_ptr, msg, error_message); png_error(png_ptr, msg); } void PNGAPI png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) { char msg[18+64]; png_format_buffer(png_ptr, msg, warning_message); png_warning(png_ptr, msg); } /* This is the default error handling function. Note that replacements for * this function MUST NOT RETURN, or the program will likely crash. This * function is used by default, or if the program supplies NULL for the * error function pointer in png_set_error_fn(). */ static void /* PRIVATE */ png_default_error(png_structp png_ptr, png_const_charp error_message) { #ifndef PNG_NO_CONSOLE_IO #ifdef PNG_ERROR_NUMBERS_SUPPORTED if (*error_message == '#') { int offset; char error_number[16]; for (offset=0; offset<15; offset++) { error_number[offset] = *(error_message+offset+1); if (*(error_message+offset) == ' ') break; } if((offset > 1) && (offset < 15)) { error_number[offset-1]='\0'; fprintf(stderr, "libpng error no. %s: %s\n", error_number, error_message+offset); } else fprintf(stderr, "libpng error: %s, offset=%d\n", error_message,offset); } else #endif fprintf(stderr, "libpng error: %s\n", error_message); #endif #ifdef PNG_SETJMP_SUPPORTED # ifdef USE_FAR_KEYWORD { jmp_buf jmpbuf; png_memcpy(jmpbuf,png_ptr->jmpbuf,png_sizeof(jmp_buf)); longjmp(jmpbuf, 1); } # else longjmp(png_ptr->jmpbuf, 1); # endif #else /* make compiler happy */ ; if (png_ptr) PNG_ABORT(); #endif #ifdef PNG_NO_CONSOLE_IO /* make compiler happy */ ; if (&error_message != NULL) return; #endif } /* This function is called when there is a warning, but the library thinks * it can continue anyway. Replacement functions don't have to do anything * here if you don't want them to. In the default configuration, png_ptr is * not used, but it is passed in case it may be useful. */ static void /* PRIVATE */ png_default_warning(png_structp png_ptr, png_const_charp warning_message) { #ifndef PNG_NO_CONSOLE_IO # ifdef PNG_ERROR_NUMBERS_SUPPORTED if (*warning_message == '#') { int offset; char warning_number[16]; for (offset=0; offset<15; offset++) { warning_number[offset]=*(warning_message+offset+1); if (*(warning_message+offset) == ' ') break; } if((offset > 1) && (offset < 15)) { warning_number[offset-1]='\0'; fprintf(stderr, "libpng warning no. %s: %s\n", warning_number, warning_message+offset); } else fprintf(stderr, "libpng warning: %s\n", warning_message); } else # endif fprintf(stderr, "libpng warning: %s\n", warning_message); #else /* make compiler happy */ ; if (warning_message) return; #endif /* make compiler happy */ ; if (png_ptr) return; } /* This function is called when the application wants to use another method * of handling errors and warnings. Note that the error function MUST NOT * return to the calling routine or serious problems will occur. The return * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1) */ void PNGAPI png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn) { png_ptr->error_ptr = error_ptr; png_ptr->error_fn = error_fn; png_ptr->warning_fn = warning_fn; } /* This function returns a pointer to the error_ptr associated with the user * functions. The application should free any memory associated with this * pointer before png_write_destroy and png_read_destroy are called. */ png_voidp PNGAPI png_get_error_ptr(png_structp png_ptr) { return ((png_voidp)png_ptr->error_ptr); } #ifdef PNG_ERROR_NUMBERS_SUPPORTED void PNGAPI png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) { if(png_ptr != NULL) { png_ptr->flags &= ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); } } #endif syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngtest.c0000664000175000017500000013307310777447272021016 0ustar evanevan /* pngtest.c - a simple test program to test libpng * * libpng 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * * This program reads in a PNG image, writes it out again, and then * compares the two files. If the files are identical, this shows that * the basic chunk handling, filtering, and (de)compression code is working * properly. It does not currently test all of the transforms, although * it probably should. * * The program will report "FAIL" in certain legitimate cases: * 1) when the compression level or filter selection method is changed. * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192. * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks * exist in the input file. * 4) others not listed here... * In these cases, it is best to check with another tool such as "pngcheck" * to see what the differences between the two files are. * * If a filename is given on the command-line, then this file is used * for the input, rather than the default "pngtest.png". This allows * testing a wide variety of files easily. You can also test a number * of files at once by typing "pngtest -m file1.png file2.png ..." */ #include "png.h" #if defined(_WIN32_WCE) # if _WIN32_WCE < 211 __error__ (f|w)printf functions are not supported on old WindowsCE.; # endif # include # include # define READFILE(file, data, length, check) \ if (ReadFile(file, data, length, &check,NULL)) check = 0 # define WRITEFILE(file, data, length, check)) \ if (WriteFile(file, data, length, &check, NULL)) check = 0 # define FCLOSE(file) CloseHandle(file) #else # include # include # include # define READFILE(file, data, length, check) \ check=(png_size_t)fread(data,(png_size_t)1,length,file) # define WRITEFILE(file, data, length, check) \ check=(png_size_t)fwrite(data,(png_size_t)1, length, file) # define FCLOSE(file) fclose(file) #endif #if defined(PNG_NO_STDIO) # if defined(_WIN32_WCE) typedef HANDLE png_FILE_p; # else typedef FILE * png_FILE_p; # endif #endif /* Makes pngtest verbose so we can find problems (needs to be before png.h) */ #ifndef PNG_DEBUG # define PNG_DEBUG 0 #endif #if !PNG_DEBUG # define SINGLE_ROWBUF_ALLOC /* makes buffer overruns easier to nail */ #endif /* Turn on CPU timing #define PNGTEST_TIMING */ #ifdef PNG_NO_FLOATING_POINT_SUPPORTED #undef PNGTEST_TIMING #endif #ifdef PNGTEST_TIMING static float t_start, t_stop, t_decode, t_encode, t_misc; #include #endif /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ #ifndef png_jmpbuf # define png_jmpbuf(png_ptr) png_ptr->jmpbuf #endif #ifdef PNGTEST_TIMING static float t_start, t_stop, t_decode, t_encode, t_misc; #if !defined(PNG_tIME_SUPPORTED) #include #endif #endif #if defined(PNG_TIME_RFC1123_SUPPORTED) static int tIME_chunk_present=0; static char tIME_string[30] = "no tIME chunk present in file"; #endif static int verbose = 0; int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname)); #ifdef __TURBOC__ #include #endif /* defined so I can write to a file on gui/windowing platforms */ /* #define STDERR stderr */ #define STDERR stdout /* for DOS */ /* example of using row callbacks to make a simple progress meter */ static int status_pass=1; static int status_dots_requested=0; static int status_dots=1; void #ifdef PNG_1_0_X PNGAPI #endif read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); void #ifdef PNG_1_0_X PNGAPI #endif read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) { if(png_ptr == NULL || row_number > PNG_UINT_31_MAX) return; if(status_pass != pass) { fprintf(stdout,"\n Pass %d: ",pass); status_pass = pass; status_dots = 31; } status_dots--; if(status_dots == 0) { fprintf(stdout, "\n "); status_dots=30; } fprintf(stdout, "r"); } void #ifdef PNG_1_0_X PNGAPI #endif write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); void #ifdef PNG_1_0_X PNGAPI #endif write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) { if(png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) return; fprintf(stdout, "w"); } #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) /* Example of using user transform callback (we don't transform anything, but merely examine the row filters. We set this to 256 rather than 5 in case illegal filter values are present.) */ static png_uint_32 filters_used[256]; void #ifdef PNG_1_0_X PNGAPI #endif count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data); void #ifdef PNG_1_0_X PNGAPI #endif count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data) { if(png_ptr != NULL && row_info != NULL) ++filters_used[*(data-1)]; } #endif #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) /* example of using user transform callback (we don't transform anything, but merely count the zero samples) */ static png_uint_32 zero_samples; void #ifdef PNG_1_0_X PNGAPI #endif count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data); void #ifdef PNG_1_0_X PNGAPI #endif count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) { png_bytep dp = data; if(png_ptr == NULL)return; /* contents of row_info: * png_uint_32 width width of row * png_uint_32 rowbytes number of bytes in row * png_byte color_type color type of pixels * png_byte bit_depth bit depth of samples * png_byte channels number of channels (1-4) * png_byte pixel_depth bits per pixel (depth*channels) */ /* counts the number of zero samples (or zero pixels if color_type is 3 */ if(row_info->color_type == 0 || row_info->color_type == 3) { int pos=0; png_uint_32 n, nstop; for (n=0, nstop=row_info->width; nbit_depth == 1) { if(((*dp << pos++ ) & 0x80) == 0) zero_samples++; if(pos == 8) { pos = 0; dp++; } } if(row_info->bit_depth == 2) { if(((*dp << (pos+=2)) & 0xc0) == 0) zero_samples++; if(pos == 8) { pos = 0; dp++; } } if(row_info->bit_depth == 4) { if(((*dp << (pos+=4)) & 0xf0) == 0) zero_samples++; if(pos == 8) { pos = 0; dp++; } } if(row_info->bit_depth == 8) if(*dp++ == 0) zero_samples++; if(row_info->bit_depth == 16) { if((*dp | *(dp+1)) == 0) zero_samples++; dp+=2; } } } else /* other color types */ { png_uint_32 n, nstop; int channel; int color_channels = row_info->channels; if(row_info->color_type > 3)color_channels--; for (n=0, nstop=row_info->width; nbit_depth == 8) if(*dp++ == 0) zero_samples++; if(row_info->bit_depth == 16) { if((*dp | *(dp+1)) == 0) zero_samples++; dp+=2; } } if(row_info->color_type > 3) { dp++; if(row_info->bit_depth == 16)dp++; } } } } #endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */ static int wrote_question = 0; #if defined(PNG_NO_STDIO) /* START of code to validate stdio-free compilation */ /* These copies of the default read/write functions come from pngrio.c and */ /* pngwio.c. They allow "don't include stdio" testing of the library. */ /* This is the function that does the actual reading of data. If you are not reading from a standard C stream, you should create a replacement read_data function and use it at run time with png_set_read_fn(), rather than changing the library. */ #ifndef USE_FAR_KEYWORD static void pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_size_t check; /* fread() returns 0 on error, so it is OK to store this in a png_size_t * instead of an int, which is what fread() actually returns. */ READFILE((png_FILE_p)png_ptr->io_ptr, data, length, check); if (check != length) { png_error(png_ptr, "Read Error!"); } } #else /* this is the model-independent version. Since the standard I/O library can't handle far buffers in the medium and small models, we have to copy the data. */ #define NEAR_BUF_SIZE 1024 #define MIN(a,b) (a <= b ? a : b) static void pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { int check; png_byte *n_data; png_FILE_p io_ptr; /* Check if data really is near. If so, use usual code. */ n_data = (png_byte *)CVT_PTR_NOCHECK(data); io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); if ((png_bytep)n_data == data) { READFILE(io_ptr, n_data, length, check); } else { png_byte buf[NEAR_BUF_SIZE]; png_size_t read, remaining, err; check = 0; remaining = length; do { read = MIN(NEAR_BUF_SIZE, remaining); READFILE(io_ptr, buf, 1, err); png_memcpy(data, buf, read); /* copy far buffer to near buffer */ if(err != read) break; else check += err; data += read; remaining -= read; } while (remaining != 0); } if (check != length) { png_error(png_ptr, "read Error"); } } #endif /* USE_FAR_KEYWORD */ #if defined(PNG_WRITE_FLUSH_SUPPORTED) static void pngtest_flush(png_structp png_ptr) { #if !defined(_WIN32_WCE) png_FILE_p io_ptr; io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); if (io_ptr != NULL) fflush(io_ptr); #endif } #endif /* This is the function that does the actual writing of data. If you are not writing to a standard C stream, you should create a replacement write_data function and use it at run time with png_set_write_fn(), rather than changing the library. */ #ifndef USE_FAR_KEYWORD static void pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_uint_32 check; WRITEFILE((png_FILE_p)png_ptr->io_ptr, data, length, check); if (check != length) { png_error(png_ptr, "Write Error"); } } #else /* this is the model-independent version. Since the standard I/O library can't handle far buffers in the medium and small models, we have to copy the data. */ #define NEAR_BUF_SIZE 1024 #define MIN(a,b) (a <= b ? a : b) static void pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_uint_32 check; png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ png_FILE_p io_ptr; /* Check if data really is near. If so, use usual code. */ near_data = (png_byte *)CVT_PTR_NOCHECK(data); io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); if ((png_bytep)near_data == data) { WRITEFILE(io_ptr, near_data, length, check); } else { png_byte buf[NEAR_BUF_SIZE]; png_size_t written, remaining, err; check = 0; remaining = length; do { written = MIN(NEAR_BUF_SIZE, remaining); png_memcpy(buf, data, written); /* copy far buffer to near buffer */ WRITEFILE(io_ptr, buf, written, err); if (err != written) break; else check += err; data += written; remaining -= written; } while (remaining != 0); } if (check != length) { png_error(png_ptr, "Write Error"); } } #endif /* USE_FAR_KEYWORD */ /* This function is called when there is a warning, but the library thinks * it can continue anyway. Replacement functions don't have to do anything * here if you don't want to. In the default configuration, png_ptr is * not used, but it is passed in case it may be useful. */ static void pngtest_warning(png_structp png_ptr, png_const_charp message) { PNG_CONST char *name = "UNKNOWN (ERROR!)"; if (png_ptr != NULL && png_ptr->error_ptr != NULL) name = png_ptr->error_ptr; fprintf(STDERR, "%s: libpng warning: %s\n", name, message); } /* This is the default error handling function. Note that replacements for * this function MUST NOT RETURN, or the program will likely crash. This * function is used by default, or if the program supplies NULL for the * error function pointer in png_set_error_fn(). */ static void pngtest_error(png_structp png_ptr, png_const_charp message) { pngtest_warning(png_ptr, message); /* We can return because png_error calls the default handler, which is * actually OK in this case. */ } #endif /* PNG_NO_STDIO */ /* END of code to validate stdio-free compilation */ /* START of code to validate memory allocation and deallocation */ #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG /* Allocate memory. For reasonable files, size should never exceed 64K. However, zlib may allocate more then 64K if you don't tell it not to. See zconf.h and png.h for more information. zlib does need to allocate exactly 64K, so whatever you call here must have the ability to do that. This piece of code can be compiled to validate max 64K allocations by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */ typedef struct memory_information { png_uint_32 size; png_voidp pointer; struct memory_information FAR *next; } memory_information; typedef memory_information FAR *memory_infop; static memory_infop pinformation = NULL; static int current_allocation = 0; static int maximum_allocation = 0; static int total_allocation = 0; static int num_allocations = 0; png_voidp png_debug_malloc PNGARG((png_structp png_ptr, png_uint_32 size)); void png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr)); png_voidp png_debug_malloc(png_structp png_ptr, png_uint_32 size) { /* png_malloc has already tested for NULL; png_create_struct calls png_debug_malloc directly, with png_ptr == NULL which is OK */ if (size == 0) return (NULL); /* This calls the library allocator twice, once to get the requested buffer and once to get a new free list entry. */ { /* Disable malloc_fn and free_fn */ memory_infop pinfo; png_set_mem_fn(png_ptr, NULL, NULL, NULL); pinfo = (memory_infop)png_malloc(png_ptr, (png_uint_32)png_sizeof (*pinfo)); pinfo->size = size; current_allocation += size; total_allocation += size; num_allocations ++; if (current_allocation > maximum_allocation) maximum_allocation = current_allocation; pinfo->pointer = (png_voidp)png_malloc(png_ptr, size); /* Restore malloc_fn and free_fn */ png_set_mem_fn(png_ptr, png_voidp_NULL, (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free); if (size != 0 && pinfo->pointer == NULL) { current_allocation -= size; total_allocation -= size; png_error(png_ptr, "out of memory in pngtest->png_debug_malloc."); } pinfo->next = pinformation; pinformation = pinfo; /* Make sure the caller isn't assuming zeroed memory. */ png_memset(pinfo->pointer, 0xdd, pinfo->size); if(verbose) printf("png_malloc %lu bytes at %x\n",size,pinfo->pointer); assert(pinfo->size != 12345678); return (png_voidp)(pinfo->pointer); } } /* Free a pointer. It is removed from the list at the same time. */ void png_debug_free(png_structp png_ptr, png_voidp ptr) { if (png_ptr == NULL) fprintf(STDERR, "NULL pointer to png_debug_free.\n"); if (ptr == 0) { #if 0 /* This happens all the time. */ fprintf(STDERR, "WARNING: freeing NULL pointer\n"); #endif return; } /* Unlink the element from the list. */ { memory_infop FAR *ppinfo = &pinformation; for (;;) { memory_infop pinfo = *ppinfo; if (pinfo->pointer == ptr) { *ppinfo = pinfo->next; current_allocation -= pinfo->size; if (current_allocation < 0) fprintf(STDERR, "Duplicate free of memory\n"); /* We must free the list element too, but first kill the memory that is to be freed. */ png_memset(ptr, 0x55, pinfo->size); png_free_default(png_ptr, pinfo); pinfo=NULL; break; } if (pinfo->next == NULL) { fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr); break; } ppinfo = &pinfo->next; } } /* Finally free the data. */ if(verbose) printf("Freeing %x\n",ptr); png_free_default(png_ptr, ptr); ptr=NULL; } #endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */ /* END of code to test memory allocation/deallocation */ /* Test one file */ int test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { static png_FILE_p fpin; static png_FILE_p fpout; /* "static" prevents setjmp corruption */ png_structp read_ptr; png_infop read_info_ptr, end_info_ptr; #ifdef PNG_WRITE_SUPPORTED png_structp write_ptr; png_infop write_info_ptr; png_infop write_end_info_ptr; #else png_structp write_ptr = NULL; png_infop write_info_ptr = NULL; png_infop write_end_info_ptr = NULL; #endif png_bytep row_buf; png_uint_32 y; png_uint_32 width, height; int num_pass, pass; int bit_depth, color_type; #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD jmp_buf jmpbuf; #endif #endif #if defined(_WIN32_WCE) TCHAR path[MAX_PATH]; #endif char inbuf[256], outbuf[256]; row_buf = NULL; #if defined(_WIN32_WCE) MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH); if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) #else if ((fpin = fopen(inname, "rb")) == NULL) #endif { fprintf(STDERR, "Could not find input file %s\n", inname); return (1); } #if defined(_WIN32_WCE) MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH); if ((fpout = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE) #else if ((fpout = fopen(outname, "wb")) == NULL) #endif { fprintf(STDERR, "Could not open output file %s\n", outname); FCLOSE(fpin); return (1); } png_debug(0, "Allocating read and write structures\n"); #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL, png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL, (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free); #else read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, png_error_ptr_NULL, png_error_ptr_NULL); #endif #if defined(PNG_NO_STDIO) png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error, pngtest_warning); #endif #ifdef PNG_WRITE_SUPPORTED #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL, png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL, (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free); #else write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, png_error_ptr_NULL, png_error_ptr_NULL); #endif #if defined(PNG_NO_STDIO) png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error, pngtest_warning); #endif #endif png_debug(0, "Allocating read_info, write_info and end_info structures\n"); read_info_ptr = png_create_info_struct(read_ptr); end_info_ptr = png_create_info_struct(read_ptr); #ifdef PNG_WRITE_SUPPORTED write_info_ptr = png_create_info_struct(write_ptr); write_end_info_ptr = png_create_info_struct(write_ptr); #endif #ifdef PNG_SETJMP_SUPPORTED png_debug(0, "Setting jmpbuf for read struct\n"); #ifdef USE_FAR_KEYWORD if (setjmp(jmpbuf)) #else if (setjmp(png_jmpbuf(read_ptr))) #endif { fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); if (row_buf) png_free(read_ptr, row_buf); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); #ifdef PNG_WRITE_SUPPORTED png_destroy_info_struct(write_ptr, &write_end_info_ptr); png_destroy_write_struct(&write_ptr, &write_info_ptr); #endif FCLOSE(fpin); FCLOSE(fpout); return (1); } #ifdef USE_FAR_KEYWORD png_memcpy(png_jmpbuf(read_ptr),jmpbuf,png_sizeof(jmp_buf)); #endif #ifdef PNG_WRITE_SUPPORTED png_debug(0, "Setting jmpbuf for write struct\n"); #ifdef USE_FAR_KEYWORD if (setjmp(jmpbuf)) #else if (setjmp(png_jmpbuf(write_ptr))) #endif { fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); png_destroy_info_struct(write_ptr, &write_end_info_ptr); #ifdef PNG_WRITE_SUPPORTED png_destroy_write_struct(&write_ptr, &write_info_ptr); #endif FCLOSE(fpin); FCLOSE(fpout); return (1); } #ifdef USE_FAR_KEYWORD png_memcpy(png_jmpbuf(write_ptr),jmpbuf,png_sizeof(jmp_buf)); #endif #endif #endif png_debug(0, "Initializing input and output streams\n"); #if !defined(PNG_NO_STDIO) png_init_io(read_ptr, fpin); # ifdef PNG_WRITE_SUPPORTED png_init_io(write_ptr, fpout); # endif #else png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data); # ifdef PNG_WRITE_SUPPORTED png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data, # if defined(PNG_WRITE_FLUSH_SUPPORTED) pngtest_flush); # else NULL); # endif # endif #endif if(status_dots_requested == 1) { #ifdef PNG_WRITE_SUPPORTED png_set_write_status_fn(write_ptr, write_row_callback); #endif png_set_read_status_fn(read_ptr, read_row_callback); } else { #ifdef PNG_WRITE_SUPPORTED png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL); #endif png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL); } #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) { int i; for(i=0; i<256; i++) filters_used[i]=0; png_set_read_user_transform_fn(read_ptr, count_filters); } #endif #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) zero_samples=0; png_set_write_user_transform_fn(write_ptr, count_zero_samples); #endif #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) # ifndef PNG_HANDLE_CHUNK_ALWAYS # define PNG_HANDLE_CHUNK_ALWAYS 3 # endif png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, png_bytep_NULL, 0); #endif #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) # ifndef PNG_HANDLE_CHUNK_IF_SAFE # define PNG_HANDLE_CHUNK_IF_SAFE 2 # endif png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE, png_bytep_NULL, 0); #endif png_debug(0, "Reading info struct\n"); png_read_info(read_ptr, read_info_ptr); png_debug(0, "Transferring info struct\n"); { int interlace_type, compression_type, filter_type; if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type)) { png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, #if defined(PNG_WRITE_INTERLACING_SUPPORTED) color_type, interlace_type, compression_type, filter_type); #else color_type, PNG_INTERLACE_NONE, compression_type, filter_type); #endif } } #if defined(PNG_FIXED_POINT_SUPPORTED) #if defined(PNG_cHRM_SUPPORTED) { png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y)) { png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); } } #endif #if defined(PNG_gAMA_SUPPORTED) { png_fixed_point gamma; if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma)) { png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); } } #endif #else /* Use floating point versions */ #if defined(PNG_FLOATING_POINT_SUPPORTED) #if defined(PNG_cHRM_SUPPORTED) { double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y)) { png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); } } #endif #if defined(PNG_gAMA_SUPPORTED) { double gamma; if (png_get_gAMA(read_ptr, read_info_ptr, &gamma)) { png_set_gAMA(write_ptr, write_info_ptr, gamma); } } #endif #endif /* floating point */ #endif /* fixed point */ #if defined(PNG_iCCP_SUPPORTED) { png_charp name; png_charp profile; png_uint_32 proflen; int compression_type; if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, &profile, &proflen)) { png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, profile, proflen); } } #endif #if defined(PNG_sRGB_SUPPORTED) { int intent; if (png_get_sRGB(read_ptr, read_info_ptr, &intent)) { png_set_sRGB(write_ptr, write_info_ptr, intent); } } #endif { png_colorp palette; int num_palette; if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette)) { png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); } } #if defined(PNG_bKGD_SUPPORTED) { png_color_16p background; if (png_get_bKGD(read_ptr, read_info_ptr, &background)) { png_set_bKGD(write_ptr, write_info_ptr, background); } } #endif #if defined(PNG_hIST_SUPPORTED) { png_uint_16p hist; if (png_get_hIST(read_ptr, read_info_ptr, &hist)) { png_set_hIST(write_ptr, write_info_ptr, hist); } } #endif #if defined(PNG_oFFs_SUPPORTED) { png_int_32 offset_x, offset_y; int unit_type; if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type)) { png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); } } #endif #if defined(PNG_pCAL_SUPPORTED) { png_charp purpose, units; png_charpp params; png_int_32 X0, X1; int type, nparams; if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, &nparams, &units, ¶ms)) { png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, nparams, units, params); } } #endif #if defined(PNG_pHYs_SUPPORTED) { png_uint_32 res_x, res_y; int unit_type; if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type)) { png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); } } #endif #if defined(PNG_sBIT_SUPPORTED) { png_color_8p sig_bit; if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit)) { png_set_sBIT(write_ptr, write_info_ptr, sig_bit); } } #endif #if defined(PNG_sCAL_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED { int unit; double scal_width, scal_height; if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, &scal_height)) { png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); } } #else #ifdef PNG_FIXED_POINT_SUPPORTED { int unit; png_charp scal_width, scal_height; if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, &scal_height)) { png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height); } } #endif #endif #endif #if defined(PNG_TEXT_SUPPORTED) { png_textp text_ptr; int num_text; if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) { png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text); png_set_text(write_ptr, write_info_ptr, text_ptr, num_text); } } #endif #if defined(PNG_tIME_SUPPORTED) { png_timep mod_time; if (png_get_tIME(read_ptr, read_info_ptr, &mod_time)) { png_set_tIME(write_ptr, write_info_ptr, mod_time); #if defined(PNG_TIME_RFC1123_SUPPORTED) /* we have to use png_strcpy instead of "=" because the string pointed to by png_convert_to_rfc1123() gets free'ed before we use it */ png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time)); tIME_chunk_present++; #endif /* PNG_TIME_RFC1123_SUPPORTED */ } } #endif #if defined(PNG_tRNS_SUPPORTED) { png_bytep trans; int num_trans; png_color_16p trans_values; if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans, &trans_values)) { png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans, trans_values); } } #endif #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) { png_unknown_chunkp unknowns; int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr, &unknowns); if (num_unknowns) { png_size_t i; png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, num_unknowns); /* copy the locations from the read_info_ptr. The automatically generated locations in write_info_ptr are wrong because we haven't written anything yet */ for (i = 0; i < (png_size_t)num_unknowns; i++) png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, unknowns[i].location); } } #endif #ifdef PNG_WRITE_SUPPORTED png_debug(0, "\nWriting info struct\n"); /* If we wanted, we could write info in two steps: png_write_info_before_PLTE(write_ptr, write_info_ptr); */ png_write_info(write_ptr, write_info_ptr); #endif #ifdef SINGLE_ROWBUF_ALLOC png_debug(0, "\nAllocating row buffer..."); row_buf = (png_bytep)png_malloc(read_ptr, png_get_rowbytes(read_ptr, read_info_ptr)); png_debug1(0, "0x%08lx\n\n", (unsigned long)row_buf); #endif /* SINGLE_ROWBUF_ALLOC */ png_debug(0, "Writing row data\n"); #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ defined(PNG_WRITE_INTERLACING_SUPPORTED) num_pass = png_set_interlace_handling(read_ptr); # ifdef PNG_WRITE_SUPPORTED png_set_interlace_handling(write_ptr); # endif #else num_pass=1; #endif #ifdef PNGTEST_TIMING t_stop = (float)clock(); t_misc += (t_stop - t_start); t_start = t_stop; #endif for (pass = 0; pass < num_pass; pass++) { png_debug1(0, "Writing row data for pass %d\n",pass); for (y = 0; y < height; y++) { #ifndef SINGLE_ROWBUF_ALLOC png_debug2(0, "\nAllocating row buffer (pass %d, y = %ld)...", pass,y); row_buf = (png_bytep)png_malloc(read_ptr, png_get_rowbytes(read_ptr, read_info_ptr)); png_debug2(0, "0x%08lx (%ld bytes)\n", (unsigned long)row_buf, png_get_rowbytes(read_ptr, read_info_ptr)); #endif /* !SINGLE_ROWBUF_ALLOC */ png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1); #ifdef PNG_WRITE_SUPPORTED #ifdef PNGTEST_TIMING t_stop = (float)clock(); t_decode += (t_stop - t_start); t_start = t_stop; #endif png_write_rows(write_ptr, (png_bytepp)&row_buf, 1); #ifdef PNGTEST_TIMING t_stop = (float)clock(); t_encode += (t_stop - t_start); t_start = t_stop; #endif #endif /* PNG_WRITE_SUPPORTED */ #ifndef SINGLE_ROWBUF_ALLOC png_debug2(0, "Freeing row buffer (pass %d, y = %ld)\n\n", pass, y); png_free(read_ptr, row_buf); #endif /* !SINGLE_ROWBUF_ALLOC */ } } #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); #endif #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); #endif png_debug(0, "Reading and writing end_info data\n"); png_read_end(read_ptr, end_info_ptr); #if defined(PNG_TEXT_SUPPORTED) { png_textp text_ptr; int num_text; if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0) { png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text); png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text); } } #endif #if defined(PNG_tIME_SUPPORTED) { png_timep mod_time; if (png_get_tIME(read_ptr, end_info_ptr, &mod_time)) { png_set_tIME(write_ptr, write_end_info_ptr, mod_time); #if defined(PNG_TIME_RFC1123_SUPPORTED) /* we have to use png_strcpy instead of "=" because the string pointed to by png_convert_to_rfc1123() gets free'ed before we use it */ png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time)); tIME_chunk_present++; #endif /* PNG_TIME_RFC1123_SUPPORTED */ } } #endif #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) { png_unknown_chunkp unknowns; int num_unknowns; num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr, &unknowns); if (num_unknowns) { png_size_t i; png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, num_unknowns); /* copy the locations from the read_info_ptr. The automatically generated locations in write_end_info_ptr are wrong because we haven't written the end_info yet */ for (i = 0; i < (png_size_t)num_unknowns; i++) png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, unknowns[i].location); } } #endif #ifdef PNG_WRITE_SUPPORTED png_write_end(write_ptr, write_end_info_ptr); #endif #ifdef PNG_EASY_ACCESS_SUPPORTED if(verbose) { png_uint_32 iwidth, iheight; iwidth = png_get_image_width(write_ptr, write_info_ptr); iheight = png_get_image_height(write_ptr, write_info_ptr); fprintf(STDERR, "Image width = %lu, height = %lu\n", iwidth, iheight); } #endif png_debug(0, "Destroying data structs\n"); #ifdef SINGLE_ROWBUF_ALLOC png_debug(1, "destroying row_buf for read_ptr\n"); png_free(read_ptr, row_buf); row_buf=NULL; #endif /* SINGLE_ROWBUF_ALLOC */ png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr\n"); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); #ifdef PNG_WRITE_SUPPORTED png_debug(1, "destroying write_end_info_ptr\n"); png_destroy_info_struct(write_ptr, &write_end_info_ptr); png_debug(1, "destroying write_ptr, write_info_ptr\n"); png_destroy_write_struct(&write_ptr, &write_info_ptr); #endif png_debug(0, "Destruction complete.\n"); FCLOSE(fpin); FCLOSE(fpout); png_debug(0, "Opening files for comparison\n"); #if defined(_WIN32_WCE) MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH); if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) #else if ((fpin = fopen(inname, "rb")) == NULL) #endif { fprintf(STDERR, "Could not find file %s\n", inname); return (1); } #if defined(_WIN32_WCE) MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH); if ((fpout = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) #else if ((fpout = fopen(outname, "rb")) == NULL) #endif { fprintf(STDERR, "Could not find file %s\n", outname); FCLOSE(fpin); return (1); } for(;;) { png_size_t num_in, num_out; READFILE(fpin, inbuf, 1, num_in); READFILE(fpout, outbuf, 1, num_out); if (num_in != num_out) { fprintf(STDERR, "\nFiles %s and %s are of a different size\n", inname, outname); if(wrote_question == 0) { fprintf(STDERR, " Was %s written with the same maximum IDAT chunk size (%d bytes),", inname,PNG_ZBUF_SIZE); fprintf(STDERR, "\n filtering heuristic (libpng default), compression"); fprintf(STDERR, " level (zlib default),\n and zlib version (%s)?\n\n", ZLIB_VERSION); wrote_question=1; } FCLOSE(fpin); FCLOSE(fpout); return (0); } if (!num_in) break; if (png_memcmp(inbuf, outbuf, num_in)) { fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname); if(wrote_question == 0) { fprintf(STDERR, " Was %s written with the same maximum IDAT chunk size (%d bytes),", inname,PNG_ZBUF_SIZE); fprintf(STDERR, "\n filtering heuristic (libpng default), compression"); fprintf(STDERR, " level (zlib default),\n and zlib version (%s)?\n\n", ZLIB_VERSION); wrote_question=1; } FCLOSE(fpin); FCLOSE(fpout); return (0); } } FCLOSE(fpin); FCLOSE(fpout); return (0); } /* input and output filenames */ #ifdef RISCOS static PNG_CONST char *inname = "pngtest/png"; static PNG_CONST char *outname = "pngout/png"; #else static PNG_CONST char *inname = "pngtest.png"; static PNG_CONST char *outname = "pngout.png"; #endif int main(int argc, char *argv[]) { int multiple = 0; int ierror = 0; fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION); fprintf(STDERR,"%s",png_get_copyright(NULL)); /* Show the version of libpng used in building the library */ fprintf(STDERR," library (%lu):%s", png_access_version_number(), png_get_header_version(NULL)); /* Show the version of libpng used in building the application */ fprintf(STDERR," pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER, PNG_HEADER_VERSION_STRING); fprintf(STDERR," png_sizeof(png_struct)=%ld, png_sizeof(png_info)=%ld\n", (long)png_sizeof(png_struct), (long)png_sizeof(png_info)); /* Do some consistency checking on the memory allocation settings, I'm not sure this matters, but it is nice to know, the first of these tests should be impossible because of the way the macros are set in pngconf.h */ #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n"); #endif /* I think the following can happen. */ #if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K) fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n"); #endif if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING)) { fprintf(STDERR, "Warning: versions are different between png.h and png.c\n"); fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING); fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver); ++ierror; } if (argc > 1) { if (strcmp(argv[1], "-m") == 0) { multiple = 1; status_dots_requested = 0; } else if (strcmp(argv[1], "-mv") == 0 || strcmp(argv[1], "-vm") == 0 ) { multiple = 1; verbose = 1; status_dots_requested = 1; } else if (strcmp(argv[1], "-v") == 0) { verbose = 1; status_dots_requested = 1; inname = argv[2]; } else { inname = argv[1]; status_dots_requested = 0; } } if (!multiple && argc == 3+verbose) outname = argv[2+verbose]; if ((!multiple && argc > 3+verbose) || (multiple && argc < 2)) { fprintf(STDERR, "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", argv[0], argv[0]); fprintf(STDERR, " reads/writes one PNG file (without -m) or multiple files (-m)\n"); fprintf(STDERR, " with -m %s is used as a temporary file\n", outname); exit(1); } if (multiple) { int i; #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG int allocation_now = current_allocation; #endif for (i=2; isize, (unsigned int) pinfo->pointer); pinfo = pinfo->next; } } #endif } #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG fprintf(STDERR, " Current memory allocation: %10d bytes\n", current_allocation); fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", maximum_allocation); fprintf(STDERR, " Total memory allocation: %10d bytes\n", total_allocation); fprintf(STDERR, " Number of allocations: %10d\n", num_allocations); #endif } else { int i; for (i=0; i<3; ++i) { int kerror; #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG int allocation_now = current_allocation; #endif if (i == 1) status_dots_requested = 1; else if(verbose == 0)status_dots_requested = 0; if (i == 0 || verbose == 1 || ierror != 0) fprintf(STDERR, "Testing %s:",inname); kerror = test_one_file(inname, outname); if(kerror == 0) { if(verbose == 1 || i == 2) { #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) int k; #endif #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) fprintf(STDERR, "\n PASS (%lu zero samples)\n",zero_samples); #else fprintf(STDERR, " PASS\n"); #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) for (k=0; k<256; k++) if(filters_used[k]) fprintf(STDERR, " Filter %d was used %lu times\n", k,filters_used[k]); #endif #if defined(PNG_TIME_RFC1123_SUPPORTED) if(tIME_chunk_present != 0) fprintf(STDERR, " tIME = %s\n",tIME_string); #endif /* PNG_TIME_RFC1123_SUPPORTED */ } } else { if(verbose == 0 && i != 2) fprintf(STDERR, "Testing %s:",inname); fprintf(STDERR, " FAIL\n"); ierror += kerror; } #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG if (allocation_now != current_allocation) fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", current_allocation-allocation_now); if (current_allocation != 0) { memory_infop pinfo = pinformation; fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", current_allocation); while (pinfo != NULL) { fprintf(STDERR," %lu bytes at %x\n", pinfo->size, (unsigned int)pinfo->pointer); pinfo = pinfo->next; } } #endif } #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG fprintf(STDERR, " Current memory allocation: %10d bytes\n", current_allocation); fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", maximum_allocation); fprintf(STDERR, " Total memory allocation: %10d bytes\n", total_allocation); fprintf(STDERR, " Number of allocations: %10d\n", num_allocations); #endif } #ifdef PNGTEST_TIMING t_stop = (float)clock(); t_misc += (t_stop - t_start); t_start = t_stop; fprintf(STDERR," CPU time used = %.3f seconds", (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); fprintf(STDERR," (decoding %.3f,\n", t_decode/(float)CLOCKS_PER_SEC); fprintf(STDERR," encoding %.3f ,", t_encode/(float)CLOCKS_PER_SEC); fprintf(STDERR," other %.3f seconds)\n\n", t_misc/(float)CLOCKS_PER_SEC); #endif if (ierror == 0) fprintf(STDERR, "libpng passes test\n"); else fprintf(STDERR, "libpng FAILS test\n"); return (int)(ierror != 0); } /* Generate a compiler error if there is an old png.h in the search path. */ typedef version_1_2_8 your_png_h_is_not_version_1_2_8; syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngread.c0000664000175000017500000013252210777447272020750 0ustar evanevan /* pngread.c - read a PNG file * * libpng 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * * This file contains routines that an application calls directly to * read a PNG file or stream. */ #define PNG_INTERNAL #include "png.h" /* Create a PNG structure for reading, and allocate any memory needed. */ png_structp PNGAPI png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn) { #ifdef PNG_USER_MEM_SUPPORTED return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn, warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL)); } /* Alternate create PNG structure for reading, and allocate any memory needed. */ png_structp PNGAPI png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn) { #endif /* PNG_USER_MEM_SUPPORTED */ png_structp png_ptr; #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD jmp_buf jmpbuf; #endif #endif int i; png_debug(1, "in png_create_read_struct\n"); #ifdef PNG_USER_MEM_SUPPORTED png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); #else png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); #endif if (png_ptr == NULL) return (NULL); #if !defined(PNG_1_0_X) #ifdef PNG_ASSEMBLER_CODE_SUPPORTED png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ #endif #endif /* PNG_1_0_X */ /* added at libpng-1.2.6 */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED png_ptr->user_width_max=PNG_USER_WIDTH_MAX; png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; #endif #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD if (setjmp(jmpbuf)) #else if (setjmp(png_ptr->jmpbuf)) #endif { png_free(png_ptr, png_ptr->zbuf); png_ptr->zbuf=NULL; #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)png_ptr); #endif return (NULL); } #ifdef USE_FAR_KEYWORD png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); #endif #endif #ifdef PNG_USER_MEM_SUPPORTED png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); #endif png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); i=0; do { if(user_png_ver[i] != png_libpng_ver[i]) png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; } while (png_libpng_ver[i++]); if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) { /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so * we must recompile any applications that use any older library version. * For versions after libpng 1.0, we will be compatible, so we need * only check the first digit. */ if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || (user_png_ver[0] == '0' && user_png_ver[2] < '9')) { #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) char msg[80]; if (user_png_ver) { sprintf(msg, "Application was compiled with png.h from libpng-%.20s", user_png_ver); png_warning(png_ptr, msg); } sprintf(msg, "Application is running with png.c from libpng-%.20s", png_libpng_ver); png_warning(png_ptr, msg); #endif #ifdef PNG_ERROR_NUMBERS_SUPPORTED png_ptr->flags=0; #endif png_error(png_ptr, "Incompatible libpng version in application and library"); } } /* initialize zbuf - compression buffer */ png_ptr->zbuf_size = PNG_ZBUF_SIZE; png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); png_ptr->zstream.zalloc = png_zalloc; png_ptr->zstream.zfree = png_zfree; png_ptr->zstream.opaque = (voidpf)png_ptr; switch (inflateInit(&png_ptr->zstream)) { case Z_OK: /* Do nothing */ break; case Z_MEM_ERROR: case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break; case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break; default: png_error(png_ptr, "Unknown zlib error"); } png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL); #ifdef PNG_SETJMP_SUPPORTED /* Applications that neglect to set up their own setjmp() and then encounter a png_error() will longjmp here. Since the jmpbuf is then meaningless we abort instead of returning. */ #ifdef USE_FAR_KEYWORD if (setjmp(jmpbuf)) PNG_ABORT(); png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); #else if (setjmp(png_ptr->jmpbuf)) PNG_ABORT(); #endif #endif return (png_ptr); } /* Initialize PNG structure for reading, and allocate any memory needed. This interface is deprecated in favour of the png_create_read_struct(), and it will eventually disappear. */ #if defined(PNG_1_0_X) || defined (PNG_1_2_X) #undef png_read_init void PNGAPI png_read_init(png_structp png_ptr) { /* We only come here via pre-1.0.7-compiled applications */ png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0); } #endif void PNGAPI png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t png_info_size) { /* We only come here via pre-1.0.12-compiled applications */ #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) if(png_sizeof(png_struct) > png_struct_size || png_sizeof(png_info) > png_info_size) { char msg[80]; png_ptr->warning_fn=NULL; if (user_png_ver) { sprintf(msg, "Application was compiled with png.h from libpng-%.20s", user_png_ver); png_warning(png_ptr, msg); } sprintf(msg, "Application is running with png.c from libpng-%.20s", png_libpng_ver); png_warning(png_ptr, msg); } #endif if(png_sizeof(png_struct) > png_struct_size) { png_ptr->error_fn=NULL; #ifdef PNG_ERROR_NUMBERS_SUPPORTED png_ptr->flags=0; #endif png_error(png_ptr, "The png struct allocated by the application for reading is too small."); } if(png_sizeof(png_info) > png_info_size) { png_ptr->error_fn=NULL; #ifdef PNG_ERROR_NUMBERS_SUPPORTED png_ptr->flags=0; #endif png_error(png_ptr, "The info struct allocated by application for reading is too small."); } png_read_init_3(&png_ptr, user_png_ver, png_struct_size); } void PNGAPI png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, png_size_t png_struct_size) { #ifdef PNG_SETJMP_SUPPORTED jmp_buf tmp_jmp; /* to save current jump buffer */ #endif int i=0; png_structp png_ptr=*ptr_ptr; do { if(user_png_ver[i] != png_libpng_ver[i]) { #ifdef PNG_LEGACY_SUPPORTED png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; #else png_ptr->warning_fn=NULL; png_warning(png_ptr, "Application uses deprecated png_read_init() and should be recompiled."); break; #endif } } while (png_libpng_ver[i++]); png_debug(1, "in png_read_init_3\n"); #ifdef PNG_SETJMP_SUPPORTED /* save jump buffer and error functions */ png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); #endif if(png_sizeof(png_struct) > png_struct_size) { png_destroy_struct(png_ptr); *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); png_ptr = *ptr_ptr; } /* reset all variables to 0 */ png_memset(png_ptr, 0, png_sizeof (png_struct)); #ifdef PNG_SETJMP_SUPPORTED /* restore jump buffer */ png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); #endif /* added at libpng-1.2.6 */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED png_ptr->user_width_max=PNG_USER_WIDTH_MAX; png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; #endif /* initialize zbuf - compression buffer */ png_ptr->zbuf_size = PNG_ZBUF_SIZE; png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); png_ptr->zstream.zalloc = png_zalloc; png_ptr->zstream.zfree = png_zfree; png_ptr->zstream.opaque = (voidpf)png_ptr; switch (inflateInit(&png_ptr->zstream)) { case Z_OK: /* Do nothing */ break; case Z_MEM_ERROR: case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break; case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break; default: png_error(png_ptr, "Unknown zlib error"); } png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL); } #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED /* Read the information before the actual image data. This has been * changed in v0.90 to allow reading a file that already has the magic * bytes read from the stream. You can tell libpng how many bytes have * been read from the beginning of the stream (up to the maximum of 8) * via png_set_sig_bytes(), and we will only check the remaining bytes * here. The application can then have access to the signature bytes we * read if it is determined that this isn't a valid PNG file. */ void PNGAPI png_read_info(png_structp png_ptr, png_infop info_ptr) { png_debug(1, "in png_read_info\n"); /* If we haven't checked all of the PNG signature bytes, do so now. */ if (png_ptr->sig_bytes < 8) { png_size_t num_checked = png_ptr->sig_bytes, num_to_check = 8 - num_checked; png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); png_ptr->sig_bytes = 8; if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) { if (num_checked < 4 && png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) png_error(png_ptr, "Not a PNG file"); else png_error(png_ptr, "PNG file corrupted by ASCII conversion"); } if (num_checked < 3) png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; } for(;;) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_IHDR; PNG_IDAT; PNG_IEND; PNG_PLTE; #if defined(PNG_READ_bKGD_SUPPORTED) PNG_bKGD; #endif #if defined(PNG_READ_cHRM_SUPPORTED) PNG_cHRM; #endif #if defined(PNG_READ_gAMA_SUPPORTED) PNG_gAMA; #endif #if defined(PNG_READ_hIST_SUPPORTED) PNG_hIST; #endif #if defined(PNG_READ_iCCP_SUPPORTED) PNG_iCCP; #endif #if defined(PNG_READ_iTXt_SUPPORTED) PNG_iTXt; #endif #if defined(PNG_READ_oFFs_SUPPORTED) PNG_oFFs; #endif #if defined(PNG_READ_pCAL_SUPPORTED) PNG_pCAL; #endif #if defined(PNG_READ_pHYs_SUPPORTED) PNG_pHYs; #endif #if defined(PNG_READ_sBIT_SUPPORTED) PNG_sBIT; #endif #if defined(PNG_READ_sCAL_SUPPORTED) PNG_sCAL; #endif #if defined(PNG_READ_sPLT_SUPPORTED) PNG_sPLT; #endif #if defined(PNG_READ_sRGB_SUPPORTED) PNG_sRGB; #endif #if defined(PNG_READ_tEXt_SUPPORTED) PNG_tEXt; #endif #if defined(PNG_READ_tIME_SUPPORTED) PNG_tIME; #endif #if defined(PNG_READ_tRNS_SUPPORTED) PNG_tRNS; #endif #if defined(PNG_READ_zTXt_SUPPORTED) PNG_zTXt; #endif #endif /* PNG_USE_LOCAL_ARRAYS */ png_byte chunk_length[4]; png_uint_32 length; png_read_data(png_ptr, chunk_length, 4); length = png_get_uint_31(png_ptr,chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name, length); /* This should be a binary subdivision search or a hash for * matching the chunk name rather than a linear search. */ if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) png_handle_IHDR(png_ptr, info_ptr, length); else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) png_handle_IEND(png_ptr, info_ptr, length); #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) { if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) png_ptr->mode |= PNG_HAVE_IDAT; png_handle_unknown(png_ptr, info_ptr, length); if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) png_ptr->mode |= PNG_HAVE_PLTE; else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) { if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before IDAT"); else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && !(png_ptr->mode & PNG_HAVE_PLTE)) png_error(png_ptr, "Missing PLTE before IDAT"); break; } } #endif else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) png_handle_PLTE(png_ptr, info_ptr, length); else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) { if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before IDAT"); else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && !(png_ptr->mode & PNG_HAVE_PLTE)) png_error(png_ptr, "Missing PLTE before IDAT"); png_ptr->idat_size = length; png_ptr->mode |= PNG_HAVE_IDAT; break; } #if defined(PNG_READ_bKGD_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) png_handle_bKGD(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_cHRM_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) png_handle_cHRM(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_gAMA_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) png_handle_gAMA(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_hIST_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) png_handle_hIST(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_oFFs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) png_handle_oFFs(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_pCAL_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) png_handle_pCAL(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sCAL_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) png_handle_sCAL(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_pHYs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) png_handle_pHYs(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sBIT_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) png_handle_sBIT(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sRGB_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) png_handle_sRGB(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_iCCP_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) png_handle_iCCP(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sPLT_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) png_handle_sPLT(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_tEXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) png_handle_tEXt(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_tIME_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) png_handle_tIME(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_tRNS_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) png_handle_tRNS(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_zTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) png_handle_zTXt(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_iTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) png_handle_iTXt(png_ptr, info_ptr, length); #endif else png_handle_unknown(png_ptr, info_ptr, length); } } #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ /* optional call to update the users info_ptr structure */ void PNGAPI png_read_update_info(png_structp png_ptr, png_infop info_ptr) { png_debug(1, "in png_read_update_info\n"); if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); else png_warning(png_ptr, "Ignoring extra png_read_update_info() call; row buffer not reallocated"); png_read_transform_info(png_ptr, info_ptr); } #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED /* Initialize palette, background, etc, after transformations * are set, but before any reading takes place. This allows * the user to obtain a gamma-corrected palette, for example. * If the user doesn't call this, we will do it ourselves. */ void PNGAPI png_start_read_image(png_structp png_ptr) { png_debug(1, "in png_start_read_image\n"); if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); } #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED void PNGAPI png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_IDAT; const int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; const int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; #endif int ret; png_debug2(1, "in png_read_row (row %lu, pass %d)\n", png_ptr->row_number, png_ptr->pass); if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); if (png_ptr->row_number == 0 && png_ptr->pass == 0) { /* check for transforms that have been set but were defined out */ #if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) if (png_ptr->transformations & PNG_INVERT_MONO) png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined."); #endif #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) if (png_ptr->transformations & PNG_FILLER) png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined."); #endif #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined."); #endif #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) if (png_ptr->transformations & PNG_PACK) png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined."); #endif #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) if (png_ptr->transformations & PNG_SHIFT) png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined."); #endif #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) if (png_ptr->transformations & PNG_BGR) png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined."); #endif #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) if (png_ptr->transformations & PNG_SWAP_BYTES) png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined."); #endif } #if defined(PNG_READ_INTERLACING_SUPPORTED) /* if interlaced and we do not need a new row, combine row and return */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { switch (png_ptr->pass) { case 0: if (png_ptr->row_number & 0x07) { if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); png_read_finish_row(png_ptr); return; } break; case 1: if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) { if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); png_read_finish_row(png_ptr); return; } break; case 2: if ((png_ptr->row_number & 0x07) != 4) { if (dsp_row != NULL && (png_ptr->row_number & 4)) png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); png_read_finish_row(png_ptr); return; } break; case 3: if ((png_ptr->row_number & 3) || png_ptr->width < 3) { if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); png_read_finish_row(png_ptr); return; } break; case 4: if ((png_ptr->row_number & 3) != 2) { if (dsp_row != NULL && (png_ptr->row_number & 2)) png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); png_read_finish_row(png_ptr); return; } break; case 5: if ((png_ptr->row_number & 1) || png_ptr->width < 2) { if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); png_read_finish_row(png_ptr); return; } break; case 6: if (!(png_ptr->row_number & 1)) { png_read_finish_row(png_ptr); return; } break; } } #endif if (!(png_ptr->mode & PNG_HAVE_IDAT)) png_error(png_ptr, "Invalid attempt to read row data"); png_ptr->zstream.next_out = png_ptr->row_buf; png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; do { if (!(png_ptr->zstream.avail_in)) { while (!png_ptr->idat_size) { png_byte chunk_length[4]; png_crc_finish(png_ptr, 0); png_read_data(png_ptr, chunk_length, 4); png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) png_error(png_ptr, "Not enough image data"); } png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; png_ptr->zstream.next_in = png_ptr->zbuf; if (png_ptr->zbuf_size > png_ptr->idat_size) png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; png_crc_read(png_ptr, png_ptr->zbuf, (png_size_t)png_ptr->zstream.avail_in); png_ptr->idat_size -= png_ptr->zstream.avail_in; } ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); if (ret == Z_STREAM_END) { if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in || png_ptr->idat_size) png_error(png_ptr, "Extra compressed data"); png_ptr->mode |= PNG_AFTER_IDAT; png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; break; } if (ret != Z_OK) png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : "Decompression error"); } while (png_ptr->zstream.avail_out); png_ptr->row_info.color_type = png_ptr->color_type; png_ptr->row_info.width = png_ptr->iwidth; png_ptr->row_info.channels = png_ptr->channels; png_ptr->row_info.bit_depth = png_ptr->bit_depth; png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->row_info.width); if(png_ptr->row_buf[0]) png_read_filter_row(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->prev_row + 1, (int)(png_ptr->row_buf[0])); png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); #if defined(PNG_MNG_FEATURES_SUPPORTED) if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) { /* Intrapixel differencing */ png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); } #endif if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) png_do_read_transformations(png_ptr); #if defined(PNG_READ_INTERLACING_SUPPORTED) /* blow up interlaced rows to full size */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { if (png_ptr->pass < 6) /* old interface (pre-1.0.9): png_do_read_interlace(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); */ png_do_read_interlace(png_ptr); if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); if (row != NULL) png_combine_row(png_ptr, row, png_pass_mask[png_ptr->pass]); } else #endif { if (row != NULL) png_combine_row(png_ptr, row, 0xff); if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, 0xff); } png_read_finish_row(png_ptr); if (png_ptr->read_row_fn != NULL) (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); } #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED /* Read one or more rows of image data. If the image is interlaced, * and png_set_interlace_handling() has been called, the rows need to * contain the contents of the rows from the previous pass. If the * image has alpha or transparency, and png_handle_alpha()[*] has been * called, the rows contents must be initialized to the contents of the * screen. * * "row" holds the actual image, and pixels are placed in it * as they arrive. If the image is displayed after each pass, it will * appear to "sparkle" in. "display_row" can be used to display a * "chunky" progressive image, with finer detail added as it becomes * available. If you do not want this "chunky" display, you may pass * NULL for display_row. If you do not want the sparkle display, and * you have not called png_handle_alpha(), you may pass NULL for rows. * If you have called png_handle_alpha(), and the image has either an * alpha channel or a transparency chunk, you must provide a buffer for * rows. In this case, you do not have to provide a display_row buffer * also, but you may. If the image is not interlaced, or if you have * not called png_set_interlace_handling(), the display_row buffer will * be ignored, so pass NULL to it. * * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.8 */ void PNGAPI png_read_rows(png_structp png_ptr, png_bytepp row, png_bytepp display_row, png_uint_32 num_rows) { png_uint_32 i; png_bytepp rp; png_bytepp dp; png_debug(1, "in png_read_rows\n"); rp = row; dp = display_row; if (rp != NULL && dp != NULL) for (i = 0; i < num_rows; i++) { png_bytep rptr = *rp++; png_bytep dptr = *dp++; png_read_row(png_ptr, rptr, dptr); } else if(rp != NULL) for (i = 0; i < num_rows; i++) { png_bytep rptr = *rp; png_read_row(png_ptr, rptr, png_bytep_NULL); rp++; } else if(dp != NULL) for (i = 0; i < num_rows; i++) { png_bytep dptr = *dp; png_read_row(png_ptr, png_bytep_NULL, dptr); dp++; } } #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED /* Read the entire image. If the image has an alpha channel or a tRNS * chunk, and you have called png_handle_alpha()[*], you will need to * initialize the image to the current image that PNG will be overlaying. * We set the num_rows again here, in case it was incorrectly set in * png_read_start_row() by a call to png_read_update_info() or * png_start_read_image() if png_set_interlace_handling() wasn't called * prior to either of these functions like it should have been. You can * only call this function once. If you desire to have an image for * each pass of a interlaced image, use png_read_rows() instead. * * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.8 */ void PNGAPI png_read_image(png_structp png_ptr, png_bytepp image) { png_uint_32 i,image_height; int pass, j; png_bytepp rp; png_debug(1, "in png_read_image\n"); #ifdef PNG_READ_INTERLACING_SUPPORTED pass = png_set_interlace_handling(png_ptr); #else if (png_ptr->interlaced) png_error(png_ptr, "Cannot read interlaced image -- interlace handler disabled."); pass = 1; #endif image_height=png_ptr->height; png_ptr->num_rows = image_height; /* Make sure this is set correctly */ for (j = 0; j < pass; j++) { rp = image; for (i = 0; i < image_height; i++) { png_read_row(png_ptr, *rp, png_bytep_NULL); rp++; } } } #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED /* Read the end of the PNG file. Will not read past the end of the * file, will verify the end is accurate, and will read any comments * or time information at the end of the file, if info is not NULL. */ void PNGAPI png_read_end(png_structp png_ptr, png_infop info_ptr) { png_byte chunk_length[4]; png_uint_32 length; png_debug(1, "in png_read_end\n"); png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ do { #ifdef PNG_USE_LOCAL_ARRAYS PNG_IHDR; PNG_IDAT; PNG_IEND; PNG_PLTE; #if defined(PNG_READ_bKGD_SUPPORTED) PNG_bKGD; #endif #if defined(PNG_READ_cHRM_SUPPORTED) PNG_cHRM; #endif #if defined(PNG_READ_gAMA_SUPPORTED) PNG_gAMA; #endif #if defined(PNG_READ_hIST_SUPPORTED) PNG_hIST; #endif #if defined(PNG_READ_iCCP_SUPPORTED) PNG_iCCP; #endif #if defined(PNG_READ_iTXt_SUPPORTED) PNG_iTXt; #endif #if defined(PNG_READ_oFFs_SUPPORTED) PNG_oFFs; #endif #if defined(PNG_READ_pCAL_SUPPORTED) PNG_pCAL; #endif #if defined(PNG_READ_pHYs_SUPPORTED) PNG_pHYs; #endif #if defined(PNG_READ_sBIT_SUPPORTED) PNG_sBIT; #endif #if defined(PNG_READ_sCAL_SUPPORTED) PNG_sCAL; #endif #if defined(PNG_READ_sPLT_SUPPORTED) PNG_sPLT; #endif #if defined(PNG_READ_sRGB_SUPPORTED) PNG_sRGB; #endif #if defined(PNG_READ_tEXt_SUPPORTED) PNG_tEXt; #endif #if defined(PNG_READ_tIME_SUPPORTED) PNG_tIME; #endif #if defined(PNG_READ_tRNS_SUPPORTED) PNG_tRNS; #endif #if defined(PNG_READ_zTXt_SUPPORTED) PNG_zTXt; #endif #endif /* PNG_USE_LOCAL_ARRAYS */ png_read_data(png_ptr, chunk_length, 4); length = png_get_uint_31(png_ptr,chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name); if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) png_handle_IHDR(png_ptr, info_ptr, length); else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) png_handle_IEND(png_ptr, info_ptr, length); #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) { if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) { if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT) png_error(png_ptr, "Too many IDAT's found"); } else png_ptr->mode |= PNG_AFTER_IDAT; png_handle_unknown(png_ptr, info_ptr, length); if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) png_ptr->mode |= PNG_HAVE_PLTE; } #endif else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) { /* Zero length IDATs are legal after the last IDAT has been * read, but not after other chunks have been read. */ if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT) png_error(png_ptr, "Too many IDAT's found"); png_crc_finish(png_ptr, length); } else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) png_handle_PLTE(png_ptr, info_ptr, length); #if defined(PNG_READ_bKGD_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) png_handle_bKGD(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_cHRM_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) png_handle_cHRM(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_gAMA_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) png_handle_gAMA(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_hIST_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) png_handle_hIST(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_oFFs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) png_handle_oFFs(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_pCAL_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) png_handle_pCAL(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sCAL_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) png_handle_sCAL(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_pHYs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) png_handle_pHYs(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sBIT_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) png_handle_sBIT(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sRGB_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) png_handle_sRGB(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_iCCP_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) png_handle_iCCP(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sPLT_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) png_handle_sPLT(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_tEXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) png_handle_tEXt(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_tIME_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) png_handle_tIME(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_tRNS_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) png_handle_tRNS(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_zTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) png_handle_zTXt(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_iTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) png_handle_iTXt(png_ptr, info_ptr, length); #endif else png_handle_unknown(png_ptr, info_ptr, length); } while (!(png_ptr->mode & PNG_HAVE_IEND)); } #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ /* free all memory used by the read */ void PNGAPI png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr) { png_structp png_ptr = NULL; png_infop info_ptr = NULL, end_info_ptr = NULL; #ifdef PNG_USER_MEM_SUPPORTED png_free_ptr free_fn; png_voidp mem_ptr; #endif png_debug(1, "in png_destroy_read_struct\n"); if (png_ptr_ptr != NULL) png_ptr = *png_ptr_ptr; if (info_ptr_ptr != NULL) info_ptr = *info_ptr_ptr; if (end_info_ptr_ptr != NULL) end_info_ptr = *end_info_ptr_ptr; #ifdef PNG_USER_MEM_SUPPORTED free_fn = png_ptr->free_fn; mem_ptr = png_ptr->mem_ptr; #endif png_read_destroy(png_ptr, info_ptr, end_info_ptr); if (info_ptr != NULL) { #if defined(PNG_TEXT_SUPPORTED) png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1); #endif #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)info_ptr); #endif *info_ptr_ptr = NULL; } if (end_info_ptr != NULL) { #if defined(PNG_READ_TEXT_SUPPORTED) png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1); #endif #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn, (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)end_info_ptr); #endif *end_info_ptr_ptr = NULL; } if (png_ptr != NULL) { #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)png_ptr); #endif *png_ptr_ptr = NULL; } } /* free all memory used by the read (old method) */ void /* PRIVATE */ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr) { #ifdef PNG_SETJMP_SUPPORTED jmp_buf tmp_jmp; #endif png_error_ptr error_fn; png_error_ptr warning_fn; png_voidp error_ptr; #ifdef PNG_USER_MEM_SUPPORTED png_free_ptr free_fn; #endif png_debug(1, "in png_read_destroy\n"); if (info_ptr != NULL) png_info_destroy(png_ptr, info_ptr); if (end_info_ptr != NULL) png_info_destroy(png_ptr, end_info_ptr); png_free(png_ptr, png_ptr->zbuf); png_free(png_ptr, png_ptr->big_row_buf); png_free(png_ptr, png_ptr->prev_row); #if defined(PNG_READ_DITHER_SUPPORTED) png_free(png_ptr, png_ptr->palette_lookup); png_free(png_ptr, png_ptr->dither_index); #endif #if defined(PNG_READ_GAMMA_SUPPORTED) png_free(png_ptr, png_ptr->gamma_table); #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) png_free(png_ptr, png_ptr->gamma_from_1); png_free(png_ptr, png_ptr->gamma_to_1); #endif #ifdef PNG_FREE_ME_SUPPORTED if (png_ptr->free_me & PNG_FREE_PLTE) png_zfree(png_ptr, png_ptr->palette); png_ptr->free_me &= ~PNG_FREE_PLTE; #else if (png_ptr->flags & PNG_FLAG_FREE_PLTE) png_zfree(png_ptr, png_ptr->palette); png_ptr->flags &= ~PNG_FLAG_FREE_PLTE; #endif #if defined(PNG_tRNS_SUPPORTED) || \ defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) #ifdef PNG_FREE_ME_SUPPORTED if (png_ptr->free_me & PNG_FREE_TRNS) png_free(png_ptr, png_ptr->trans); png_ptr->free_me &= ~PNG_FREE_TRNS; #else if (png_ptr->flags & PNG_FLAG_FREE_TRNS) png_free(png_ptr, png_ptr->trans); png_ptr->flags &= ~PNG_FLAG_FREE_TRNS; #endif #endif #if defined(PNG_READ_hIST_SUPPORTED) #ifdef PNG_FREE_ME_SUPPORTED if (png_ptr->free_me & PNG_FREE_HIST) png_free(png_ptr, png_ptr->hist); png_ptr->free_me &= ~PNG_FREE_HIST; #else if (png_ptr->flags & PNG_FLAG_FREE_HIST) png_free(png_ptr, png_ptr->hist); png_ptr->flags &= ~PNG_FLAG_FREE_HIST; #endif #endif #if defined(PNG_READ_GAMMA_SUPPORTED) if (png_ptr->gamma_16_table != NULL) { int i; int istop = (1 << (8 - png_ptr->gamma_shift)); for (i = 0; i < istop; i++) { png_free(png_ptr, png_ptr->gamma_16_table[i]); } png_free(png_ptr, png_ptr->gamma_16_table); } #if defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->gamma_16_from_1 != NULL) { int i; int istop = (1 << (8 - png_ptr->gamma_shift)); for (i = 0; i < istop; i++) { png_free(png_ptr, png_ptr->gamma_16_from_1[i]); } png_free(png_ptr, png_ptr->gamma_16_from_1); } if (png_ptr->gamma_16_to_1 != NULL) { int i; int istop = (1 << (8 - png_ptr->gamma_shift)); for (i = 0; i < istop; i++) { png_free(png_ptr, png_ptr->gamma_16_to_1[i]); } png_free(png_ptr, png_ptr->gamma_16_to_1); } #endif #endif #if defined(PNG_TIME_RFC1123_SUPPORTED) png_free(png_ptr, png_ptr->time_buffer); #endif inflateEnd(&png_ptr->zstream); #ifdef PNG_PROGRESSIVE_READ_SUPPORTED png_free(png_ptr, png_ptr->save_buffer); #endif #ifdef PNG_PROGRESSIVE_READ_SUPPORTED #ifdef PNG_TEXT_SUPPORTED png_free(png_ptr, png_ptr->current_text); #endif /* PNG_TEXT_SUPPORTED */ #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ /* Save the important info out of the png_struct, in case it is * being used again. */ #ifdef PNG_SETJMP_SUPPORTED png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); #endif error_fn = png_ptr->error_fn; warning_fn = png_ptr->warning_fn; error_ptr = png_ptr->error_ptr; #ifdef PNG_USER_MEM_SUPPORTED free_fn = png_ptr->free_fn; #endif png_memset(png_ptr, 0, png_sizeof (png_struct)); png_ptr->error_fn = error_fn; png_ptr->warning_fn = warning_fn; png_ptr->error_ptr = error_ptr; #ifdef PNG_USER_MEM_SUPPORTED png_ptr->free_fn = free_fn; #endif #ifdef PNG_SETJMP_SUPPORTED png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); #endif } void PNGAPI png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn) { png_ptr->read_row_fn = read_row_fn; } #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED #if defined(PNG_INFO_IMAGE_SUPPORTED) void PNGAPI png_read_png(png_structp png_ptr, png_infop info_ptr, int transforms, voidp params) { int row; #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) /* invert the alpha channel from opacity to transparency */ if (transforms & PNG_TRANSFORM_INVERT_ALPHA) png_set_invert_alpha(png_ptr); #endif /* png_read_info() gives us all of the information from the * PNG file before the first IDAT (image data chunk). */ png_read_info(png_ptr, info_ptr); if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) png_error(png_ptr,"Image is too high to process with png_read_png()"); /* -------------- image transformations start here ------------------- */ #if defined(PNG_READ_16_TO_8_SUPPORTED) /* tell libpng to strip 16 bit/color files down to 8 bits per color */ if (transforms & PNG_TRANSFORM_STRIP_16) png_set_strip_16(png_ptr); #endif #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) /* Strip alpha bytes from the input data without combining with * the background (not recommended). */ if (transforms & PNG_TRANSFORM_STRIP_ALPHA) png_set_strip_alpha(png_ptr); #endif #if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single * byte into separate bytes (useful for paletted and grayscale images). */ if (transforms & PNG_TRANSFORM_PACKING) png_set_packing(png_ptr); #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED) /* Change the order of packed pixels to least significant bit first * (not useful if you are using png_set_packing). */ if (transforms & PNG_TRANSFORM_PACKSWAP) png_set_packswap(png_ptr); #endif #if defined(PNG_READ_EXPAND_SUPPORTED) /* Expand paletted colors into true RGB triplets * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel * Expand paletted or RGB images with transparency to full alpha * channels so the data will be available as RGBA quartets. */ if (transforms & PNG_TRANSFORM_EXPAND) if ((png_ptr->bit_depth < 8) || (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) png_set_expand(png_ptr); #endif /* We don't handle background color or gamma transformation or dithering. */ #if defined(PNG_READ_INVERT_SUPPORTED) /* invert monochrome files to have 0 as white and 1 as black */ if (transforms & PNG_TRANSFORM_INVERT_MONO) png_set_invert_mono(png_ptr); #endif #if defined(PNG_READ_SHIFT_SUPPORTED) /* If you want to shift the pixel values from the range [0,255] or * [0,65535] to the original [0,7] or [0,31], or whatever range the * colors were originally in: */ if ((transforms & PNG_TRANSFORM_SHIFT) && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) { png_color_8p sig_bit; png_get_sBIT(png_ptr, info_ptr, &sig_bit); png_set_shift(png_ptr, sig_bit); } #endif #if defined(PNG_READ_BGR_SUPPORTED) /* flip the RGB pixels to BGR (or RGBA to BGRA) */ if (transforms & PNG_TRANSFORM_BGR) png_set_bgr(png_ptr); #endif #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ if (transforms & PNG_TRANSFORM_SWAP_ALPHA) png_set_swap_alpha(png_ptr); #endif #if defined(PNG_READ_SWAP_SUPPORTED) /* swap bytes of 16 bit files to least significant byte first */ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) png_set_swap(png_ptr); #endif /* We don't handle adding filler bytes */ /* Optional call to gamma correct and add the background to the palette * and update info structure. REQUIRED if you are expecting libpng to * update the palette for you (i.e., you selected such a transform above). */ png_read_update_info(png_ptr, info_ptr); /* -------------- image transformations end here ------------------- */ #ifdef PNG_FREE_ME_SUPPORTED png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); #endif if(info_ptr->row_pointers == NULL) { info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, info_ptr->height * png_sizeof(png_bytep)); #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_ROWS; #endif for (row = 0; row < (int)info_ptr->height; row++) { info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); } } png_read_image(png_ptr, info_ptr->row_pointers); info_ptr->valid |= PNG_INFO_IDAT; /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ png_read_end(png_ptr, info_ptr); if(transforms == 0 || params == NULL) /* quiet compiler warnings */ return; } #endif #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngmem.c0000664000175000017500000004033310777447272020611 0ustar evanevan /* pngmem.c - stub functions for memory allocation * * libpng version 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * * This file provides a location for all memory allocation. Users who * need special memory handling are expected to supply replacement * functions for png_malloc() and png_free(), and to use * png_create_read_struct_2() and png_create_write_struct_2() to * identify the replacement functions. */ #define PNG_INTERNAL #include "png.h" /* Borland DOS special memory handler */ #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) /* if you change this, be sure to change the one in png.h also */ /* Allocate memory for a png_struct. The malloc and memset can be replaced by a single call to calloc() if this is thought to improve performance. */ png_voidp /* PRIVATE */ png_create_struct(int type) { #ifdef PNG_USER_MEM_SUPPORTED return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL)); } /* Alternate version of png_create_struct, for use with user-defined malloc. */ png_voidp /* PRIVATE */ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) { #endif /* PNG_USER_MEM_SUPPORTED */ png_size_t size; png_voidp struct_ptr; if (type == PNG_STRUCT_INFO) size = png_sizeof(png_info); else if (type == PNG_STRUCT_PNG) size = png_sizeof(png_struct); else return (png_get_copyright(NULL)); #ifdef PNG_USER_MEM_SUPPORTED if(malloc_fn != NULL) { png_struct dummy_struct; png_structp png_ptr = &dummy_struct; png_ptr->mem_ptr=mem_ptr; struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size); } else #endif /* PNG_USER_MEM_SUPPORTED */ struct_ptr = (png_voidp)farmalloc(size); if (struct_ptr != NULL) png_memset(struct_ptr, 0, size); return (struct_ptr); } /* Free memory allocated by a png_create_struct() call */ void /* PRIVATE */ png_destroy_struct(png_voidp struct_ptr) { #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL); } /* Free memory allocated by a png_create_struct() call */ void /* PRIVATE */ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, png_voidp mem_ptr) { #endif if (struct_ptr != NULL) { #ifdef PNG_USER_MEM_SUPPORTED if(free_fn != NULL) { png_struct dummy_struct; png_structp png_ptr = &dummy_struct; png_ptr->mem_ptr=mem_ptr; (*(free_fn))(png_ptr, struct_ptr); return; } #endif /* PNG_USER_MEM_SUPPORTED */ farfree (struct_ptr); } } /* Allocate memory. For reasonable files, size should never exceed * 64K. However, zlib may allocate more then 64K if you don't tell * it not to. See zconf.h and png.h for more information. zlib does * need to allocate exactly 64K, so whatever you call here must * have the ability to do that. * * Borland seems to have a problem in DOS mode for exactly 64K. * It gives you a segment with an offset of 8 (perhaps to store its * memory stuff). zlib doesn't like this at all, so we have to * detect and deal with it. This code should not be needed in * Windows or OS/2 modes, and only in 16 bit mode. This code has * been updated by Alexander Lehmann for version 0.89 to waste less * memory. * * Note that we can't use png_size_t for the "size" declaration, * since on some systems a png_size_t is a 16-bit quantity, and as a * result, we would be truncating potentially larger memory requests * (which should cause a fatal error) and introducing major problems. */ png_voidp PNGAPI png_malloc(png_structp png_ptr, png_uint_32 size) { png_voidp ret; if (png_ptr == NULL || size == 0) return (NULL); #ifdef PNG_USER_MEM_SUPPORTED if(png_ptr->malloc_fn != NULL) ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); else ret = (png_malloc_default(png_ptr, size)); if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of memory!"); return (ret); } png_voidp PNGAPI png_malloc_default(png_structp png_ptr, png_uint_32 size) { png_voidp ret; #endif /* PNG_USER_MEM_SUPPORTED */ #ifdef PNG_MAX_MALLOC_64K if (size > (png_uint_32)65536L) { png_warning(png_ptr, "Cannot Allocate > 64K"); ret = NULL; } else #endif if (size != (size_t)size) ret = NULL; else if (size == (png_uint_32)65536L) { if (png_ptr->offset_table == NULL) { /* try to see if we need to do any of this fancy stuff */ ret = farmalloc(size); if (ret == NULL || ((png_size_t)ret & 0xffff)) { int num_blocks; png_uint_32 total_size; png_bytep table; int i; png_byte huge * hptr; if (ret != NULL) { farfree(ret); ret = NULL; } if(png_ptr->zlib_window_bits > 14) num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14)); else num_blocks = 1; if (png_ptr->zlib_mem_level >= 7) num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7)); else num_blocks++; total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16; table = farmalloc(total_size); if (table == NULL) { #ifndef PNG_USER_MEM_SUPPORTED if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */ else png_warning(png_ptr, "Out Of Memory."); #endif return (NULL); } if ((png_size_t)table & 0xfff0) { #ifndef PNG_USER_MEM_SUPPORTED if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Farmalloc didn't return normalized pointer"); else png_warning(png_ptr, "Farmalloc didn't return normalized pointer"); #endif return (NULL); } png_ptr->offset_table = table; png_ptr->offset_table_ptr = farmalloc(num_blocks * png_sizeof (png_bytep)); if (png_ptr->offset_table_ptr == NULL) { #ifndef PNG_USER_MEM_SUPPORTED if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */ else png_warning(png_ptr, "Out Of memory."); #endif return (NULL); } hptr = (png_byte huge *)table; if ((png_size_t)hptr & 0xf) { hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */ } for (i = 0; i < num_blocks; i++) { png_ptr->offset_table_ptr[i] = (png_bytep)hptr; hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */ } png_ptr->offset_table_number = num_blocks; png_ptr->offset_table_count = 0; png_ptr->offset_table_count_free = 0; } } if (png_ptr->offset_table_count >= png_ptr->offset_table_number) { #ifndef PNG_USER_MEM_SUPPORTED if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */ else png_warning(png_ptr, "Out of Memory."); #endif return (NULL); } ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++]; } else ret = farmalloc(size); #ifndef PNG_USER_MEM_SUPPORTED if (ret == NULL) { if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */ else png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */ } #endif return (ret); } /* free a pointer allocated by png_malloc(). In the default configuration, png_ptr is not used, but is passed in case it is needed. If ptr is NULL, return without taking any action. */ void PNGAPI png_free(png_structp png_ptr, png_voidp ptr) { if (png_ptr == NULL || ptr == NULL) return; #ifdef PNG_USER_MEM_SUPPORTED if (png_ptr->free_fn != NULL) { (*(png_ptr->free_fn))(png_ptr, ptr); return; } else png_free_default(png_ptr, ptr); } void PNGAPI png_free_default(png_structp png_ptr, png_voidp ptr) { #endif /* PNG_USER_MEM_SUPPORTED */ if (png_ptr->offset_table != NULL) { int i; for (i = 0; i < png_ptr->offset_table_count; i++) { if (ptr == png_ptr->offset_table_ptr[i]) { ptr = NULL; png_ptr->offset_table_count_free++; break; } } if (png_ptr->offset_table_count_free == png_ptr->offset_table_count) { farfree(png_ptr->offset_table); farfree(png_ptr->offset_table_ptr); png_ptr->offset_table = NULL; png_ptr->offset_table_ptr = NULL; } } if (ptr != NULL) { farfree(ptr); } } #else /* Not the Borland DOS special memory handler */ /* Allocate memory for a png_struct or a png_info. The malloc and memset can be replaced by a single call to calloc() if this is thought to improve performance noticably. */ png_voidp /* PRIVATE */ png_create_struct(int type) { #ifdef PNG_USER_MEM_SUPPORTED return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL)); } /* Allocate memory for a png_struct or a png_info. The malloc and memset can be replaced by a single call to calloc() if this is thought to improve performance noticably. */ png_voidp /* PRIVATE */ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) { #endif /* PNG_USER_MEM_SUPPORTED */ png_size_t size; png_voidp struct_ptr; if (type == PNG_STRUCT_INFO) size = png_sizeof(png_info); else if (type == PNG_STRUCT_PNG) size = png_sizeof(png_struct); else return (NULL); #ifdef PNG_USER_MEM_SUPPORTED if(malloc_fn != NULL) { png_struct dummy_struct; png_structp png_ptr = &dummy_struct; png_ptr->mem_ptr=mem_ptr; struct_ptr = (*(malloc_fn))(png_ptr, size); if (struct_ptr != NULL) png_memset(struct_ptr, 0, size); return (struct_ptr); } #endif /* PNG_USER_MEM_SUPPORTED */ #if defined(__TURBOC__) && !defined(__FLAT__) struct_ptr = (png_voidp)farmalloc(size); #else # if defined(_MSC_VER) && defined(MAXSEG_64K) struct_ptr = (png_voidp)halloc(size,1); # else struct_ptr = (png_voidp)malloc(size); # endif #endif if (struct_ptr != NULL) png_memset(struct_ptr, 0, size); return (struct_ptr); } /* Free memory allocated by a png_create_struct() call */ void /* PRIVATE */ png_destroy_struct(png_voidp struct_ptr) { #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL); } /* Free memory allocated by a png_create_struct() call */ void /* PRIVATE */ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, png_voidp mem_ptr) { #endif /* PNG_USER_MEM_SUPPORTED */ if (struct_ptr != NULL) { #ifdef PNG_USER_MEM_SUPPORTED if(free_fn != NULL) { png_struct dummy_struct; png_structp png_ptr = &dummy_struct; png_ptr->mem_ptr=mem_ptr; (*(free_fn))(png_ptr, struct_ptr); return; } #endif /* PNG_USER_MEM_SUPPORTED */ #if defined(__TURBOC__) && !defined(__FLAT__) farfree(struct_ptr); #else # if defined(_MSC_VER) && defined(MAXSEG_64K) hfree(struct_ptr); # else free(struct_ptr); # endif #endif } } /* Allocate memory. For reasonable files, size should never exceed 64K. However, zlib may allocate more then 64K if you don't tell it not to. See zconf.h and png.h for more information. zlib does need to allocate exactly 64K, so whatever you call here must have the ability to do that. */ png_voidp PNGAPI png_malloc(png_structp png_ptr, png_uint_32 size) { png_voidp ret; #ifdef PNG_USER_MEM_SUPPORTED if (png_ptr == NULL || size == 0) return (NULL); if(png_ptr->malloc_fn != NULL) ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); else ret = (png_malloc_default(png_ptr, size)); if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of Memory!"); return (ret); } png_voidp PNGAPI png_malloc_default(png_structp png_ptr, png_uint_32 size) { png_voidp ret; #endif /* PNG_USER_MEM_SUPPORTED */ if (png_ptr == NULL || size == 0) return (NULL); #ifdef PNG_MAX_MALLOC_64K if (size > (png_uint_32)65536L) { #ifndef PNG_USER_MEM_SUPPORTED if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Cannot Allocate > 64K"); else #endif return NULL; } #endif /* Check for overflow */ #if defined(__TURBOC__) && !defined(__FLAT__) if (size != (unsigned long)size) ret = NULL; else ret = farmalloc(size); #else # if defined(_MSC_VER) && defined(MAXSEG_64K) if (size != (unsigned long)size) ret = NULL; else ret = halloc(size, 1); # else if (size != (size_t)size) ret = NULL; else ret = malloc((size_t)size); # endif #endif #ifndef PNG_USER_MEM_SUPPORTED if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of Memory"); #endif return (ret); } /* Free a pointer allocated by png_malloc(). If ptr is NULL, return without taking any action. */ void PNGAPI png_free(png_structp png_ptr, png_voidp ptr) { if (png_ptr == NULL || ptr == NULL) return; #ifdef PNG_USER_MEM_SUPPORTED if (png_ptr->free_fn != NULL) { (*(png_ptr->free_fn))(png_ptr, ptr); return; } else png_free_default(png_ptr, ptr); } void PNGAPI png_free_default(png_structp png_ptr, png_voidp ptr) { if (png_ptr == NULL || ptr == NULL) return; #endif /* PNG_USER_MEM_SUPPORTED */ #if defined(__TURBOC__) && !defined(__FLAT__) farfree(ptr); #else # if defined(_MSC_VER) && defined(MAXSEG_64K) hfree(ptr); # else free(ptr); # endif #endif } #endif /* Not Borland DOS special memory handler */ #if defined(PNG_1_0_X) # define png_malloc_warn png_malloc #else /* This function was added at libpng version 1.2.3. The png_malloc_warn() * function will set up png_malloc() to issue a png_warning and return NULL * instead of issuing a png_error, if it fails to allocate the requested * memory. */ png_voidp PNGAPI png_malloc_warn(png_structp png_ptr, png_uint_32 size) { png_voidp ptr; png_uint_32 save_flags=png_ptr->flags; png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; ptr = (png_voidp)png_malloc((png_structp)png_ptr, size); png_ptr->flags=save_flags; return(ptr); } #endif png_voidp PNGAPI png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2, png_uint_32 length) { png_size_t size; size = (png_size_t)length; if ((png_uint_32)size != length) png_error(png_ptr,"Overflow in png_memcpy_check."); return(png_memcpy (s1, s2, size)); } png_voidp PNGAPI png_memset_check (png_structp png_ptr, png_voidp s1, int value, png_uint_32 length) { png_size_t size; size = (png_size_t)length; if ((png_uint_32)size != length) png_error(png_ptr,"Overflow in png_memset_check."); return (png_memset (s1, value, size)); } #ifdef PNG_USER_MEM_SUPPORTED /* This function is called when the application wants to use another method * of allocating and freeing memory. */ void PNGAPI png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn) { png_ptr->mem_ptr = mem_ptr; png_ptr->malloc_fn = malloc_fn; png_ptr->free_fn = free_fn; } /* This function returns a pointer to the mem_ptr associated with the user * functions. The application should free any memory associated with this * pointer before png_write_destroy and png_read_destroy are called. */ png_voidp PNGAPI png_get_mem_ptr(png_structp png_ptr) { return ((png_voidp)png_ptr->mem_ptr); } #endif /* PNG_USER_MEM_SUPPORTED */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/libpngpf.30000664000175000017500000006062510777447272021055 0ustar evanevan.TH LIBPNGPF 3 "December 3, 2004" .SH NAME libpng \- Portable Network Graphics (PNG) Reference Library 1.2.8 (private functions) .SH SYNOPSIS \fB\fB#include \fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_build_gamma_table (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_build_grayscale_palette (int \fP\fI\fP\fIbit_depth\fP\fB\fP\fB, png_colorp \fI\fIpalette\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_calculate_crc (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIptr\fP\fB\fP\fB, png_size_t \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_check_chunk_name (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fI\fIchunk_name\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBpng_size_t png_check_keyword (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIkey\fP\fB\fP\fB, png_charpp \fI\fInew_key\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_combine_row (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, int \fI\fImask\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_correct_palette (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_colorp \fP\fI\fP\fIpalette\fP\fB\fP\fB, int \fI\fInum_palette\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBint png_crc_error (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBint png_crc_finish (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIskip\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_crc_read (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIbuf\fP\fB\fP\fB, png_size_t \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBpng_voidp png_create_struct (int \fI\fItype\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBpng_voidp png_create_struct_2 (int \fP\fI\fP\fItype\fP\fB\fP\fB, png_malloc_ptr \fP\fI\fP\fImalloc_fn\fP\fB\fP\fB, png_voidp \fI\fImem_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBpng_charp png_decompress_chunk (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, int \fP\fI\fP\fIcomp_type\fP\fB\fP\fB, png_charp \fP\fI\fP\fIchunkdata\fP\fB\fP\fB, png_size_t \fP\fI\fP\fIchunklength\fP\fB\fP\fB, png_size_t \fP\fI\fP\fIprefix_length\fP\fB\fP\fB, png_size_t \fI\fI*data_length\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_destroy_struct (png_voidp \fI\fIstruct_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_destroy_struct_2 (png_voidp \fP\fI\fP\fIstruct_ptr\fP\fB\fP\fB, png_free_ptr \fP\fI\fP\fIfree_fn\fP\fB\fP\fB, png_voidp \fI\fImem_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_background (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_color_16p \fP\fI\fP\fItrans_values\fP\fB\fP\fB, png_color_16p \fP\fI\fP\fIbackground\fP\fB\fP\fB, png_color_16p \fP\fI\fP\fIbackground_1\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIgamma_table\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIgamma_from_1\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIgamma_to_1\fP\fB\fP\fB, png_uint_16pp \fP\fI\fP\fIgamma_16\fP\fB\fP\fB, png_uint_16pp \fP\fI\fP\fIgamma_16_from_1\fP\fB\fP\fB, png_uint_16pp \fP\fI\fP\fIgamma_16_to_1\fP\fB\fP\fB, int \fI\fIgamma_shift\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_bgr (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_chop (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_dither (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIpalette_lookup\fP\fB\fP\fB, png_bytep \fI\fIdither_lookup\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_expand (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_color_16p \fI\fItrans_value\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_expand_palette (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_colorp \fP\fI\fP\fIpalette\fP\fB\fP\fB, png_bytep \fP\fI\fP\fItrans\fP\fB\fP\fB, int \fI\fInum_trans\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_gamma (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIgamma_table\fP\fB\fP\fB, png_uint_16pp \fP\fI\fP\fIgamma_16_table\fP\fB\fP\fB, int \fI\fIgamma_shift\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_gray_to_rgb (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_invert (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_pack (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_uint_32 \fI\fIbit_depth\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_packswap (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_read_filler (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIfiller\fP\fB\fP\fB, png_uint_32 \fI\fIflags\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_read_interlace (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, int \fP\fI\fP\fIpass\fP\fB\fP\fB, png_uint_32 \fI\fItransformations\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_read_invert_alpha (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_read_swap_alpha (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_read_transformations (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBint png_do_rgb_to_gray (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_shift (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_color_8p \fI\fIbit_depth\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_strip_filler (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_uint_32 \fI\fIflags\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_swap (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_unpack (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_unshift (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_color_8p \fI\fIsig_bits\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_write_interlace (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, int \fI\fIpass\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_write_invert_alpha (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_write_swap_alpha (png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_do_write_transformations (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid *png_far_to_near (png_structp png_ptr,png_voidp \fP\fI\fP\fIptr\fP\fB\fP\fB, int \fI\fIcheck\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_flush (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBpng_int_32 png_get_int_32 (png_bytep \fI\fIbuf\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBpng_uint_16 png_get_uint_16 (png_bytep \fI\fIbuf\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBpng_uint_32 png_get_uint_31 (png_bytep \fI\fIbuf\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBpng_uint_32 png_get_uint_32 (png_bytep \fI\fIbuf\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_bKGD (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_cHRM (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_gAMA (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_hIST (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_IEND (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_IHDR (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_iCCP (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_iTXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_oFFs (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_pCAL (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_pHYs (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_PLTE (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_sBIT (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_sCAL (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_sPLT (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_sRGB (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_tEXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_tIME (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_tRNS (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_unknown (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_handle_zTXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_info_destroy (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_init_mmx_flags (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_init_read_transformations (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_process_IDAT_data (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIbuffer\fP\fB\fP\fB, png_size_t \fI\fIbuffer_length\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_process_some_data (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_check_crc (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_crc_finish (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_crc_skip (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_fill_buffer (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIbuffer\fP\fB\fP\fB, png_size_t \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_handle_tEXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_handle_unknown (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_handle_zTXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_have_end (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_have_info (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_have_row (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fI\fIrow\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_process_row (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_read_chunk (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_read_end (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_read_IDAT (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_read_sig (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_read_tEXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_read_zTXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_restore_buffer (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIbuffer\fP\fB\fP\fB, png_size_t \fI\fIbuffer_length\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_push_save_buffer (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_read_data (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIdata\fP\fB\fP\fB, png_size_t \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_read_filter_row (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_row_infop \fP\fI\fP\fIrow_info\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIrow\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIprev_row\fP\fB\fP\fB, int \fI\fIfilter\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_read_finish_row (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_read_push_finish_row (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_read_start_row (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_read_transform_info (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fI\fIinfo_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_reset_crc (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_save_int_32 (png_bytep \fP\fI\fP\fIbuf\fP\fB\fP\fB, png_int_32 \fI\fIi\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_save_uint_16 (png_bytep \fP\fI\fP\fIbuf\fP\fB\fP\fB, unsigned int \fI\fIi\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_save_uint_32 (png_bytep \fP\fI\fP\fIbuf\fP\fB\fP\fB, png_uint_32 \fI\fIi\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBint png_set_text_2 (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_infop \fP\fI\fP\fIinfo_ptr\fP\fB\fP\fB, png_textp \fP\fI\fP\fItext_ptr\fP\fB\fP\fB, int \fI\fInum_text\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_cHRM (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, double \fP\fI\fP\fIwhite_x\fP\fB\fP\fB, double \fP\fI\fP\fIwhite_y\fP\fB\fP\fB, double \fP\fI\fP\fIred_x\fP\fB\fP\fB, double \fP\fI\fP\fIred_y\fP\fB\fP\fB, double \fP\fI\fP\fIgreen_x\fP\fB\fP\fB, double \fP\fI\fP\fIgreen_y\fP\fB\fP\fB, double \fP\fI\fP\fIblue_x\fP\fB\fP\fB, double \fI\fIblue_y\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_cHRM_fixed (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIwhite_x\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIwhite_y\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIred_x\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIred_y\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIgreen_x\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIgreen_y\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIblue_x\fP\fB\fP\fB, png_uint_32 \fI\fIblue_y\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_data (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIdata\fP\fB\fP\fB, png_size_t \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_filtered_row (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fI\fIfiltered_row\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_find_filter (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_row_infop \fI\fIrow_info\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_finish_row (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_gAMA (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, double \fI\fIfile_gamma\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_gAMA_fixed (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fI\fIint_file_gamma\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_hIST (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_16p \fP\fI\fP\fIhist\fP\fB\fP\fB, int \fI\fInum_hist\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_iCCP (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIname\fP\fB\fP\fB, int \fP\fI\fP\fIcompression_type\fP\fB\fP\fB, png_charp \fP\fI\fP\fIprofile\fP\fB\fP\fB, int \fI\fIproflen\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_IDAT (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fIdata\fP\fB\fP\fB, png_size_t \fI\fIlength\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_IEND (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_IHDR (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIwidth\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIheight\fP\fB\fP\fB, int \fP\fI\fP\fIbit_depth\fP\fB\fP\fB, int \fP\fI\fP\fIcolor_type\fP\fB\fP\fB, int \fP\fI\fP\fIcompression_type\fP\fB\fP\fB, int \fP\fI\fP\fIfilter_type\fP\fB\fP\fB, int \fI\fIinterlace_type\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_iTXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, int \fP\fI\fP\fIcompression\fP\fB\fP\fB, png_charp \fP\fI\fP\fIkey\fP\fB\fP\fB, png_charp \fP\fI\fP\fIlang\fP\fB\fP\fB, png_charp \fP\fI\fP\fItranslated_key\fP\fB\fP\fB, png_charp \fI\fItext\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_oFFs (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIx_offset\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIy_offset\fP\fB\fP\fB, int \fI\fIunit_type\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_pCAL (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIpurpose\fP\fB\fP\fB, png_int_32 \fP\fI\fP\fIX0\fP\fB\fP\fB, png_int_32 \fP\fI\fP\fIX1\fP\fB\fP\fB, int \fP\fI\fP\fItype\fP\fB\fP\fB, int \fP\fI\fP\fInparams\fP\fB\fP\fB, png_charp \fP\fI\fP\fIunits\fP\fB\fP\fB, png_charpp \fI\fIparams\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_pHYs (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIx_pixels_per_unit\fP\fB\fP\fB, png_uint_32 \fP\fI\fP\fIy_pixels_per_unit\fP\fB\fP\fB, int \fI\fIunit_type\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_PLTE (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_colorp \fP\fI\fP\fIpalette\fP\fB\fP\fB, png_uint_32 \fI\fInum_pal\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_sBIT (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_color_8p \fP\fI\fP\fIsbit\fP\fB\fP\fB, int \fI\fIcolor_type\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_sCAL (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIunit\fP\fB\fP\fB, double \fP\fI\fP\fIwidth\fP\fB\fP\fB, double \fI\fIheight\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_sCAL_s (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIunit\fP\fB\fP\fB, png_charp \fP\fI\fP\fIwidth\fP\fB\fP\fB, png_charp \fI\fIheight\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_sig (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_sRGB (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, int \fI\fIintent\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_sPLT (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_spalette_p \fI\fIpalette\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_start_row (png_structp \fI\fIpng_ptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_tEXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIkey\fP\fB\fP\fB, png_charp \fP\fI\fP\fItext\fP\fB\fP\fB, png_size_t \fI\fItext_len\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_tIME (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_timep \fI\fImod_time\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_tRNS (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_bytep \fP\fI\fP\fItrans\fP\fB\fP\fB, png_color_16p \fP\fI\fP\fIvalues\fP\fB\fP\fB, int \fP\fI\fP\fInumber\fP\fB\fP\fB, int \fI\fIcolor_type\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_write_zTXt (png_structp \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, png_charp \fP\fI\fP\fIkey\fP\fB\fP\fB, png_charp \fP\fI\fP\fItext\fP\fB\fP\fB, png_size_t \fP\fI\fP\fItext_len\fP\fB\fP\fB, int \fI\fIcompression\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoidpf png_zalloc (voidpf \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, uInt \fP\fI\fP\fIitems\fP\fB\fP\fB, uInt \fI\fIsize\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB \fB\fBvoid png_zfree (voidpf \fP\fI\fP\fIpng_ptr\fP\fB\fP\fB, voidpf \fI\fIptr\fP\fB\fP\fB);\fP\fP \fI\fB \fI\fB\fI\fB \fI\fB .SH DESCRIPTION The functions listed above are used privately by libpng and are not recommended for use by applications. They are not "exported" to applications using shared libraries. They are listed alphabetically here as an aid to libpng maintainers. See png.h for more information on these functions. .SH SEE ALSO libpng(3), png(5) .SH AUTHOR Glenn Randers-Pehrson syslinux-legacy-3.63+dfsg/com32/lib/libpng/ANNOUNCE0000664000175000017500000000270410777447272020313 0ustar evanevan Libpng 1.2.8 - December 3, 2004 This is a public release of libpng, intended for use in production codes. Changes since the last public release (1.2.7): Fixed bug in png_text_compress() that would fail to complete a large block. Fixed bug, introduced in libpng-1.2.7, that overruns a buffer during strip alpha operation in png_do_strip_filler(). Added PNG_1_2_X definition in pngconf.h #ifdef out png_info_init in png.c and png_read_init in pngread.c (as of 1.3.0) Reduce color_type to a nonalpha type after strip alpha operation in png_do_strip_filler(). Revised definitions of PNG_MAX_UINT_32, PNG_MAX_SIZE, and PNG_MAXSUM Fixed (again) definition of PNG_LIBPNG_VER_DLLNUM in png.h (Cosmin). Added PNG_LIBPNG_BUILD_PRIVATE in png.h (Cosmin). Set png_ptr->zstream.data_type to Z_BINARY, to avoid unnecessary detection of data type in deflate (Cosmin). Deprecated but continue to support SPECIALBUILD and PRIVATEBUILD in favor of PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. Despammed mailing addresses by masking "@" with "at". Added scripts/makefile.elf with supporting code in pngconf.h for symbol versioning (John Bowler). Added projects/visualc71 (Simon-pierre). Send comments/corrections/commendations to png-implement at ccrc.wustl.edu (subscription required; write to majordomo at ccrc.wustl.edu with "subscribe png-implement" in the message) or to glennrp at users.sourceforge.net Glenn R-P syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngpread.c0000664000175000017500000013164310777447272021133 0ustar evanevan /* pngpread.c - read a png file in push mode * * libpng version 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ #define PNG_INTERNAL #include "png.h" #ifdef PNG_PROGRESSIVE_READ_SUPPORTED /* push model modes */ #define PNG_READ_SIG_MODE 0 #define PNG_READ_CHUNK_MODE 1 #define PNG_READ_IDAT_MODE 2 #define PNG_SKIP_MODE 3 #define PNG_READ_tEXt_MODE 4 #define PNG_READ_zTXt_MODE 5 #define PNG_READ_DONE_MODE 6 #define PNG_READ_iTXt_MODE 7 #define PNG_ERROR_MODE 8 void PNGAPI png_process_data(png_structp png_ptr, png_infop info_ptr, png_bytep buffer, png_size_t buffer_size) { png_push_restore_buffer(png_ptr, buffer, buffer_size); while (png_ptr->buffer_size) { png_process_some_data(png_ptr, info_ptr); } } /* What we do with the incoming data depends on what we were previously * doing before we ran out of data... */ void /* PRIVATE */ png_process_some_data(png_structp png_ptr, png_infop info_ptr) { switch (png_ptr->process_mode) { case PNG_READ_SIG_MODE: { png_push_read_sig(png_ptr, info_ptr); break; } case PNG_READ_CHUNK_MODE: { png_push_read_chunk(png_ptr, info_ptr); break; } case PNG_READ_IDAT_MODE: { png_push_read_IDAT(png_ptr); break; } #if defined(PNG_READ_tEXt_SUPPORTED) case PNG_READ_tEXt_MODE: { png_push_read_tEXt(png_ptr, info_ptr); break; } #endif #if defined(PNG_READ_zTXt_SUPPORTED) case PNG_READ_zTXt_MODE: { png_push_read_zTXt(png_ptr, info_ptr); break; } #endif #if defined(PNG_READ_iTXt_SUPPORTED) case PNG_READ_iTXt_MODE: { png_push_read_iTXt(png_ptr, info_ptr); break; } #endif case PNG_SKIP_MODE: { png_push_crc_finish(png_ptr); break; } default: { png_ptr->buffer_size = 0; break; } } } /* Read any remaining signature bytes from the stream and compare them with * the correct PNG signature. It is possible that this routine is called * with bytes already read from the signature, either because they have been * checked by the calling application, or because of multiple calls to this * routine. */ void /* PRIVATE */ png_push_read_sig(png_structp png_ptr, png_infop info_ptr) { png_size_t num_checked = png_ptr->sig_bytes, num_to_check = 8 - num_checked; if (png_ptr->buffer_size < num_to_check) { num_to_check = png_ptr->buffer_size; } png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+num_to_check); if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) { if (num_checked < 4 && png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) png_error(png_ptr, "Not a PNG file"); else png_error(png_ptr, "PNG file corrupted by ASCII conversion"); } else { if (png_ptr->sig_bytes >= 8) { png_ptr->process_mode = PNG_READ_CHUNK_MODE; } } } void /* PRIVATE */ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_IHDR; PNG_IDAT; PNG_IEND; PNG_PLTE; #if defined(PNG_READ_bKGD_SUPPORTED) PNG_bKGD; #endif #if defined(PNG_READ_cHRM_SUPPORTED) PNG_cHRM; #endif #if defined(PNG_READ_gAMA_SUPPORTED) PNG_gAMA; #endif #if defined(PNG_READ_hIST_SUPPORTED) PNG_hIST; #endif #if defined(PNG_READ_iCCP_SUPPORTED) PNG_iCCP; #endif #if defined(PNG_READ_iTXt_SUPPORTED) PNG_iTXt; #endif #if defined(PNG_READ_oFFs_SUPPORTED) PNG_oFFs; #endif #if defined(PNG_READ_pCAL_SUPPORTED) PNG_pCAL; #endif #if defined(PNG_READ_pHYs_SUPPORTED) PNG_pHYs; #endif #if defined(PNG_READ_sBIT_SUPPORTED) PNG_sBIT; #endif #if defined(PNG_READ_sCAL_SUPPORTED) PNG_sCAL; #endif #if defined(PNG_READ_sRGB_SUPPORTED) PNG_sRGB; #endif #if defined(PNG_READ_sPLT_SUPPORTED) PNG_sPLT; #endif #if defined(PNG_READ_tEXt_SUPPORTED) PNG_tEXt; #endif #if defined(PNG_READ_tIME_SUPPORTED) PNG_tIME; #endif #if defined(PNG_READ_tRNS_SUPPORTED) PNG_tRNS; #endif #if defined(PNG_READ_zTXt_SUPPORTED) PNG_zTXt; #endif #endif /* PNG_USE_LOCAL_ARRAYS */ /* First we make sure we have enough data for the 4 byte chunk name * and the 4 byte chunk length before proceeding with decoding the * chunk data. To fully decode each of these chunks, we also make * sure we have enough data in the buffer for the 4 byte CRC at the * end of every chunk (except IDAT, which is handled separately). */ if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) { png_byte chunk_length[4]; if (png_ptr->buffer_size < 8) { png_push_save_buffer(png_ptr); return; } png_push_fill_buffer(png_ptr, chunk_length, 4); png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; } if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); } else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); png_ptr->process_mode = PNG_READ_DONE_MODE; png_push_have_end(png_ptr, info_ptr); } #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) png_ptr->mode |= PNG_HAVE_IDAT; png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) png_ptr->mode |= PNG_HAVE_PLTE; else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) { if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before IDAT"); else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && !(png_ptr->mode & PNG_HAVE_PLTE)) png_error(png_ptr, "Missing PLTE before IDAT"); } } #endif else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); } else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) { /* If we reach an IDAT chunk, this means we have read all of the * header chunks, and we can start reading the image (or if this * is called after the image has been read - we have an error). */ if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before IDAT"); else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && !(png_ptr->mode & PNG_HAVE_PLTE)) png_error(png_ptr, "Missing PLTE before IDAT"); if (png_ptr->mode & PNG_HAVE_IDAT) { if (png_ptr->push_length == 0) return; if (png_ptr->mode & PNG_AFTER_IDAT) png_error(png_ptr, "Too many IDAT's found"); } png_ptr->idat_size = png_ptr->push_length; png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->process_mode = PNG_READ_IDAT_MODE; png_push_have_info(png_ptr, info_ptr); png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; png_ptr->zstream.next_out = png_ptr->row_buf; return; } #if defined(PNG_READ_gAMA_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_sBIT_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_cHRM_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_sRGB_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_iCCP_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_sPLT_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_tRNS_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_bKGD_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_hIST_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_pHYs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_oFFs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_pCAL_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_sCAL_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_tIME_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_tEXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_zTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_iTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); } #endif else { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); } png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; } void /* PRIVATE */ png_push_crc_skip(png_structp png_ptr, png_uint_32 skip) { png_ptr->process_mode = PNG_SKIP_MODE; png_ptr->skip_length = skip; } void /* PRIVATE */ png_push_crc_finish(png_structp png_ptr) { if (png_ptr->skip_length && png_ptr->save_buffer_size) { png_size_t save_size; if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size) save_size = (png_size_t)png_ptr->skip_length; else save_size = png_ptr->save_buffer_size; png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); png_ptr->skip_length -= save_size; png_ptr->buffer_size -= save_size; png_ptr->save_buffer_size -= save_size; png_ptr->save_buffer_ptr += save_size; } if (png_ptr->skip_length && png_ptr->current_buffer_size) { png_size_t save_size; if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size) save_size = (png_size_t)png_ptr->skip_length; else save_size = png_ptr->current_buffer_size; png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); png_ptr->skip_length -= save_size; png_ptr->buffer_size -= save_size; png_ptr->current_buffer_size -= save_size; png_ptr->current_buffer_ptr += save_size; } if (!png_ptr->skip_length) { if (png_ptr->buffer_size < 4) { png_push_save_buffer(png_ptr); return; } png_crc_finish(png_ptr, 0); png_ptr->process_mode = PNG_READ_CHUNK_MODE; } } void PNGAPI png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) { png_bytep ptr; ptr = buffer; if (png_ptr->save_buffer_size) { png_size_t save_size; if (length < png_ptr->save_buffer_size) save_size = length; else save_size = png_ptr->save_buffer_size; png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size); length -= save_size; ptr += save_size; png_ptr->buffer_size -= save_size; png_ptr->save_buffer_size -= save_size; png_ptr->save_buffer_ptr += save_size; } if (length && png_ptr->current_buffer_size) { png_size_t save_size; if (length < png_ptr->current_buffer_size) save_size = length; else save_size = png_ptr->current_buffer_size; png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size); png_ptr->buffer_size -= save_size; png_ptr->current_buffer_size -= save_size; png_ptr->current_buffer_ptr += save_size; } } void /* PRIVATE */ png_push_save_buffer(png_structp png_ptr) { if (png_ptr->save_buffer_size) { if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) { png_size_t i,istop; png_bytep sp; png_bytep dp; istop = png_ptr->save_buffer_size; for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; i < istop; i++, sp++, dp++) { *dp = *sp; } } } if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > png_ptr->save_buffer_max) { png_size_t new_max; png_bytep old_buffer; if (png_ptr->save_buffer_size > PNG_SIZE_MAX - (png_ptr->current_buffer_size + 256)) { png_error(png_ptr, "Potential overflow of save_buffer"); } new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; old_buffer = png_ptr->save_buffer; png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr, (png_uint_32)new_max); png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); png_free(png_ptr, old_buffer); png_ptr->save_buffer_max = new_max; } if (png_ptr->current_buffer_size) { png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); png_ptr->save_buffer_size += png_ptr->current_buffer_size; png_ptr->current_buffer_size = 0; } png_ptr->save_buffer_ptr = png_ptr->save_buffer; png_ptr->buffer_size = 0; } void /* PRIVATE */ png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, png_size_t buffer_length) { png_ptr->current_buffer = buffer; png_ptr->current_buffer_size = buffer_length; png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; png_ptr->current_buffer_ptr = png_ptr->current_buffer; } void /* PRIVATE */ png_push_read_IDAT(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_IDAT; #endif if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) { png_byte chunk_length[4]; if (png_ptr->buffer_size < 8) { png_push_save_buffer(png_ptr); return; } png_push_fill_buffer(png_ptr, chunk_length, 4); png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) { png_ptr->process_mode = PNG_READ_CHUNK_MODE; if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) png_error(png_ptr, "Not enough compressed data"); return; } png_ptr->idat_size = png_ptr->push_length; } if (png_ptr->idat_size && png_ptr->save_buffer_size) { png_size_t save_size; if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size) { save_size = (png_size_t)png_ptr->idat_size; /* check for overflow */ if((png_uint_32)save_size != png_ptr->idat_size) png_error(png_ptr, "save_size overflowed in pngpread"); } else save_size = png_ptr->save_buffer_size; png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); png_ptr->idat_size -= save_size; png_ptr->buffer_size -= save_size; png_ptr->save_buffer_size -= save_size; png_ptr->save_buffer_ptr += save_size; } if (png_ptr->idat_size && png_ptr->current_buffer_size) { png_size_t save_size; if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size) { save_size = (png_size_t)png_ptr->idat_size; /* check for overflow */ if((png_uint_32)save_size != png_ptr->idat_size) png_error(png_ptr, "save_size overflowed in pngpread"); } else save_size = png_ptr->current_buffer_size; png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); png_ptr->idat_size -= save_size; png_ptr->buffer_size -= save_size; png_ptr->current_buffer_size -= save_size; png_ptr->current_buffer_ptr += save_size; } if (!png_ptr->idat_size) { if (png_ptr->buffer_size < 4) { png_push_save_buffer(png_ptr); return; } png_crc_finish(png_ptr, 0); png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; png_ptr->mode |= PNG_AFTER_IDAT; } } void /* PRIVATE */ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, png_size_t buffer_length) { int ret; if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length) png_error(png_ptr, "Extra compression data"); png_ptr->zstream.next_in = buffer; png_ptr->zstream.avail_in = (uInt)buffer_length; for(;;) { ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); if (ret != Z_OK) { if (ret == Z_STREAM_END) { if (png_ptr->zstream.avail_in) png_error(png_ptr, "Extra compressed data"); if (!(png_ptr->zstream.avail_out)) { png_push_process_row(png_ptr); } png_ptr->mode |= PNG_AFTER_IDAT; png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; break; } else if (ret == Z_BUF_ERROR) break; else png_error(png_ptr, "Decompression Error"); } if (!(png_ptr->zstream.avail_out)) { if (( #if defined(PNG_READ_INTERLACING_SUPPORTED) png_ptr->interlaced && png_ptr->pass > 6) || (!png_ptr->interlaced && #endif png_ptr->row_number == png_ptr->num_rows)) { if (png_ptr->zstream.avail_in) png_warning(png_ptr, "Too much data in IDAT chunks"); png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; break; } png_push_process_row(png_ptr); png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; png_ptr->zstream.next_out = png_ptr->row_buf; } else break; } } void /* PRIVATE */ png_push_process_row(png_structp png_ptr) { png_ptr->row_info.color_type = png_ptr->color_type; png_ptr->row_info.width = png_ptr->iwidth; png_ptr->row_info.channels = png_ptr->channels; png_ptr->row_info.bit_depth = png_ptr->bit_depth; png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->row_info.width); png_read_filter_row(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->prev_row + 1, (int)(png_ptr->row_buf[0])); png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) png_do_read_transformations(png_ptr); #if defined(PNG_READ_INTERLACING_SUPPORTED) /* blow up interlaced rows to full size */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { if (png_ptr->pass < 6) /* old interface (pre-1.0.9): png_do_read_interlace(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); */ png_do_read_interlace(png_ptr); switch (png_ptr->pass) { case 0: { int i; for (i = 0; i < 8 && png_ptr->pass == 0; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */ } if (png_ptr->pass == 2) /* pass 1 might be empty */ { for (i = 0; i < 4 && png_ptr->pass == 2; i++) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } } if (png_ptr->pass == 4 && png_ptr->height <= 4) { for (i = 0; i < 2 && png_ptr->pass == 4; i++) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } } if (png_ptr->pass == 6 && png_ptr->height <= 4) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } break; } case 1: { int i; for (i = 0; i < 8 && png_ptr->pass == 1; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } if (png_ptr->pass == 2) /* skip top 4 generated rows */ { for (i = 0; i < 4 && png_ptr->pass == 2; i++) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } } break; } case 2: { int i; for (i = 0; i < 4 && png_ptr->pass == 2; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } for (i = 0; i < 4 && png_ptr->pass == 2; i++) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } if (png_ptr->pass == 4) /* pass 3 might be empty */ { for (i = 0; i < 2 && png_ptr->pass == 4; i++) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } } break; } case 3: { int i; for (i = 0; i < 4 && png_ptr->pass == 3; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } if (png_ptr->pass == 4) /* skip top two generated rows */ { for (i = 0; i < 2 && png_ptr->pass == 4; i++) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } } break; } case 4: { int i; for (i = 0; i < 2 && png_ptr->pass == 4; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } for (i = 0; i < 2 && png_ptr->pass == 4; i++) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } if (png_ptr->pass == 6) /* pass 5 might be empty */ { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } break; } case 5: { int i; for (i = 0; i < 2 && png_ptr->pass == 5; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } if (png_ptr->pass == 6) /* skip top generated row */ { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } break; } case 6: { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); if (png_ptr->pass != 6) break; png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } } } else #endif { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } } void /* PRIVATE */ png_read_push_finish_row(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* start of interlace block */ const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; /* offset to next interlace block */ const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; /* start of interlace block in the y direction */ const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; /* offset to next interlace block in the y direction */ const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; /* Width of interlace block. This is not currently used - if you need * it, uncomment it here and in png.h const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ /* Height of interlace block. This is not currently used - if you need * it, uncomment it here and in png.h const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; */ #endif png_ptr->row_number++; if (png_ptr->row_number < png_ptr->num_rows) return; if (png_ptr->interlaced) { png_ptr->row_number = 0; png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1); do { png_ptr->pass++; if ((png_ptr->pass == 1 && png_ptr->width < 5) || (png_ptr->pass == 3 && png_ptr->width < 3) || (png_ptr->pass == 5 && png_ptr->width < 2)) png_ptr->pass++; if (png_ptr->pass > 7) png_ptr->pass--; if (png_ptr->pass >= 7) break; png_ptr->iwidth = (png_ptr->width + png_pass_inc[png_ptr->pass] - 1 - png_pass_start[png_ptr->pass]) / png_pass_inc[png_ptr->pass]; png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1; if (png_ptr->transformations & PNG_INTERLACE) break; png_ptr->num_rows = (png_ptr->height + png_pass_yinc[png_ptr->pass] - 1 - png_pass_ystart[png_ptr->pass]) / png_pass_yinc[png_ptr->pass]; } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); } } #if defined(PNG_READ_tEXt_SUPPORTED) void /* PRIVATE */ png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { png_error(png_ptr, "Out of place tEXt"); /* to quiet some compiler warnings */ if(info_ptr == NULL) return; } #ifdef PNG_MAX_MALLOC_64K png_ptr->skip_length = 0; /* This may not be necessary */ if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ { png_warning(png_ptr, "tEXt chunk too large to fit in memory"); png_ptr->skip_length = length - (png_uint_32)65535L; length = (png_uint_32)65535L; } #endif png_ptr->current_text = (png_charp)png_malloc(png_ptr, (png_uint_32)(length+1)); png_ptr->current_text[length] = '\0'; png_ptr->current_text_ptr = png_ptr->current_text; png_ptr->current_text_size = (png_size_t)length; png_ptr->current_text_left = (png_size_t)length; png_ptr->process_mode = PNG_READ_tEXt_MODE; } void /* PRIVATE */ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) { if (png_ptr->buffer_size && png_ptr->current_text_left) { png_size_t text_size; if (png_ptr->buffer_size < png_ptr->current_text_left) text_size = png_ptr->buffer_size; else text_size = png_ptr->current_text_left; png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); png_ptr->current_text_left -= text_size; png_ptr->current_text_ptr += text_size; } if (!(png_ptr->current_text_left)) { png_textp text_ptr; png_charp text; png_charp key; int ret; if (png_ptr->buffer_size < 4) { png_push_save_buffer(png_ptr); return; } png_push_crc_finish(png_ptr); #if defined(PNG_MAX_MALLOC_64K) if (png_ptr->skip_length) return; #endif key = png_ptr->current_text; for (text = key; *text; text++) /* empty loop */ ; if (text != key + png_ptr->current_text_size) text++; text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)png_sizeof(png_text)); text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; text_ptr->key = key; #ifdef PNG_iTXt_SUPPORTED text_ptr->lang = NULL; text_ptr->lang_key = NULL; #endif text_ptr->text = text; ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, key); png_free(png_ptr, text_ptr); png_ptr->current_text = NULL; if (ret) png_warning(png_ptr, "Insufficient memory to store text chunk."); } } #endif #if defined(PNG_READ_zTXt_SUPPORTED) void /* PRIVATE */ png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { png_error(png_ptr, "Out of place zTXt"); /* to quiet some compiler warnings */ if(info_ptr == NULL) return; } #ifdef PNG_MAX_MALLOC_64K /* We can't handle zTXt chunks > 64K, since we don't have enough space * to be able to store the uncompressed data. Actually, the threshold * is probably around 32K, but it isn't as definite as 64K is. */ if (length > (png_uint_32)65535L) { png_warning(png_ptr, "zTXt chunk too large to fit in memory"); png_push_crc_skip(png_ptr, length); return; } #endif png_ptr->current_text = (png_charp)png_malloc(png_ptr, (png_uint_32)(length+1)); png_ptr->current_text[length] = '\0'; png_ptr->current_text_ptr = png_ptr->current_text; png_ptr->current_text_size = (png_size_t)length; png_ptr->current_text_left = (png_size_t)length; png_ptr->process_mode = PNG_READ_zTXt_MODE; } void /* PRIVATE */ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) { if (png_ptr->buffer_size && png_ptr->current_text_left) { png_size_t text_size; if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left) text_size = png_ptr->buffer_size; else text_size = png_ptr->current_text_left; png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); png_ptr->current_text_left -= text_size; png_ptr->current_text_ptr += text_size; } if (!(png_ptr->current_text_left)) { png_textp text_ptr; png_charp text; png_charp key; int ret; png_size_t text_size, key_size; if (png_ptr->buffer_size < 4) { png_push_save_buffer(png_ptr); return; } png_push_crc_finish(png_ptr); key = png_ptr->current_text; for (text = key; *text; text++) /* empty loop */ ; /* zTXt can't have zero text */ if (text == key + png_ptr->current_text_size) { png_ptr->current_text = NULL; png_free(png_ptr, key); return; } text++; if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */ { png_ptr->current_text = NULL; png_free(png_ptr, key); return; } text++; png_ptr->zstream.next_in = (png_bytep )text; png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size - (text - key)); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; key_size = text - key; text_size = 0; text = NULL; ret = Z_STREAM_END; while (png_ptr->zstream.avail_in) { ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); if (ret != Z_OK && ret != Z_STREAM_END) { inflateReset(&png_ptr->zstream); png_ptr->zstream.avail_in = 0; png_ptr->current_text = NULL; png_free(png_ptr, key); png_free(png_ptr, text); return; } if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END) { if (text == NULL) { text = (png_charp)png_malloc(png_ptr, (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out + key_size + 1)); png_memcpy(text + key_size, png_ptr->zbuf, png_ptr->zbuf_size - png_ptr->zstream.avail_out); png_memcpy(text, key, key_size); text_size = key_size + png_ptr->zbuf_size - png_ptr->zstream.avail_out; *(text + text_size) = '\0'; } else { png_charp tmp; tmp = text; text = (png_charp)png_malloc(png_ptr, text_size + (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); png_memcpy(text, tmp, text_size); png_free(png_ptr, tmp); png_memcpy(text + text_size, png_ptr->zbuf, png_ptr->zbuf_size - png_ptr->zstream.avail_out); text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; *(text + text_size) = '\0'; } if (ret != Z_STREAM_END) { png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; } } else { break; } if (ret == Z_STREAM_END) break; } inflateReset(&png_ptr->zstream); png_ptr->zstream.avail_in = 0; if (ret != Z_STREAM_END) { png_ptr->current_text = NULL; png_free(png_ptr, key); png_free(png_ptr, text); return; } png_ptr->current_text = NULL; png_free(png_ptr, key); key = text; text += key_size; text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)png_sizeof(png_text)); text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; text_ptr->key = key; #ifdef PNG_iTXt_SUPPORTED text_ptr->lang = NULL; text_ptr->lang_key = NULL; #endif text_ptr->text = text; ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, key); png_free(png_ptr, text_ptr); if (ret) png_warning(png_ptr, "Insufficient memory to store text chunk."); } } #endif #if defined(PNG_READ_iTXt_SUPPORTED) void /* PRIVATE */ png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { png_error(png_ptr, "Out of place iTXt"); /* to quiet some compiler warnings */ if(info_ptr == NULL) return; } #ifdef PNG_MAX_MALLOC_64K png_ptr->skip_length = 0; /* This may not be necessary */ if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ { png_warning(png_ptr, "iTXt chunk too large to fit in memory"); png_ptr->skip_length = length - (png_uint_32)65535L; length = (png_uint_32)65535L; } #endif png_ptr->current_text = (png_charp)png_malloc(png_ptr, (png_uint_32)(length+1)); png_ptr->current_text[length] = '\0'; png_ptr->current_text_ptr = png_ptr->current_text; png_ptr->current_text_size = (png_size_t)length; png_ptr->current_text_left = (png_size_t)length; png_ptr->process_mode = PNG_READ_iTXt_MODE; } void /* PRIVATE */ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) { if (png_ptr->buffer_size && png_ptr->current_text_left) { png_size_t text_size; if (png_ptr->buffer_size < png_ptr->current_text_left) text_size = png_ptr->buffer_size; else text_size = png_ptr->current_text_left; png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); png_ptr->current_text_left -= text_size; png_ptr->current_text_ptr += text_size; } if (!(png_ptr->current_text_left)) { png_textp text_ptr; png_charp key; int comp_flag; png_charp lang; png_charp lang_key; png_charp text; int ret; if (png_ptr->buffer_size < 4) { png_push_save_buffer(png_ptr); return; } png_push_crc_finish(png_ptr); #if defined(PNG_MAX_MALLOC_64K) if (png_ptr->skip_length) return; #endif key = png_ptr->current_text; for (lang = key; *lang; lang++) /* empty loop */ ; if (lang != key + png_ptr->current_text_size) lang++; comp_flag = *lang++; lang++; /* skip comp_type, always zero */ for (lang_key = lang; *lang_key; lang_key++) /* empty loop */ ; lang_key++; /* skip NUL separator */ for (text = lang_key; *text; text++) /* empty loop */ ; if (text != key + png_ptr->current_text_size) text++; text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)png_sizeof(png_text)); text_ptr->compression = comp_flag + 2; text_ptr->key = key; text_ptr->lang = lang; text_ptr->lang_key = lang_key; text_ptr->text = text; text_ptr->text_length = 0; text_ptr->itxt_length = png_strlen(text); ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_ptr->current_text = NULL; png_free(png_ptr, text_ptr); if (ret) png_warning(png_ptr, "Insufficient memory to store iTXt chunk."); } } #endif /* This function is called when we haven't found a handler for this * chunk. If there isn't a problem with the chunk itself (ie a bad chunk * name or a critical chunk), the chunk is (currently) silently ignored. */ void /* PRIVATE */ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_uint_32 skip=0; png_check_chunk_name(png_ptr, png_ptr->chunk_name); if (!(png_ptr->chunk_name[0] & 0x20)) { #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != PNG_HANDLE_CHUNK_ALWAYS #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) && png_ptr->read_user_chunk_fn == NULL #endif ) #endif png_chunk_error(png_ptr, "unknown critical chunk"); /* to quiet compiler warnings about unused info_ptr */ if (info_ptr == NULL) return; } #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) { png_unknown_chunk chunk; #ifdef PNG_MAX_MALLOC_64K if (length > (png_uint_32)65535L) { png_warning(png_ptr, "unknown chunk too large to fit in memory"); skip = length - (png_uint_32)65535L; length = (png_uint_32)65535L; } #endif png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name); chunk.data = (png_bytep)png_malloc(png_ptr, length); png_crc_read(png_ptr, chunk.data, length); chunk.size = length; #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) if(png_ptr->read_user_chunk_fn != NULL) { /* callback to user unknown chunk handler */ if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0) { if (!(png_ptr->chunk_name[0] & 0x20)) if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != PNG_HANDLE_CHUNK_ALWAYS) png_chunk_error(png_ptr, "unknown critical chunk"); } png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); } else #endif png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); png_free(png_ptr, chunk.data); } else #endif skip=length; png_push_crc_skip(png_ptr, skip); } void /* PRIVATE */ png_push_have_info(png_structp png_ptr, png_infop info_ptr) { if (png_ptr->info_fn != NULL) (*(png_ptr->info_fn))(png_ptr, info_ptr); } void /* PRIVATE */ png_push_have_end(png_structp png_ptr, png_infop info_ptr) { if (png_ptr->end_fn != NULL) (*(png_ptr->end_fn))(png_ptr, info_ptr); } void /* PRIVATE */ png_push_have_row(png_structp png_ptr, png_bytep row) { if (png_ptr->row_fn != NULL) (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, (int)png_ptr->pass); } void PNGAPI png_progressive_combine_row (png_structp png_ptr, png_bytep old_row, png_bytep new_row) { #ifdef PNG_USE_LOCAL_ARRAYS const int FARDATA png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; #endif if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */ png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]); } void PNGAPI png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn) { png_ptr->info_fn = info_fn; png_ptr->row_fn = row_fn; png_ptr->end_fn = end_fn; png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); } png_voidp PNGAPI png_get_progressive_ptr(png_structp png_ptr) { return png_ptr->io_ptr; } #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/png.c0000664000175000017500000005627610777447272020127 0ustar evanevan /* png.c - location for general purpose libpng functions * * libpng version 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ #define PNG_INTERNAL #define PNG_NO_EXTERN #include "png.h" /* Generate a compiler error if there is an old png.h in the search path. */ typedef version_1_2_8 Your_png_h_is_not_version_1_2_8; /* Version information for C files. This had better match the version * string defined in png.h. */ #ifdef PNG_USE_GLOBAL_ARRAYS /* png_libpng_ver was changed to a function in version 1.0.5c */ const char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING; /* png_sig was changed to a function in version 1.0.5c */ /* Place to hold the signature string for a PNG file. */ const png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; /* Invoke global declarations for constant strings for known chunk types */ PNG_IHDR; PNG_IDAT; PNG_IEND; PNG_PLTE; PNG_bKGD; PNG_cHRM; PNG_gAMA; PNG_hIST; PNG_iCCP; PNG_iTXt; PNG_oFFs; PNG_pCAL; PNG_sCAL; PNG_pHYs; PNG_sBIT; PNG_sPLT; PNG_sRGB; PNG_tEXt; PNG_tIME; PNG_tRNS; PNG_zTXt; /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* start of interlace block */ const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; /* offset to next interlace block */ const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; /* start of interlace block in the y direction */ const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; /* offset to next interlace block in the y direction */ const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; /* width of interlace block (used in assembler routines only) */ #ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; #endif /* Height of interlace block. This is not currently used - if you need * it, uncomment it here and in png.h const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; */ /* Mask to determine which pixels are valid in a pass */ const int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; /* Mask to determine which pixels to overwrite while displaying */ const int FARDATA png_pass_dsp_mask[] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; #endif /* PNG_USE_GLOBAL_ARRAYS */ /* Tells libpng that we have already handled the first "num_bytes" bytes * of the PNG file signature. If the PNG data is embedded into another * stream we can set num_bytes = 8 so that libpng will not attempt to read * or write any of the magic bytes before it starts on the IHDR. */ void PNGAPI png_set_sig_bytes(png_structp png_ptr, int num_bytes) { png_debug(1, "in png_set_sig_bytes\n"); if (num_bytes > 8) png_error(png_ptr, "Too many bytes for PNG signature."); png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes); } /* Checks whether the supplied bytes match the PNG signature. We allow * checking less than the full 8-byte signature so that those apps that * already read the first few bytes of a file to determine the file type * can simply check the remaining bytes for extra assurance. Returns * an integer less than, equal to, or greater than zero if sig is found, * respectively, to be less than, to match, or be greater than the correct * PNG signature (this is the same behaviour as strcmp, memcmp, etc). */ int PNGAPI png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check) { png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; if (num_to_check > 8) num_to_check = 8; else if (num_to_check < 1) return (0); if (start > 7) return (0); if (start + num_to_check > 8) num_to_check = 8 - start; return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check))); } /* (Obsolete) function to check signature bytes. It does not allow one * to check a partial signature. This function might be removed in the * future - use png_sig_cmp(). Returns true (nonzero) if the file is a PNG. */ int PNGAPI png_check_sig(png_bytep sig, int num) { return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num)); } /* Function to allocate memory for zlib and clear it to 0. */ #ifdef PNG_1_0_X voidpf PNGAPI #else voidpf /* private */ #endif png_zalloc(voidpf png_ptr, uInt items, uInt size) { png_voidp ptr; png_structp p=png_ptr; png_uint_32 save_flags=p->flags; png_uint_32 num_bytes; if (items > PNG_UINT_32_MAX/size) { png_warning (png_ptr, "Potential overflow in png_zalloc()"); return (NULL); } num_bytes = (png_uint_32)items * size; p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); p->flags=save_flags; #if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO) if (ptr == NULL) return ((voidpf)ptr); if (num_bytes > (png_uint_32)0x8000L) { png_memset(ptr, 0, (png_size_t)0x8000L); png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0, (png_size_t)(num_bytes - (png_uint_32)0x8000L)); } else { png_memset(ptr, 0, (png_size_t)num_bytes); } #endif return ((voidpf)ptr); } /* function to free memory for zlib */ #ifdef PNG_1_0_X void PNGAPI #else void /* private */ #endif png_zfree(voidpf png_ptr, voidpf ptr) { png_free((png_structp)png_ptr, (png_voidp)ptr); } /* Reset the CRC variable to 32 bits of 1's. Care must be taken * in case CRC is > 32 bits to leave the top bits 0. */ void /* PRIVATE */ png_reset_crc(png_structp png_ptr) { png_ptr->crc = crc32(0, Z_NULL, 0); } /* Calculate the CRC over a section of data. We can only pass as * much data to this routine as the largest single buffer size. We * also check that this data will actually be used before going to the * trouble of calculating it. */ void /* PRIVATE */ png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length) { int need_crc = 1; if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ { if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) need_crc = 0; } else /* critical */ { if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) need_crc = 0; } if (need_crc) png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length); } /* Allocate the memory for an info_struct for the application. We don't * really need the png_ptr, but it could potentially be useful in the * future. This should be used in favour of malloc(png_sizeof(png_info)) * and png_info_init() so that applications that want to use a shared * libpng don't have to be recompiled if png_info changes size. */ png_infop PNGAPI png_create_info_struct(png_structp png_ptr) { png_infop info_ptr; png_debug(1, "in png_create_info_struct\n"); if(png_ptr == NULL) return (NULL); #ifdef PNG_USER_MEM_SUPPORTED info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO, png_ptr->malloc_fn, png_ptr->mem_ptr); #else info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); #endif if (info_ptr != NULL) png_info_init_3(&info_ptr, png_sizeof(png_info)); return (info_ptr); } /* This function frees the memory associated with a single info struct. * Normally, one would use either png_destroy_read_struct() or * png_destroy_write_struct() to free an info struct, but this may be * useful for some applications. */ void PNGAPI png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr) { png_infop info_ptr = NULL; png_debug(1, "in png_destroy_info_struct\n"); if (info_ptr_ptr != NULL) info_ptr = *info_ptr_ptr; if (info_ptr != NULL) { png_info_destroy(png_ptr, info_ptr); #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn, png_ptr->mem_ptr); #else png_destroy_struct((png_voidp)info_ptr); #endif *info_ptr_ptr = NULL; } } /* Initialize the info structure. This is now an internal function (0.89) * and applications using it are urged to use png_create_info_struct() * instead. */ #if defined(PNG_1_0_X) || defined (PNG_1_2_X) #undef png_info_init void PNGAPI png_info_init(png_infop info_ptr) { /* We only come here via pre-1.0.12-compiled applications */ png_info_init_3(&info_ptr, 0); } #endif void PNGAPI png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) { png_infop info_ptr = *ptr_ptr; png_debug(1, "in png_info_init_3\n"); if(png_sizeof(png_info) > png_info_struct_size) { png_destroy_struct(info_ptr); info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); *ptr_ptr = info_ptr; } /* set everything to 0 */ png_memset(info_ptr, 0, png_sizeof (png_info)); } #ifdef PNG_FREE_ME_SUPPORTED void PNGAPI png_data_freer(png_structp png_ptr, png_infop info_ptr, int freer, png_uint_32 mask) { png_debug(1, "in png_data_freer\n"); if (png_ptr == NULL || info_ptr == NULL) return; if(freer == PNG_DESTROY_WILL_FREE_DATA) info_ptr->free_me |= mask; else if(freer == PNG_USER_WILL_FREE_DATA) info_ptr->free_me &= ~mask; else png_warning(png_ptr, "Unknown freer parameter in png_data_freer."); } #endif void PNGAPI png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, int num) { png_debug(1, "in png_free_data\n"); if (png_ptr == NULL || info_ptr == NULL) return; #if defined(PNG_TEXT_SUPPORTED) /* free text item num or (if num == -1) all text items */ #ifdef PNG_FREE_ME_SUPPORTED if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) #else if (mask & PNG_FREE_TEXT) #endif { if (num != -1) { if (info_ptr->text && info_ptr->text[num].key) { png_free(png_ptr, info_ptr->text[num].key); info_ptr->text[num].key = NULL; } } else { int i; for (i = 0; i < info_ptr->num_text; i++) png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i); png_free(png_ptr, info_ptr->text); info_ptr->text = NULL; info_ptr->num_text=0; } } #endif #if defined(PNG_tRNS_SUPPORTED) /* free any tRNS entry */ #ifdef PNG_FREE_ME_SUPPORTED if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) #else if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS)) #endif { png_free(png_ptr, info_ptr->trans); info_ptr->valid &= ~PNG_INFO_tRNS; #ifndef PNG_FREE_ME_SUPPORTED png_ptr->flags &= ~PNG_FLAG_FREE_TRNS; #endif info_ptr->trans = NULL; } #endif #if defined(PNG_sCAL_SUPPORTED) /* free any sCAL entry */ #ifdef PNG_FREE_ME_SUPPORTED if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) #else if (mask & PNG_FREE_SCAL) #endif { #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) png_free(png_ptr, info_ptr->scal_s_width); png_free(png_ptr, info_ptr->scal_s_height); info_ptr->scal_s_width = NULL; info_ptr->scal_s_height = NULL; #endif info_ptr->valid &= ~PNG_INFO_sCAL; } #endif #if defined(PNG_pCAL_SUPPORTED) /* free any pCAL entry */ #ifdef PNG_FREE_ME_SUPPORTED if ((mask & PNG_FREE_PCAL) & info_ptr->free_me) #else if (mask & PNG_FREE_PCAL) #endif { png_free(png_ptr, info_ptr->pcal_purpose); png_free(png_ptr, info_ptr->pcal_units); info_ptr->pcal_purpose = NULL; info_ptr->pcal_units = NULL; if (info_ptr->pcal_params != NULL) { int i; for (i = 0; i < (int)info_ptr->pcal_nparams; i++) { png_free(png_ptr, info_ptr->pcal_params[i]); info_ptr->pcal_params[i]=NULL; } png_free(png_ptr, info_ptr->pcal_params); info_ptr->pcal_params = NULL; } info_ptr->valid &= ~PNG_INFO_pCAL; } #endif #if defined(PNG_iCCP_SUPPORTED) /* free any iCCP entry */ #ifdef PNG_FREE_ME_SUPPORTED if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) #else if (mask & PNG_FREE_ICCP) #endif { png_free(png_ptr, info_ptr->iccp_name); png_free(png_ptr, info_ptr->iccp_profile); info_ptr->iccp_name = NULL; info_ptr->iccp_profile = NULL; info_ptr->valid &= ~PNG_INFO_iCCP; } #endif #if defined(PNG_sPLT_SUPPORTED) /* free a given sPLT entry, or (if num == -1) all sPLT entries */ #ifdef PNG_FREE_ME_SUPPORTED if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) #else if (mask & PNG_FREE_SPLT) #endif { if (num != -1) { if(info_ptr->splt_palettes) { png_free(png_ptr, info_ptr->splt_palettes[num].name); png_free(png_ptr, info_ptr->splt_palettes[num].entries); info_ptr->splt_palettes[num].name = NULL; info_ptr->splt_palettes[num].entries = NULL; } } else { if(info_ptr->splt_palettes_num) { int i; for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i); png_free(png_ptr, info_ptr->splt_palettes); info_ptr->splt_palettes = NULL; info_ptr->splt_palettes_num = 0; } info_ptr->valid &= ~PNG_INFO_sPLT; } } #endif #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) #ifdef PNG_FREE_ME_SUPPORTED if ((mask & PNG_FREE_UNKN) & info_ptr->free_me) #else if (mask & PNG_FREE_UNKN) #endif { if (num != -1) { if(info_ptr->unknown_chunks) { png_free(png_ptr, info_ptr->unknown_chunks[num].data); info_ptr->unknown_chunks[num].data = NULL; } } else { int i; if(info_ptr->unknown_chunks_num) { for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++) png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i); png_free(png_ptr, info_ptr->unknown_chunks); info_ptr->unknown_chunks = NULL; info_ptr->unknown_chunks_num = 0; } } } #endif #if defined(PNG_hIST_SUPPORTED) /* free any hIST entry */ #ifdef PNG_FREE_ME_SUPPORTED if ((mask & PNG_FREE_HIST) & info_ptr->free_me) #else if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST)) #endif { png_free(png_ptr, info_ptr->hist); info_ptr->hist = NULL; info_ptr->valid &= ~PNG_INFO_hIST; #ifndef PNG_FREE_ME_SUPPORTED png_ptr->flags &= ~PNG_FLAG_FREE_HIST; #endif } #endif /* free any PLTE entry that was internally allocated */ #ifdef PNG_FREE_ME_SUPPORTED if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) #else if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE)) #endif { png_zfree(png_ptr, info_ptr->palette); info_ptr->palette = NULL; info_ptr->valid &= ~PNG_INFO_PLTE; #ifndef PNG_FREE_ME_SUPPORTED png_ptr->flags &= ~PNG_FLAG_FREE_PLTE; #endif info_ptr->num_palette = 0; } #if defined(PNG_INFO_IMAGE_SUPPORTED) /* free any image bits attached to the info structure */ #ifdef PNG_FREE_ME_SUPPORTED if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) #else if (mask & PNG_FREE_ROWS) #endif { if(info_ptr->row_pointers) { int row; for (row = 0; row < (int)info_ptr->height; row++) { png_free(png_ptr, info_ptr->row_pointers[row]); info_ptr->row_pointers[row]=NULL; } png_free(png_ptr, info_ptr->row_pointers); info_ptr->row_pointers=NULL; } info_ptr->valid &= ~PNG_INFO_IDAT; } #endif #ifdef PNG_FREE_ME_SUPPORTED if(num == -1) info_ptr->free_me &= ~mask; else info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL); #endif } /* This is an internal routine to free any memory that the info struct is * pointing to before re-using it or freeing the struct itself. Recall * that png_free() checks for NULL pointers for us. */ void /* PRIVATE */ png_info_destroy(png_structp png_ptr, png_infop info_ptr) { png_debug(1, "in png_info_destroy\n"); png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) if (png_ptr->num_chunk_list) { png_free(png_ptr, png_ptr->chunk_list); png_ptr->chunk_list=NULL; png_ptr->num_chunk_list=0; } #endif png_info_init_3(&info_ptr, png_sizeof(png_info)); } /* This function returns a pointer to the io_ptr associated with the user * functions. The application should free any memory associated with this * pointer before png_write_destroy() or png_read_destroy() are called. */ png_voidp PNGAPI png_get_io_ptr(png_structp png_ptr) { return (png_ptr->io_ptr); } #if !defined(PNG_NO_STDIO) /* Initialize the default input/output functions for the PNG file. If you * use your own read or write routines, you can call either png_set_read_fn() * or png_set_write_fn() instead of png_init_io(). If you have defined * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't * necessarily available. */ void PNGAPI png_init_io(png_structp png_ptr, png_FILE_p fp) { png_debug(1, "in png_init_io\n"); png_ptr->io_ptr = (png_voidp)fp; } #endif #if defined(PNG_TIME_RFC1123_SUPPORTED) /* Convert the supplied time into an RFC 1123 string suitable for use in * a "Creation Time" or other text-based time string. */ png_charp PNGAPI png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) { static PNG_CONST char short_months[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; if (png_ptr->time_buffer == NULL) { png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29* png_sizeof(char))); } #if defined(_WIN32_WCE) { wchar_t time_buf[29]; wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"), ptime->day % 32, short_months[(ptime->month - 1) % 12], ptime->year, ptime->hour % 24, ptime->minute % 60, ptime->second % 61); WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29, NULL, NULL); } #else #ifdef USE_FAR_KEYWORD { char near_time_buf[29]; sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000", ptime->day % 32, short_months[(ptime->month - 1) % 12], ptime->year, ptime->hour % 24, ptime->minute % 60, ptime->second % 61); png_memcpy(png_ptr->time_buffer, near_time_buf, 29*png_sizeof(char)); } #else sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000", ptime->day % 32, short_months[(ptime->month - 1) % 12], ptime->year, ptime->hour % 24, ptime->minute % 60, ptime->second % 61); #endif #endif /* _WIN32_WCE */ return ((png_charp)png_ptr->time_buffer); } #endif /* PNG_TIME_RFC1123_SUPPORTED */ #if 0 /* Signature string for a PNG file. */ png_bytep PNGAPI png_sig_bytes(void) { return ((png_bytep)"\211\120\116\107\015\012\032\012"); } #endif png_charp PNGAPI png_get_copyright(png_structp png_ptr) { if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ return ((png_charp) "\n libpng version 1.2.8 - December 3, 2004\n\ Copyright (c) 1998-2004 Glenn Randers-Pehrson\n\ Copyright (c) 1996-1997 Andreas Dilger\n\ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n"); return ((png_charp) ""); } /* The following return the library version as a short string in the * format 1.0.0 through 99.99.99zz. To get the version of *.h files * used with your application, print out PNG_LIBPNG_VER_STRING, which * is defined in png.h. * Note: now there is no difference between png_get_libpng_ver() and * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, * it is guaranteed that png.c uses the correct version of png.h. */ png_charp PNGAPI png_get_libpng_ver(png_structp png_ptr) { /* Version of *.c files used when building libpng */ if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ return ((png_charp) PNG_LIBPNG_VER_STRING); return ((png_charp) ""); } png_charp PNGAPI png_get_header_ver(png_structp png_ptr) { /* Version of *.h files used when building libpng */ if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ return ((png_charp) PNG_LIBPNG_VER_STRING); return ((png_charp) ""); } png_charp PNGAPI png_get_header_version(png_structp png_ptr) { /* Returns longer string containing both version and date */ if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ return ((png_charp) PNG_HEADER_VERSION_STRING); return ((png_charp) ""); } #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED int PNGAPI png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name) { /* check chunk_name and return "keep" value if it's on the list, else 0 */ int i; png_bytep p; if((png_ptr == NULL && chunk_name == NULL) || png_ptr->num_chunk_list<=0) return 0; p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5; for (i = png_ptr->num_chunk_list; i; i--, p-=5) if (!png_memcmp(chunk_name, p, 4)) return ((int)*(p+4)); return 0; } #endif /* This function, added to libpng-1.0.6g, is untested. */ int PNGAPI png_reset_zstream(png_structp png_ptr) { return (inflateReset(&png_ptr->zstream)); } /* This function was added to libpng-1.0.7 */ png_uint_32 PNGAPI png_access_version_number(void) { /* Version of *.c files used when building libpng */ return((png_uint_32) PNG_LIBPNG_VER); } #if !defined(PNG_1_0_X) #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */ /* this INTERNAL function was added to libpng 1.2.0 */ void /* PRIVATE */ png_init_mmx_flags (png_structp png_ptr) { png_ptr->mmx_rowbytes_threshold = 0; png_ptr->mmx_bitdepth_threshold = 0; # if (defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD)) png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED; if (png_mmx_support() > 0) { png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU # ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW | PNG_ASM_FLAG_MMX_READ_COMBINE_ROW # endif # ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE | PNG_ASM_FLAG_MMX_READ_INTERLACE # endif # ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW ; # else | PNG_ASM_FLAG_MMX_READ_FILTER_SUB | PNG_ASM_FLAG_MMX_READ_FILTER_UP | PNG_ASM_FLAG_MMX_READ_FILTER_AVG | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; png_ptr->mmx_rowbytes_threshold = PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT; png_ptr->mmx_bitdepth_threshold = PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT; # endif } else { png_ptr->asm_flags &= ~( PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU | PNG_MMX_READ_FLAGS | PNG_MMX_WRITE_FLAGS ); } # else /* !((PNGVCRD || PNGGCCRD) && PNG_ASSEMBLER_CODE_SUPPORTED)) */ /* clear all MMX flags; no support is compiled in */ png_ptr->asm_flags &= ~( PNG_MMX_FLAGS ); # endif /* ?(PNGVCRD || PNGGCCRD) */ } #endif /* !(PNG_ASSEMBLER_CODE_SUPPORTED) */ /* this function was added to libpng 1.2.0 */ #if !defined(PNG_USE_PNGGCCRD) && \ !(defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD)) int PNGAPI png_mmx_support(void) { return -1; } #endif #endif /* PNG_1_0_X */ #ifdef PNG_SIZE_T /* Added at libpng version 1.2.6 */ PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)); png_size_t PNGAPI png_convert_size(size_t size) { if (size > (png_size_t)-1) PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */ return ((png_size_t)size); } #endif /* PNG_SIZE_T */ syslinux-legacy-3.63+dfsg/com32/lib/libpng/KNOWNBUG0000664000175000017500000000062110777447272020333 0ustar evanevan Known bugs in libpng version 1.2.8 1. April 22, 2001: pnggccrd.c has been reported to crash on NetBSD when reading interlaced PNG files, when assembler code is enabled but running on a non-MMX i386 platform. STATUS: Under investigation. The change to pnggccrd.c in libpng-1.2.1 fixed a problem under FreeBSD but not the problem with NetBSD, which still fails as of libpng-1.2.2rc1. syslinux-legacy-3.63+dfsg/com32/lib/libpng/pngrio.c0000664000175000017500000001235210777447272020624 0ustar evanevan /* pngrio.c - functions for data input * * libpng 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * * This file provides a location for all input. Users who need * special handling are expected to write a function that has the same * arguments as this and performs a similar function, but that possibly * has a different input method. Note that you shouldn't change this * function, but rather write a replacement function and then make * libpng use it at run time with png_set_read_fn(...). */ #define PNG_INTERNAL #include "png.h" /* Read the data from whatever input you are using. The default routine reads from a file pointer. Note that this routine sometimes gets called with very small lengths, so you should implement some kind of simple buffering if you are using unbuffered reads. This should never be asked to read more then 64K on a 16 bit machine. */ void /* PRIVATE */ png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_debug1(4,"reading %d bytes\n", (int)length); if (png_ptr->read_data_fn != NULL) (*(png_ptr->read_data_fn))(png_ptr, data, length); else png_error(png_ptr, "Call to NULL read function"); } #if !defined(PNG_NO_STDIO) /* This is the function that does the actual reading of data. If you are not reading from a standard C stream, you should create a replacement read_data function and use it at run time with png_set_read_fn(), rather than changing the library. */ #ifndef USE_FAR_KEYWORD void PNGAPI png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_size_t check; /* fread() returns 0 on error, so it is OK to store this in a png_size_t * instead of an int, which is what fread() actually returns. */ #if defined(_WIN32_WCE) if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) ) check = 0; #else check = (png_size_t)fread(data, (png_size_t)1, length, (png_FILE_p)png_ptr->io_ptr); #endif if (check != length) png_error(png_ptr, "Read Error"); } #else /* this is the model-independent version. Since the standard I/O library can't handle far buffers in the medium and small models, we have to copy the data. */ #define NEAR_BUF_SIZE 1024 #define MIN(a,b) (a <= b ? a : b) static void /* PRIVATE */ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { int check; png_byte *n_data; png_FILE_p io_ptr; /* Check if data really is near. If so, use usual code. */ n_data = (png_byte *)CVT_PTR_NOCHECK(data); io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); if ((png_bytep)n_data == data) { #if defined(_WIN32_WCE) if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) ) check = 0; #else check = fread(n_data, 1, length, io_ptr); #endif } else { png_byte buf[NEAR_BUF_SIZE]; png_size_t read, remaining, err; check = 0; remaining = length; do { read = MIN(NEAR_BUF_SIZE, remaining); #if defined(_WIN32_WCE) if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) ) err = 0; #else err = fread(buf, (png_size_t)1, read, io_ptr); #endif png_memcpy(data, buf, read); /* copy far buffer to near buffer */ if(err != read) break; else check += err; data += read; remaining -= read; } while (remaining != 0); } if ((png_uint_32)check != (png_uint_32)length) png_error(png_ptr, "read Error"); } #endif #endif /* This function allows the application to supply a new input function for libpng if standard C streams aren't being used. This function takes as its arguments: png_ptr - pointer to a png input data structure io_ptr - pointer to user supplied structure containing info about the input functions. May be NULL. read_data_fn - pointer to a new input function that takes as its arguments a pointer to a png_struct, a pointer to a location where input data can be stored, and a 32-bit unsigned int that is the number of bytes to be read. To exit and output any fatal error messages the new write function should call png_error(png_ptr, "Error msg"). */ void PNGAPI png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn) { png_ptr->io_ptr = io_ptr; #if !defined(PNG_NO_STDIO) if (read_data_fn != NULL) png_ptr->read_data_fn = read_data_fn; else png_ptr->read_data_fn = png_default_read_data; #else png_ptr->read_data_fn = read_data_fn; #endif /* It is an error to write to a read device */ if (png_ptr->write_data_fn != NULL) { png_ptr->write_data_fn = NULL; png_warning(png_ptr, "It's an error to set both read_data_fn and write_data_fn in the "); png_warning(png_ptr, "same structure. Resetting write_data_fn to NULL."); } #if defined(PNG_WRITE_FLUSH_SUPPORTED) png_ptr->output_flush_fn = NULL; #endif } syslinux-legacy-3.63+dfsg/com32/lib/vsnprintf.c0000664000175000017500000002254110777447272020105 0ustar evanevan/* * vsnprintf.c * * vsnprintf(), from which the rest of the printf() * family is built */ #include #include #include #include #include #include enum flags { FL_ZERO = 0x01, /* Zero modifier */ FL_MINUS = 0x02, /* Minus modifier */ FL_PLUS = 0x04, /* Plus modifier */ FL_TICK = 0x08, /* ' modifier */ FL_SPACE = 0x10, /* Space modifier */ FL_HASH = 0x20, /* # modifier */ FL_SIGNED = 0x40, /* Number is signed */ FL_UPPER = 0x80 /* Upper case digits */ }; /* These may have to be adjusted on certain implementations */ enum ranks { rank_char = -2, rank_short = -1, rank_int = 0, rank_long = 1, rank_longlong = 2 }; #define MIN_RANK rank_char #define MAX_RANK rank_longlong #define INTMAX_RANK rank_longlong #define SIZE_T_RANK rank_long #define PTRDIFF_T_RANK rank_long #define EMIT(x) ({ if (o nchars ) { while ( width > nchars ) { EMIT(' '); width--; } } /* Emit nondigits */ if ( minus ) EMIT('-'); else if ( flags & FL_PLUS ) EMIT('+'); else if ( flags & FL_SPACE ) EMIT(' '); if ( (flags & FL_HASH) && base == 16 ) { EMIT('0'); EMIT((flags & FL_UPPER) ? 'X' : 'x'); } /* Emit zero padding */ if ( (flags & (FL_MINUS|FL_ZERO)) == FL_ZERO && width > ndigits ) { while ( width > nchars ) { EMIT('0'); width--; } } /* Generate the number. This is done from right to left. */ q += ndigits; /* Advance the pointer to end of number */ o += ndigits; qq = q; oo = o; /* Temporary values */ b4tick = tickskip; while ( ndigits > 0 ) { if ( !b4tick-- ) { qq--; oo--; ndigits--; if ( oo < n ) *qq = '_'; b4tick = tickskip-1; } qq--; oo--; ndigits--; if ( oo < n ) *qq = digits[val%base]; val /= base; } /* Emit late space padding */ while ( (flags & FL_MINUS) && width > nchars ) { EMIT(' '); width--; } return o; } int vsnprintf(char *buffer, size_t n, const char *format, va_list ap) { const char *p = format; char ch; char *q = buffer; size_t o = 0; /* Number of characters output */ uintmax_t val = 0; int rank = rank_int; /* Default rank */ int width = 0; int prec = -1; int base; size_t sz; enum flags flags = 0; enum { st_normal, /* Ground state */ st_flags, /* Special flags */ st_width, /* Field width */ st_prec, /* Field precision */ st_modifiers /* Length or conversion modifiers */ } state = st_normal; const char *sarg; /* %s string argument */ char carg; /* %c char argument */ int slen; /* String length */ while ( (ch = *p++) ) { switch ( state ) { case st_normal: if ( ch == '%' ) { state = st_flags; flags = 0; rank = rank_int; width = 0; prec = -1; } else { EMIT(ch); } break; case st_flags: switch ( ch ) { case '-': flags |= FL_MINUS; break; case '+': flags |= FL_PLUS; break; case '\'': flags |= FL_TICK; break; case ' ': flags |= FL_SPACE; break; case '#': flags |= FL_HASH; break; case '0': flags |= FL_ZERO; break; default: state = st_width; p--; /* Process this character again */ break; } break; case st_width: if ( ch >= '0' && ch <= '9' ) { width = width*10+(ch-'0'); } else if ( ch == '*' ) { width = va_arg(ap, int); if ( width < 0 ) { width = -width; flags |= FL_MINUS; } } else if ( ch == '.' ) { prec = 0; /* Precision given */ state = st_prec; } else { state = st_modifiers; p--; /* Process this character again */ } break; case st_prec: if ( ch >= '0' && ch <= '9' ) { prec = prec*10+(ch-'0'); } else if ( ch == '*' ) { prec = va_arg(ap, int); if ( prec < 0 ) prec = -1; } else { state = st_modifiers; p--; /* Process this character again */ } break; case st_modifiers: switch ( ch ) { /* Length modifiers - nonterminal sequences */ case 'h': rank--; /* Shorter rank */ break; case 'l': rank++; /* Longer rank */ break; case 'j': rank = INTMAX_RANK; break; case 'z': rank = SIZE_T_RANK; break; case 't': rank = PTRDIFF_T_RANK; break; case 'L': case 'q': rank += 2; break; default: /* Output modifiers - terminal sequences */ state = st_normal; /* Next state will be normal */ if ( rank < MIN_RANK ) /* Canonicalize rank */ rank = MIN_RANK; else if ( rank > MAX_RANK ) rank = MAX_RANK; switch ( ch ) { case 'P': /* Upper case pointer */ flags |= FL_UPPER; /* fall through */ case 'p': /* Pointer */ base = 16; prec = (CHAR_BIT*sizeof(void *)+3)/4; flags |= FL_HASH; val = (uintmax_t)(uintptr_t)va_arg(ap, void *); goto is_integer; case 'd': /* Signed decimal output */ case 'i': base = 10; flags |= FL_SIGNED; switch (rank) { case rank_char: /* Yes, all these casts are needed... */ val = (uintmax_t)(intmax_t)(signed char)va_arg(ap, signed int); break; case rank_short: val = (uintmax_t)(intmax_t)(signed short)va_arg(ap, signed int); break; case rank_int: val = (uintmax_t)(intmax_t)va_arg(ap, signed int); break; case rank_long: val = (uintmax_t)(intmax_t)va_arg(ap, signed long); break; case rank_longlong: val = (uintmax_t)(intmax_t)va_arg(ap, signed long long); break; } goto is_integer; case 'o': /* Octal */ base = 8; goto is_unsigned; case 'u': /* Unsigned decimal */ base = 10; goto is_unsigned; case 'X': /* Upper case hexadecimal */ flags |= FL_UPPER; /* fall through */ case 'x': /* Hexadecimal */ base = 16; goto is_unsigned; is_unsigned: switch (rank) { case rank_char: val = (uintmax_t)(unsigned char)va_arg(ap, unsigned int); break; case rank_short: val = (uintmax_t)(unsigned short)va_arg(ap, unsigned int); break; case rank_int: val = (uintmax_t)va_arg(ap, unsigned int); break; case rank_long: val = (uintmax_t)va_arg(ap, unsigned long); break; case rank_longlong: val = (uintmax_t)va_arg(ap, unsigned long long); break; } /* fall through */ is_integer: sz = format_int(q, (o prec ) slen = prec; if ( width > slen && !(flags & FL_MINUS) ) { char pad = (flags & FL_ZERO) ? '0' : ' '; while ( width > slen ) { EMIT(pad); width--; } } for ( i = slen ; i ; i-- ) { sch = *sarg++; EMIT(sch); } if ( width > slen && (flags & FL_MINUS) ) { while ( width > slen ) { EMIT(' '); width--; } } } break; case 'n': /* Output the number of characters written */ { switch (rank) { case rank_char: *va_arg(ap, signed char *) = o; break; case rank_short: *va_arg(ap, signed short *) = o; break; case rank_int: *va_arg(ap, signed int *) = o; break; case rank_long: *va_arg(ap, signed long *) = o; break; case rank_longlong: *va_arg(ap, signed long long *) = o; break; } } break; default: /* Anything else, including % */ EMIT(ch); break; } } } } /* Null-terminate the string */ if ( o0 ) buffer[n-1] = '\0'; /* Overflow - terminate at end of buffer */ return o; } syslinux-legacy-3.63+dfsg/com32/lib/stpncpy.c0000664000175000017500000000040210777447272017544 0ustar evanevan/* * stpncpy.c * * stpncpy() */ #include char *stpncpy(char *dst, const char *src, size_t n) { char *q = dst; const char *p = src; char ch; while ( n-- ) { *q = ch = *p++; if ( !ch ) break; q++; } return q; } syslinux-legacy-3.63+dfsg/com32/lib/memset.c0000664000175000017500000000115110777447272017340 0ustar evanevan/* * memset.c */ #include #include void *memset(void *dst, int c, size_t n) { char *q = dst; #if defined(__i386__) size_t nl = n >> 2; asm volatile("cld ; rep ; stosl ; movl %3,%0 ; rep ; stosb" : "+c" (nl), "+D" (q) : "a" ((unsigned char)c * 0x01010101U), "r" (n & 3)); #elif defined(__x86_64__) size_t nq = n >> 3; asm volatile("cld ; rep ; stosq ; movl %3,%%ecx ; rep ; stosb" : "+c" (nq), "+D" (q) : "a" ((unsigned char)c * 0x0101010101010101U), "r" ((uint32_t)n & 7)); #else while ( n-- ) { *q++ = c; } #endif return dst; } syslinux-legacy-3.63+dfsg/com32/lib/strtoimax.c0000664000175000017500000000010110777447272020072 0ustar evanevan#define TYPE intmax_t #define NAME strtoimax #include "strtox.c" syslinux-legacy-3.63+dfsg/com32/lib/mempcpy.S0000664000175000017500000000067110777447272017506 0ustar evanevan# # mempcpy.S # .text .globl mempcpy .type mempcpy, @function mempcpy: pushl %esi pushl %edi #ifdef REGPARM movl %edx, %esi #else movl 12(%esp), %eax movl 16(%esp), %esi movl 20(%esp), %ecx #endif movl %eax, %edi movl %ecx, %edx shrl $2, %ecx cld rep ; movsl jnc 1f # The shrl had carry out if odd word count movsw 1: testb $1, %dl jz 2f movsb 2: movl %edi, %eax popl %edi popl %esi ret .size mempcpy, .-mempcpy syslinux-legacy-3.63+dfsg/com32/lib/strstr.c0000664000175000017500000000026110777447272017410 0ustar evanevan/* * strstr.c */ #include char *strstr(const char *haystack, const char *needle) { return (char *)memmem(haystack, strlen(haystack), needle, strlen(needle)); } syslinux-legacy-3.63+dfsg/com32/lib/vfprintf.c0000664000175000017500000000062210777447272017706 0ustar evanevan/* * vfprintf.c */ #include #include #include #include #define BUFFER_SIZE 32768 int vfprintf(FILE *file, const char *format, va_list ap) { int rv; char buffer[BUFFER_SIZE]; rv = vsnprintf(buffer, BUFFER_SIZE, format, ap); if ( rv < 0 ) return rv; if ( rv > BUFFER_SIZE-1 ) rv = BUFFER_SIZE-1; return _fwrite(buffer, rv, file); } syslinux-legacy-3.63+dfsg/com32/lib/strntoimax.c0000664000175000017500000000033210777447272020256 0ustar evanevan/* * strntoimax.c * * strntoimax() */ #include #include intmax_t strntoimax(const char *nptr, char **endptr, int base, size_t n) { return (intmax_t) strntoumax(nptr, endptr, base, n); } syslinux-legacy-3.63+dfsg/com32/lib/perror.c0000664000175000017500000000023510777447272017361 0ustar evanevan/* * perror.c */ #include #include #include void perror(const char *s) { fprintf(stderr, "%s: error %d\n", s, errno); } syslinux-legacy-3.63+dfsg/com32/lib/free.c0000664000175000017500000000326310777447272016775 0ustar evanevan/* * free.c * * Very simple linked-list based malloc()/free(). */ #include #include "malloc.h" static struct free_arena_header * __free_block(struct free_arena_header *ah) { struct free_arena_header *pah, *nah; pah = ah->a.prev; nah = ah->a.next; if ( pah->a.type == ARENA_TYPE_FREE && (char *)pah+pah->a.size == (char *)ah ) { /* Coalesce into the previous block */ pah->a.size += ah->a.size; pah->a.next = nah; nah->a.prev = pah; #ifdef DEBUG_MALLOC ah->a.type = ARENA_TYPE_DEAD; #endif ah = pah; pah = ah->a.prev; } else { /* Need to add this block to the free chain */ ah->a.type = ARENA_TYPE_FREE; ah->next_free = __malloc_head.next_free; ah->prev_free = &__malloc_head; __malloc_head.next_free = ah; ah->next_free->prev_free = ah; } /* In either of the previous cases, we might be able to merge with the subsequent block... */ if ( nah->a.type == ARENA_TYPE_FREE && (char *)ah+ah->a.size == (char *)nah ) { ah->a.size += nah->a.size; /* Remove the old block from the chains */ nah->next_free->prev_free = nah->prev_free; nah->prev_free->next_free = nah->next_free; ah->a.next = nah->a.next; nah->a.next->a.prev = ah; #ifdef DEBUG_MALLOC nah->a.type = ARENA_TYPE_DEAD; #endif } /* Return the block that contains the called block */ return ah; } void free(void *ptr) { struct free_arena_header *ah; if ( !ptr ) return; ah = (struct free_arena_header *) ((struct arena_header *)ptr - 1); #ifdef DEBUG_MALLOC assert( ah->a.type == ARENA_TYPE_USED ); #endif __free_block(ah); /* Here we could insert code to return memory to the system. */ } syslinux-legacy-3.63+dfsg/com32/lib/math/0000775000175000017500000000000010777447344016635 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/lib/math/pow.S0000664000175000017500000000041210777447272017563 0ustar evanevan# # pow.S # # double pow(double base, double exponent) # .text .globl pow .type pow,@function pow: fldl 12(%esp) fldl 4(%esp) fyl2x fld %st(0) frndint fsubr %st,%st(1) fxch %st(1) f2xm1 fld1 faddp %st,%st(1) fscale fstp %st(1) ret .size pow,.-pow syslinux-legacy-3.63+dfsg/com32/lib/math/strtod.c0000664000175000017500000000715510777447272020330 0ustar evanevan/* * strtod.c * * Convert string to double * * Copyright (C) 2002 Michael Ringgaard. All rights reserved. * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include static inline int is_real(double x) { const double Inf = 1.0/0.0; return (x < Inf) && (x >= -Inf); } double strtod(const char *str, char **endptr) { double number; int exponent; int negative; char *p = (char *) str; double p10; int n; int num_digits; int num_decimals; const double Inf = 1.0/0.0; // Skip leading whitespace while (isspace(*p)) p++; // Handle optional sign negative = 0; switch (*p) { case '-': negative = 1; // Fall through to increment position case '+': p++; } number = 0.; exponent = 0; num_digits = 0; num_decimals = 0; // Process string of digits while (isdigit(*p)) { number = number * 10. + (*p - '0'); p++; num_digits++; } // Process decimal part if (*p == '.') { p++; while (isdigit(*p)) { number = number * 10. + (*p - '0'); p++; num_digits++; num_decimals++; } exponent -= num_decimals; } if (num_digits == 0) { errno = ERANGE; return 0.0; } // Correct for sign if (negative) number = -number; // Process an exponent string if (*p == 'e' || *p == 'E') { // Handle optional sign negative = 0; switch(*++p) { case '-': negative = 1; // Fall through to increment pos case '+': p++; } // Process string of digits n = 0; while (isdigit(*p)) { n = n * 10 + (*p - '0'); p++; } if (negative) exponent -= n; else exponent += n; } if (exponent < __DBL_MIN_EXP__ || exponent > __DBL_MAX_EXP__) { errno = ERANGE; return Inf; } // Scale the result p10 = 10.; n = exponent; if (n < 0) n = -n; while (n) { if (n & 1) { if (exponent < 0) number /= p10; else number *= p10; } n >>= 1; p10 *= p10; } if (!is_real(number)) errno = ERANGE; if (endptr) *endptr = p; return number; } syslinux-legacy-3.63+dfsg/com32/lib/lrand48.c0000664000175000017500000000127010777447272017324 0ustar evanevan/* * lrand48.c */ #include #include unsigned short __rand48_seed[3]; long jrand48(unsigned short xsubi[3]) { uint64_t x; /* The xsubi[] array is littleendian by spec */ x = (uint64_t)xsubi[0] + ((uint64_t)xsubi[1] << 16) + ((uint64_t)xsubi[2] << 32); x = (0x5deece66dULL * x) + 0xb; xsubi[0] = (unsigned short)x; xsubi[1] = (unsigned short)(x >> 16); xsubi[2] = (unsigned short)(x >> 32); return (long)(int32_t)(x >> 16); } long mrand48(void) { return jrand48(__rand48_seed); } long nrand48(unsigned short xsubi[3]) { return (long)((uint32_t)jrand48(xsubi) >> 1); } long lrand48(void) { return (long)((uint32_t)(mrand48() >> 1)); } syslinux-legacy-3.63+dfsg/com32/lib/sscanf.c0000664000175000017500000000031710777447272017326 0ustar evanevan/* * sscanf() */ #include int sscanf(const char *str, const char *format, ...) { va_list ap; int rv; va_start(ap, format); rv = vsscanf(str, format, ap); va_end(ap); return rv; } syslinux-legacy-3.63+dfsg/com32/lib/strntoumax.c0000664000175000017500000000245010777447272020275 0ustar evanevan/* * strntoumax.c * * The strntoumax() function and associated */ #include #include #include static inline int digitval(int ch) { if ( ch >= '0' && ch <= '9' ) { return ch-'0'; } else if ( ch >= 'A' && ch <= 'Z' ) { return ch-'A'+10; } else if ( ch >= 'a' && ch <= 'z' ) { return ch-'a'+10; } else { return -1; } } uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n) { int minus = 0; uintmax_t v = 0; int d; while ( n && isspace((unsigned char)*nptr) ) { nptr++; n--; } /* Single optional + or - */ if ( n && *nptr == '-' ) { minus = 1; nptr++; n--; } else if ( n && *nptr == '+' ) { nptr++; } if ( base == 0 ) { if ( n >= 2 && nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X') ) { n -= 2; nptr += 2; base = 16; } else if ( n >= 1 && nptr[0] == '0' ) { n--; nptr++; base = 8; } else { base = 10; } } else if ( base == 16 ) { if ( n >= 2 && nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X') ) { n -= 2; nptr += 2; } } while ( n && (d = digitval(*nptr)) >= 0 && d < base ) { v = v*base + d; n--; nptr++; } if ( endptr ) *endptr = (char *)nptr; return minus ? -v : v; } syslinux-legacy-3.63+dfsg/com32/lib/vsscanf.c0000664000175000017500000001773110777447272017524 0ustar evanevan/* * vsscanf.c * * vsscanf(), from which the rest of the scanf() * family is built */ #include #include #include #include #include #include #include #ifndef LONG_BIT #define LONG_BIT (CHAR_BIT*sizeof(long)) #endif enum flags { FL_SPLAT = 0x01, /* Drop the value, do not assign */ FL_INV = 0x02, /* Character-set with inverse */ FL_WIDTH = 0x04, /* Field width specified */ FL_MINUS = 0x08, /* Negative number */ }; enum ranks { rank_char = -2, rank_short = -1, rank_int = 0, rank_long = 1, rank_longlong = 2, rank_ptr = INT_MAX /* Special value used for pointers */ }; #define MIN_RANK rank_char #define MAX_RANK rank_longlong #define INTMAX_RANK rank_longlong #define SIZE_T_RANK rank_long #define PTRDIFF_T_RANK rank_long enum bail { bail_none = 0, /* No error condition */ bail_eof, /* Hit EOF */ bail_err /* Conversion mismatch */ }; static inline const char * skipspace(const char *p) { while ( isspace((unsigned char)*p) ) p++; return p; } #undef set_bit static inline void set_bit(unsigned long *bitmap, unsigned int bit) { bitmap[bit/LONG_BIT] |= 1UL << (bit%LONG_BIT); } #undef test_bit static inline int test_bit(unsigned long *bitmap, unsigned int bit) { return (int)(bitmap[bit/LONG_BIT] >> (bit%LONG_BIT)) & 1; } int vsscanf(const char *buffer, const char *format, va_list ap) { const char *p = format; char ch; const char *q = buffer; const char *qq; uintmax_t val = 0; int rank = rank_int; /* Default rank */ unsigned int width = UINT_MAX; int base; enum flags flags = 0; enum { st_normal, /* Ground state */ st_flags, /* Special flags */ st_width, /* Field width */ st_modifiers, /* Length or conversion modifiers */ st_match_init, /* Initial state of %[ sequence */ st_match, /* Main state of %[ sequence */ st_match_range, /* After - in a %[ sequence */ } state = st_normal; char *sarg = NULL; /* %s %c or %[ string argument */ enum bail bail = bail_none; int sign; int converted = 0; /* Successful conversions */ unsigned long matchmap[((1 << CHAR_BIT)+(LONG_BIT-1))/LONG_BIT]; int matchinv = 0; /* Is match map inverted? */ unsigned char range_start = 0; while ( (ch = *p++) && !bail ) { switch ( state ) { case st_normal: if ( ch == '%' ) { state = st_flags; flags = 0; rank = rank_int; width = UINT_MAX; } else if ( isspace((unsigned char)ch) ) { q = skipspace(q); } else { if ( *q == ch ) q++; else bail = bail_err; /* Match failure */ } break; case st_flags: switch ( ch ) { case '*': flags |= FL_SPLAT; break; case '0' ... '9': width = (ch-'0'); state = st_width; flags |= FL_WIDTH; break; default: state = st_modifiers; p--; /* Process this character again */ break; } break; case st_width: if ( ch >= '0' && ch <= '9' ) { width = width*10+(ch-'0'); } else { state = st_modifiers; p--; /* Process this character again */ } break; case st_modifiers: switch ( ch ) { /* Length modifiers - nonterminal sequences */ case 'h': rank--; /* Shorter rank */ break; case 'l': rank++; /* Longer rank */ break; case 'j': rank = INTMAX_RANK; break; case 'z': rank = SIZE_T_RANK; break; case 't': rank = PTRDIFF_T_RANK; break; case 'L': case 'q': rank = rank_longlong; /* long double/long long */ break; default: /* Output modifiers - terminal sequences */ state = st_normal; /* Next state will be normal */ if ( rank < MIN_RANK ) /* Canonicalize rank */ rank = MIN_RANK; else if ( rank > MAX_RANK ) rank = MAX_RANK; switch ( ch ) { case 'P': /* Upper case pointer */ case 'p': /* Pointer */ #if 0 /* Enable this to allow null pointers by name */ q = skipspace(q); if ( !isdigit((unsigned char)*q) ) { static const char * const nullnames[] = { "null", "nul", "nil", "(null)", "(nul)", "(nil)", 0 }; const char * const *np; /* Check to see if it's a null pointer by name */ for ( np = nullnames ; *np ; np++ ) { if ( !strncasecmp(q, *np, strlen(*np)) ) { val = (uintmax_t)((void *)NULL); goto set_integer; } } /* Failure */ bail = bail_err; break; } /* else */ #endif rank = rank_ptr; base = 0; sign = 0; goto scan_int; case 'i': /* Base-independent integer */ base = 0; sign = 1; goto scan_int; case 'd': /* Decimal integer */ base = 10; sign = 1; goto scan_int; case 'o': /* Octal integer */ base = 8; sign = 0; goto scan_int; case 'u': /* Unsigned decimal integer */ base = 10; sign = 0; goto scan_int; case 'x': /* Hexadecimal integer */ case 'X': base = 16; sign = 0; goto scan_int; case 'n': /* Number of characters consumed */ val = (q-buffer); goto set_integer; scan_int: q = skipspace(q); if ( !*q ) { bail = bail_eof; break; } val = strntoumax(q, (char **)&qq, base, width); if ( qq == q ) { bail = bail_err; break; } q = qq; converted++; /* fall through */ set_integer: if ( !(flags & FL_SPLAT) ) { switch(rank) { case rank_char: *va_arg(ap, unsigned char *) = (unsigned char)val; break; case rank_short: *va_arg(ap, unsigned short *) = (unsigned short)val; break; case rank_int: *va_arg(ap, unsigned int *) = (unsigned int)val; break; case rank_long: *va_arg(ap, unsigned long *) = (unsigned long)val; break; case rank_longlong: *va_arg(ap, unsigned long long *) = (unsigned long long)val; break; case rank_ptr: *va_arg(ap, void **) = (void *)(uintptr_t)val; break; } } break; case 'c': /* Character */ width = (flags & FL_WIDTH) ? width : 1; /* Default width == 1 */ sarg = va_arg(ap, char *); while ( width-- ) { if ( !*q ) { bail = bail_eof; break; } *sarg++ = *q++; } if ( !bail ) converted++; break; case 's': /* String */ { char *sp; sp = sarg = va_arg(ap, char *); while ( width-- && *q && !isspace((unsigned char)*q) ) { *sp++ = *q++; } if ( sarg != sp ) { *sp = '\0'; /* Terminate output */ converted++; } else { bail = bail_eof; } } break; case '[': /* Character range */ sarg = va_arg(ap, char *); state = st_match_init; matchinv = 0; memset(matchmap, 0, sizeof matchmap); break; case '%': /* %% sequence */ if ( *q == '%' ) q++; else bail = bail_err; break; default: /* Anything else */ bail = bail_err; /* Unknown sequence */ break; } } break; case st_match_init: /* Initial state for %[ match */ if ( ch == '^' && !(flags & FL_INV) ) { matchinv = 1; } else { set_bit(matchmap, (unsigned char)ch); state = st_match; } break; case st_match: /* Main state for %[ match */ if ( ch == ']' ) { goto match_run; } else if ( ch == '-' ) { range_start = (unsigned char)ch; state = st_match_range; } else { set_bit(matchmap, (unsigned char)ch); } break; case st_match_range: /* %[ match after - */ if ( ch == ']' ) { set_bit(matchmap, (unsigned char)'-'); /* - was last character */ goto match_run; } else { int i; for ( i = range_start ; i < (unsigned char)ch ; i++ ) set_bit(matchmap, i); state = st_match; } break; match_run: /* Match expression finished */ qq = q; while ( width && *q && test_bit(matchmap, (unsigned char)*q)^matchinv ) { *sarg++ = *q++; } if ( q != qq ) { *sarg = '\0'; converted++; } else { bail = *q ? bail_err : bail_eof; } break; } } if ( bail == bail_eof && !converted ) converted = -1; /* Return EOF (-1) */ return converted; } syslinux-legacy-3.63+dfsg/com32/lib/strerror.c0000664000175000017500000000055310777447272017735 0ustar evanevan/* * strerror.c */ #include char *strerror(int errnum) { static char message[32] = "error "; /* enough for error 2^63-1 */ char numbuf[32]; char *p; p = numbuf+sizeof numbuf; *--p = '\0'; do { *--p = (errnum % 10) + '0'; errnum /= 10; } while ( errnum ); return (char *)memcpy(message+6, p, (numbuf+sizeof numbuf)-p); } syslinux-legacy-3.63+dfsg/com32/lib/strncasecmp.c0000664000175000017500000000070710777447272020376 0ustar evanevan/* * strncasecmp.c */ #include #include int strncasecmp(const char *s1, const char *s2, size_t n) { const unsigned char *c1 = s1, *c2 = s2; unsigned char ch; int d = 0; while ( n-- ) { /* toupper() expects an unsigned char (implicitly cast to int) as input, and returns an int, which is exactly what we want. */ d = toupper(ch = *c1++) - toupper(*c2++); if ( d || !ch ) break; } return d; } syslinux-legacy-3.63+dfsg/com32/lib/strchr.c0000664000175000017500000000026110777447272017354 0ustar evanevan/* * strchr.c */ #include char *strchr(const char *s, int c) { while ( *s != (char)c ) { if ( ! *s ) return NULL; s++; } return (char *)s; } syslinux-legacy-3.63+dfsg/com32/lib/putchar.c0000664000175000017500000000032510777447272017516 0ustar evanevan/* * putchar.c * * gcc "printf decompilation" expects this to exist... */ #include #undef putchar int putchar(int c) { unsigned char ch = c; return _fwrite(&ch, 1, stdout) == 1 ? ch : EOF; } syslinux-legacy-3.63+dfsg/com32/lib/malloc.c0000664000175000017500000000576210777447272017331 0ustar evanevan/* * malloc.c * * Very simple linked-list based malloc()/free(). */ #include #include "init.h" #include "malloc.h" struct free_arena_header __malloc_head = { { ARENA_TYPE_HEAD, 0, &__malloc_head, &__malloc_head, }, &__malloc_head, &__malloc_head }; /* This is extern so it can be overridden by the user application */ extern size_t __stack_size; extern void *__mem_end; /* Produced after argv parsing */ static inline size_t sp(void) { size_t sp; asm volatile("movl %%esp,%0" : "=rm" (sp)); return sp; } static void __constructor init_memory_arena(void) { struct free_arena_header *fp; size_t start, total_space; start = (size_t)ARENA_ALIGN_UP(__mem_end); total_space = sp() - start; if ( __stack_size == 0 || __stack_size > total_space >> 1 ) __stack_size = total_space >> 1; /* Half for the stack, half for the heap... */ if ( total_space < __stack_size + 4*sizeof(struct arena_header) ) __stack_size = total_space - 4*sizeof(struct arena_header); fp = (struct free_arena_header *)start; fp->a.type = ARENA_TYPE_FREE; fp->a.size = total_space - __stack_size; /* Insert into chains */ fp->a.next = fp->a.prev = &__malloc_head; fp->next_free = fp->prev_free = &__malloc_head; __malloc_head.a.next = __malloc_head.a.prev = fp; __malloc_head.next_free = __malloc_head.prev_free = fp; } static void *__malloc_from_block(struct free_arena_header *fp, size_t size) { size_t fsize; struct free_arena_header *nfp, *na; fsize = fp->a.size; /* We need the 2* to account for the larger requirements of a free block */ if ( fsize >= size+2*sizeof(struct arena_header) ) { /* Bigger block than required -- split block */ nfp = (struct free_arena_header *)((char *)fp + size); na = fp->a.next; nfp->a.type = ARENA_TYPE_FREE; nfp->a.size = fsize-size; fp->a.type = ARENA_TYPE_USED; fp->a.size = size; /* Insert into all-block chain */ nfp->a.prev = fp; nfp->a.next = na; na->a.prev = nfp; fp->a.next = nfp; /* Replace current block on free chain */ nfp->next_free = fp->next_free; nfp->prev_free = fp->prev_free; fp->next_free->prev_free = nfp; fp->prev_free->next_free = nfp; } else { /* Allocate the whole block */ fp->a.type = ARENA_TYPE_USED; /* Remove from free chain */ fp->next_free->prev_free = fp->prev_free; fp->prev_free->next_free = fp->next_free; } return (void *)(&fp->a + 1); } void *malloc(size_t size) { struct free_arena_header *fp; if ( size == 0 ) return NULL; /* Add the obligatory arena header, and round up */ size = (size+2*sizeof(struct arena_header)-1) & ARENA_SIZE_MASK; for ( fp = __malloc_head.next_free ; fp->a.type != ARENA_TYPE_HEAD ; fp = fp->next_free ) { if ( fp->a.size >= size ) { /* Found fit -- allocate out of this block */ return __malloc_from_block(fp, size); } } /* Nothing found... need to request a block from the kernel */ return NULL; /* No kernel to get stuff from */ } syslinux-legacy-3.63+dfsg/com32/lib/fputs.c0000664000175000017500000000043510777447272017213 0ustar evanevan/* * fputs.c * * This isn't quite fputs() in the stdio sense, since we don't * have stdio, but it takes a file descriptor argument instead * of the FILE *. */ #include #include int fputs(const char *s, FILE *file) { return _fwrite(s, strlen(s), file); } syslinux-legacy-3.63+dfsg/com32/lib/zlib/0000775000175000017500000000000010777447344016644 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/lib/zlib/inffast.h0000664000175000017500000000062710777447272020454 0ustar evanevan/* inffast.h -- header to use inffast.c * Copyright (C) 1995-2003 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ void inflate_fast OF((z_streamp strm, unsigned start)); syslinux-legacy-3.63+dfsg/com32/lib/zlib/zlib.30000664000175000017500000001061210777447272017670 0ustar evanevan.TH ZLIB 3 "17 November 2003" .SH NAME zlib \- compression/decompression library .SH SYNOPSIS [see .I zlib.h for full description] .SH DESCRIPTION The .I zlib library is a general purpose data compression library. The code is thread safe. It provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms will be added later and will have the same stream interface. .LP Compression can be done in a single step if the buffers are large enough (for example if an input file is mmap'ed), or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. .LP The library also supports reading and writing files in .IR gzip (1) (.gz) format with an interface similar to that of stdio. .LP The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. .LP All functions of the compression library are documented in the file .IR zlib.h . The distribution source includes examples of use of the library in the files .I example.c and .IR minigzip.c . .LP Changes to this version are documented in the file .I ChangeLog that accompanies the source, and are concerned primarily with bug fixes and portability enhancements. .LP A Java implementation of .I zlib is available in the Java Development Kit 1.1: .IP http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html .LP A Perl interface to .IR zlib , written by Paul Marquess (pmqs@cpan.org), is available at CPAN (Comprehensive Perl Archive Network) sites, including: .IP http://www.cpan.org/modules/by-module/Compress/ .LP A Python interface to .IR zlib , written by A.M. Kuchling (amk@magnet.com), is available in Python 1.5 and later versions: .IP http://www.python.org/doc/lib/module-zlib.html .LP A .I zlib binding for .IR tcl (1), written by Andreas Kupries (a.kupries@westend.com), is availlable at: .IP http://www.westend.com/~kupries/doc/trf/man/man.html .LP An experimental package to read and write files in .zip format, written on top of .I zlib by Gilles Vollant (info@winimage.com), is available at: .IP http://www.winimage.com/zLibDll/unzip.html and also in the .I contrib/minizip directory of the main .I zlib web site. .SH "SEE ALSO" The .I zlib web site can be found at either of these locations: .IP http://www.zlib.org .br http://www.gzip.org/zlib/ .LP The data format used by the zlib library is described by RFC (Request for Comments) 1950 to 1952 in the files: .IP http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format) .br http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format) .br http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format) .LP These documents are also available in other formats from: .IP ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html .LP Mark Nelson (markn@ieee.org) wrote an article about .I zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at: .IP http://dogma.net/markn/articles/zlibtool/zlibtool.htm .SH "REPORTING PROBLEMS" Before reporting a problem, please check the .I zlib web site to verify that you have the latest version of .IR zlib ; otherwise, obtain the latest version and see if the problem still exists. Please read the .I zlib FAQ at: .IP http://www.gzip.org/zlib/zlib_faq.html .LP before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). .SH AUTHORS Version 1.2.1 Copyright (C) 1995-2003 Jean-loup Gailly (jloup@gzip.org) and Mark Adler (madler@alumni.caltech.edu). .LP This software is provided "as-is," without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. See the distribution directory with respect to requirements governing redistribution. The deflate format used by .I zlib was defined by Phil Katz. The deflate and .I zlib specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in .IR zlib ; who are too numerous to cite here. .LP UNIX manual page by R. P. C. Rodgers, U.S. National Library of Medicine (rodgers@nlm.nih.gov). .\" end of man page syslinux-legacy-3.63+dfsg/com32/lib/zlib/zutil.c0000664000175000017500000001551710777447272020170 0ustar evanevan/* zutil.c -- target dependent utility functions for the compression library * Copyright (C) 1995-2003 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #ifndef NO_DUMMY_DECL struct internal_state {int dummy;}; /* for buggy compilers */ #endif #ifndef STDC extern void exit OF((int)); #endif const char * const z_errmsg[10] = { "need dictionary", /* Z_NEED_DICT 2 */ "stream end", /* Z_STREAM_END 1 */ "", /* Z_OK 0 */ "file error", /* Z_ERRNO (-1) */ "stream error", /* Z_STREAM_ERROR (-2) */ "data error", /* Z_DATA_ERROR (-3) */ "insufficient memory", /* Z_MEM_ERROR (-4) */ "buffer error", /* Z_BUF_ERROR (-5) */ "incompatible version",/* Z_VERSION_ERROR (-6) */ ""}; const char * ZEXPORT zlibVersion() { return ZLIB_VERSION; } uLong ZEXPORT zlibCompileFlags() { uLong flags; flags = 0; switch (sizeof(uInt)) { case 2: break; case 4: flags += 1; break; case 8: flags += 2; break; default: flags += 3; } switch (sizeof(uLong)) { case 2: break; case 4: flags += 1 << 2; break; case 8: flags += 2 << 2; break; default: flags += 3 << 2; } switch (sizeof(voidpf)) { case 2: break; case 4: flags += 1 << 4; break; case 8: flags += 2 << 4; break; default: flags += 3 << 4; } switch (sizeof(z_off_t)) { case 2: break; case 4: flags += 1 << 6; break; case 8: flags += 2 << 6; break; default: flags += 3 << 6; } #ifdef DEBUG flags += 1 << 8; #endif #if defined(ASMV) || defined(ASMINF) flags += 1 << 9; #endif #ifdef ZLIB_WINAPI flags += 1 << 10; #endif #ifdef BUILDFIXED flags += 1 << 12; #endif #ifdef DYNAMIC_CRC_TABLE flags += 1 << 13; #endif #ifdef NO_GZCOMPRESS flags += 1 << 16; #endif #ifdef NO_GZIP flags += 1 << 17; #endif #ifdef PKZIP_BUG_WORKAROUND flags += 1 << 20; #endif #ifdef FASTEST flags += 1 << 21; #endif #ifdef STDC # ifdef NO_vsnprintf flags += 1 << 25; # ifdef HAS_vsprintf_void flags += 1 << 26; # endif # else # ifdef HAS_vsnprintf_void flags += 1 << 26; # endif # endif #else flags += 1 << 24; # ifdef NO_snprintf flags += 1 << 25; # ifdef HAS_sprintf_void flags += 1 << 26; # endif # else # ifdef HAS_snprintf_void flags += 1 << 26; # endif # endif #endif return flags; } #ifdef DEBUG # ifndef verbose # define verbose 0 # endif int z_verbose = verbose; void z_error (m) char *m; { fprintf(stderr, "%s\n", m); exit(1); } #endif /* exported to allow conversion of error code to string for compress() and * uncompress() */ const char * ZEXPORT zError(err) int err; { return ERR_MSG(err); } #if defined(_WIN32_WCE) /* does not exist on WCE */ int errno = 0; #endif #ifndef HAVE_MEMCPY void zmemcpy(dest, source, len) Bytef* dest; const Bytef* source; uInt len; { if (len == 0) return; do { *dest++ = *source++; /* ??? to be unrolled */ } while (--len != 0); } int zmemcmp(s1, s2, len) const Bytef* s1; const Bytef* s2; uInt len; { uInt j; for (j = 0; j < len; j++) { if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; } return 0; } void zmemzero(dest, len) Bytef* dest; uInt len; { if (len == 0) return; do { *dest++ = 0; /* ??? to be unrolled */ } while (--len != 0); } #endif #ifdef SYS16BIT #ifdef __TURBOC__ /* Turbo C in 16-bit mode */ # define MY_ZCALLOC /* Turbo C malloc() does not allow dynamic allocation of 64K bytes * and farmalloc(64K) returns a pointer with an offset of 8, so we * must fix the pointer. Warning: the pointer must be put back to its * original form in order to free it, use zcfree(). */ #define MAX_PTR 10 /* 10*64K = 640K */ local int next_ptr = 0; typedef struct ptr_table_s { voidpf org_ptr; voidpf new_ptr; } ptr_table; local ptr_table table[MAX_PTR]; /* This table is used to remember the original form of pointers * to large buffers (64K). Such pointers are normalized with a zero offset. * Since MSDOS is not a preemptive multitasking OS, this table is not * protected from concurrent access. This hack doesn't work anyway on * a protected system like OS/2. Use Microsoft C instead. */ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) { voidpf buf = opaque; /* just to make some compilers happy */ ulg bsize = (ulg)items*size; /* If we allocate less than 65520 bytes, we assume that farmalloc * will return a usable pointer which doesn't have to be normalized. */ if (bsize < 65520L) { buf = farmalloc(bsize); if (*(ush*)&buf != 0) return buf; } else { buf = farmalloc(bsize + 16L); } if (buf == NULL || next_ptr >= MAX_PTR) return NULL; table[next_ptr].org_ptr = buf; /* Normalize the pointer to seg:0 */ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; *(ush*)&buf = 0; table[next_ptr++].new_ptr = buf; return buf; } void zcfree (voidpf opaque, voidpf ptr) { int n; if (*(ush*)&ptr != 0) { /* object < 64K */ farfree(ptr); return; } /* Find the original pointer */ for (n = 0; n < next_ptr; n++) { if (ptr != table[n].new_ptr) continue; farfree(table[n].org_ptr); while (++n < next_ptr) { table[n-1] = table[n]; } next_ptr--; return; } ptr = opaque; /* just to make some compilers happy */ Assert(0, "zcfree: ptr not found"); } #endif /* __TURBOC__ */ #ifdef M_I86 /* Microsoft C in 16-bit mode */ # define MY_ZCALLOC #if (!defined(_MSC_VER) || (_MSC_VER <= 600)) # define _halloc halloc # define _hfree hfree #endif voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) { if (opaque) opaque = 0; /* to make compiler happy */ return _halloc((long)items, size); } void zcfree (voidpf opaque, voidpf ptr) { if (opaque) opaque = 0; /* to make compiler happy */ _hfree(ptr); } #endif /* M_I86 */ #endif /* SYS16BIT */ #ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef STDC extern voidp malloc OF((uInt size)); extern voidp calloc OF((uInt items, uInt size)); extern void free OF((voidpf ptr)); #endif voidpf zcalloc (opaque, items, size) voidpf opaque; unsigned items; unsigned size; { if (opaque) items += size - size; /* make compiler happy */ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } void zcfree (opaque, ptr) voidpf opaque; voidpf ptr; { free(ptr); if (opaque) return; /* make compiler happy */ } #endif /* MY_ZCALLOC */ syslinux-legacy-3.63+dfsg/com32/lib/zlib/minigzip.c0000664000175000017500000001751310777447272020645 0ustar evanevan/* minigzip.c -- simulate gzip using the zlib compression library * Copyright (C) 1995-2002 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* * minigzip is a minimal implementation of the gzip utility. This is * only an example of using zlib and isn't meant to replace the * full-featured gzip. No attempt is made to deal with file systems * limiting names to 14 or 8+3 characters, etc... Error checking is * very limited. So use minigzip only for testing; use gzip for the * real thing. On MSDOS, use only on file names without extension * or in pipe mode. */ #include #include "zlib.h" #ifdef STDC # include # include #else extern void exit OF((int)); #endif #ifdef USE_MMAP # include # include # include #endif #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) # include # include # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) #else # define SET_BINARY_MODE(file) #endif #ifdef VMS # define unlink delete # define GZ_SUFFIX "-gz" #endif #ifdef RISCOS # define unlink remove # define GZ_SUFFIX "-gz" # define fileno(file) file->__file #endif #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os # include /* for fileno */ #endif #ifndef WIN32 /* unlink already in stdio.h for WIN32 */ extern int unlink OF((const char *)); #endif #ifndef GZ_SUFFIX # define GZ_SUFFIX ".gz" #endif #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) #define BUFLEN 16384 #define MAX_NAME_LEN 1024 #ifdef MAXSEG_64K # define local static /* Needed for systems with limitation on stack size. */ #else # define local #endif char *prog; void error OF((const char *msg)); void gz_compress OF((FILE *in, gzFile out)); #ifdef USE_MMAP int gz_compress_mmap OF((FILE *in, gzFile out)); #endif void gz_uncompress OF((gzFile in, FILE *out)); void file_compress OF((char *file, char *mode)); void file_uncompress OF((char *file)); int main OF((int argc, char *argv[])); /* =========================================================================== * Display error message and exit */ void error(msg) const char *msg; { fprintf(stderr, "%s: %s\n", prog, msg); exit(1); } /* =========================================================================== * Compress input to output then close both files. */ void gz_compress(in, out) FILE *in; gzFile out; { local char buf[BUFLEN]; int len; int err; #ifdef USE_MMAP /* Try first compressing with mmap. If mmap fails (minigzip used in a * pipe), use the normal fread loop. */ if (gz_compress_mmap(in, out) == Z_OK) return; #endif for (;;) { errno = 0; len = (int)fread(buf, 1, sizeof(buf), in); if (!len && errno) { perror("fread"); exit(1); } if (len == 0) break; if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); } fclose(in); if (gzclose(out) != Z_OK) error("failed gzclose"); } #ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ /* Try compressing the input file at once using mmap. Return Z_OK if * if success, Z_ERRNO otherwise. */ int gz_compress_mmap(in, out) FILE *in; gzFile out; { int len; int err; int ifd = fileno(in); caddr_t buf; /* mmap'ed buffer for the entire input file */ off_t buf_len; /* length of the input file */ struct stat sb; /* Determine the size of the file, needed for mmap: */ if (fstat(ifd, &sb) < 0) return Z_ERRNO; buf_len = sb.st_size; if (buf_len <= 0) return Z_ERRNO; /* Now do the actual mmap: */ buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); if (buf == (caddr_t)(-1)) return Z_ERRNO; /* Compress the whole file at once: */ len = gzwrite(out, (char *)buf, (unsigned)buf_len); if (len != (int)buf_len) error(gzerror(out, &err)); munmap(buf, buf_len); fclose(in); if (gzclose(out) != Z_OK) error("failed gzclose"); return Z_OK; } #endif /* USE_MMAP */ /* =========================================================================== * Uncompress input to output then close both files. */ void gz_uncompress(in, out) gzFile in; FILE *out; { local char buf[BUFLEN]; int len; int err; for (;;) { len = gzread(in, buf, sizeof(buf)); if (len < 0) error (gzerror(in, &err)); if (len == 0) break; if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { error("failed fwrite"); } } if (fclose(out)) error("failed fclose"); if (gzclose(in) != Z_OK) error("failed gzclose"); } /* =========================================================================== * Compress the given file: create a corresponding .gz file and remove the * original. */ void file_compress(file, mode) char *file; char *mode; { local char outfile[MAX_NAME_LEN]; FILE *in; gzFile out; strcpy(outfile, file); strcat(outfile, GZ_SUFFIX); in = fopen(file, "rb"); if (in == NULL) { perror(file); exit(1); } out = gzopen(outfile, mode); if (out == NULL) { fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); exit(1); } gz_compress(in, out); unlink(file); } /* =========================================================================== * Uncompress the given file and remove the original. */ void file_uncompress(file) char *file; { local char buf[MAX_NAME_LEN]; char *infile, *outfile; FILE *out; gzFile in; uInt len = (uInt)strlen(file); strcpy(buf, file); if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { infile = file; outfile = buf; outfile[len-3] = '\0'; } else { outfile = file; infile = buf; strcat(infile, GZ_SUFFIX); } in = gzopen(infile, "rb"); if (in == NULL) { fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); exit(1); } out = fopen(outfile, "wb"); if (out == NULL) { perror(file); exit(1); } gz_uncompress(in, out); unlink(infile); } /* =========================================================================== * Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...] * -d : decompress * -f : compress with Z_FILTERED * -h : compress with Z_HUFFMAN_ONLY * -r : compress with Z_RLE * -1 to -9 : compression level */ int main(argc, argv) int argc; char *argv[]; { int uncompr = 0; gzFile file; char outmode[20]; strcpy(outmode, "wb6 "); prog = argv[0]; argc--, argv++; while (argc > 0) { if (strcmp(*argv, "-d") == 0) uncompr = 1; else if (strcmp(*argv, "-f") == 0) outmode[3] = 'f'; else if (strcmp(*argv, "-h") == 0) outmode[3] = 'h'; else if (strcmp(*argv, "-r") == 0) outmode[3] = 'R'; else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && (*argv)[2] == 0) outmode[2] = (*argv)[1]; else break; argc--, argv++; } if (argc == 0) { SET_BINARY_MODE(stdin); SET_BINARY_MODE(stdout); if (uncompr) { file = gzdopen(fileno(stdin), "rb"); if (file == NULL) error("can't gzdopen stdin"); gz_uncompress(file, stdout); } else { file = gzdopen(fileno(stdout), outmode); if (file == NULL) error("can't gzdopen stdout"); gz_compress(stdin, file); } } else { do { if (uncompr) { file_uncompress(*argv); } else { file_compress(*argv, outmode); } } while (argv++, --argc); } return 0; } syslinux-legacy-3.63+dfsg/com32/lib/zlib/zutil.h0000664000175000017500000001452010777447272020166 0ustar evanevan/* zutil.h -- internal interface and configuration of the compression library * Copyright (C) 1995-2003 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ #ifndef ZUTIL_H #define ZUTIL_H #define ZLIB_INTERNAL #include "zlib.h" #ifdef STDC # include # include # include #endif #ifdef NO_ERRNO_H extern int errno; #else # include #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ typedef unsigned char uch; typedef uch FAR uchf; typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_RETURN(strm,err) \ return (strm->msg = (char*)ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ /* common constants */ #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif /* default windowBits for decompression. MAX_WBITS is for compression only */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default memLevel */ #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #define MIN_MATCH 3 #define MAX_MATCH 258 /* The minimum and maximum match lengths */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ /* target dependencies */ #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) # define OS_CODE 0x00 # if defined(__TURBOC__) || defined(__BORLANDC__) # if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) /* Allow compilation with ANSI keywords only enabled */ void _Cdecl farfree( void *block ); void *_Cdecl farmalloc( unsigned long nbytes ); # else # include # endif # else /* MSC or DJGPP */ # include # endif #endif #ifdef AMIGA # define OS_CODE 0x01 #endif #if defined(VAXC) || defined(VMS) # define OS_CODE 0x02 # define F_OPEN(name, mode) \ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") #endif #if defined(ATARI) || defined(atarist) # define OS_CODE 0x05 #endif #ifdef OS2 # define OS_CODE 0x06 #endif #if defined(MACOS) || defined(TARGET_OS_MAC) # define OS_CODE 0x07 # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os # include /* for fdopen */ # else # ifndef fdopen # define fdopen(fd,mode) NULL /* No fdopen() */ # endif # endif #endif #ifdef TOPS20 # define OS_CODE 0x0a #endif #ifdef WIN32 # ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ # define OS_CODE 0x0b # endif #endif #ifdef __50SERIES /* Prime/PRIMOS */ # define OS_CODE 0x0f #endif #if defined(_BEOS_) || defined(RISCOS) # define fdopen(fd,mode) NULL /* No fdopen() */ #endif #if (defined(_MSC_VER) && (_MSC_VER > 600)) # if defined(_WIN32_WCE) # define fdopen(fd,mode) NULL /* No fdopen() */ # ifndef _PTRDIFF_T_DEFINED typedef int ptrdiff_t; # define _PTRDIFF_T_DEFINED # endif # else # define fdopen(fd,type) _fdopen(fd,type) # endif #endif /* common defaults */ #ifndef OS_CODE # define OS_CODE 0x03 /* assume Unix */ #endif #ifndef F_OPEN # define F_OPEN(name, mode) fopen((name), (mode)) #endif /* functions */ #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #if defined(__CYGWIN__) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #ifndef HAVE_VSNPRINTF # ifdef MSDOS /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), but for now we just assume it doesn't. */ # define NO_vsnprintf # endif # ifdef __TURBOC__ # define NO_vsnprintf # endif # ifdef WIN32 /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ # if !defined(vsnprintf) && !defined(NO_vsnprintf) # define vsnprintf _vsnprintf # endif # endif # ifdef __SASC # define NO_vsnprintf # endif #endif #ifdef HAVE_STRERROR extern char *strerror OF((int)); # define zstrerror(errnum) strerror(errnum) #else # define zstrerror(errnum) "" #endif #if defined(pyr) # define NO_MEMCPY #endif #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) /* Use our own functions for small and medium model with MSC <= 5.0. * You may have to use the same strategy for Borland C (untested). * The __SC__ check is for Symantec. */ # define NO_MEMCPY #endif #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) # define HAVE_MEMCPY #endif #ifdef HAVE_MEMCPY # ifdef SMALL_MEDIUM /* MSDOS small or medium model */ # define zmemcpy _fmemcpy # define zmemcmp _fmemcmp # define zmemzero(dest, len) _fmemset(dest, 0, len) # else # define zmemcpy memcpy # define zmemcmp memcmp # define zmemzero(dest, len) memset(dest, 0, len) # endif #else extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); extern void zmemzero OF((Bytef* dest, uInt len)); #endif /* Diagnostic functions */ #ifdef DEBUG # include extern int z_verbose; extern void z_error OF((char *m)); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) {if (z_verbose>=0) fprintf x ;} # define Tracev(x) {if (z_verbose>0) fprintf x ;} # define Tracevv(x) {if (z_verbose>1) fprintf x ;} # define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} # define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} #else # define Assert(cond,msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) #endif voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); void zcfree OF((voidpf opaque, voidpf ptr)); #define ZALLOC(strm, items, size) \ (*((strm)->zalloc))((strm)->opaque, (items), (size)) #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} #endif /* ZUTIL_H */ syslinux-legacy-3.63+dfsg/com32/lib/zlib/FAQ0000664000175000017500000003347610777447272017213 0ustar evanevan Frequently Asked Questions about zlib If your question is not there, please check the zlib home page http://www.zlib.org which may have more recent information. The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html 1. Is zlib Y2K-compliant? Yes. zlib doesn't handle dates. 2. Where can I get a Windows DLL version? The zlib sources can be compiled without change to produce a DLL. See the file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the precompiled DLL are found in the zlib web site at http://www.zlib.org. 3. Where can I get a Visual Basic interface to zlib? See * http://www.winimage.com/zLibDll/ * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm * contrib/visual-basic.txt in the zlib distribution 4. compress() returns Z_BUF_ERROR Make sure that before the call of compress, the length of the compressed buffer is equal to the total size of the compressed buffer and not zero. For Visual Basic, check that this parameter is passed by reference ("as any"), not by value ("as long"). 5. deflate() or inflate() returns Z_BUF_ERROR Before making the call, make sure that avail_in and avail_out are not zero. When setting the parameter flush equal to Z_FINISH, also make sure that avail_out is big enough to allow processing all pending input. Note that a Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be made with more input or output space. A Z_BUF_ERROR may in fact be unavoidable depending on how the functions are used, since it is not possible to tell whether or not there is more output pending when strm.avail_out returns with zero. 6. Where's the zlib documentation (man pages, etc.)? It's in zlib.h for the moment, and Francis S. Lin has converted it to a web page zlib.html. Volunteers to transform this to Unix-style man pages, please contact Jean-loup Gailly (jloup@gzip.org). Examples of zlib usage are in the files example.c and minigzip.c. 7. Why don't you use GNU autoconf or libtool or ...? Because we would like to keep zlib as a very small and simple package. zlib is rather portable and doesn't need much configuration. 8. I found a bug in zlib. Most of the time, such problems are due to an incorrect usage of zlib. Please try to reproduce the problem with a small program and send the corresponding source to us at zlib@gzip.org . Do not send multi-megabyte data files without prior agreement. 9. Why do I get "undefined reference to gzputc"? If "make test" produces something like example.o(.text+0x154): undefined reference to `gzputc' check that you don't have old files libz.* in /usr/lib, /usr/local/lib or /usr/X11R6/lib. Remove any old versions, then do "make install". 10. I need a Delphi interface to zlib. See the contrib/delphi directory in the zlib distribution. 11. Can zlib handle .zip archives? See the directory contrib/minizip in the zlib distribution. 12. Can zlib handle .Z files? No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt the code of uncompress on your own. 13. How can I make a Unix shared library? make clean ./configure -s make 14. How do I install a shared zlib library on Unix? make install However, many flavors of Unix come with a shared zlib already installed. Before going to the trouble of compiling a shared version of zlib and trying to install it, you may want to check if it's already there! If you can #include , it's there. The -lz option will probably link to it. 15. I have a question about OttoPDF We are not the authors of OttoPDF. The real author is on the OttoPDF web site Joel Hainley jhainley@myndkryme.com. 16. Why does gzip give an error on a file I make with compress/deflate? The compress and deflate functions produce data in the zlib format, which is different and incompatible with the gzip format. The gz* functions in zlib on the other hand use the gzip format. Both the zlib and gzip formats use the same compressed data format internally, but have different headers and trailers around the compressed data. 17. Ok, so why are there two different formats? The gzip format was designed to retain the directory information about a single file, such as the name and last modification date. The zlib format on the other hand was designed for in-memory and communication channel applications, and has a much more compact header and trailer and uses a faster integrity check than gzip. 18. Well that's nice, but how do I make a gzip file in memory? You can request that deflate write the gzip format instead of the zlib format using deflateInit2(). You can also request that inflate decode the gzip format using inflateInit2(). Read zlib.h for more details. Note that you cannot specify special gzip header contents (e.g. a file name or modification date), nor will inflate tell you what was in the gzip header. If you need to customize the header or see what's in it, you can use the raw deflate and inflate operations and the crc32() function and roll your own gzip encoding and decoding. Read the gzip RFC 1952 for details of the header and trailer format. 19. Is zlib thread-safe? Yes. However any library routines that zlib uses and any application- provided memory allocation routines must also be thread-safe. zlib's gz* functions use stdio library routines, and most of zlib's functions use the library memory allocation routines by default. zlib's Init functions allow for the application to provide custom memory allocation routines. Of course, you should only operate on any given zlib or gzip stream from a single thread at a time. 20. Can I use zlib in my commercial application? Yes. Please read the license in zlib.h. 21. Is zlib under the GNU license? No. Please read the license in zlib.h. 22. The license says that altered source versions must be "plainly marked". So what exactly do I need to do to meet that requirement? You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In particular, the final version number needs to be changed to "f", and an identification string should be appended to ZLIB_VERSION. Version numbers x.x.x.f are reserved for modifications to zlib by others than the zlib maintainers. For example, if the version of the base zlib you are altering is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also update the version strings in deflate.c and inftrees.c. For altered source distributions, you should also note the origin and nature of the changes in zlib.h, as well as in ChangeLog and README, along with the dates of the alterations. The origin should include at least your name (or your company's name), and an email address to contact for help or issues with the library. Note that distributing a compiled zlib library along with zlib.h and zconf.h is also a source distribution, and so you should change ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes in zlib.h as you would for a full source distribution. 23. Will zlib work on a big-endian or little-endian architecture, and can I exchange compressed data between them? Yes and yes. 24. Will zlib work on a 64-bit machine? It should. It has been tested on 64-bit machines, and has no dependence on any data types being limited to 32-bits in length. If you have any difficulties, please provide a complete problem report to zlib@gzip.org 25. Will zlib decompress data from the PKWare Data Compression Library? No. The PKWare DCL uses a completely different compressed data format than does PKZIP and zlib. However, you can look in zlib's contrib/blast directory for a possible solution to your problem. 26. Can I access data randomly in a compressed stream? No, not without some preparation. If when compressing you periodically use Z_FULL_FLUSH, carefully write all the pending data at those points, and keep an index of those locations, then you can start decompression at those points. You have to be careful to not use Z_FULL_FLUSH too often, since it can significantly degrade compression. 27. Does zlib work on MVS, OS/390, CICS, etc.? We don't know for sure. We have heard occasional reports of success on these systems. If you do use it on one of these, please provide us with a report, instructions, and patches that we can reference when we get these questions. Thanks. 28. Is there some simpler, easier to read version of inflate I can look at to understand the deflate format? First off, you should read RFC 1951. Second, yes. Look in zlib's contrib/puff directory. 29. Does zlib infringe on any patents? As far as we know, no. In fact, that was originally the whole point behind zlib. Look here for some more information: http://www.gzip.org/#faq11 30. Can zlib work with greater than 4 GB of data? Yes. inflate() and deflate() will process any amount of data correctly. Each call of inflate() or deflate() is limited to input and output chunks of the maximum value that can be stored in the compiler's "unsigned int" type, but there is no limit to the number of chunks. Note however that the strm.total_in and strm_total_out counters may be limited to 4 GB. These counters are provided as a convenience and are not used internally by inflate() or deflate(). The application can easily set up its own counters updated after each call of inflate() or deflate() to count beyond 4 GB. compress() and uncompress() may be limited to 4 GB, since they operate in a single call. gzseek() and gztell() may be limited to 4 GB depending on how zlib is compiled. See the zlibCompileFlags() function in zlib.h. The word "may" appears several times above since there is a 4 GB limit only if the compiler's "long" type is 32 bits. If the compiler's "long" type is 64 bits, then the limit is 16 exabytes. 31. Does zlib have any security vulnerabilities? The only one that we are aware of is potentially in gzprintf(). If zlib is compiled to use sprintf() or vsprintf(), then there is no protection against a buffer overflow of a 4K string space, other than the caller of gzprintf() assuring that the output will not exceed 4K. On the other hand, if zlib is compiled to use snprintf() or vsnprintf(), which should normally be the case, then there is no vulnerability. The ./configure script will display warnings if an insecure variation of sprintf() will be used by gzprintf(). Also the zlibCompileFlags() function will return information on what variant of sprintf() is used by gzprintf(). If you don't have snprintf() or vsnprintf() and would like one, you can find a portable implementation here: http://www.ijs.si/software/snprintf/ Note that you should be using the most recent version of zlib. Versions 1.1.3 and before were subject to a double-free vulnerability. 32. Is there a Java version of zlib? Probably what you want is to use zlib in Java. zlib is already included as part of the Java SDK in the java.util.zip package. If you really want a version of zlib written in the Java language, look on the zlib home page for links: http://www.zlib.org/ 33. I get this or that compiler or source-code scanner warning when I crank it up to maximally-pendantic. Can't you guys write proper code? Many years ago, we gave up attempting to avoid warnings on every compiler in the universe. It just got to be a waste of time, and some compilers were downright silly. So now, we simply make sure that the code always works. 34. Will zlib read the (insert any ancient or arcane format here) compressed data format? Probably not. Look in the comp.compression FAQ for pointers to various formats and associated software. 35. How can I encrypt/decrypt zip files with zlib? zlib doesn't support encryption. The original PKZIP encryption is very weak and can be broken with freely available programs. To get strong encryption, use gpg ( http://www.gnupg.org/ ) which already includes zlib compression. For PKZIP compatible "encryption", look at http://www.info-zip.org/ 36. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? "gzip" is the gzip format, and "deflate" is the zlib format. They should probably have called the second one "zlib" instead to avoid confusion with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 correctly points to the zlib specification in RFC 1950 for the "deflate" transfer encoding, there have been reports of servers and browsers that incorrectly produce or expect raw deflate data per the deflate specficiation in RFC 1951, most notably Microsoft. So even though the "deflate" transfer encoding using the zlib format would be the more efficient approach (and in fact exactly what the zlib format was designed for), using the "gzip" transfer encoding is probably more reliable due to an unfortunate choice of name on the part of the HTTP 1.1 authors. Bottom line: use the gzip format for HTTP 1.1 encoding. 37. Does zlib support the new "Deflate64" format introduced by PKWare? No. PKWare has apparently decided to keep that format proprietary, since they have not documented it as they have previous compression formats. In any case, the compression improvements are so modest compared to other more modern approaches, that it's not worth the effort to implement. 38. Can you please sign these lengthy legal documents and fax them back to us so that we can use your software in our product? No. Go away. Shoo. syslinux-legacy-3.63+dfsg/com32/lib/zlib/example.c0000664000175000017500000004004410777447272020445 0ustar evanevan/* example.c -- usage example of the zlib compression library * Copyright (C) 1995-2003 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ #include #include "zlib.h" #ifdef STDC # include # include #else extern void exit OF((int)); #endif #if defined(VMS) || defined(RISCOS) # define TESTFILE "foo-gz" #else # define TESTFILE "foo.gz" #endif #define CHECK_ERR(err, msg) { \ if (err != Z_OK) { \ fprintf(stderr, "%s error: %d\n", msg, err); \ exit(1); \ } \ } const char hello[] = "hello, hello!"; /* "hello world" would be more standard, but the repeated "hello" * stresses the compression code better, sorry... */ const char dictionary[] = "hello"; uLong dictId; /* Adler32 value of the dictionary */ void test_compress OF((Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)); void test_gzio OF((const char *fname, Byte *uncompr, uLong uncomprLen)); void test_deflate OF((Byte *compr, uLong comprLen)); void test_inflate OF((Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)); void test_large_deflate OF((Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)); void test_large_inflate OF((Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)); void test_flush OF((Byte *compr, uLong *comprLen)); void test_sync OF((Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)); void test_dict_deflate OF((Byte *compr, uLong comprLen)); void test_dict_inflate OF((Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)); int main OF((int argc, char *argv[])); /* =========================================================================== * Test compress() and uncompress() */ void test_compress(compr, comprLen, uncompr, uncomprLen) Byte *compr, *uncompr; uLong comprLen, uncomprLen; { int err; uLong len = (uLong)strlen(hello)+1; err = compress(compr, &comprLen, (const Bytef*)hello, len); CHECK_ERR(err, "compress"); strcpy((char*)uncompr, "garbage"); err = uncompress(uncompr, &uncomprLen, compr, comprLen); CHECK_ERR(err, "uncompress"); if (strcmp((char*)uncompr, hello)) { fprintf(stderr, "bad uncompress\n"); exit(1); } else { printf("uncompress(): %s\n", (char *)uncompr); } } /* =========================================================================== * Test read/write of .gz files */ void test_gzio(fname, uncompr, uncomprLen) const char *fname; /* compressed file name */ Byte *uncompr; uLong uncomprLen; { #ifdef NO_GZCOMPRESS fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); #else int err; int len = (int)strlen(hello)+1; gzFile file; z_off_t pos; file = gzopen(fname, "wb"); if (file == NULL) { fprintf(stderr, "gzopen error\n"); exit(1); } gzputc(file, 'h'); if (gzputs(file, "ello") != 4) { fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); exit(1); } if (gzprintf(file, ", %s!", "hello") != 8) { fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); exit(1); } gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ gzclose(file); file = gzopen(fname, "rb"); if (file == NULL) { fprintf(stderr, "gzopen error\n"); exit(1); } strcpy((char*)uncompr, "garbage"); if (gzread(file, uncompr, (unsigned)uncomprLen) != len) { fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); exit(1); } if (strcmp((char*)uncompr, hello)) { fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); exit(1); } else { printf("gzread(): %s\n", (char*)uncompr); } pos = gzseek(file, -8L, SEEK_CUR); if (pos != 6 || gztell(file) != pos) { fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)gztell(file)); exit(1); } if (gzgetc(file) != ' ') { fprintf(stderr, "gzgetc error\n"); exit(1); } if (gzungetc(' ', file) != ' ') { fprintf(stderr, "gzungetc error\n"); exit(1); } gzgets(file, (char*)uncompr, (int)uncomprLen); if (strlen((char*)uncompr) != 7) { /* " hello!" */ fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); exit(1); } if (strcmp((char*)uncompr, hello + 6)) { fprintf(stderr, "bad gzgets after gzseek\n"); exit(1); } else { printf("gzgets() after gzseek: %s\n", (char*)uncompr); } gzclose(file); #endif } /* =========================================================================== * Test deflate() with small buffers */ void test_deflate(compr, comprLen) Byte *compr; uLong comprLen; { z_stream c_stream; /* compression stream */ int err; uLong len = (uLong)strlen(hello)+1; c_stream.zalloc = (alloc_func)0; c_stream.zfree = (free_func)0; c_stream.opaque = (voidpf)0; err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); CHECK_ERR(err, "deflateInit"); c_stream.next_in = (Bytef*)hello; c_stream.next_out = compr; while (c_stream.total_in != len && c_stream.total_out < comprLen) { c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ err = deflate(&c_stream, Z_NO_FLUSH); CHECK_ERR(err, "deflate"); } /* Finish the stream, still forcing small buffers: */ for (;;) { c_stream.avail_out = 1; err = deflate(&c_stream, Z_FINISH); if (err == Z_STREAM_END) break; CHECK_ERR(err, "deflate"); } err = deflateEnd(&c_stream); CHECK_ERR(err, "deflateEnd"); } /* =========================================================================== * Test inflate() with small buffers */ void test_inflate(compr, comprLen, uncompr, uncomprLen) Byte *compr, *uncompr; uLong comprLen, uncomprLen; { int err; z_stream d_stream; /* decompression stream */ strcpy((char*)uncompr, "garbage"); d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_in = compr; d_stream.avail_in = 0; d_stream.next_out = uncompr; err = inflateInit(&d_stream); CHECK_ERR(err, "inflateInit"); while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END) break; CHECK_ERR(err, "inflate"); } err = inflateEnd(&d_stream); CHECK_ERR(err, "inflateEnd"); if (strcmp((char*)uncompr, hello)) { fprintf(stderr, "bad inflate\n"); exit(1); } else { printf("inflate(): %s\n", (char *)uncompr); } } /* =========================================================================== * Test deflate() with large buffers and dynamic change of compression level */ void test_large_deflate(compr, comprLen, uncompr, uncomprLen) Byte *compr, *uncompr; uLong comprLen, uncomprLen; { z_stream c_stream; /* compression stream */ int err; c_stream.zalloc = (alloc_func)0; c_stream.zfree = (free_func)0; c_stream.opaque = (voidpf)0; err = deflateInit(&c_stream, Z_BEST_SPEED); CHECK_ERR(err, "deflateInit"); c_stream.next_out = compr; c_stream.avail_out = (uInt)comprLen; /* At this point, uncompr is still mostly zeroes, so it should compress * very well: */ c_stream.next_in = uncompr; c_stream.avail_in = (uInt)uncomprLen; err = deflate(&c_stream, Z_NO_FLUSH); CHECK_ERR(err, "deflate"); if (c_stream.avail_in != 0) { fprintf(stderr, "deflate not greedy\n"); exit(1); } /* Feed in already compressed data and switch to no compression: */ deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); c_stream.next_in = compr; c_stream.avail_in = (uInt)comprLen/2; err = deflate(&c_stream, Z_NO_FLUSH); CHECK_ERR(err, "deflate"); /* Switch back to compressing mode: */ deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); c_stream.next_in = uncompr; c_stream.avail_in = (uInt)uncomprLen; err = deflate(&c_stream, Z_NO_FLUSH); CHECK_ERR(err, "deflate"); err = deflate(&c_stream, Z_FINISH); if (err != Z_STREAM_END) { fprintf(stderr, "deflate should report Z_STREAM_END\n"); exit(1); } err = deflateEnd(&c_stream); CHECK_ERR(err, "deflateEnd"); } /* =========================================================================== * Test inflate() with large buffers */ void test_large_inflate(compr, comprLen, uncompr, uncomprLen) Byte *compr, *uncompr; uLong comprLen, uncomprLen; { int err; z_stream d_stream; /* decompression stream */ strcpy((char*)uncompr, "garbage"); d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_in = compr; d_stream.avail_in = (uInt)comprLen; err = inflateInit(&d_stream); CHECK_ERR(err, "inflateInit"); for (;;) { d_stream.next_out = uncompr; /* discard the output */ d_stream.avail_out = (uInt)uncomprLen; err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END) break; CHECK_ERR(err, "large inflate"); } err = inflateEnd(&d_stream); CHECK_ERR(err, "inflateEnd"); if (d_stream.total_out != 2*uncomprLen + comprLen/2) { fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); exit(1); } else { printf("large_inflate(): OK\n"); } } /* =========================================================================== * Test deflate() with full flush */ void test_flush(compr, comprLen) Byte *compr; uLong *comprLen; { z_stream c_stream; /* compression stream */ int err; uInt len = (uInt)strlen(hello)+1; c_stream.zalloc = (alloc_func)0; c_stream.zfree = (free_func)0; c_stream.opaque = (voidpf)0; err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); CHECK_ERR(err, "deflateInit"); c_stream.next_in = (Bytef*)hello; c_stream.next_out = compr; c_stream.avail_in = 3; c_stream.avail_out = (uInt)*comprLen; err = deflate(&c_stream, Z_FULL_FLUSH); CHECK_ERR(err, "deflate"); compr[3]++; /* force an error in first compressed block */ c_stream.avail_in = len - 3; err = deflate(&c_stream, Z_FINISH); if (err != Z_STREAM_END) { CHECK_ERR(err, "deflate"); } err = deflateEnd(&c_stream); CHECK_ERR(err, "deflateEnd"); *comprLen = c_stream.total_out; } /* =========================================================================== * Test inflateSync() */ void test_sync(compr, comprLen, uncompr, uncomprLen) Byte *compr, *uncompr; uLong comprLen, uncomprLen; { int err; z_stream d_stream; /* decompression stream */ strcpy((char*)uncompr, "garbage"); d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_in = compr; d_stream.avail_in = 2; /* just read the zlib header */ err = inflateInit(&d_stream); CHECK_ERR(err, "inflateInit"); d_stream.next_out = uncompr; d_stream.avail_out = (uInt)uncomprLen; inflate(&d_stream, Z_NO_FLUSH); CHECK_ERR(err, "inflate"); d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ err = inflateSync(&d_stream); /* but skip the damaged part */ CHECK_ERR(err, "inflateSync"); err = inflate(&d_stream, Z_FINISH); if (err != Z_DATA_ERROR) { fprintf(stderr, "inflate should report DATA_ERROR\n"); /* Because of incorrect adler32 */ exit(1); } err = inflateEnd(&d_stream); CHECK_ERR(err, "inflateEnd"); printf("after inflateSync(): hel%s\n", (char *)uncompr); } /* =========================================================================== * Test deflate() with preset dictionary */ void test_dict_deflate(compr, comprLen) Byte *compr; uLong comprLen; { z_stream c_stream; /* compression stream */ int err; c_stream.zalloc = (alloc_func)0; c_stream.zfree = (free_func)0; c_stream.opaque = (voidpf)0; err = deflateInit(&c_stream, Z_BEST_COMPRESSION); CHECK_ERR(err, "deflateInit"); err = deflateSetDictionary(&c_stream, (const Bytef*)dictionary, sizeof(dictionary)); CHECK_ERR(err, "deflateSetDictionary"); dictId = c_stream.adler; c_stream.next_out = compr; c_stream.avail_out = (uInt)comprLen; c_stream.next_in = (Bytef*)hello; c_stream.avail_in = (uInt)strlen(hello)+1; err = deflate(&c_stream, Z_FINISH); if (err != Z_STREAM_END) { fprintf(stderr, "deflate should report Z_STREAM_END\n"); exit(1); } err = deflateEnd(&c_stream); CHECK_ERR(err, "deflateEnd"); } /* =========================================================================== * Test inflate() with a preset dictionary */ void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) Byte *compr, *uncompr; uLong comprLen, uncomprLen; { int err; z_stream d_stream; /* decompression stream */ strcpy((char*)uncompr, "garbage"); d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_in = compr; d_stream.avail_in = (uInt)comprLen; err = inflateInit(&d_stream); CHECK_ERR(err, "inflateInit"); d_stream.next_out = uncompr; d_stream.avail_out = (uInt)uncomprLen; for (;;) { err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END) break; if (err == Z_NEED_DICT) { if (d_stream.adler != dictId) { fprintf(stderr, "unexpected dictionary"); exit(1); } err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, sizeof(dictionary)); } CHECK_ERR(err, "inflate with dict"); } err = inflateEnd(&d_stream); CHECK_ERR(err, "inflateEnd"); if (strcmp((char*)uncompr, hello)) { fprintf(stderr, "bad inflate with dict\n"); exit(1); } else { printf("inflate with dictionary: %s\n", (char *)uncompr); } } /* =========================================================================== * Usage: example [output.gz [input.gz]] */ int main(argc, argv) int argc; char *argv[]; { Byte *compr, *uncompr; uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ uLong uncomprLen = comprLen; static const char* myVersion = ZLIB_VERSION; if (zlibVersion()[0] != myVersion[0]) { fprintf(stderr, "incompatible zlib version\n"); exit(1); } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { fprintf(stderr, "warning: different zlib version\n"); } printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); compr = (Byte*)calloc((uInt)comprLen, 1); uncompr = (Byte*)calloc((uInt)uncomprLen, 1); /* compr and uncompr are cleared to avoid reading uninitialized * data and to ensure that uncompr compresses well. */ if (compr == Z_NULL || uncompr == Z_NULL) { printf("out of memory\n"); exit(1); } test_compress(compr, comprLen, uncompr, uncomprLen); test_gzio((argc > 1 ? argv[1] : TESTFILE), uncompr, uncomprLen); test_deflate(compr, comprLen); test_inflate(compr, comprLen, uncompr, uncomprLen); test_large_deflate(compr, comprLen, uncompr, uncomprLen); test_large_inflate(compr, comprLen, uncompr, uncomprLen); test_flush(compr, &comprLen); test_sync(compr, comprLen, uncompr, uncomprLen); comprLen = uncomprLen; test_dict_deflate(compr, comprLen); test_dict_inflate(compr, comprLen, uncompr, uncomprLen); free(compr); free(uncompr); return 0; } syslinux-legacy-3.63+dfsg/com32/lib/zlib/deflate.h0000664000175000017500000002722610777447272020432 0ustar evanevan/* deflate.h -- internal compression state * Copyright (C) 1995-2002 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ #ifndef DEFLATE_H #define DEFLATE_H #include "zutil.h" /* define NO_GZIP when compiling if you want to disable gzip header and trailer creation by deflate(). NO_GZIP would be used to avoid linking in the crc code when it is not needed. For shared libraries, gzip encoding should be left enabled. */ #ifndef NO_GZIP # define GZIP #endif /* =========================================================================== * Internal compression state. */ #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ #define LITERALS 256 /* number of literal bytes 0..255 */ #define L_CODES (LITERALS+1+LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ #define D_CODES 30 /* number of distance codes */ #define BL_CODES 19 /* number of codes used to transfer the bit lengths */ #define HEAP_SIZE (2*L_CODES+1) /* maximum heap size */ #define MAX_BITS 15 /* All codes must not exceed MAX_BITS bits */ #define INIT_STATE 42 #define BUSY_STATE 113 #define FINISH_STATE 666 /* Stream status */ /* Data structure describing a single value and its code string. */ typedef struct ct_data_s { union { ush freq; /* frequency count */ ush code; /* bit string */ } fc; union { ush dad; /* father node in Huffman tree */ ush len; /* length of bit string */ } dl; } FAR ct_data; #define Freq fc.freq #define Code fc.code #define Dad dl.dad #define Len dl.len typedef struct static_tree_desc_s static_tree_desc; typedef struct tree_desc_s { ct_data *dyn_tree; /* the dynamic tree */ int max_code; /* largest code with non zero frequency */ static_tree_desc *stat_desc; /* the corresponding static tree */ } FAR tree_desc; typedef ush Pos; typedef Pos FAR Posf; typedef unsigned IPos; /* A Pos is an index in the character window. We use short instead of int to * save space in the various tables. IPos is used only for parameter passing. */ typedef struct internal_state { z_streamp strm; /* pointer back to this zlib stream */ int status; /* as the name implies */ Bytef *pending_buf; /* output still pending */ ulg pending_buf_size; /* size of pending_buf */ Bytef *pending_out; /* next pending byte to output to the stream */ int pending; /* nb of bytes in the pending buffer */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ Byte data_type; /* UNKNOWN, BINARY or ASCII */ Byte method; /* STORED (for zip only) or DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ /* used by deflate.c: */ uInt w_size; /* LZ77 window size (32K by default) */ uInt w_bits; /* log2(w_size) (8..16) */ uInt w_mask; /* w_size - 1 */ Bytef *window; /* Sliding window. Input bytes are read into the second half of the window, * and move to the first half later to keep a dictionary of at least wSize * bytes. With this organization, matches are limited to a distance of * wSize-MAX_MATCH bytes, but this ensures that IO is always * performed with a length multiple of the block size. Also, it limits * the window size to 64K, which is quite useful on MSDOS. * To do: use the user input buffer as sliding window. */ ulg window_size; /* Actual size of window: 2*wSize, except when the user input buffer * is directly used as sliding window. */ Posf *prev; /* Link to older string with same hash index. To limit the size of this * array to 64K, this link is maintained only for the last 32K strings. * An index in this array is thus a window index modulo 32K. */ Posf *head; /* Heads of the hash chains or NIL. */ uInt ins_h; /* hash index of string to be inserted */ uInt hash_size; /* number of elements in hash table */ uInt hash_bits; /* log2(hash_size) */ uInt hash_mask; /* hash_size-1 */ uInt hash_shift; /* Number of bits by which ins_h must be shifted at each input * step. It must be such that after MIN_MATCH steps, the oldest * byte no longer takes part in the hash key, that is: * hash_shift * MIN_MATCH >= hash_bits */ long block_start; /* Window position at the beginning of the current output block. Gets * negative when the window is moved backwards. */ uInt match_length; /* length of best match */ IPos prev_match; /* previous match */ int match_available; /* set if previous match exists */ uInt strstart; /* start of string to insert */ uInt match_start; /* start of matching string */ uInt lookahead; /* number of valid bytes ahead in window */ uInt prev_length; /* Length of the best match at previous step. Matches not greater than this * are discarded. This is used in the lazy match evaluation. */ uInt max_chain_length; /* To speed up deflation, hash chains are never searched beyond this * length. A higher limit improves compression ratio but degrades the * speed. */ uInt max_lazy_match; /* Attempt to find a better match only when the current match is strictly * smaller than this value. This mechanism is used only for compression * levels >= 4. */ # define max_insert_length max_lazy_match /* Insert new strings in the hash table only if the match length is not * greater than this length. This saves time but degrades compression. * max_insert_length is used only for compression levels <= 3. */ int level; /* compression level (1..9) */ int strategy; /* favor or force Huffman coding*/ uInt good_match; /* Use a faster search when the previous match is longer than this */ int nice_match; /* Stop searching when current match exceeds this */ /* used by trees.c: */ /* Didn't use ct_data typedef below to supress compiler warning */ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ struct tree_desc_s l_desc; /* desc. for literal tree */ struct tree_desc_s d_desc; /* desc. for distance tree */ struct tree_desc_s bl_desc; /* desc. for bit length tree */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ int heap_len; /* number of elements in the heap */ int heap_max; /* element of largest frequency */ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. * The same heap array is used to build all trees. */ uch depth[2*L_CODES+1]; /* Depth of each subtree used as tie breaker for trees of equal frequency */ uchf *l_buf; /* buffer for literals or lengths */ uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for * limiting lit_bufsize to 64K: * - frequencies can be kept in 16 bit counters * - if compression is not successful for the first block, all input * data is still in the window so we can still emit a stored block even * when input comes from standard input. (This can also be done for * all blocks if lit_bufsize is not greater than 32K.) * - if compression is not successful for a file smaller than 64K, we can * even emit a stored file instead of a stored block (saving 5 bytes). * This is applicable only for zip (not gzip or zlib). * - creating new Huffman trees less frequently may not provide fast * adaptation to changes in the input data statistics. (Take for * example a binary file with poorly compressible code followed by * a highly compressible string table.) Smaller buffer sizes give * fast adaptation but have of course the overhead of transmitting * trees more frequently. * - I can't count above 4 */ uInt last_lit; /* running index in l_buf */ ushf *d_buf; /* Buffer for distances. To simplify the code, d_buf and l_buf have * the same number of elements. To use different lengths, an extra flag * array would be necessary. */ ulg opt_len; /* bit length of current block with optimal trees */ ulg static_len; /* bit length of current block with static trees */ uInt matches; /* number of string matches in current block */ int last_eob_len; /* bit length of EOB code for last block */ #ifdef DEBUG ulg compressed_len; /* total bit length of compressed file mod 2^32 */ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ #endif ush bi_buf; /* Output buffer. bits are inserted starting at the bottom (least * significant bits). */ int bi_valid; /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ } FAR deflate_state; /* Output a byte on the stream. * IN assertion: there is enough room in pending_buf. */ #define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) /* In order to simplify the code, particularly on 16 bit machines, match * distances are limited to MAX_DIST instead of WSIZE. */ /* in trees.c */ void _tr_init OF((deflate_state *s)); int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof)); void _tr_align OF((deflate_state *s)); void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof)); #define d_code(dist) \ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. _dist_code[256] and _dist_code[257] are never * used. */ #ifndef DEBUG /* Inline versions of _tr_tally for speed: */ #if defined(GEN_TREES_H) || !defined(STDC) extern uch _length_code[]; extern uch _dist_code[]; #else extern const uch _length_code[]; extern const uch _dist_code[]; #endif # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->d_buf[s->last_lit] = 0; \ s->l_buf[s->last_lit++] = cc; \ s->dyn_ltree[cc].Freq++; \ flush = (s->last_lit == s->lit_bufsize-1); \ } # define _tr_tally_dist(s, distance, length, flush) \ { uch len = (length); \ ush dist = (distance); \ s->d_buf[s->last_lit] = dist; \ s->l_buf[s->last_lit++] = len; \ dist--; \ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->last_lit == s->lit_bufsize-1); \ } #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ flush = _tr_tally(s, distance, length) #endif #endif /* DEFLATE_H */ syslinux-legacy-3.63+dfsg/com32/lib/zlib/inftrees.h0000664000175000017500000000450510777447272020640 0ustar evanevan/* inftrees.h -- header to use inftrees.c * Copyright (C) 1995-2003 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* Structure for decoding tables. Each entry provides either the information needed to do the operation requested by the code that indexed that table entry, or it provides a pointer to another table that indexes more bits of the code. op indicates whether the entry is a pointer to another table, a literal, a length or distance, an end-of-block, or an invalid code. For a table pointer, the low four bits of op is the number of index bits of that table. For a length or distance, the low four bits of op is the number of extra bits to get after the code. bits is the number of bits in this code or part of the code to drop off of the bit buffer. val is the actual byte to output in the case of a literal, the base length or distance, or the offset from the current table to the next table. Each entry is four bytes. */ typedef struct { unsigned char op; /* operation, extra bits, table bits */ unsigned char bits; /* bits in this part of the code */ unsigned short val; /* offset in table or code value */ } code; /* op values as set by inflate_table(): 00000000 - literal 0000tttt - table link, tttt != 0 is the number of table index bits 0001eeee - length or distance, eeee is the number of extra bits 01100000 - end of block 01000000 - invalid code */ /* Maximum size of dynamic tree. The maximum found in a long but non- exhaustive search was 1004 code structures (850 for length/literals and 154 for distances, the latter actually the result of an exhaustive search). The true maximum is not known, but the value below is more than safe. */ #define ENOUGH 1440 #define MAXD 154 /* Type of code to build for inftable() */ typedef enum { CODES, LENS, DISTS } codetype; extern int inflate_table OF((codetype type, unsigned short FAR *lens, unsigned codes, code FAR * FAR *table, unsigned FAR *bits, unsigned short FAR *work)); syslinux-legacy-3.63+dfsg/com32/lib/zlib/inffixed.h0000664000175000017500000001430710777447272020616 0ustar evanevan /* inffixed.h -- table for decoding fixed codes * Generated automatically by makefixed(). */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ static const code lenfix[512] = { {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, {0,9,255} }; static const code distfix[32] = { {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, {22,5,193},{64,5,0} }; syslinux-legacy-3.63+dfsg/com32/lib/zlib/inflate.h0000664000175000017500000001325210777447272020442 0ustar evanevan/* inflate.h -- internal inflate state definition * Copyright (C) 1995-2003 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* define NO_GZIP when compiling if you want to disable gzip header and trailer decoding by inflate(). NO_GZIP would be used to avoid linking in the crc code when it is not needed. For shared libraries, gzip decoding should be left enabled. */ #ifndef NO_GZIP # define GUNZIP #endif /* Possible inflate modes between inflate() calls */ typedef enum { HEAD, /* i: waiting for magic header */ #ifdef GUNZIP FLAGS, /* i: waiting for method and flags (gzip) */ TIME, /* i: waiting for modification time (gzip) */ OS, /* i: waiting for extra flags and operating system (gzip) */ EXLEN, /* i: waiting for extra length (gzip) */ EXTRA, /* i: waiting for extra bytes (gzip) */ NAME, /* i: waiting for end of file name (gzip) */ COMMENT, /* i: waiting for end of comment (gzip) */ HCRC, /* i: waiting for header crc (gzip) */ #endif DICTID, /* i: waiting for dictionary check value */ DICT, /* waiting for inflateSetDictionary() call */ TYPE, /* i: waiting for type bits, including last-flag bit */ TYPEDO, /* i: same, but skip check to exit inflate on new block */ STORED, /* i: waiting for stored size (length and complement) */ COPY, /* i/o: waiting for input or output to copy stored block */ TABLE, /* i: waiting for dynamic block table lengths */ LENLENS, /* i: waiting for code length code lengths */ CODELENS, /* i: waiting for length/lit and distance code lengths */ LEN, /* i: waiting for length/lit code */ LENEXT, /* i: waiting for length extra bits */ DIST, /* i: waiting for distance code */ DISTEXT, /* i: waiting for distance extra bits */ MATCH, /* o: waiting for output space to copy string */ LIT, /* o: waiting for output space to write literal */ CHECK, /* i: waiting for 32-bit check value */ #ifdef GUNZIP LENGTH, /* i: waiting for 32-bit length (gzip) */ #endif DONE, /* finished check, done -- remain here until reset */ BAD, /* got a data error -- remain here until reset */ MEM, /* got an inflate() memory error -- remain here until reset */ SYNC /* looking for synchronization bytes to restart inflate() */ } inflate_mode; /* State transitions between above modes - (most modes can go to the BAD or MEM mode -- not shown for clarity) Process header: HEAD -> (gzip) or (zlib) (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME NAME -> COMMENT -> HCRC -> TYPE (zlib) -> DICTID or TYPE DICTID -> DICT -> TYPE Read deflate blocks: TYPE -> STORED or TABLE or LEN or CHECK STORED -> COPY -> TYPE TABLE -> LENLENS -> CODELENS -> LEN Read deflate codes: LEN -> LENEXT or LIT or TYPE LENEXT -> DIST -> DISTEXT -> MATCH -> LEN LIT -> LEN Process trailer: CHECK -> LENGTH -> DONE */ /* state maintained between inflate() calls. Approximately 7K bytes. */ struct inflate_state { inflate_mode mode; /* current inflate mode */ int last; /* true if processing last block */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ int havedict; /* true if dictionary provided */ int flags; /* gzip header method and flags (0 if zlib) */ unsigned long check; /* protected copy of check value */ unsigned long total; /* protected copy of output count */ /* sliding window */ unsigned wbits; /* log base 2 of requested window size */ unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned write; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if needed */ /* bit accumulator */ unsigned long hold; /* input bit accumulator */ unsigned bits; /* number of bits in "in" */ /* for string and stored block copying */ unsigned length; /* literal or length of data to copy */ unsigned offset; /* distance back to copy string from */ /* for table and code decoding */ unsigned extra; /* extra bits needed */ /* fixed and dynamic code tables */ code const FAR *lencode; /* starting table for length/literal codes */ code const FAR *distcode; /* starting table for distance codes */ unsigned lenbits; /* index bits for lencode */ unsigned distbits; /* index bits for distcode */ /* dynamic table building */ unsigned ncode; /* number of code length code lengths */ unsigned nlen; /* number of length code lengths */ unsigned ndist; /* number of distance code lengths */ unsigned have; /* number of code lengths in lens[] */ code FAR *next; /* next available space in codes[] */ unsigned short lens[320]; /* temporary storage for code lengths */ unsigned short work[288]; /* work area for code table building */ code codes[ENOUGH]; /* space for code tables */ }; syslinux-legacy-3.63+dfsg/com32/lib/zlib/infback.c0000664000175000017500000005302610777447272020413 0ustar evanevan/* infback.c -- inflate using a call-back interface * Copyright (C) 1995-2003 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* This code is largely copied from inflate.c. Normally either infback.o or inflate.o would be linked into an application--not both. The interface with inffast.c is retained so that optimized assembler-coded versions of inflate_fast() can be used with either inflate.c or infback.c. */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" /* function prototypes */ local void fixedtables OF((struct inflate_state FAR *state)); /* strm provides memory allocation functions in zalloc and zfree, or Z_NULL to use the library memory allocation functions. windowBits is in the range 8..15, and window is a user-supplied window and output buffer that is 2**windowBits bytes. */ int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) z_stream FAR *strm; int windowBits; unsigned char FAR *window; const char *version; int stream_size; { struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) return Z_VERSION_ERROR; if (strm == Z_NULL || window == Z_NULL || windowBits < 8 || windowBits > 15) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { strm->zalloc = zcalloc; strm->opaque = (voidpf)0; } if (strm->zfree == (free_func)0) strm->zfree = zcfree; state = (struct inflate_state FAR *)ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (voidpf)state; state->wbits = windowBits; state->wsize = 1U << windowBits; state->window = window; state->write = 0; state->whave = 0; return Z_OK; } /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. If BUILDFIXED is defined, then instead this routine builds the tables the first time it's called, and returns those tables the first time and thereafter. This reduces the size of the code by about 2K bytes, in exchange for a little execution time. However, BUILDFIXED should not be used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ local void fixedtables(state) struct inflate_state FAR *state; { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; static code fixed[544]; /* build fixed huffman tables if first call (may not be thread safe) */ if (virgin) { unsigned sym, bits; static code *next; /* literal/length table */ sym = 0; while (sym < 144) state->lens[sym++] = 8; while (sym < 256) state->lens[sym++] = 9; while (sym < 280) state->lens[sym++] = 7; while (sym < 288) state->lens[sym++] = 8; next = fixed; lenfix = next; bits = 9; inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); /* distance table */ sym = 0; while (sym < 32) state->lens[sym++] = 5; distfix = next; bits = 5; inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); /* do this just once */ virgin = 0; } #else /* !BUILDFIXED */ # include "inffixed.h" #endif /* BUILDFIXED */ state->lencode = lenfix; state->lenbits = 9; state->distcode = distfix; state->distbits = 5; } /* Macros for inflateBack(): */ /* Load returned state from inflate_fast() */ #define LOAD() \ do { \ put = strm->next_out; \ left = strm->avail_out; \ next = strm->next_in; \ have = strm->avail_in; \ hold = state->hold; \ bits = state->bits; \ } while (0) /* Set state from registers for inflate_fast() */ #define RESTORE() \ do { \ strm->next_out = put; \ strm->avail_out = left; \ strm->next_in = next; \ strm->avail_in = have; \ state->hold = hold; \ state->bits = bits; \ } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ do { \ hold = 0; \ bits = 0; \ } while (0) /* Assure that some input is available. If input is requested, but denied, then return a Z_BUF_ERROR from inflateBack(). */ #define PULL() \ do { \ if (have == 0) { \ have = in(in_desc, &next); \ if (have == 0) { \ next = Z_NULL; \ ret = Z_BUF_ERROR; \ goto inf_leave; \ } \ } \ } while (0) /* Get a byte of input into the bit accumulator, or return from inflateBack() with an error if there is no input available. */ #define PULLBYTE() \ do { \ PULL(); \ have--; \ hold += (unsigned long)(*next++) << bits; \ bits += 8; \ } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflateBack() with an error. */ #define NEEDBITS(n) \ do { \ while (bits < (unsigned)(n)) \ PULLBYTE(); \ } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ ((unsigned)hold & ((1U << (n)) - 1)) /* Remove n bits from the bit accumulator */ #define DROPBITS(n) \ do { \ hold >>= (n); \ bits -= (unsigned)(n); \ } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ #define BYTEBITS() \ do { \ hold >>= bits & 7; \ bits -= bits & 7; \ } while (0) /* Assure that some output space is available, by writing out the window if it's full. If the write fails, return from inflateBack() with a Z_BUF_ERROR. */ #define ROOM() \ do { \ if (left == 0) { \ put = state->window; \ left = state->wsize; \ state->whave = left; \ if (out(out_desc, put, left)) { \ ret = Z_BUF_ERROR; \ goto inf_leave; \ } \ } \ } while (0) /* strm provides the memory allocation functions and window buffer on input, and provides information on the unused input on return. For Z_DATA_ERROR returns, strm will also provide an error message. in() and out() are the call-back input and output functions. When inflateBack() needs more input, it calls in(). When inflateBack() has filled the window with output, or when it completes with data in the window, it calls out() to write out the data. The application must not change the provided input until in() is called again or inflateBack() returns. The application must not change the window/output buffer until inflateBack() returns. in() and out() are called with a descriptor parameter provided in the inflateBack() call. This parameter can be a structure that provides the information required to do the read or write, as well as accumulated information on the input and output such as totals and check values. in() should return zero on failure. out() should return non-zero on failure. If either in() or out() fails, than inflateBack() returns a Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it was in() or out() that caused in the error. Otherwise, inflateBack() returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format error, or Z_MEM_ERROR if it could not allocate memory for the state. inflateBack() can also return Z_STREAM_ERROR if the input parameters are not correct, i.e. strm is Z_NULL or the state was not initialized. */ int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) z_stream FAR *strm; in_func in; void FAR *in_desc; out_func out; void FAR *out_desc; { struct inflate_state FAR *state; unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ code this; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* Check that the strm exists and that the state was initialized */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* Reset the state */ strm->msg = Z_NULL; state->mode = TYPE; state->last = 0; state->whave = 0; next = strm->next_in; have = next != Z_NULL ? strm->avail_in : 0; hold = 0; bits = 0; put = state->window; left = state->wsize; /* Inflate until end of block marked as last */ for (;;) switch (state->mode) { case TYPE: /* determine and dispatch block type */ if (state->last) { BYTEBITS(); state->mode = DONE; break; } NEEDBITS(3); state->last = BITS(1); DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN; /* decode codes */ break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; case 3: strm->msg = (char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); break; case STORED: /* get and verify stored block length */ BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { strm->msg = (char *)"invalid stored block lengths"; state->mode = BAD; break; } state->length = (unsigned)hold & 0xffff; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); /* copy stored block from input to output */ while (state->length != 0) { copy = state->length; PULL(); ROOM(); if (copy > have) copy = have; if (copy > left) copy = left; zmemcpy(put, next, copy); have -= copy; next += copy; left -= copy; put += copy; state->length -= copy; } Tracev((stderr, "inflate: stored end\n")); state->mode = TYPE; break; case TABLE: /* get dynamic table entries descriptor */ NEEDBITS(14); state->nlen = BITS(5) + 257; DROPBITS(5); state->ndist = BITS(5) + 1; DROPBITS(5); state->ncode = BITS(4) + 4; DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { strm->msg = (char *)"too many length or distance symbols"; state->mode = BAD; break; } #endif Tracev((stderr, "inflate: table sizes ok\n")); /* get code length code lengths (not a typo) */ state->have = 0; while (state->have < state->ncode) { NEEDBITS(3); state->lens[order[state->have++]] = (unsigned short)BITS(3); DROPBITS(3); } while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid code lengths set"; state->mode = BAD; break; } Tracev((stderr, "inflate: code lengths ok\n")); /* get length and distance code code lengths */ state->have = 0; while (state->have < state->nlen + state->ndist) { for (;;) { this = state->lencode[BITS(state->lenbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if (this.val < 16) { NEEDBITS(this.bits); DROPBITS(this.bits); state->lens[state->have++] = this.val; } else { if (this.val == 16) { NEEDBITS(this.bits + 2); DROPBITS(this.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } len = (unsigned)(state->lens[state->have - 1]); copy = 3 + BITS(2); DROPBITS(2); } else if (this.val == 17) { NEEDBITS(this.bits + 3); DROPBITS(this.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { NEEDBITS(this.bits + 7); DROPBITS(this.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } while (copy--) state->lens[state->have++] = (unsigned short)len; } } /* build code tables */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid literal/lengths set"; state->mode = BAD; break; } state->distcode = (code const FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { strm->msg = (char *)"invalid distances set"; state->mode = BAD; break; } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN; case LEN: /* use inflate_fast() if we have enough input and output */ if (have >= 6 && left >= 258) { RESTORE(); if (state->whave < state->wsize) state->whave = state->wsize - left; inflate_fast(strm, state->wsize); LOAD(); break; } /* get a literal, length, or end-of-block code */ for (;;) { this = state->lencode[BITS(state->lenbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if (this.op && (this.op & 0xf0) == 0) { last = this; for (;;) { this = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + this.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(this.bits); state->length = (unsigned)this.val; /* process literal */ if (this.op == 0) { Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", this.val)); ROOM(); *put++ = (unsigned char)(state->length); left--; state->mode = LEN; break; } /* process end of block */ if (this.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } /* invalid code */ if (this.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } /* length code -- get extra bits, if any */ state->extra = (unsigned)(this.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); } Tracevv((stderr, "inflate: length %u\n", state->length)); /* get distance code */ for (;;) { this = state->distcode[BITS(state->distbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if ((this.op & 0xf0) == 0) { last = this; for (;;) { this = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + this.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(this.bits); if (this.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } state->offset = (unsigned)this.val; /* get distance extra bits, if any */ state->extra = (unsigned)(this.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); } if (state->offset > state->wsize - (state->whave < state->wsize ? left : 0)) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } Tracevv((stderr, "inflate: distance %u\n", state->offset)); /* copy match from window to output */ do { ROOM(); copy = state->wsize - state->offset; if (copy < left) { from = put + copy; copy = left - copy; } else { from = put - state->offset; copy = left; } if (copy > state->length) copy = state->length; state->length -= copy; left -= copy; do { *put++ = *from++; } while (--copy); } while (state->length != 0); break; case DONE: /* inflate stream terminated properly -- write leftover output */ ret = Z_STREAM_END; if (left < state->wsize) { if (out(out_desc, state->window, state->wsize - left)) ret = Z_BUF_ERROR; } goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; default: /* can't happen, but makes compilers happy */ ret = Z_STREAM_ERROR; goto inf_leave; } /* Return unused input */ inf_leave: strm->next_in = next; strm->avail_in = have; return ret; } int ZEXPORT inflateBackEnd(strm) z_stream FAR *strm; { if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; ZFREE(strm, strm->state); strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; } syslinux-legacy-3.63+dfsg/com32/lib/zlib/crc32.c0000664000175000017500000002275310777447272017735 0ustar evanevan/* crc32.c -- compute the CRC-32 of a data stream * Copyright (C) 1995-2003 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h * * Thanks to Rodney Brown for his contribution of faster * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing * tables for updating the shift register in one step with three exclusive-ors * instead of four steps with four exclusive-ors. This results about a factor * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. */ #ifdef MAKECRCH # include # ifndef DYNAMIC_CRC_TABLE # define DYNAMIC_CRC_TABLE # endif /* !DYNAMIC_CRC_TABLE */ #endif /* MAKECRCH */ #include "zutil.h" /* for STDC and FAR definitions */ #define local static /* Find a four-byte integer type for crc32_little() and crc32_big(). */ #ifndef NOBYFOUR # ifdef STDC /* need ANSI C limits.h to determine sizes */ # include # define BYFOUR # if (UINT_MAX == 0xffffffffUL) typedef unsigned int u4; # else # if (ULONG_MAX == 0xffffffffUL) typedef unsigned long u4; # else # if (USHRT_MAX == 0xffffffffUL) typedef unsigned short u4; # else # undef BYFOUR /* can't find a four-byte integer type! */ # endif # endif # endif # endif /* STDC */ #endif /* !NOBYFOUR */ /* Definitions for doing the crc four data bytes at a time. */ #ifdef BYFOUR # define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ (((w)&0xff00)<<8)+(((w)&0xff)<<24)) local unsigned long crc32_little OF((unsigned long, const unsigned char FAR *, unsigned)); local unsigned long crc32_big OF((unsigned long, const unsigned char FAR *, unsigned)); # define TBLS 8 #else # define TBLS 1 #endif /* BYFOUR */ #ifdef DYNAMIC_CRC_TABLE local int crc_table_empty = 1; local unsigned long FAR crc_table[TBLS][256]; local void make_crc_table OF((void)); #ifdef MAKECRCH local void write_table OF((FILE *, const unsigned long FAR *)); #endif /* MAKECRCH */ /* Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. Polynomials over GF(2) are represented in binary, one bit per coefficient, with the lowest powers in the most significant bit. Then adding polynomials is just exclusive-or, and multiplying a polynomial by x is a right shift by one. If we call the above polynomial p, and represent a byte as the polynomial q, also with the lowest power in the most significant bit (so the byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, where a mod b means the remainder after dividing a by b. This calculation is done using the shift-register method of multiplying and taking the remainder. The register is initialized to zero, and for each incoming bit, x^32 is added mod p to the register if the bit is a one (where x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x (which is shifting right by one and adding x^32 mod p if the bit shifted out is a one). We start with the highest power (least significant bit) of q and repeat for all eight bits of q. The first table is simply the CRC of all possible eight bit values. This is all the information needed to generate CRCs on data a byte at a time for all combinations of CRC register values and incoming bytes. The remaining tables allow for word-at-a-time CRC calculation for both big-endian and little- endian machines, where a word is four bytes. */ local void make_crc_table() { unsigned long c; int n, k; unsigned long poly; /* polynomial exclusive-or pattern */ /* terms of polynomial defining this crc (except x^32): */ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; /* make exclusive-or pattern from polynomial (0xedb88320UL) */ poly = 0UL; for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) poly |= 1UL << (31 - p[n]); /* generate a crc for every 8-bit value */ for (n = 0; n < 256; n++) { c = (unsigned long)n; for (k = 0; k < 8; k++) c = c & 1 ? poly ^ (c >> 1) : c >> 1; crc_table[0][n] = c; } #ifdef BYFOUR /* generate crc for each value followed by one, two, and three zeros, and then the byte reversal of those as well as the first table */ for (n = 0; n < 256; n++) { c = crc_table[0][n]; crc_table[4][n] = REV(c); for (k = 1; k < 4; k++) { c = crc_table[0][c & 0xff] ^ (c >> 8); crc_table[k][n] = c; crc_table[k + 4][n] = REV(c); } } #endif /* BYFOUR */ crc_table_empty = 0; #ifdef MAKECRCH /* write out CRC tables to crc32.h */ { FILE *out; out = fopen("crc32.h", "w"); if (out == NULL) return; fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); fprintf(out, "local const unsigned long FAR "); fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); write_table(out, crc_table[0]); # ifdef BYFOUR fprintf(out, "#ifdef BYFOUR\n"); for (k = 1; k < 8; k++) { fprintf(out, " },\n {\n"); write_table(out, crc_table[k]); } fprintf(out, "#endif\n"); # endif /* BYFOUR */ fprintf(out, " }\n};\n"); fclose(out); } #endif /* MAKECRCH */ } #ifdef MAKECRCH local void write_table(out, table) FILE *out; const unsigned long FAR *table; { int n; for (n = 0; n < 256; n++) fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); } #endif /* MAKECRCH */ #else /* !DYNAMIC_CRC_TABLE */ /* ======================================================================== * Tables of CRC-32s of all single-byte values, made by make_crc_table(). */ #include "crc32.h" #endif /* DYNAMIC_CRC_TABLE */ /* ========================================================================= * This function can be used by asm versions of crc32() */ const unsigned long FAR * ZEXPORT get_crc_table() { #ifdef DYNAMIC_CRC_TABLE if (crc_table_empty) make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ return (const unsigned long FAR *)crc_table; } /* ========================================================================= */ #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 /* ========================================================================= */ unsigned long ZEXPORT crc32(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { if (buf == Z_NULL) return 0UL; #ifdef DYNAMIC_CRC_TABLE if (crc_table_empty) make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ #ifdef BYFOUR if (sizeof(void *) == sizeof(ptrdiff_t)) { u4 endian; endian = 1; if (*((unsigned char *)(&endian))) return crc32_little(crc, buf, len); else return crc32_big(crc, buf, len); } #endif /* BYFOUR */ crc = crc ^ 0xffffffffUL; while (len >= 8) { DO8; len -= 8; } if (len) do { DO1; } while (--len); return crc ^ 0xffffffffUL; } #ifdef BYFOUR /* ========================================================================= */ #define DOLIT4 c ^= *buf4++; \ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 /* ========================================================================= */ local unsigned long crc32_little(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { register u4 c; register const u4 FAR *buf4; c = (u4)crc; c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); len--; } buf4 = (const u4 FAR *)buf; while (len >= 32) { DOLIT32; len -= 32; } while (len >= 4) { DOLIT4; len -= 4; } buf = (const unsigned char FAR *)buf4; if (len) do { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); } while (--len); c = ~c; return (unsigned long)c; } /* ========================================================================= */ #define DOBIG4 c ^= *++buf4; \ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 /* ========================================================================= */ local unsigned long crc32_big(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { register u4 c; register const u4 FAR *buf4; c = REV((u4)crc); c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); len--; } buf4 = (const u4 FAR *)buf; buf4--; while (len >= 32) { DOBIG32; len -= 32; } while (len >= 4) { DOBIG4; len -= 4; } buf4++; buf = (const unsigned char FAR *)buf4; if (len) do { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); } while (--len); c = ~c; return (unsigned long)(REV(c)); } #endif /* BYFOUR */ syslinux-legacy-3.63+dfsg/com32/lib/zlib/compress.c0000664000175000017500000000465110777447272020651 0ustar evanevan/* compress.c -- compress a memory buffer * Copyright (C) 1995-2002 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ #define ZLIB_INTERNAL #include "zlib.h" /* =========================================================================== Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least 0.1% larger than sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) Bytef *dest; uLongf *destLen; const Bytef *source; uLong sourceLen; int level; { z_stream stream; int err; stream.next_in = (Bytef*)source; stream.avail_in = (uInt)sourceLen; #ifdef MAXSEG_64K /* Check for source > 64K on 16-bit machine: */ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; #endif stream.next_out = dest; stream.avail_out = (uInt)*destLen; if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; stream.opaque = (voidpf)0; err = deflateInit(&stream, level); if (err != Z_OK) return err; err = deflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { deflateEnd(&stream); return err == Z_OK ? Z_BUF_ERROR : err; } *destLen = stream.total_out; err = deflateEnd(&stream); return err; } /* =========================================================================== */ int ZEXPORT compress (dest, destLen, source, sourceLen) Bytef *dest; uLongf *destLen; const Bytef *source; uLong sourceLen; { return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); } /* =========================================================================== If the default memLevel or windowBits for deflateInit() is changed, then this function needs to be updated. */ uLong ZEXPORT compressBound (sourceLen) uLong sourceLen; { return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; } syslinux-legacy-3.63+dfsg/com32/lib/zlib/trees.c0000664000175000017500000012577110777447272020147 0ustar evanevan/* trees.c -- output deflated data using Huffman coding * Copyright (C) 1995-2003 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process uses several Huffman trees. The more * common source values are represented by shorter bit sequences. * * Each code tree is stored in a compressed form which is itself * a Huffman encoding of the lengths of all the code strings (in * ascending order by source values). The actual code strings are * reconstructed from the lengths in the inflate process, as described * in the deflate specification. * * REFERENCES * * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc * * Storer, James A. * Data Compression: Methods and Theory, pp. 49-50. * Computer Science Press, 1988. ISBN 0-7167-8156-5. * * Sedgewick, R. * Algorithms, p290. * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ /* #define GEN_TREES_H */ #include "deflate.h" #ifdef DEBUG # include #endif /* =========================================================================== * Constants */ #define MAX_BL_BITS 7 /* Bit length codes must not exceed MAX_BL_BITS bits */ #define END_BLOCK 256 /* end of block literal code */ #define REP_3_6 16 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ #define REPZ_3_10 17 /* repeat a zero length 3-10 times (3 bits of repeat count) */ #define REPZ_11_138 18 /* repeat a zero length 11-138 times (7 bits of repeat count) */ local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; local const int extra_dbits[D_CODES] /* extra bits for each distance code */ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; local const uch bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ #define Buf_size (8 * 2*sizeof(char)) /* Number of bits used within bi_buf. (bi_buf might be implemented on * more than 16 bits on some systems.) */ /* =========================================================================== * Local data. These are initialized only once. */ #define DIST_CODE_LEN 512 /* see definition of array dist_code below */ #if defined(GEN_TREES_H) || !defined(STDC) /* non ANSI compilers may not accept trees.h */ local ct_data static_ltree[L_CODES+2]; /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see _tr_init * below). */ local ct_data static_dtree[D_CODES]; /* The static distance tree. (Actually a trivial tree since all codes use * 5 bits.) */ uch _dist_code[DIST_CODE_LEN]; /* Distance codes. The first 256 values correspond to the distances * 3 .. 258, the last 256 values correspond to the top 8 bits of * the 15 bit distances. */ uch _length_code[MAX_MATCH-MIN_MATCH+1]; /* length code for each normalized match length (0 == MIN_MATCH) */ local int base_length[LENGTH_CODES]; /* First normalized length for each code (0 = MIN_MATCH) */ local int base_dist[D_CODES]; /* First normalized distance for each code (0 = distance of 1) */ #else # include "trees.h" #endif /* GEN_TREES_H */ struct static_tree_desc_s { const ct_data *static_tree; /* static tree or NULL */ const intf *extra_bits; /* extra bits for each code or NULL */ int extra_base; /* base index for extra_bits */ int elems; /* max number of elements in the tree */ int max_length; /* max bit length for the codes */ }; local static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; local static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; local static_tree_desc static_bl_desc = {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== * Local (static) routines in this file. */ local void tr_static_init OF((void)); local void init_block OF((deflate_state *s)); local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); local void build_tree OF((deflate_state *s, tree_desc *desc)); local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); local int build_bl_tree OF((deflate_state *s)); local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, int blcodes)); local void compress_block OF((deflate_state *s, ct_data *ltree, ct_data *dtree)); local void set_data_type OF((deflate_state *s)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((deflate_state *s)); local void bi_flush OF((deflate_state *s)); local void copy_block OF((deflate_state *s, charf *buf, unsigned len, int header)); #ifdef GEN_TREES_H local void gen_trees_header OF((void)); #endif #ifndef DEBUG # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ #else /* DEBUG */ # define send_code(s, c, tree) \ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ send_bits(s, tree[c].Code, tree[c].Len); } #endif /* =========================================================================== * Output a short LSB first on the stream. * IN assertion: there is enough room in pendingBuf. */ #define put_short(s, w) { \ put_byte(s, (uch)((w) & 0xff)); \ put_byte(s, (uch)((ush)(w) >> 8)); \ } /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ #ifdef DEBUG local void send_bits OF((deflate_state *s, int value, int length)); local void send_bits(s, value, length) deflate_state *s; int value; /* value to send */ int length; /* number of bits */ { Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (ulg)length; /* If not enough room in bi_buf, use (valid) bits from bi_buf and * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) * unused bits in value. */ if (s->bi_valid > (int)Buf_size - length) { s->bi_buf |= (value << s->bi_valid); put_short(s, s->bi_buf); s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); s->bi_valid += length - Buf_size; } else { s->bi_buf |= value << s->bi_valid; s->bi_valid += length; } } #else /* !DEBUG */ #define send_bits(s, value, length) \ { int len = length;\ if (s->bi_valid > (int)Buf_size - len) {\ int val = value;\ s->bi_buf |= (val << s->bi_valid);\ put_short(s, s->bi_buf);\ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ s->bi_valid += len - Buf_size;\ } else {\ s->bi_buf |= (value) << s->bi_valid;\ s->bi_valid += len;\ }\ } #endif /* DEBUG */ /* the arguments must not have side effects */ /* =========================================================================== * Initialize the various 'constant' tables. */ local void tr_static_init() { #if defined(GEN_TREES_H) || !defined(STDC) static int static_init_done = 0; int n; /* iterates over tree elements */ int bits; /* bit counter */ int length; /* length value */ int code; /* code value */ int dist; /* distance index */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ if (static_init_done) return; /* For some embedded targets, global variables are not initialized: */ static_l_desc.static_tree = static_ltree; static_l_desc.extra_bits = extra_lbits; static_d_desc.static_tree = static_dtree; static_d_desc.extra_bits = extra_dbits; static_bl_desc.extra_bits = extra_blbits; /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; for (code = 0; code < LENGTH_CODES-1; code++) { base_length[code] = length; for (n = 0; n < (1< dist code (0..29) */ dist = 0; for (code = 0 ; code < 16; code++) { base_dist[code] = dist; for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ for ( ; code < D_CODES; code++) { base_dist[code] = dist << 7; for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { _dist_code[256 + dist++] = (uch)code; } } Assert (dist == 256, "tr_static_init: 256+dist != 512"); /* Construct the codes of the static literal tree */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; n = 0; while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; /* Codes 286 and 287 do not exist, but we must include them in the * tree construction to get a canonical Huffman tree (longest code * all ones) */ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); /* The static distance tree is trivial: */ for (n = 0; n < D_CODES; n++) { static_dtree[n].Len = 5; static_dtree[n].Code = bi_reverse((unsigned)n, 5); } static_init_done = 1; # ifdef GEN_TREES_H gen_trees_header(); # endif #endif /* defined(GEN_TREES_H) || !defined(STDC) */ } /* =========================================================================== * Genererate the file trees.h describing the static trees. */ #ifdef GEN_TREES_H # ifndef DEBUG # include # endif # define SEPARATOR(i, last, width) \ ((i) == (last)? "\n};\n\n" : \ ((i) % (width) == (width)-1 ? ",\n" : ", ")) void gen_trees_header() { FILE *header = fopen("trees.h", "w"); int i; Assert (header != NULL, "Can't open trees.h"); fprintf(header, "/* header created automatically with -DGEN_TREES_H */\n\n"); fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); for (i = 0; i < L_CODES+2; i++) { fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); } fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); for (i = 0; i < D_CODES; i++) { fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); } fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); for (i = 0; i < DIST_CODE_LEN; i++) { fprintf(header, "%2u%s", _dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); } fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { fprintf(header, "%2u%s", _length_code[i], SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); } fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); for (i = 0; i < LENGTH_CODES; i++) { fprintf(header, "%1u%s", base_length[i], SEPARATOR(i, LENGTH_CODES-1, 20)); } fprintf(header, "local const int base_dist[D_CODES] = {\n"); for (i = 0; i < D_CODES; i++) { fprintf(header, "%5u%s", base_dist[i], SEPARATOR(i, D_CODES-1, 10)); } fclose(header); } #endif /* GEN_TREES_H */ /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ void _tr_init(s) deflate_state *s; { tr_static_init(); s->l_desc.dyn_tree = s->dyn_ltree; s->l_desc.stat_desc = &static_l_desc; s->d_desc.dyn_tree = s->dyn_dtree; s->d_desc.stat_desc = &static_d_desc; s->bl_desc.dyn_tree = s->bl_tree; s->bl_desc.stat_desc = &static_bl_desc; s->bi_buf = 0; s->bi_valid = 0; s->last_eob_len = 8; /* enough lookahead for inflate */ #ifdef DEBUG s->compressed_len = 0L; s->bits_sent = 0L; #endif /* Initialize the first block of the first file: */ init_block(s); } /* =========================================================================== * Initialize a new block. */ local void init_block(s) deflate_state *s; { int n; /* iterates over tree elements */ /* Initialize the trees. */ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; s->dyn_ltree[END_BLOCK].Freq = 1; s->opt_len = s->static_len = 0L; s->last_lit = s->matches = 0; } #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ /* =========================================================================== * Remove the smallest element from the heap and recreate the heap with * one less element. Updates heap and heap_len. */ #define pqremove(s, tree, top) \ {\ top = s->heap[SMALLEST]; \ s->heap[SMALLEST] = s->heap[s->heap_len--]; \ pqdownheap(s, tree, SMALLEST); \ } /* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ #define smaller(tree, n, m, depth) \ (tree[n].Freq < tree[m].Freq || \ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) /* =========================================================================== * Restore the heap property by moving down the tree starting at node k, * exchanging a node with the smallest of its two sons if necessary, stopping * when the heap property is re-established (each father smaller than its * two sons). */ local void pqdownheap(s, tree, k) deflate_state *s; ct_data *tree; /* the tree to restore */ int k; /* node to move down */ { int v = s->heap[k]; int j = k << 1; /* left son of k */ while (j <= s->heap_len) { /* Set j to the smallest of the two sons: */ if (j < s->heap_len && smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { j++; } /* Exit if v is smaller than both sons */ if (smaller(tree, v, s->heap[j], s->depth)) break; /* Exchange v with the smallest son */ s->heap[k] = s->heap[j]; k = j; /* And continue down the tree, setting j to the left son of k */ j <<= 1; } s->heap[k] = v; } /* =========================================================================== * Compute the optimal bit lengths for a tree and update the total bit length * for the current block. * IN assertion: the fields freq and dad are set, heap[heap_max] and * above are the tree nodes sorted by increasing frequency. * OUT assertions: the field len is set to the optimal bit length, the * array bl_count contains the frequencies for each bit length. * The length opt_len is updated; static_len is also updated if stree is * not null. */ local void gen_bitlen(s, desc) deflate_state *s; tree_desc *desc; /* the tree descriptor */ { ct_data *tree = desc->dyn_tree; int max_code = desc->max_code; const ct_data *stree = desc->stat_desc->static_tree; const intf *extra = desc->stat_desc->extra_bits; int base = desc->stat_desc->extra_base; int max_length = desc->stat_desc->max_length; int h; /* heap index */ int n, m; /* iterate over the tree elements */ int bits; /* bit length */ int xbits; /* extra bits */ ush f; /* frequency */ int overflow = 0; /* number of elements with bit length too large */ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ for (h = s->heap_max+1; h < HEAP_SIZE; h++) { n = s->heap[h]; bits = tree[tree[n].Dad].Len + 1; if (bits > max_length) bits = max_length, overflow++; tree[n].Len = (ush)bits; /* We overwrite tree[n].Dad which is no longer needed */ if (n > max_code) continue; /* not a leaf node */ s->bl_count[bits]++; xbits = 0; if (n >= base) xbits = extra[n-base]; f = tree[n].Freq; s->opt_len += (ulg)f * (bits + xbits); if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); } if (overflow == 0) return; Trace((stderr,"\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ do { bits = max_length-1; while (s->bl_count[bits] == 0) bits--; s->bl_count[bits]--; /* move one leaf down the tree */ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ s->bl_count[max_length]--; /* The brother of the overflow item also moves one step up, * but this does not affect bl_count[max_length] */ overflow -= 2; } while (overflow > 0); /* Now recompute all bit lengths, scanning in increasing frequency. * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all * lengths instead of fixing only the wrong ones. This idea is taken * from 'ar' written by Haruhiko Okumura.) */ for (bits = max_length; bits != 0; bits--) { n = s->bl_count[bits]; while (n != 0) { m = s->heap[--h]; if (m > max_code) continue; if (tree[m].Len != (unsigned) bits) { Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); s->opt_len += ((long)bits - (long)tree[m].Len) *(long)tree[m].Freq; tree[m].Len = (ush)bits; } n--; } } } /* =========================================================================== * Generate the codes for a given tree and bit counts (which need not be * optimal). * IN assertion: the array bl_count contains the bit length statistics for * the given tree and the field len is set for all tree elements. * OUT assertion: the field code is set for all tree elements of non * zero code length. */ local void gen_codes (tree, max_code, bl_count) ct_data *tree; /* the tree to decorate */ int max_code; /* largest code with non zero frequency */ ushf *bl_count; /* number of codes at each bit length */ { ush next_code[MAX_BITS+1]; /* next code value for each bit length */ ush code = 0; /* running code value */ int bits; /* bit index */ int n; /* code index */ /* The distribution counts are first used to generate the code values * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { next_code[bits] = code = (code + bl_count[bits-1]) << 1; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. */ Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; const ct_data *stree = desc->stat_desc->static_tree; int elems = desc->stat_desc->elems; int n, m; /* iterate over heap elements */ int max_code = -1; /* largest code with non zero frequency */ int node; /* new node being created */ /* Construct the initial heap, with least frequent element in * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. * heap[0] is not used. */ s->heap_len = 0, s->heap_max = HEAP_SIZE; for (n = 0; n < elems; n++) { if (tree[n].Freq != 0) { s->heap[++(s->heap_len)] = max_code = n; s->depth[n] = 0; } else { tree[n].Len = 0; } } /* The pkzip format requires that at least one distance code exists, * and that at least one bit should be sent even if there is only one * possible code. So to avoid special checks later on we force at least * two codes of non zero frequency. */ while (s->heap_len < 2) { node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); tree[node].Freq = 1; s->depth[node] = 0; s->opt_len--; if (stree) s->static_len -= stree[node].Len; /* node is 0 or 1 so it does not have extra bits */ } desc->max_code = max_code; /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, * establish sub-heaps of increasing lengths: */ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); /* Construct the Huffman tree by repeatedly combining the least two * frequent nodes. */ node = elems; /* next internal node of the tree */ do { pqremove(s, tree, n); /* n = node of least frequency */ m = s->heap[SMALLEST]; /* m = node of next least frequency */ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ s->heap[--(s->heap_max)] = m; /* Create a new node father of n and m */ tree[node].Freq = tree[n].Freq + tree[m].Freq; s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? s->depth[n] : s->depth[m]) + 1); tree[n].Dad = tree[m].Dad = (ush)node; #ifdef DUMP_BL_TREE if (tree == s->bl_tree) { fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); } #endif /* and insert the new node in the heap */ s->heap[SMALLEST] = node++; pqdownheap(s, tree, SMALLEST); } while (s->heap_len >= 2); s->heap[--(s->heap_max)] = s->heap[SMALLEST]; /* At this point, the fields freq and dad are set. We can now * generate the bit lengths. */ gen_bitlen(s, (tree_desc *)desc); /* The field len is now set, we can generate the bit codes */ gen_codes ((ct_data *)tree, max_code, s->bl_count); } /* =========================================================================== * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ local void scan_tree (s, tree, max_code) deflate_state *s; ct_data *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ if (nextlen == 0) max_count = 138, min_count = 3; tree[max_code+1].Len = (ush)0xffff; /* guard */ for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { s->bl_tree[curlen].Freq += count; } else if (curlen != 0) { if (curlen != prevlen) s->bl_tree[curlen].Freq++; s->bl_tree[REP_3_6].Freq++; } else if (count <= 10) { s->bl_tree[REPZ_3_10].Freq++; } else { s->bl_tree[REPZ_11_138].Freq++; } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ local void send_tree (s, tree, max_code) deflate_state *s; ct_data *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ /* tree[max_code+1].Len = -1; */ /* guard already set */ if (nextlen == 0) max_count = 138, min_count = 3; for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(s, curlen, s->bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(s, curlen, s->bl_tree); count--; } Assert(count >= 3 && count <= 6, " 3_6?"); send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); } else if (count <= 10) { send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); } else { send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ local int build_bl_tree(s) deflate_state *s; { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); /* Build the bit length tree: */ build_tree(s, (tree_desc *)(&(s->bl_desc))); /* opt_len now includes the length of the tree representations, except * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. */ /* Determine the number of bit length codes to send. The pkzip format * requires that at least 4 bit length codes be sent. (appnote.txt says * 3 but the actual value used is 4.) */ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ s->opt_len += 3*(max_blindex+1) + 5+5+4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); return max_blindex; } /* =========================================================================== * Send the header for a block using dynamic Huffman trees: the counts, the * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ local void send_all_trees(s, lcodes, dcodes, blcodes) deflate_state *s; int lcodes, dcodes, blcodes; /* number of codes for each tree */ { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); Tracev((stderr, "\nbl counts: ")); send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ send_bits(s, dcodes-1, 5); send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ for (rank = 0; rank < blcodes; rank++) { Tracev((stderr, "\nbl code %2d ", bl_order[rank])); send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); } Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); } /* =========================================================================== * Send a stored block */ void _tr_stored_block(s, buf, stored_len, eof) deflate_state *s; charf *buf; /* input block */ ulg stored_len; /* length of input block */ int eof; /* true if this is the last block for a file */ { send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ #ifdef DEBUG s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; #endif copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ } /* =========================================================================== * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. * The current inflate code requires 9 bits of lookahead. If the * last two codes for the previous block (real code plus EOB) were coded * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode * the last real code. In this case we send two empty static blocks instead * of one. (There are no problems if the previous block is stored or fixed.) * To simplify the code, we assume the worst case of last real code encoded * on one bit only. */ void _tr_align(s) deflate_state *s; { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); #ifdef DEBUG s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ #endif bi_flush(s); /* Of the 10 bits for the empty block, we have already sent * (10 - bi_valid) bits. The lookahead for the last real code (before * the EOB of the previous block) was thus at least one plus the length * of the EOB plus what we have just sent of the empty static block. */ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); #ifdef DEBUG s->compressed_len += 10L; #endif bi_flush(s); } s->last_eob_len = 7; } /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. */ void _tr_flush_block(s, buf, stored_len, eof) deflate_state *s; charf *buf; /* input block, or NULL if too old */ ulg stored_len; /* length of input block */ int eof; /* true if this is the last block for a file */ { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ /* Build the Huffman trees unless a stored block is forced */ if (s->level > 0) { /* Check if the file is ascii or binary */ if (s->data_type == Z_UNKNOWN) set_data_type(s); /* Construct the literal and distance trees */ build_tree(s, (tree_desc *)(&(s->l_desc))); Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len)); build_tree(s, (tree_desc *)(&(s->d_desc))); Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, s->static_len)); /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. */ /* Build the bit length tree for the above two trees, and get the index * in bl_order of the last bit length code to send. */ max_blindex = build_bl_tree(s); /* Determine the best encoding. Compute the block lengths in bytes. */ opt_lenb = (s->opt_len+3+7)>>3; static_lenb = (s->static_len+3+7)>>3; Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, s->last_lit)); if (static_lenb <= opt_lenb) opt_lenb = static_lenb; } else { Assert(buf != (char*)0, "lost buf"); opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ } #ifdef FORCE_STORED if (buf != (char*)0) { /* force stored block */ #else if (stored_len+4 <= opt_lenb && buf != (char*)0) { /* 4: two words for the lengths */ #endif /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. * Otherwise we can't have processed more than WSIZE input bytes since * the last block flush, because compression would have been * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ _tr_stored_block(s, buf, stored_len, eof); #ifdef FORCE_STATIC } else if (static_lenb >= 0) { /* force static trees */ #else } else if (static_lenb == opt_lenb) { #endif send_bits(s, (STATIC_TREES<<1)+eof, 3); compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); #ifdef DEBUG s->compressed_len += 3 + s->static_len; #endif } else { send_bits(s, (DYN_TREES<<1)+eof, 3); send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); #ifdef DEBUG s->compressed_len += 3 + s->opt_len; #endif } Assert (s->compressed_len == s->bits_sent, "bad compressed size"); /* The above check is made mod 2^32, for files larger than 512 MB * and uLong implemented on 32 bits. */ init_block(s); if (eof) { bi_windup(s); #ifdef DEBUG s->compressed_len += 7; /* align on byte boundary */ #endif } Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*eof)); } /* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ int _tr_tally (s, dist, lc) deflate_state *s; unsigned dist; /* distance of matched string */ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ { s->d_buf[s->last_lit] = (ush)dist; s->l_buf[s->last_lit++] = (uch)lc; if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; } else { s->matches++; /* Here, lc is the match length - MIN_MATCH */ dist--; /* dist = match distance - 1 */ Assert((ush)dist < (ush)MAX_DIST(s) && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; s->dyn_dtree[d_code(dist)].Freq++; } #ifdef TRUNCATE_BLOCK /* Try to guess if it is profitable to stop the current block here */ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { /* Compute an upper bound for the compressed length */ ulg out_length = (ulg)s->last_lit*8L; ulg in_length = (ulg)((long)s->strstart - s->block_start); int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { out_length += (ulg)s->dyn_dtree[dcode].Freq * (5L+extra_dbits[dcode]); } out_length >>= 3; Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", s->last_lit, in_length, out_length, 100L - out_length*100L/in_length)); if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; } #endif return (s->last_lit == s->lit_bufsize-1); /* We avoid equality with lit_bufsize because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. */ } /* =========================================================================== * Send the block data compressed using the given Huffman trees */ local void compress_block(s, ltree, dtree) deflate_state *s; ct_data *ltree; /* literal tree */ ct_data *dtree; /* distance tree */ { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ unsigned lx = 0; /* running index in l_buf */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->last_lit != 0) do { dist = s->d_buf[lx]; lc = s->l_buf[lx++]; if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); } else { /* Here, lc is the match length - MIN_MATCH */ code = _length_code[lc]; send_code(s, code+LITERALS+1, ltree); /* send the length code */ extra = extra_lbits[code]; if (extra != 0) { lc -= base_length[code]; send_bits(s, lc, extra); /* send the extra length bits */ } dist--; /* dist is now the match distance - 1 */ code = d_code(dist); Assert (code < D_CODES, "bad d_code"); send_code(s, code, dtree); /* send the distance code */ extra = extra_dbits[code]; if (extra != 0) { dist -= base_dist[code]; send_bits(s, dist, extra); /* send the extra distance bits */ } } /* literal or match pair ? */ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, "pendingBuf overflow"); } while (lx < s->last_lit); send_code(s, END_BLOCK, ltree); s->last_eob_len = ltree[END_BLOCK].Len; } /* =========================================================================== * Set the data type to ASCII or BINARY, using a crude approximation: * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. * IN assertion: the fields freq of dyn_ltree are set and the total of all * frequencies does not exceed 64K (to fit in an int on 16 bit machines). */ local void set_data_type(s) deflate_state *s; { int n = 0; unsigned ascii_freq = 0; unsigned bin_freq = 0; while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); } /* =========================================================================== * Reverse the first len bits of a code, using straightforward code (a faster * method would use a table) * IN assertion: 1 <= len <= 15 */ local unsigned bi_reverse(code, len) unsigned code; /* the value to invert */ int len; /* its bit length */ { register unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; } while (--len > 0); return res >> 1; } /* =========================================================================== * Flush the bit buffer, keeping at most 7 bits in it. */ local void bi_flush(s) deflate_state *s; { if (s->bi_valid == 16) { put_short(s, s->bi_buf); s->bi_buf = 0; s->bi_valid = 0; } else if (s->bi_valid >= 8) { put_byte(s, (Byte)s->bi_buf); s->bi_buf >>= 8; s->bi_valid -= 8; } } /* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */ local void bi_windup(s) deflate_state *s; { if (s->bi_valid > 8) { put_short(s, s->bi_buf); } else if (s->bi_valid > 0) { put_byte(s, (Byte)s->bi_buf); } s->bi_buf = 0; s->bi_valid = 0; #ifdef DEBUG s->bits_sent = (s->bits_sent+7) & ~7; #endif } /* =========================================================================== * Copy a stored block, storing first the length and its * one's complement if requested. */ local void copy_block(s, buf, len, header) deflate_state *s; charf *buf; /* the input data */ unsigned len; /* its length */ int header; /* true if block header must be written */ { bi_windup(s); /* align on byte boundary */ s->last_eob_len = 8; /* enough lookahead for inflate */ if (header) { put_short(s, (ush)len); put_short(s, (ush)~len); #ifdef DEBUG s->bits_sent += 2*16; #endif } #ifdef DEBUG s->bits_sent += (ulg)len<<3; #endif while (len--) { put_byte(s, *buf++); } } syslinux-legacy-3.63+dfsg/com32/lib/zlib/trees.h0000664000175000017500000002037310777447272020144 0ustar evanevan/* header created automatically with -DGEN_TREES_H */ local const ct_data static_ltree[L_CODES+2] = { {{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, {{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, {{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, {{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, {{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, {{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, {{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, {{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, {{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, {{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, {{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, {{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, {{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, {{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, {{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, {{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, {{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, {{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, {{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, {{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, {{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, {{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, {{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, {{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, {{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, {{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, {{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, {{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, {{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, {{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, {{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, {{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, {{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, {{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, {{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, {{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, {{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, {{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, {{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, {{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, {{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, {{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, {{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, {{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, {{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, {{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, {{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, {{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, {{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, {{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, {{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, {{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, {{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, {{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, {{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, {{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, {{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, {{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} }; local const ct_data static_dtree[D_CODES] = { {{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, {{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, {{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, {{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, {{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, {{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} }; const uch _dist_code[DIST_CODE_LEN] = { 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 }; const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 }; local const int base_length[LENGTH_CODES] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 }; local const int base_dist[D_CODES] = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 }; syslinux-legacy-3.63+dfsg/com32/lib/zlib/crc32.h0000664000175000017500000007355010777447272017743 0ustar evanevan/* crc32.h -- tables for rapid CRC calculation * Generated automatically by crc32.c */ local const unsigned long FAR crc_table[TBLS][256] = { { 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, 0x2d02ef8dUL #ifdef BYFOUR }, { 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, 0x9324fd72UL }, { 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, 0xbe9834edUL }, { 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, 0xde0506f1UL }, { 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, 0x8def022dUL }, { 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, 0x72fd2493UL }, { 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, 0xed3498beUL }, { 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, 0xf10605deUL #endif } }; syslinux-legacy-3.63+dfsg/com32/lib/zlib/zconf.in.h0000664000175000017500000002132610777447272020545 0ustar evanevan/* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-2003 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ #ifndef ZCONF_H #define ZCONF_H /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. */ #ifdef Z_PREFIX # define deflateInit_ z_deflateInit_ # define deflate z_deflate # define deflateEnd z_deflateEnd # define inflateInit_ z_inflateInit_ # define inflate z_inflate # define inflateEnd z_inflateEnd # define deflateInit2_ z_deflateInit2_ # define deflateSetDictionary z_deflateSetDictionary # define deflateCopy z_deflateCopy # define deflateReset z_deflateReset # define deflatePrime z_deflatePrime # define deflateParams z_deflateParams # define deflateBound z_deflateBound # define inflateInit2_ z_inflateInit2_ # define inflateSetDictionary z_inflateSetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateCopy z_inflateCopy # define inflateReset z_inflateReset # define compress z_compress # define compress2 z_compress2 # define compressBound z_compressBound # define uncompress z_uncompress # define adler32 z_adler32 # define crc32 z_crc32 # define get_crc_table z_get_crc_table # define Byte z_Byte # define uInt z_uInt # define uLong z_uLong # define Bytef z_Bytef # define charf z_charf # define intf z_intf # define uIntf z_uIntf # define uLongf z_uLongf # define voidpf z_voidpf # define voidp z_voidp #endif #if defined(__MSDOS__) && !defined(MSDOS) # define MSDOS #endif #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) # define OS2 #endif #if defined(_WINDOWS) && !defined(WINDOWS) # define WINDOWS #endif #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) # define WIN32 #endif #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) # ifndef SYS16BIT # define SYS16BIT # endif # endif #endif /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). */ #ifdef SYS16BIT # define MAXSEG_64K #endif #ifdef MSDOS # define UNALIGNED_OK #endif #ifdef __STDC_VERSION__ # ifndef STDC # define STDC # endif # if __STDC_VERSION__ >= 199901L # ifndef STDC99 # define STDC99 # endif # endif #endif #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) # define STDC #endif #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) # define STDC #endif #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) # define STDC #endif #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) # define STDC #endif #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ # define STDC #endif #ifndef STDC # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # define const /* note: need a more gentle solution here */ # endif #endif /* Some Mac compilers merge all .h files incorrectly: */ #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) # define NO_DUMMY_DECL #endif /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # ifdef MAXSEG_64K # define MAX_MEM_LEVEL 8 # else # define MAX_MEM_LEVEL 9 # endif #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files * created by gzip. (Files created by minigzip can still be extracted by * gzip.) */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Type declarations */ #ifndef OF /* function prototypes */ # ifdef STDC # define OF(args) args # else # define OF(args) () # endif #endif /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * just define FAR to be empty. */ #ifdef SYS16BIT # if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */ # define SMALL_MEDIUM # ifdef _MSC_VER # define FAR _far # else # define FAR far # endif # endif # if (defined(__SMALL__) || defined(__MEDIUM__)) /* Turbo C small or medium model */ # define SMALL_MEDIUM # ifdef __BORLANDC__ # define FAR _far # else # define FAR far # endif # endif #endif #if defined(WINDOWS) || defined(WIN32) /* If building or using zlib as a DLL, define ZLIB_DLL. * This is not mandatory, but it offers a little performance increase. */ # ifdef ZLIB_DLL # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) # ifdef ZLIB_INTERNAL # define ZEXTERN extern __declspec(dllexport) # else # define ZEXTERN extern __declspec(dllimport) # endif # endif # endif /* ZLIB_DLL */ /* If building or using zlib with the WINAPI/WINAPIV calling convention, * define ZLIB_WINAPI. * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. */ # ifdef ZLIB_WINAPI # ifdef FAR # undef FAR # endif # include /* No need for _export, use ZLIB.DEF instead. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */ # define ZEXPORT WINAPI # ifdef WIN32 # define ZEXPORTVA WINAPIV # else # define ZEXPORTVA FAR CDECL # endif # endif #endif #if defined (__BEOS__) # ifdef ZLIB_DLL # ifdef ZLIB_INTERNAL # define ZEXPORT __declspec(dllexport) # define ZEXPORTVA __declspec(dllexport) # else # define ZEXPORT __declspec(dllimport) # define ZEXPORTVA __declspec(dllimport) # endif # endif #endif #ifndef ZEXTERN # define ZEXTERN extern #endif #ifndef ZEXPORT # define ZEXPORT #endif #ifndef ZEXPORTVA # define ZEXPORTVA #endif #ifndef FAR # define FAR #endif #if !defined(__MACTYPES__) typedef unsigned char Byte; /* 8 bits */ #endif typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ #ifdef SMALL_MEDIUM /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ # define Bytef Byte FAR #else typedef Byte FAR Bytef; #endif typedef char FAR charf; typedef int FAR intf; typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC typedef void const *voidpc; typedef void FAR *voidpf; typedef void *voidp; #else typedef Byte const *voidpc; typedef Byte FAR *voidpf; typedef Byte *voidp; #endif #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ # include /* for off_t */ # include /* for SEEK_* and off_t */ # ifdef VMS # include /* for off_t */ # endif # define z_off_t off_t #endif #ifndef SEEK_SET # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif #ifndef z_off_t # define z_off_t long #endif #if defined(__OS400__) #define NO_vsnprintf #endif #if defined(__MVS__) # define NO_vsnprintf # ifdef FAR # undef FAR # endif #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) # pragma map(deflateInit_,"DEIN") # pragma map(deflateInit2_,"DEIN2") # pragma map(deflateEnd,"DEEND") # pragma map(deflateBound,"DEBND") # pragma map(inflateInit_,"ININ") # pragma map(inflateInit2_,"ININ2") # pragma map(inflateEnd,"INEND") # pragma map(inflateSync,"INSY") # pragma map(inflateSetDictionary,"INSEDI") # pragma map(compressBound,"CMBND") # pragma map(inflate_table,"INTABL") # pragma map(inflate_fast,"INFA") # pragma map(inflate_copyright,"INCOPY") #endif #endif /* ZCONF_H */ syslinux-legacy-3.63+dfsg/com32/lib/zlib/README0000664000175000017500000001312210777447272017523 0ustar evanevanZLIB DATA COMPRESSION LIBRARY zlib 1.2.1 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). These documents are also available in other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html All functions of the compression library are documented in the file zlib.h (volunteer to write man pages welcome, contact zlib@gzip.org). A usage example of the library is given in the file example.c which also tests that the library is working correctly. Another example is given in the file minigzip.c. The compression library itself is composed of all source files except example.c and minigzip.c. To compile all files and run the test program, follow the instructions given at the top of Makefile. In short "make test; make install" should work for most machines. For Unix: "./configure; make test; make install" For MSDOS, use one of the special makefiles such as Makefile.msc. For VMS, use Make_vms.com or descrip.mms. Questions about zlib should be sent to , or to Gilles Vollant for the Windows DLL version. The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, please check this site to verify that you have the latest version of zlib; otherwise get the latest version and check whether the problem still exists or not. PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking for help. Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available in http://dogma.net/markn/articles/zlibtool/zlibtool.htm The changes made in version 1.2.1 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory "contrib". A Java implementation of zlib is available in the Java Development Kit http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html See the zlib home page http://www.zlib.org for details. A Perl interface to zlib written by Paul Marquess is in the CPAN (Comprehensive Perl Archive Network) sites http://www.cpan.org/modules/by-module/Compress/ A Python interface to zlib written by A.M. Kuchling is available in Python 1.5 and later versions, see http://www.python.org/doc/lib/module-zlib.html A zlib binding for TCL written by Andreas Kupries is availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html An experimental package to read and write files in .zip format, written on top of zlib by Gilles Vollant , is available in the contrib/minizip directory of zlib. Notes for some targets: - For Windows DLL versions, please see win32/DLL_FAQ.txt - For 64-bit Irix, deflate.c must be compiled without any optimization. With -O, one libpng test fails. The test works in 32 bit mode (with the -n32 compiler flag). The compiler bug has been reported to SGI. - zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works when compiled with cc. - On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is necessary to get gzprintf working correctly. This is done by configure. - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with other compilers. Use "make test" to check your compiler. - gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. - For PalmOs, see http://palmzlib.sourceforge.net/ - When building a shared, i.e. dynamic library on Mac OS X, the library must be installed before testing (do "make install" before "make test"), since the library location is specified in the library. Acknowledgments: The deflate format used by zlib was defined by Phil Katz. The deflate and zlib specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in zlib; they are too numerous to cite here. Copyright notice: (C) 1995-2003 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu If you use the zlib library in a product, we would appreciate *not* receiving lengthy legal documents to sign. The sources are provided for free but without warranty of any kind. The library has been entirely written by Jean-loup Gailly and Mark Adler; it does not include third-party code. If you redistribute modified sources, we would appreciate that you include in the file ChangeLog history information documenting your changes. Please read the FAQ for more information on the distribution of modified source versions. syslinux-legacy-3.63+dfsg/com32/lib/zlib/deflate.c0000664000175000017500000015324410777447272020425 0ustar evanevan/* deflate.c -- compress data using the deflation algorithm * Copyright (C) 1995-2003 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process depends on being able to identify portions * of the input text which are identical to earlier input (within a * sliding window trailing behind the input currently being processed). * * The most straightforward technique turns out to be the fastest for * most input files: try all possible matches and select the longest. * The key feature of this algorithm is that insertions into the string * dictionary are very simple and thus fast, and deletions are avoided * completely. Insertions are performed at each input character, whereas * string matches are performed only when the previous match ends. So it * is preferable to spend more time in matches to allow very fast string * insertions and avoid deletions. The matching algorithm for small * strings is inspired from that of Rabin & Karp. A brute force approach * is used to find longer strings when a small match has been found. * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze * (by Leonid Broukhis). * A previous version of this file used a more sophisticated algorithm * (by Fiala and Greene) which is guaranteed to run in linear amortized * time, but has a larger average cost, uses more memory and is patented. * However the F&G algorithm may be faster for some highly redundant * files if the parameter max_chain_length (described below) is too large. * * ACKNOWLEDGEMENTS * * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and * I found it in 'freeze' written by Leonid Broukhis. * Thanks to many people for bug reports and testing. * * REFERENCES * * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". * Available in http://www.ietf.org/rfc/rfc1951.txt * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. * * Fiala,E.R., and Greene,D.H. * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 * */ #include "deflate.h" const char deflate_copyright[] = " deflate 1.2.1 Copyright 1995-2003 Jean-loup Gailly "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ /* =========================================================================== * Function prototypes. */ typedef enum { need_more, /* block not completed, need more input or more output */ block_done, /* block flush performed */ finish_started, /* finish started, need only more output at next deflate */ finish_done /* finish done, accept no more input or output */ } block_state; typedef block_state (*compress_func) OF((deflate_state *s, int flush)); /* Compression function. Returns the block state after the call. */ local void fill_window OF((deflate_state *s)); local block_state deflate_stored OF((deflate_state *s, int flush)); local block_state deflate_fast OF((deflate_state *s, int flush)); #ifndef FASTEST local block_state deflate_slow OF((deflate_state *s, int flush)); #endif local void lm_init OF((deflate_state *s)); local void putShortMSB OF((deflate_state *s, uInt b)); local void flush_pending OF((z_streamp strm)); local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); #ifndef FASTEST #ifdef ASMV void match_init OF((void)); /* asm code initialization */ uInt longest_match OF((deflate_state *s, IPos cur_match)); #else local uInt longest_match OF((deflate_state *s, IPos cur_match)); #endif #endif local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); #ifdef DEBUG local void check_match OF((deflate_state *s, IPos start, IPos match, int length)); #endif /* =========================================================================== * Local data */ #define NIL 0 /* Tail of hash chains */ #ifndef TOO_FAR # define TOO_FAR 4096 #endif /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be * found for specific files. */ typedef struct config_s { ush good_length; /* reduce lazy search above this match length */ ush max_lazy; /* do not perform lazy search above this match length */ ush nice_length; /* quit search above this match length */ ush max_chain; compress_func func; } config; #ifdef FASTEST local const config configuration_table[2] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ #else local const config configuration_table[10] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ /* 2 */ {4, 5, 16, 8, deflate_fast}, /* 3 */ {4, 6, 32, 32, deflate_fast}, /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ /* 5 */ {8, 16, 32, 32, deflate_slow}, /* 6 */ {8, 16, 128, 128, deflate_slow}, /* 7 */ {8, 32, 128, 256, deflate_slow}, /* 8 */ {32, 128, 258, 1024, deflate_slow}, /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ #endif /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different * meaning. */ #define EQUAL 0 /* result of memcmp for equal strings */ #ifndef NO_DUMMY_DECL struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ #endif /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to to UPDATE_HASH are made with consecutive * input characters, so that a running hash key can be computed from the * previous key instead of complete recalculation each time. */ #define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) /* =========================================================================== * Insert string str in the dictionary and set match_head to the previous head * of the hash chain (the most recent string with same hash key). Return * the previous length of the hash chain. * If this file is compiled with -DFASTEST, the compression level is forced * to 1, and no hash chains are maintained. * IN assertion: all calls to to INSERT_STRING are made with consecutive * input characters and the first MIN_MATCH bytes of str are valid * (except for the last MIN_MATCH-1 bytes of the input file). */ #ifdef FASTEST #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ match_head = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) #else #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) #endif /* =========================================================================== * Initialize the hash table (avoiding 64K overflow for 16 bit systems). * prev[] will be initialized on the fly. */ #define CLEAR_HASH(s) \ s->head[s->hash_size-1] = NIL; \ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); /* ========================================================================= */ int ZEXPORT deflateInit_(strm, level, version, stream_size) z_streamp strm; int level; const char *version; int stream_size; { return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, version, stream_size) z_streamp strm; int level; int method; int windowBits; int memLevel; int strategy; const char *version; int stream_size; { deflate_state *s; int wrap = 1; static const char my_version[] = ZLIB_VERSION; ushf *overlay; /* We overlay pending_buf and d_buf+l_buf. This works since the average * output size for (length,distance) codes is <= 24 bits. */ if (version == Z_NULL || version[0] != my_version[0] || stream_size != sizeof(z_stream)) { return Z_VERSION_ERROR; } if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; if (strm->zalloc == (alloc_func)0) { strm->zalloc = zcalloc; strm->opaque = (voidpf)0; } if (strm->zfree == (free_func)0) strm->zfree = zcfree; #ifdef FASTEST if (level != 0) level = 1; #else if (level == Z_DEFAULT_COMPRESSION) level = 6; #endif if (windowBits < 0) { /* suppress zlib wrapper */ wrap = 0; windowBits = -windowBits; } #ifdef GZIP else if (windowBits > 15) { wrap = 2; /* write gzip wrapper instead */ windowBits -= 16; } #endif if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_RLE) { return Z_STREAM_ERROR; } if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); if (s == Z_NULL) return Z_MEM_ERROR; strm->state = (struct internal_state FAR *)s; s->strm = strm; s->wrap = wrap; s->w_bits = windowBits; s->w_size = 1 << s->w_bits; s->w_mask = s->w_size - 1; s->hash_bits = memLevel + 7; s->hash_size = 1 << s->hash_bits; s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); s->pending_buf = (uchf *) overlay; s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || s->pending_buf == Z_NULL) { s->status = FINISH_STATE; strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); deflateEnd (strm); return Z_MEM_ERROR; } s->d_buf = overlay + s->lit_bufsize/sizeof(ush); s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; s->level = level; s->strategy = strategy; s->method = (Byte)method; return deflateReset(strm); } /* ========================================================================= */ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; { deflate_state *s; uInt length = dictLength; uInt n; IPos hash_head = 0; if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || strm->state->wrap == 2 || (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) return Z_STREAM_ERROR; s = strm->state; if (s->wrap) strm->adler = adler32(strm->adler, dictionary, dictLength); if (length < MIN_MATCH) return Z_OK; if (length > MAX_DIST(s)) { length = MAX_DIST(s); #ifndef USE_DICT_HEAD dictionary += dictLength - length; /* use the tail of the dictionary */ #endif } zmemcpy(s->window, dictionary, length); s->strstart = length; s->block_start = (long)length; /* Insert all strings in the hash table (except for the last two bytes). * s->lookahead stays null, so s->ins_h will be recomputed at the next * call of fill_window. */ s->ins_h = s->window[0]; UPDATE_HASH(s, s->ins_h, s->window[1]); for (n = 0; n <= length - MIN_MATCH; n++) { INSERT_STRING(s, n, hash_head); } if (hash_head) hash_head = 0; /* to make compiler happy */ return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateReset (strm) z_streamp strm; { deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { return Z_STREAM_ERROR; } strm->total_in = strm->total_out = 0; strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ strm->data_type = Z_UNKNOWN; s = (deflate_state *)strm->state; s->pending = 0; s->pending_out = s->pending_buf; if (s->wrap < 0) { s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ } s->status = s->wrap ? INIT_STATE : BUSY_STATE; strm->adler = #ifdef GZIP s->wrap == 2 ? crc32(0L, Z_NULL, 0) : #endif adler32(0L, Z_NULL, 0); s->last_flush = Z_NO_FLUSH; _tr_init(s); lm_init(s); return Z_OK; } /* ========================================================================= */ int ZEXPORT deflatePrime (strm, bits, value) z_streamp strm; int bits; int value; { if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; strm->state->bi_valid = bits; strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateParams(strm, level, strategy) z_streamp strm; int level; int strategy; { deflate_state *s; compress_func func; int err = Z_OK; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; s = strm->state; #ifdef FASTEST if (level != 0) level = 1; #else if (level == Z_DEFAULT_COMPRESSION) level = 6; #endif if (level < 0 || level > 9 || strategy < 0 || strategy > Z_RLE) { return Z_STREAM_ERROR; } func = configuration_table[s->level].func; if (func != configuration_table[level].func && strm->total_in != 0) { /* Flush the last buffer: */ err = deflate(strm, Z_PARTIAL_FLUSH); } if (s->level != level) { s->level = level; s->max_lazy_match = configuration_table[level].max_lazy; s->good_match = configuration_table[level].good_length; s->nice_match = configuration_table[level].nice_length; s->max_chain_length = configuration_table[level].max_chain; } s->strategy = strategy; return err; } /* ========================================================================= * For the default windowBits of 15 and memLevel of 8, this function returns * a close to exact, as well as small, upper bound on the compressed size. * They are coded as constants here for a reason--if the #define's are * changed, then this function needs to be changed as well. The return * value for 15 and 8 only works for those exact settings. * * For any setting other than those defaults for windowBits and memLevel, * the value returned is a conservative worst case for the maximum expansion * resulting from using fixed blocks instead of stored blocks, which deflate * can emit on compressed data for some combinations of the parameters. * * This function could be more sophisticated to provide closer upper bounds * for every combination of windowBits and memLevel, as well as wrap. * But even the conservative upper bound of about 14% expansion does not * seem onerous for output buffer allocation. */ uLong ZEXPORT deflateBound(strm, sourceLen) z_streamp strm; uLong sourceLen; { deflate_state *s; uLong destLen; /* conservative upper bound */ destLen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; /* if can't get parameters, return conservative bound */ if (strm == Z_NULL || strm->state == Z_NULL) return destLen; /* if not default parameters, return conservative bound */ s = strm->state; if (s->w_bits != 15 || s->hash_bits != 8 + 7) return destLen; /* default settings: return tight bound for that case */ return compressBound(sourceLen); } /* ========================================================================= * Put a short in the pending buffer. The 16-bit value is put in MSB order. * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ local void putShortMSB (s, b) deflate_state *s; uInt b; { put_byte(s, (Byte)(b >> 8)); put_byte(s, (Byte)(b & 0xff)); } /* ========================================================================= * Flush as much pending output as possible. All deflate() output goes * through this function so some applications may wish to modify it * to avoid allocating a large strm->next_out buffer and copying into it. * (See also read_buf()). */ local void flush_pending(strm) z_streamp strm; { unsigned len = strm->state->pending; if (len > strm->avail_out) len = strm->avail_out; if (len == 0) return; zmemcpy(strm->next_out, strm->state->pending_out, len); strm->next_out += len; strm->state->pending_out += len; strm->total_out += len; strm->avail_out -= len; strm->state->pending -= len; if (strm->state->pending == 0) { strm->state->pending_out = strm->state->pending_buf; } } /* ========================================================================= */ int ZEXPORT deflate (strm, flush) z_streamp strm; int flush; { int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || flush > Z_FINISH || flush < 0) { return Z_STREAM_ERROR; } s = strm->state; if (strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0) || (s->status == FINISH_STATE && flush != Z_FINISH)) { ERR_RETURN(strm, Z_STREAM_ERROR); } if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); s->strm = strm; /* just in case */ old_flush = s->last_flush; s->last_flush = flush; /* Write the header */ if (s->status == INIT_STATE) { #ifdef GZIP if (s->wrap == 2) { put_byte(s, 31); put_byte(s, 139); put_byte(s, 8); put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); put_byte(s, 255); s->status = BUSY_STATE; strm->adler = crc32(0L, Z_NULL, 0); } else #endif { uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; uInt level_flags; if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) level_flags = 0; else if (s->level < 6) level_flags = 1; else if (s->level == 6) level_flags = 2; else level_flags = 3; header |= (level_flags << 6); if (s->strstart != 0) header |= PRESET_DICT; header += 31 - (header % 31); s->status = BUSY_STATE; putShortMSB(s, header); /* Save the adler32 of the preset dictionary: */ if (s->strstart != 0) { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } strm->adler = adler32(0L, Z_NULL, 0); } } /* Flush as much pending output as possible */ if (s->pending != 0) { flush_pending(strm); if (strm->avail_out == 0) { /* Since avail_out is 0, deflate will be called again with * more output space, but possibly with both pending and * avail_in equal to zero. There won't be anything to do, * but this is not an error situation so make sure we * return OK instead of BUF_ERROR at next call of deflate: */ s->last_flush = -1; return Z_OK; } /* Make sure there is something to do and avoid duplicate consecutive * flushes. For repeated and useless calls with Z_FINISH, we keep * returning Z_STREAM_END instead of Z_BUF_ERROR. */ } else if (strm->avail_in == 0 && flush <= old_flush && flush != Z_FINISH) { ERR_RETURN(strm, Z_BUF_ERROR); } /* User must not provide more input after the first FINISH: */ if (s->status == FINISH_STATE && strm->avail_in != 0) { ERR_RETURN(strm, Z_BUF_ERROR); } /* Start a new block or continue the current one. */ if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; bstate = (*(configuration_table[s->level].func))(s, flush); if (bstate == finish_started || bstate == finish_done) { s->status = FINISH_STATE; } if (bstate == need_more || bstate == finish_started) { if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ } return Z_OK; /* If flush != Z_NO_FLUSH && avail_out == 0, the next call * of deflate should use the same flush parameter to make sure * that the flush is complete. So we don't have to output an * empty block here, this will be done at next call. This also * ensures that for a very small output buffer, we emit at most * one empty block. */ } if (bstate == block_done) { if (flush == Z_PARTIAL_FLUSH) { _tr_align(s); } else { /* FULL_FLUSH or SYNC_FLUSH */ _tr_stored_block(s, (char*)0, 0L, 0); /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ if (flush == Z_FULL_FLUSH) { CLEAR_HASH(s); /* forget history */ } } flush_pending(strm); if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ return Z_OK; } } } Assert(strm->avail_out > 0, "bug2"); if (flush != Z_FINISH) return Z_OK; if (s->wrap <= 0) return Z_STREAM_END; /* Write the trailer */ #ifdef GZIP if (s->wrap == 2) { put_byte(s, (Byte)(strm->adler & 0xff)); put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); put_byte(s, (Byte)(strm->total_in & 0xff)); put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); } else #endif { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } flush_pending(strm); /* If avail_out is zero, the application will call deflate again * to flush the rest. */ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ return s->pending != 0 ? Z_OK : Z_STREAM_END; } /* ========================================================================= */ int ZEXPORT deflateEnd (strm) z_streamp strm; { int status; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; status = strm->state->status; if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) { return Z_STREAM_ERROR; } /* Deallocate in reverse order of allocations: */ TRY_FREE(strm, strm->state->pending_buf); TRY_FREE(strm, strm->state->head); TRY_FREE(strm, strm->state->prev); TRY_FREE(strm, strm->state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } /* ========================================================================= * Copy the source state to the destination state. * To simplify the source, this is not supported for 16-bit MSDOS (which * doesn't have enough memory anyway to duplicate compression states). */ int ZEXPORT deflateCopy (dest, source) z_streamp dest; z_streamp source; { #ifdef MAXSEG_64K return Z_STREAM_ERROR; #else deflate_state *ds; deflate_state *ss; ushf *overlay; if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { return Z_STREAM_ERROR; } ss = source->state; *dest = *source; ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); if (ds == Z_NULL) return Z_MEM_ERROR; dest->state = (struct internal_state FAR *) ds; *ds = *ss; ds->strm = dest; ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); ds->pending_buf = (uchf *) overlay; if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { deflateEnd (dest); return Z_MEM_ERROR; } /* following zmemcpy do not work for 16-bit MSDOS */ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; ds->bl_desc.dyn_tree = ds->bl_tree; return Z_OK; #endif /* MAXSEG_64K */ } /* =========================================================================== * Read a new buffer from the current input stream, update the adler32 * and total number of bytes read. All deflate() input goes through * this function so some applications may wish to modify it to avoid * allocating a large strm->next_in buffer and copying from it. * (See also flush_pending()). */ local int read_buf(strm, buf, size) z_streamp strm; Bytef *buf; unsigned size; { unsigned len = strm->avail_in; if (len > size) len = size; if (len == 0) return 0; strm->avail_in -= len; if (strm->state->wrap == 1) { strm->adler = adler32(strm->adler, strm->next_in, len); } #ifdef GZIP else if (strm->state->wrap == 2) { strm->adler = crc32(strm->adler, strm->next_in, len); } #endif zmemcpy(buf, strm->next_in, len); strm->next_in += len; strm->total_in += len; return (int)len; } /* =========================================================================== * Initialize the "longest match" routines for a new zlib stream */ local void lm_init (s) deflate_state *s; { s->window_size = (ulg)2L*s->w_size; CLEAR_HASH(s); /* Set the default configuration parameters: */ s->max_lazy_match = configuration_table[s->level].max_lazy; s->good_match = configuration_table[s->level].good_length; s->nice_match = configuration_table[s->level].nice_length; s->max_chain_length = configuration_table[s->level].max_chain; s->strstart = 0; s->block_start = 0L; s->lookahead = 0; s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; s->ins_h = 0; #ifdef ASMV match_init(); /* initialize the asm code */ #endif } #ifndef FASTEST /* =========================================================================== * Set match_start to the longest match starting at the given string and * return its length. Matches shorter or equal to prev_length are discarded, * in which case the result is equal to prev_length and match_start is * garbage. * IN assertions: cur_match is the head of the hash chain for the current * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */ #ifndef ASMV /* For 80x86 and 680x0, an optimized version will be provided in match.asm or * match.S. The code will be functionally equivalent. */ local uInt longest_match(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ int best_len = s->prev_length; /* best match length so far */ int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? s->strstart - (IPos)MAX_DIST(s) : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, * we prevent matches with the string of window index 0. */ Posf *prev = s->prev; uInt wmask = s->w_mask; #ifdef UNALIGNED_OK /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; register ush scan_start = *(ushf*)scan; register ush scan_end = *(ushf*)(scan+best_len-1); #else register Bytef *strend = s->window + s->strstart + MAX_MATCH; register Byte scan_end1 = scan[best_len-1]; register Byte scan_end = scan[best_len]; #endif /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); /* Do not waste too much time if we already have a good match: */ if (s->prev_length >= s->good_match) { chain_length >>= 2; } /* Do not look for matches beyond the end of the input. This is necessary * to make deflate deterministic. */ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); do { Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Skip to next match if the match length cannot increase * or if the match length is less than 2: */ #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) /* This code assumes sizeof(unsigned short) == 2. Do not use * UNALIGNED_OK if your compiler uses a different size. */ if (*(ushf*)(match+best_len-1) != scan_end || *(ushf*)match != scan_start) continue; /* It is not necessary to compare scan[2] and match[2] since they are * always equal when the other bytes match, given that the hash keys * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at * strstart+3, +5, ... up to strstart+257. We check for insufficient * lookahead only every 4th comparison; the 128th check will be made * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is * necessary to put more guard bytes at the end of the window, or * to check more often for insufficient lookahead. */ Assert(scan[2] == match[2], "scan[2]?"); scan++, match++; do { } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && scan < strend); /* The funny "do {}" generates better code on most compilers */ /* Here, scan <= window+strstart+257 */ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); if (*scan == *match) scan++; len = (MAX_MATCH - 1) - (int)(strend-scan); scan = strend - (MAX_MATCH-1); #else /* UNALIGNED_OK */ if (match[best_len] != scan_end || match[best_len-1] != scan_end1 || *match != *scan || *++match != scan[1]) continue; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match++; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; #endif /* UNALIGNED_OK */ if (len > best_len) { s->match_start = cur_match; best_len = len; if (len >= nice_match) break; #ifdef UNALIGNED_OK scan_end = *(ushf*)(scan+best_len-1); #else scan_end1 = scan[best_len-1]; scan_end = scan[best_len]; #endif } } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length != 0); if ((uInt)best_len <= s->lookahead) return (uInt)best_len; return s->lookahead; } #endif /* ASMV */ #endif /* FASTEST */ /* --------------------------------------------------------------------------- * Optimized version for level == 1 or strategy == Z_RLE only */ local uInt longest_match_fast(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ register Bytef *strend = s->window + s->strstart + MAX_MATCH; /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Return failure if the match length is less than 2: */ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match += 2; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); if (len < MIN_MATCH) return MIN_MATCH - 1; s->match_start = cur_match; return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; } #ifdef DEBUG /* =========================================================================== * Check that the match at match_start is indeed a match. */ local void check_match(s, start, match, length) deflate_state *s; IPos start, match; int length; { /* check that the match is indeed a match */ if (zmemcmp(s->window + match, s->window + start, length) != EQUAL) { fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); do { fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); } while (--length != 0); z_error("invalid match"); } if (z_verbose > 1) { fprintf(stderr,"\\[%d,%d]", start-match, length); do { putc(s->window[start++], stderr); } while (--length != 0); } } #else # define check_match(s, start, match, length) #endif /* DEBUG */ /* =========================================================================== * Fill the window when the lookahead becomes insufficient. * Updates strstart and lookahead. * * IN assertion: lookahead < MIN_LOOKAHEAD * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD * At least one byte has been read, or avail_in == 0; reads are * performed for at least two bytes (required for the zip translate_eol * option -- not supported here). */ local void fill_window(s) deflate_state *s; { register unsigned n, m; register Posf *p; unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; do { more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); /* Deal with !@#$% 64K limit: */ if (sizeof(int) <= 2) { if (more == 0 && s->strstart == 0 && s->lookahead == 0) { more = wsize; } else if (more == (unsigned)(-1)) { /* Very unlikely, but possible on 16 bit machine if * strstart == 0 && lookahead == 1 (input done a byte at time) */ more--; } } /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ if (s->strstart >= wsize+MAX_DIST(s)) { zmemcpy(s->window, s->window+wsize, (unsigned)wsize); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ s->block_start -= (long) wsize; /* Slide the hash table (could be avoided with 32 bit values at the expense of memory usage). We slide even when level == 0 to keep the hash table consistent if we switch back to level > 0 later. (Using level 0 permanently is not an optimal usage of zlib, so we don't care about this pathological case.) */ n = s->hash_size; p = &s->head[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); } while (--n); n = wsize; #ifndef FASTEST p = &s->prev[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); /* If n is not on any hash chain, prev[n] is garbage but * its value will never be used. */ } while (--n); #endif more += wsize; } if (s->strm->avail_in == 0) return; /* If there was no sliding: * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && * more == window_size - lookahead - strstart * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) * => more >= window_size - 2*WSIZE + 2 * In the BIG_MEM or MMAP case (not yet supported), * window_size == input_size + MIN_LOOKAHEAD && * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. * Otherwise, window_size == 2*WSIZE so more >= 2. * If there was sliding, more >= WSIZE. So in all cases, more >= 2. */ Assert(more >= 2, "more < 2"); n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); s->lookahead += n; /* Initialize the hash value now that we have some input: */ if (s->lookahead >= MIN_MATCH) { s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif } /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, * but this is not important since only literal bytes will be emitted. */ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); } /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ #define FLUSH_BLOCK_ONLY(s, eof) { \ _tr_flush_block(s, (s->block_start >= 0L ? \ (charf *)&s->window[(unsigned)s->block_start] : \ (charf *)Z_NULL), \ (ulg)((long)s->strstart - s->block_start), \ (eof)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ Tracev((stderr,"[FLUSH]")); \ } /* Same but force premature exit if necessary. */ #define FLUSH_BLOCK(s, eof) { \ FLUSH_BLOCK_ONLY(s, eof); \ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ } /* =========================================================================== * Copy without compression as much as possible from the input stream, return * the current block state. * This function does not insert new strings in the dictionary since * uncompressible data is probably not useful. This function is used * only for the level=0 compression option. * NOTE: this function should be optimized to avoid extra copying from * window to pending_buf. */ local block_state deflate_stored(s, flush) deflate_state *s; int flush; { /* Stored blocks are limited to 0xffff bytes, pending_buf is limited * to pending_buf_size, and each stored block has a 5 byte header: */ ulg max_block_size = 0xffff; ulg max_start; if (max_block_size > s->pending_buf_size - 5) { max_block_size = s->pending_buf_size - 5; } /* Copy as much as possible from input to output: */ for (;;) { /* Fill the window as much as possible: */ if (s->lookahead <= 1) { Assert(s->strstart < s->w_size+MAX_DIST(s) || s->block_start >= (long)s->w_size, "slide too late"); fill_window(s); if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; if (s->lookahead == 0) break; /* flush the current block */ } Assert(s->block_start >= 0L, "block gone"); s->strstart += s->lookahead; s->lookahead = 0; /* Emit a stored block if pending_buf will be full: */ max_start = s->block_start + max_block_size; if (s->strstart == 0 || (ulg)s->strstart >= max_start) { /* strstart == 0 is possible when wraparound on 16-bit machine */ s->lookahead = (uInt)(s->strstart - max_start); s->strstart = (uInt)max_start; FLUSH_BLOCK(s, 0); } /* Flush if we may have to slide, otherwise block_start may become * negative and the data will be gone: */ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { FLUSH_BLOCK(s, 0); } } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } /* =========================================================================== * Compress as much as possible from the input stream, return the current * block state. * This function does not perform lazy evaluation of matches and inserts * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ local block_state deflate_fast(s, flush) deflate_state *s; int flush; { IPos hash_head = NIL; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ #ifdef FASTEST if ((s->strategy < Z_HUFFMAN_ONLY) || (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { s->match_length = longest_match_fast (s, hash_head); } #else if (s->strategy < Z_HUFFMAN_ONLY) { s->match_length = longest_match (s, hash_head); } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { s->match_length = longest_match_fast (s, hash_head); } #endif /* longest_match() or longest_match_fast() sets match_start */ } if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->match_start, s->match_length); _tr_tally_dist(s, s->strstart - s->match_start, s->match_length - MIN_MATCH, bflush); s->lookahead -= s->match_length; /* Insert new strings in the hash table only if the match length * is not too large. This saves time but degrades compression. */ #ifndef FASTEST if (s->match_length <= s->max_insert_length && s->lookahead >= MIN_MATCH) { s->match_length--; /* string at strstart already in table */ do { s->strstart++; INSERT_STRING(s, s->strstart, hash_head); /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. */ } while (--s->match_length != 0); s->strstart++; } else #endif { s->strstart += s->match_length; s->match_length = 0; s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not * matter since it will be recomputed at next deflate call. */ } } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit (s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; } if (bflush) FLUSH_BLOCK(s, 0); } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } #ifndef FASTEST /* =========================================================================== * Same as above, but achieves better compression. We use a lazy * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ local block_state deflate_slow(s, flush) deflate_state *s; int flush; { IPos hash_head = NIL; /* head of hash chain */ int bflush; /* set if current block must be flushed */ /* Process the input block. */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. */ s->prev_length = s->match_length, s->prev_match = s->match_start; s->match_length = MIN_MATCH-1; if (hash_head != NIL && s->prev_length < s->max_lazy_match && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ if (s->strategy < Z_HUFFMAN_ONLY) { s->match_length = longest_match (s, hash_head); } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { s->match_length = longest_match_fast (s, hash_head); } /* longest_match() or longest_match_fast() sets match_start */ if (s->match_length <= 5 && (s->strategy == Z_FILTERED #if TOO_FAR <= 32767 || (s->match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR) #endif )) { /* If prev_match is also MIN_MATCH, match_start is garbage * but we will ignore the current match anyway. */ s->match_length = MIN_MATCH-1; } } /* If there was a match at the previous step and the current * match is not better, output the previous match: */ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; /* Do not insert strings in hash table beyond this. */ check_match(s, s->strstart-1, s->prev_match, s->prev_length); _tr_tally_dist(s, s->strstart -1 - s->prev_match, s->prev_length - MIN_MATCH, bflush); /* Insert in hash table all strings up to the end of the match. * strstart-1 and strstart are already inserted. If there is not * enough lookahead, the last two strings are not inserted in * the hash table. */ s->lookahead -= s->prev_length-1; s->prev_length -= 2; do { if (++s->strstart <= max_insert) { INSERT_STRING(s, s->strstart, hash_head); } } while (--s->prev_length != 0); s->match_available = 0; s->match_length = MIN_MATCH-1; s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); } else if (s->match_available) { /* If there was no match at the previous position, output a * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ Tracevv((stderr,"%c", s->window[s->strstart-1])); _tr_tally_lit(s, s->window[s->strstart-1], bflush); if (bflush) { FLUSH_BLOCK_ONLY(s, 0); } s->strstart++; s->lookahead--; if (s->strm->avail_out == 0) return need_more; } else { /* There is no previous match to compare with, wait for * the next step to decide. */ s->match_available = 1; s->strstart++; s->lookahead--; } } Assert (flush != Z_NO_FLUSH, "no flush?"); if (s->match_available) { Tracevv((stderr,"%c", s->window[s->strstart-1])); _tr_tally_lit(s, s->window[s->strstart-1], bflush); s->match_available = 0; } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } #endif /* FASTEST */ syslinux-legacy-3.63+dfsg/com32/lib/zlib/algorithm.txt0000664000175000017500000002217010777447272021375 0ustar evanevan1. Compression algorithm (deflate) The deflation algorithm used by gzip (also zip and zlib) is a variation of LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in the input data. The second occurrence of a string is replaced by a pointer to the previous string, in the form of a pair (distance, length). Distances are limited to 32K bytes, and lengths are limited to 258 bytes. When a string does not occur anywhere in the previous 32K bytes, it is emitted as a sequence of literal bytes. (In this description, `string' must be taken as an arbitrary sequence of bytes, and is not restricted to printable characters.) Literals or match lengths are compressed with one Huffman tree, and match distances are compressed with another tree. The trees are stored in a compact form at the start of each block. The blocks can have any size (except that the compressed data for one block must fit in available memory). A block is terminated when deflate() determines that it would be useful to start another block with fresh trees. (This is somewhat similar to the behavior of LZW-based _compress_.) Duplicated strings are found using a hash table. All input strings of length 3 are inserted in the hash table. A hash index is computed for the next 3 bytes. If the hash chain for this index is not empty, all strings in the chain are compared with the current input string, and the longest match is selected. The hash chains are searched starting with the most recent strings, to favor small distances and thus take advantage of the Huffman encoding. The hash chains are singly linked. There are no deletions from the hash chains, the algorithm simply discards matches that are too old. To avoid a worst-case situation, very long hash chains are arbitrarily truncated at a certain length, determined by a runtime option (level parameter of deflateInit). So deflate() does not always find the longest possible match but generally finds a match which is long enough. deflate() also defers the selection of matches with a lazy evaluation mechanism. After a match of length N has been found, deflate() searches for a longer match at the next input byte. If a longer match is found, the previous match is truncated to a length of one (thus producing a single literal byte) and the process of lazy evaluation begins again. Otherwise, the original match is kept, and the next match search is attempted only N steps later. The lazy match evaluation is also subject to a runtime parameter. If the current match is long enough, deflate() reduces the search for a longer match, thus speeding up the whole process. If compression ratio is more important than speed, deflate() attempts a complete second search even if the first match is already long enough. The lazy match evaluation is not performed for the fastest compression modes (level parameter 1 to 3). For these fast modes, new strings are inserted in the hash table only when no match was found, or when the match is not too long. This degrades the compression ratio but saves time since there are both fewer insertions and fewer searches. 2. Decompression algorithm (inflate) 2.1 Introduction The key question is how to represent a Huffman code (or any prefix code) so that you can decode fast. The most important characteristic is that shorter codes are much more common than longer codes, so pay attention to decoding the short codes fast, and let the long codes take longer to decode. inflate() sets up a first level table that covers some number of bits of input less than the length of longest code. It gets that many bits from the stream, and looks it up in the table. The table will tell if the next code is that many bits or less and how many, and if it is, it will tell the value, else it will point to the next level table for which inflate() grabs more bits and tries to decode a longer code. How many bits to make the first lookup is a tradeoff between the time it takes to decode and the time it takes to build the table. If building the table took no time (and if you had infinite memory), then there would only be a first level table to cover all the way to the longest code. However, building the table ends up taking a lot longer for more bits since short codes are replicated many times in such a table. What inflate() does is simply to make the number of bits in the first table a variable, and then to set that variable for the maximum speed. For inflate, which has 286 possible codes for the literal/length tree, the size of the first table is nine bits. Also the distance trees have 30 possible values, and the size of the first table is six bits. Note that for each of those cases, the table ended up one bit longer than the ``average'' code length, i.e. the code length of an approximately flat code which would be a little more than eight bits for 286 symbols and a little less than five bits for 30 symbols. 2.2 More details on the inflate table lookup Ok, you want to know what this cleverly obfuscated inflate tree actually looks like. You are correct that it's not a Huffman tree. It is simply a lookup table for the first, let's say, nine bits of a Huffman symbol. The symbol could be as short as one bit or as long as 15 bits. If a particular symbol is shorter than nine bits, then that symbol's translation is duplicated in all those entries that start with that symbol's bits. For example, if the symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a symbol is nine bits long, it appears in the table once. If the symbol is longer than nine bits, then that entry in the table points to another similar table for the remaining bits. Again, there are duplicated entries as needed. The idea is that most of the time the symbol will be short and there will only be one table look up. (That's whole idea behind data compression in the first place.) For the less frequent long symbols, there will be two lookups. If you had a compression method with really long symbols, you could have as many levels of lookups as is efficient. For inflate, two is enough. So a table entry either points to another table (in which case nine bits in the above example are gobbled), or it contains the translation for the symbol and the number of bits to gobble. Then you start again with the next ungobbled bit. You may wonder: why not just have one lookup table for how ever many bits the longest symbol is? The reason is that if you do that, you end up spending more time filling in duplicate symbol entries than you do actually decoding. At least for deflate's output that generates new trees every several 10's of kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code would take too long if you're only decoding several thousand symbols. At the other extreme, you could make a new table for every bit in the code. In fact, that's essentially a Huffman tree. But then you spend two much time traversing the tree while decoding, even for short symbols. So the number of bits for the first lookup table is a trade of the time to fill out the table vs. the time spent looking at the second level and above of the table. Here is an example, scaled down: The code being decoded, with 10 symbols, from 1 to 6 bits long: A: 0 B: 10 C: 1100 D: 11010 E: 11011 F: 11100 G: 11101 H: 11110 I: 111110 J: 111111 Let's make the first table three bits long (eight entries): 000: A,1 001: A,1 010: A,1 011: A,1 100: B,2 101: B,2 110: -> table X (gobble 3 bits) 111: -> table Y (gobble 3 bits) Each entry is what the bits decode as and how many bits that is, i.e. how many bits to gobble. Or the entry points to another table, with the number of bits to gobble implicit in the size of the table. Table X is two bits long since the longest code starting with 110 is five bits long: 00: C,1 01: C,1 10: D,2 11: E,2 Table Y is three bits long since the longest code starting with 111 is six bits long: 000: F,2 001: F,2 010: G,2 011: G,2 100: H,2 101: H,2 110: I,3 111: J,3 So what we have here are three tables with a total of 20 entries that had to be constructed. That's compared to 64 entries for a single table. Or compared to 16 entries for a Huffman tree (six two entry tables and one four entry table). Assuming that the code ideally represents the probability of the symbols, it takes on the average 1.25 lookups per symbol. That's compared to one lookup for the single table, or 1.66 lookups per symbol for the Huffman tree. There, I think that gives you a picture of what's going on. For inflate, the meaning of a particular symbol is often more than just a letter. It can be a byte (a "literal"), or it can be either a length or a distance which indicates a base value and a number of bits to fetch after the code that is added to the base value. Or it might be the special end-of-block code. The data structures created in inftrees.c try to encode all that information compactly in the tables. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu References: [LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, pp. 337-343. ``DEFLATE Compressed Data Format Specification'' available in http://www.ietf.org/rfc/rfc1951.txt syslinux-legacy-3.63+dfsg/com32/lib/zlib/adler32.c0000664000175000017500000000425510777447272020252 0ustar evanevan/* adler32.c -- compute the Adler-32 checksum of a data stream * Copyright (C) 1995-2003 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #define ZLIB_INTERNAL #include "zlib.h" #define BASE 65521UL /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ #define DO1(buf,i) {s1 += buf[i]; s2 += s1;} #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); #ifdef NO_DIVIDE # define MOD(a) \ do { \ if (a >= (BASE << 16)) a -= (BASE << 16); \ if (a >= (BASE << 15)) a -= (BASE << 15); \ if (a >= (BASE << 14)) a -= (BASE << 14); \ if (a >= (BASE << 13)) a -= (BASE << 13); \ if (a >= (BASE << 12)) a -= (BASE << 12); \ if (a >= (BASE << 11)) a -= (BASE << 11); \ if (a >= (BASE << 10)) a -= (BASE << 10); \ if (a >= (BASE << 9)) a -= (BASE << 9); \ if (a >= (BASE << 8)) a -= (BASE << 8); \ if (a >= (BASE << 7)) a -= (BASE << 7); \ if (a >= (BASE << 6)) a -= (BASE << 6); \ if (a >= (BASE << 5)) a -= (BASE << 5); \ if (a >= (BASE << 4)) a -= (BASE << 4); \ if (a >= (BASE << 3)) a -= (BASE << 3); \ if (a >= (BASE << 2)) a -= (BASE << 2); \ if (a >= (BASE << 1)) a -= (BASE << 1); \ if (a >= BASE) a -= BASE; \ } while (0) #else # define MOD(a) a %= BASE #endif /* ========================================================================= */ uLong ZEXPORT adler32(adler, buf, len) uLong adler; const Bytef *buf; uInt len; { unsigned long s1 = adler & 0xffff; unsigned long s2 = (adler >> 16) & 0xffff; int k; if (buf == Z_NULL) return 1L; while (len > 0) { k = len < NMAX ? (int)len : NMAX; len -= k; while (k >= 16) { DO16(buf); buf += 16; k -= 16; } if (k != 0) do { s1 += *buf++; s2 += s1; } while (--k); MOD(s1); MOD(s2); } return (s2 << 16) | s1; } syslinux-legacy-3.63+dfsg/com32/lib/zlib/inftrees.c0000664000175000017500000003202010777447272020624 0ustar evanevan/* inftrees.c -- generate Huffman trees for efficient decoding * Copyright (C) 1995-2003 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "inftrees.h" #define MAXBITS 15 const char inflate_copyright[] = " inflate 1.2.1 Copyright 1995-2003 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ /* Build a set of tables to decode the provided canonical Huffman code. The code lengths are lens[0..codes-1]. The result starts at *table, whose indices are 0..2^bits-1. work is a writable array of at least lens shorts, which is used as a work area. type is the type of code to be generated, CODES, LENS, or DISTS. On return, zero is success, -1 is an invalid code, and +1 means that ENOUGH isn't enough. table on return points to the next available entry's address. bits is the requested root table index bits, and on return it is the actual root table index bits. It will differ if the request is greater than the longest code or if it is less than the shortest code. */ int inflate_table(type, lens, codes, table, bits, work) codetype type; unsigned short FAR *lens; unsigned codes; code FAR * FAR *table; unsigned FAR *bits; unsigned short FAR *work; { unsigned len; /* a code's length in bits */ unsigned sym; /* index of code symbols */ unsigned min, max; /* minimum and maximum code lengths */ unsigned root; /* number of index bits for root table */ unsigned curr; /* number of index bits for current table */ unsigned drop; /* code bits to drop for sub-table */ int left; /* number of prefix codes available */ unsigned used; /* code entries in table used */ unsigned huff; /* Huffman code */ unsigned incr; /* for incrementing code, index */ unsigned fill; /* index for replicating entries */ unsigned low; /* low bits for current root entry */ unsigned mask; /* mask for low root bits */ code this; /* table entry for duplication */ code FAR *next; /* next available space in table */ const unsigned short FAR *base; /* base value table to use */ const unsigned short FAR *extra; /* extra bits table to use */ int end; /* use base and extra for symbol > end */ unsigned short count[MAXBITS+1]; /* number of codes of each length */ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ static const unsigned short lbase[31] = { /* Length codes 257..285 base */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 76, 66}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0}; static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64}; /* Process a set of code lengths to create a canonical Huffman code. The code lengths are lens[0..codes-1]. Each length corresponds to the symbols 0..codes-1. The Huffman code is generated by first sorting the symbols by length from short to long, and retaining the symbol order for codes with equal lengths. Then the code starts with all zero bits for the first code of the shortest length, and the codes are integer increments for the same length, and zeros are appended as the length increases. For the deflate format, these bits are stored backwards from their more natural integer increment ordering, and so when the decoding tables are built in the large loop below, the integer codes are incremented backwards. This routine assumes, but does not check, that all of the entries in lens[] are in the range 0..MAXBITS. The caller must assure this. 1..MAXBITS is interpreted as that code length. zero means that that symbol does not occur in this code. The codes are sorted by computing a count of codes for each length, creating from that a table of starting indices for each length in the sorted table, and then entering the symbols in order in the sorted table. The sorted table is work[], with that space being provided by the caller. The length counts are used for other purposes as well, i.e. finding the minimum and maximum length codes, determining if there are any codes at all, checking for a valid set of lengths, and looking ahead at length counts to determine sub-table sizes when building the decoding tables. */ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ for (len = 0; len <= MAXBITS; len++) count[len] = 0; for (sym = 0; sym < codes; sym++) count[lens[sym]]++; /* bound code lengths, force root to be within code lengths */ root = *bits; for (max = MAXBITS; max >= 1; max--) if (count[max] != 0) break; if (root > max) root = max; if (max == 0) return -1; /* no codes! */ for (min = 1; min <= MAXBITS; min++) if (count[min] != 0) break; if (root < min) root = min; /* check for an over-subscribed or incomplete set of lengths */ left = 1; for (len = 1; len <= MAXBITS; len++) { left <<= 1; left -= count[len]; if (left < 0) return -1; /* over-subscribed */ } if (left > 0 && (type == CODES || (codes - count[0] != 1))) return -1; /* incomplete set */ /* generate offsets into symbol table for each length for sorting */ offs[1] = 0; for (len = 1; len < MAXBITS; len++) offs[len + 1] = offs[len] + count[len]; /* sort symbols by length, by symbol order within each length */ for (sym = 0; sym < codes; sym++) if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; /* Create and fill in decoding tables. In this loop, the table being filled is at next and has curr index bits. The code being used is huff with length len. That code is converted to an index by dropping drop bits off of the bottom. For codes where len is less than drop + curr, those top drop + curr - len bits are incremented through all values to fill the table with replicated entries. root is the number of index bits for the root table. When len exceeds root, sub-tables are created pointed to by the root entry with an index of the low root bits of huff. This is saved in low to check for when a new sub-table should be started. drop is zero when the root table is being filled, and drop is root when sub-tables are being filled. When a new sub-table is needed, it is necessary to look ahead in the code lengths to determine what size sub-table is needed. The length counts are used for this, and so count[] is decremented as codes are entered in the tables. used keeps track of how many table entries have been allocated from the provided *table space. It is checked when a LENS table is being made against the space in *table, ENOUGH, minus the maximum space needed by the worst case distance code, MAXD. This should never happen, but the sufficiency of ENOUGH has not been proven exhaustively, hence the check. This assumes that when type == LENS, bits == 9. sym increments through all symbols, and the loop terminates when all codes of length max, i.e. all codes, have been processed. This routine permits incomplete codes, so another loop after this one fills in the rest of the decoding tables with invalid code markers. */ /* set up for code type */ switch (type) { case CODES: base = extra = work; /* dummy value--not used */ end = 19; break; case LENS: base = lbase; base -= 257; extra = lext; extra -= 257; end = 256; break; default: /* DISTS */ base = dbase; extra = dext; end = -1; } /* initialize state for loop */ huff = 0; /* starting code */ sym = 0; /* starting code symbol */ len = min; /* starting code length */ next = *table; /* current table to fill in */ curr = root; /* current table index bits */ drop = 0; /* current bits to drop from code for index */ low = (unsigned)(-1); /* trigger new sub-table when len > root */ used = 1U << root; /* use root table entries */ mask = used - 1; /* mask for comparing low */ /* check available table space */ if (type == LENS && used >= ENOUGH - MAXD) return 1; /* process all codes and make table entries */ for (;;) { /* create table entry */ this.bits = (unsigned char)(len - drop); if ((int)(work[sym]) < end) { this.op = (unsigned char)0; this.val = work[sym]; } else if ((int)(work[sym]) > end) { this.op = (unsigned char)(extra[work[sym]]); this.val = base[work[sym]]; } else { this.op = (unsigned char)(32 + 64); /* end of block */ this.val = 0; } /* replicate for those indices with low len bits equal to huff */ incr = 1U << (len - drop); fill = 1U << curr; do { fill -= incr; next[(huff >> drop) + fill] = this; } while (fill != 0); /* backwards increment the len-bit code huff */ incr = 1U << (len - 1); while (huff & incr) incr >>= 1; if (incr != 0) { huff &= incr - 1; huff += incr; } else huff = 0; /* go to next symbol, update count, len */ sym++; if (--(count[len]) == 0) { if (len == max) break; len = lens[work[sym]]; } /* create new sub-table if needed */ if (len > root && (huff & mask) != low) { /* if first time, transition to sub-tables */ if (drop == 0) drop = root; /* increment past last table */ next += 1U << curr; /* determine length of next table */ curr = len - drop; left = (int)(1 << curr); while (curr + drop < max) { left -= count[curr + drop]; if (left <= 0) break; curr++; left <<= 1; } /* check for enough space */ used += 1U << curr; if (type == LENS && used >= ENOUGH - MAXD) return 1; /* point entry in root table to sub-table */ low = huff & mask; (*table)[low].op = (unsigned char)curr; (*table)[low].bits = (unsigned char)root; (*table)[low].val = (unsigned short)(next - *table); } } /* Fill in rest of table for incomplete codes. This loop is similar to the loop above in incrementing huff for table indices. It is assumed that len is equal to curr + drop, so there is no loop needed to increment through high index bits. When the current sub-table is filled, the loop drops back to the root table to fill in any remaining entries there. */ this.op = (unsigned char)64; /* invalid code marker */ this.bits = (unsigned char)(len - drop); this.val = (unsigned short)0; while (huff != 0) { /* when done with sub-table, drop back to root table */ if (drop != 0 && (huff & mask) != low) { drop = 0; len = root; next = *table; curr = root; this.bits = (unsigned char)len; } /* put invalid code marker in table */ next[huff >> drop] = this; /* backwards increment the len-bit code huff */ incr = 1U << (len - 1); while (huff & incr) incr >>= 1; if (incr != 0) { huff &= incr - 1; huff += incr; } else huff = 0; } /* set return parameters */ *table += used; *bits = root; return 0; } syslinux-legacy-3.63+dfsg/com32/lib/zlib/uncompr.c0000664000175000017500000000402710777447272020476 0ustar evanevan/* uncompr.c -- decompress a memory buffer * Copyright (C) 1995-2003 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ #define ZLIB_INTERNAL #include "zlib.h" /* =========================================================================== Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the compressed buffer. This function can be used to decompress a whole file at once if the input file is mmap'ed. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted. */ int ZEXPORT uncompress (dest, destLen, source, sourceLen) Bytef *dest; uLongf *destLen; const Bytef *source; uLong sourceLen; { z_stream stream; int err; stream.next_in = (Bytef*)source; stream.avail_in = (uInt)sourceLen; /* Check for source > 64K on 16-bit machine: */ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; stream.next_out = dest; stream.avail_out = (uInt)*destLen; if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; err = inflateInit(&stream); if (err != Z_OK) return err; err = inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { inflateEnd(&stream); if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) return Z_DATA_ERROR; return err; } *destLen = stream.total_out; err = inflateEnd(&stream); return err; } syslinux-legacy-3.63+dfsg/com32/lib/zlib/gzio.c0000664000175000017500000007374010777447272017773 0ustar evanevan/* gzio.c -- IO on .gz files * Copyright (C) 1995-2003 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h * * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. */ #include #include "zutil.h" #ifdef NO_DEFLATE /* for compatiblity with old definition */ # define NO_GZCOMPRESS #endif #ifndef NO_DUMMY_DECL struct internal_state {int dummy;}; /* for buggy compilers */ #endif #ifndef Z_BUFSIZE # ifdef MAXSEG_64K # define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ # else # define Z_BUFSIZE 16384 # endif #endif #ifndef Z_PRINTF_BUFSIZE # define Z_PRINTF_BUFSIZE 4096 #endif #ifdef __MVS__ # pragma map (fdopen , "\174\174FDOPEN") FILE *fdopen(int, const char *); #endif #ifndef STDC extern voidp malloc OF((uInt size)); extern void free OF((voidpf ptr)); #endif #define ALLOC(size) malloc(size) #define TRYFREE(p) {if (p) free(p);} static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define RESERVED 0xE0 /* bits 5..7: reserved */ typedef struct gz_stream { z_stream stream; int z_err; /* error code for last stream operation */ int z_eof; /* set if end of input file */ FILE *file; /* .gz file */ Byte *inbuf; /* input buffer */ Byte *outbuf; /* output buffer */ uLong crc; /* crc32 of uncompressed data */ char *msg; /* error message */ char *path; /* path name for debugging only */ int transparent; /* 1 if input file is not a .gz file */ char mode; /* 'w' or 'r' */ z_off_t start; /* start of compressed data in file (header skipped) */ z_off_t in; /* bytes into deflate or inflate */ z_off_t out; /* bytes out of deflate or inflate */ int back; /* one character push-back */ int last; /* true if push-back is last character */ } gz_stream; local gzFile gz_open OF((const char *path, const char *mode, int fd)); local int do_flush OF((gzFile file, int flush)); local int get_byte OF((gz_stream *s)); local void check_header OF((gz_stream *s)); local int destroy OF((gz_stream *s)); local void putLong OF((FILE *file, uLong x)); local uLong getLong OF((gz_stream *s)); /* =========================================================================== Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb"). The file is given either by file descriptor or path name (if fd == -1). gz_open returns NULL if the file could not be opened or if there was insufficient memory to allocate the (de)compression state; errno can be checked to distinguish the two cases (if errno is zero, the zlib error is Z_MEM_ERROR). */ local gzFile gz_open (path, mode, fd) const char *path; const char *mode; int fd; { int err; int level = Z_DEFAULT_COMPRESSION; /* compression level */ int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ char *p = (char*)mode; gz_stream *s; char fmode[80]; /* copy of mode, without the compression level */ char *m = fmode; if (!path || !mode) return Z_NULL; s = (gz_stream *)ALLOC(sizeof(gz_stream)); if (!s) return Z_NULL; s->stream.zalloc = (alloc_func)0; s->stream.zfree = (free_func)0; s->stream.opaque = (voidpf)0; s->stream.next_in = s->inbuf = Z_NULL; s->stream.next_out = s->outbuf = Z_NULL; s->stream.avail_in = s->stream.avail_out = 0; s->file = NULL; s->z_err = Z_OK; s->z_eof = 0; s->in = 0; s->out = 0; s->back = EOF; s->crc = crc32(0L, Z_NULL, 0); s->msg = NULL; s->transparent = 0; s->path = (char*)ALLOC(strlen(path)+1); if (s->path == NULL) { return destroy(s), (gzFile)Z_NULL; } strcpy(s->path, path); /* do this early for debugging */ s->mode = '\0'; do { if (*p == 'r') s->mode = 'r'; if (*p == 'w' || *p == 'a') s->mode = 'w'; if (*p >= '0' && *p <= '9') { level = *p - '0'; } else if (*p == 'f') { strategy = Z_FILTERED; } else if (*p == 'h') { strategy = Z_HUFFMAN_ONLY; } else if (*p == 'R') { strategy = Z_RLE; } else { *m++ = *p; /* copy the mode */ } } while (*p++ && m != fmode + sizeof(fmode)); if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; if (s->mode == 'w') { #ifdef NO_GZCOMPRESS err = Z_STREAM_ERROR; #else err = deflateInit2(&(s->stream), level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); /* windowBits is passed < 0 to suppress zlib header */ s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); #endif if (err != Z_OK || s->outbuf == Z_NULL) { return destroy(s), (gzFile)Z_NULL; } } else { s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); err = inflateInit2(&(s->stream), -MAX_WBITS); /* windowBits is passed < 0 to tell that there is no zlib header. * Note that in this case inflate *requires* an extra "dummy" byte * after the compressed stream in order to complete decompression and * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are * present after the compressed stream. */ if (err != Z_OK || s->inbuf == Z_NULL) { return destroy(s), (gzFile)Z_NULL; } } s->stream.avail_out = Z_BUFSIZE; errno = 0; s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); if (s->file == NULL) { return destroy(s), (gzFile)Z_NULL; } if (s->mode == 'w') { /* Write a very simple .gz header: */ fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); s->start = 10L; /* We use 10L instead of ftell(s->file) to because ftell causes an * fflush on some systems. This version of the library doesn't use * start anyway in write mode, so this initialization is not * necessary. */ } else { check_header(s); /* skip the .gz header */ s->start = ftell(s->file) - s->stream.avail_in; } return (gzFile)s; } /* =========================================================================== Opens a gzip (.gz) file for reading or writing. */ gzFile ZEXPORT gzopen (path, mode) const char *path; const char *mode; { return gz_open (path, mode, -1); } /* =========================================================================== Associate a gzFile with the file descriptor fd. fd is not dup'ed here to mimic the behavio(u)r of fdopen. */ gzFile ZEXPORT gzdopen (fd, mode) int fd; const char *mode; { char name[20]; if (fd < 0) return (gzFile)Z_NULL; sprintf(name, "", fd); /* for debugging */ return gz_open (name, mode, fd); } /* =========================================================================== * Update the compression level and strategy */ int ZEXPORT gzsetparams (file, level, strategy) gzFile file; int level; int strategy; { gz_stream *s = (gz_stream*)file; if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; /* Make room to allow flushing */ if (s->stream.avail_out == 0) { s->stream.next_out = s->outbuf; if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { s->z_err = Z_ERRNO; } s->stream.avail_out = Z_BUFSIZE; } return deflateParams (&(s->stream), level, strategy); } /* =========================================================================== Read a byte from a gz_stream; update next_in and avail_in. Return EOF for end of file. IN assertion: the stream s has been sucessfully opened for reading. */ local int get_byte(s) gz_stream *s; { if (s->z_eof) return EOF; if (s->stream.avail_in == 0) { errno = 0; s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); if (s->stream.avail_in == 0) { s->z_eof = 1; /* klibc hack */ if (errno) s->z_err = Z_ERRNO; return EOF; } s->stream.next_in = s->inbuf; } s->stream.avail_in--; return *(s->stream.next_in)++; } /* =========================================================================== Check the gzip header of a gz_stream opened for reading. Set the stream mode to transparent if the gzip magic header is not present; set s->err to Z_DATA_ERROR if the magic header is present but the rest of the header is incorrect. IN assertion: the stream s has already been created sucessfully; s->stream.avail_in is zero for the first time, but may be non-zero for concatenated .gz files. */ local void check_header(s) gz_stream *s; { int method; /* method byte */ int flags; /* flags byte */ uInt len; int c; /* Assure two bytes in the buffer so we can peek ahead -- handle case where first byte of header is at the end of the buffer after the last gzip segment */ len = s->stream.avail_in; if (len < 2) { if (len) s->inbuf[0] = s->stream.next_in[0]; errno = 0; len = fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); /* klibc hack */ if (len == 0 && errno) s->z_err = Z_ERRNO; s->stream.avail_in += len; s->stream.next_in = s->inbuf; if (s->stream.avail_in < 2) { s->transparent = s->stream.avail_in; return; } } /* Peek ahead to check the gzip magic header */ if (s->stream.next_in[0] != gz_magic[0] || s->stream.next_in[1] != gz_magic[1]) { s->transparent = 1; return; } s->stream.avail_in -= 2; s->stream.next_in += 2; /* Check the rest of the gzip header */ method = get_byte(s); flags = get_byte(s); if (method != Z_DEFLATED || (flags & RESERVED) != 0) { s->z_err = Z_DATA_ERROR; return; } /* Discard time, xflags and OS code: */ for (len = 0; len < 6; len++) (void)get_byte(s); if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ len = (uInt)get_byte(s); len += ((uInt)get_byte(s))<<8; /* len is garbage if EOF but the loop below will quit anyway */ while (len-- != 0 && get_byte(s) != EOF) ; } if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ while ((c = get_byte(s)) != 0 && c != EOF) ; } if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ while ((c = get_byte(s)) != 0 && c != EOF) ; } if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ for (len = 0; len < 2; len++) (void)get_byte(s); } s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; } /* =========================================================================== * Cleanup then free the given gz_stream. Return a zlib error code. Try freeing in the reverse order of allocations. */ local int destroy (s) gz_stream *s; { int err = Z_OK; if (!s) return Z_STREAM_ERROR; TRYFREE(s->msg); if (s->stream.state != NULL) { if (s->mode == 'w') { #ifdef NO_GZCOMPRESS err = Z_STREAM_ERROR; #else err = deflateEnd(&(s->stream)); #endif } else if (s->mode == 'r') { err = inflateEnd(&(s->stream)); } } if (s->file != NULL && fclose(s->file)) { #ifdef ESPIPE if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ #endif err = Z_ERRNO; } if (s->z_err < 0) err = s->z_err; TRYFREE(s->inbuf); TRYFREE(s->outbuf); TRYFREE(s->path); TRYFREE(s); return err; } /* =========================================================================== Reads the given number of uncompressed bytes from the compressed file. gzread returns the number of bytes actually read (0 for end of file). */ int ZEXPORT gzread (file, buf, len) gzFile file; voidp buf; unsigned len; { gz_stream *s = (gz_stream*)file; Bytef *start = (Bytef*)buf; /* starting point for crc computation */ Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; if (s->z_err == Z_STREAM_END) return 0; /* EOF */ next_out = (Byte*)buf; s->stream.next_out = (Bytef*)buf; s->stream.avail_out = len; if (s->stream.avail_out && s->back != EOF) { *next_out++ = s->back; s->stream.next_out++; s->stream.avail_out--; s->back = EOF; s->out++; if (s->last) { s->z_err = Z_STREAM_END; return 1; } } while (s->stream.avail_out != 0) { if (s->transparent) { /* Copy first the lookahead bytes: */ uInt n = s->stream.avail_in; if (n > s->stream.avail_out) n = s->stream.avail_out; if (n > 0) { zmemcpy(s->stream.next_out, s->stream.next_in, n); next_out += n; s->stream.next_out = next_out; s->stream.next_in += n; s->stream.avail_out -= n; s->stream.avail_in -= n; } if (s->stream.avail_out > 0) { s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, s->file); } len -= s->stream.avail_out; s->in += len; s->out += len; if (len == 0) s->z_eof = 1; return (int)len; } if (s->stream.avail_in == 0 && !s->z_eof) { errno = 0; s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); if (s->stream.avail_in == 0) { s->z_eof = 1; if (errno) { s->z_err = Z_ERRNO; break; } } s->stream.next_in = s->inbuf; } s->in += s->stream.avail_in; s->out += s->stream.avail_out; s->z_err = inflate(&(s->stream), Z_NO_FLUSH); s->in -= s->stream.avail_in; s->out -= s->stream.avail_out; if (s->z_err == Z_STREAM_END) { /* Check CRC and original size */ s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); start = s->stream.next_out; if (getLong(s) != s->crc) { s->z_err = Z_DATA_ERROR; } else { (void)getLong(s); /* The uncompressed length returned by above getlong() may be * different from s->out in case of concatenated .gz files. * Check for such files: */ check_header(s); if (s->z_err == Z_OK) { inflateReset(&(s->stream)); s->crc = crc32(0L, Z_NULL, 0); } } } if (s->z_err != Z_OK || s->z_eof) break; } s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); return (int)(len - s->stream.avail_out); } /* =========================================================================== Reads one byte from the compressed file. gzgetc returns this byte or -1 in case of end of file or error. */ int ZEXPORT gzgetc(file) gzFile file; { unsigned char c; return gzread(file, &c, 1) == 1 ? c : -1; } /* =========================================================================== Push one byte back onto the stream. */ int ZEXPORT gzungetc(c, file) int c; gzFile file; { gz_stream *s = (gz_stream*)file; if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; s->back = c; s->out--; s->last = (s->z_err == Z_STREAM_END); if (s->last) s->z_err = Z_OK; s->z_eof = 0; return c; } /* =========================================================================== Reads bytes from the compressed file until len-1 characters are read, or a newline character is read and transferred to buf, or an end-of-file condition is encountered. The string is then terminated with a null character. gzgets returns buf, or Z_NULL in case of error. The current implementation is not optimized at all. */ char * ZEXPORT gzgets(file, buf, len) gzFile file; char *buf; int len; { char *b = buf; if (buf == Z_NULL || len <= 0) return Z_NULL; while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; *buf = '\0'; return b == buf && len > 0 ? Z_NULL : b; } #ifndef NO_GZCOMPRESS /* =========================================================================== Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of bytes actually written (0 in case of error). */ int ZEXPORT gzwrite (file, buf, len) gzFile file; voidpc buf; unsigned len; { gz_stream *s = (gz_stream*)file; if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; s->stream.next_in = (Bytef*)buf; s->stream.avail_in = len; while (s->stream.avail_in != 0) { if (s->stream.avail_out == 0) { s->stream.next_out = s->outbuf; if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { s->z_err = Z_ERRNO; break; } s->stream.avail_out = Z_BUFSIZE; } s->in += s->stream.avail_in; s->out += s->stream.avail_out; s->z_err = deflate(&(s->stream), Z_NO_FLUSH); s->in -= s->stream.avail_in; s->out -= s->stream.avail_out; if (s->z_err != Z_OK) break; } s->crc = crc32(s->crc, (const Bytef *)buf, len); return (int)(len - s->stream.avail_in); } /* =========================================================================== Converts, formats, and writes the args to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of uncompressed bytes actually written (0 in case of error). */ #ifdef STDC #include int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) { char buf[Z_PRINTF_BUFSIZE]; va_list va; int len; buf[sizeof(buf) - 1] = 0; va_start(va, format); #ifdef NO_vsnprintf # ifdef HAS_vsprintf_void (void)vsprintf(buf, format, va); va_end(va); for (len = 0; len < sizeof(buf); len++) if (buf[len] == 0) break; # else len = vsprintf(buf, format, va); va_end(va); # endif #else # ifdef HAS_vsnprintf_void (void)vsnprintf(buf, sizeof(buf), format, va); va_end(va); len = strlen(buf); # else len = vsnprintf(buf, sizeof(buf), format, va); va_end(va); # endif #endif if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) return 0; return gzwrite(file, buf, (unsigned)len); } #else /* not ANSI C */ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) gzFile file; const char *format; int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; { char buf[Z_PRINTF_BUFSIZE]; int len; buf[sizeof(buf) - 1] = 0; #ifdef NO_snprintf # ifdef HAS_sprintf_void sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); for (len = 0; len < sizeof(buf); len++) if (buf[len] == 0) break; # else len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); # endif #else # ifdef HAS_snprintf_void snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); len = strlen(buf); # else len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); # endif #endif if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) return 0; return gzwrite(file, buf, len); } #endif /* =========================================================================== Writes c, converted to an unsigned char, into the compressed file. gzputc returns the value that was written, or -1 in case of error. */ int ZEXPORT gzputc(file, c) gzFile file; int c; { unsigned char cc = (unsigned char) c; /* required for big endian systems */ return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; } /* =========================================================================== Writes the given null-terminated string to the compressed file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. */ int ZEXPORT gzputs(file, s) gzFile file; const char *s; { return gzwrite(file, (char*)s, (unsigned)strlen(s)); } /* =========================================================================== Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. */ local int do_flush (file, flush) gzFile file; int flush; { uInt len; int done = 0; gz_stream *s = (gz_stream*)file; if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; s->stream.avail_in = 0; /* should be zero already anyway */ for (;;) { len = Z_BUFSIZE - s->stream.avail_out; if (len != 0) { if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { s->z_err = Z_ERRNO; return Z_ERRNO; } s->stream.next_out = s->outbuf; s->stream.avail_out = Z_BUFSIZE; } if (done) break; s->out += s->stream.avail_out; s->z_err = deflate(&(s->stream), flush); s->out -= s->stream.avail_out; /* Ignore the second of two consecutive flushes: */ if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; /* deflate has finished flushing only when it hasn't used up * all the available space in the output buffer: */ done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; } return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; } int ZEXPORT gzflush (file, flush) gzFile file; int flush; { gz_stream *s = (gz_stream*)file; int err = do_flush (file, flush); if (err) return err; fflush(s->file); return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; } #endif /* NO_GZCOMPRESS */ /* =========================================================================== Sets the starting position for the next gzread or gzwrite on the given compressed file. The offset represents a number of bytes in the gzseek returns the resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error. SEEK_END is not implemented, returns error. In this version of the library, gzseek can be extremely slow. */ #if 0 /* COM32: seek not supported */ z_off_t ZEXPORT gzseek (file, offset, whence) gzFile file; z_off_t offset; int whence; { gz_stream *s = (gz_stream*)file; if (s == NULL || whence == SEEK_END || s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { return -1L; } if (s->mode == 'w') { #ifdef NO_GZCOMPRESS return -1L; #else if (whence == SEEK_SET) { offset -= s->in; } if (offset < 0) return -1L; /* At this point, offset is the number of zero bytes to write. */ if (s->inbuf == Z_NULL) { s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ if (s->inbuf == Z_NULL) return -1L; zmemzero(s->inbuf, Z_BUFSIZE); } while (offset > 0) { uInt size = Z_BUFSIZE; if (offset < Z_BUFSIZE) size = (uInt)offset; size = gzwrite(file, s->inbuf, size); if (size == 0) return -1L; offset -= size; } return s->in; #endif } /* Rest of function is for reading only */ /* compute absolute position */ if (whence == SEEK_CUR) { offset += s->out; } if (offset < 0) return -1L; if (s->transparent) { /* map to fseek */ s->back = EOF; s->stream.avail_in = 0; s->stream.next_in = s->inbuf; if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; s->in = s->out = offset; return offset; } /* For a negative seek, rewind and use positive seek */ if (offset >= s->out) { offset -= s->out; } else if (gzrewind(file) < 0) { return -1L; } /* offset is now the number of bytes to skip. */ if (offset != 0 && s->outbuf == Z_NULL) { s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); if (s->outbuf == Z_NULL) return -1L; } if (offset && s->back != EOF) { s->back = EOF; s->out++; offset--; if (s->last) s->z_err = Z_STREAM_END; } while (offset > 0) { int size = Z_BUFSIZE; if (offset < Z_BUFSIZE) size = (int)offset; size = gzread(file, s->outbuf, (uInt)size); if (size <= 0) return -1L; offset -= size; } return s->out; } #endif /* =========================================================================== Rewinds input file. */ #if 0 /* COM32: seek not supported */ int ZEXPORT gzrewind (file) gzFile file; { gz_stream *s = (gz_stream*)file; if (s == NULL || s->mode != 'r') return -1; s->z_err = Z_OK; s->z_eof = 0; s->back = EOF; s->stream.avail_in = 0; s->stream.next_in = s->inbuf; s->crc = crc32(0L, Z_NULL, 0); if (!s->transparent) (void)inflateReset(&s->stream); s->in = 0; s->out = 0; return fseek(s->file, s->start, SEEK_SET); } #endif /* =========================================================================== Returns the starting position for the next gzread or gzwrite on the given compressed file. This position represents a number of bytes in the uncompressed data stream. */ #if 0 /* COM32: seek not supported */ z_off_t ZEXPORT gztell (file) gzFile file; { return gzseek(file, 0L, SEEK_CUR); } #endif /* =========================================================================== Returns 1 when EOF has previously been detected reading the given input stream, otherwise zero. */ int ZEXPORT gzeof (file) gzFile file; { gz_stream *s = (gz_stream*)file; /* With concatenated compressed files that can have embedded * crc trailers, z_eof is no longer the only/best indicator of EOF * on a gz_stream. Handle end-of-stream error explicitly here. */ if (s == NULL || s->mode != 'r') return 0; if (s->z_eof) return 1; return s->z_err == Z_STREAM_END; } /* =========================================================================== Outputs a long in LSB order to the given file */ local void putLong (file, x) FILE *file; uLong x; { int n; for (n = 0; n < 4; n++) { fputc((int)(x & 0xff), file); x >>= 8; } } /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets z_err in case of error. */ local uLong getLong (s) gz_stream *s; { uLong x = (uLong)get_byte(s); int c; x += ((uLong)get_byte(s))<<8; x += ((uLong)get_byte(s))<<16; c = get_byte(s); if (c == EOF) s->z_err = Z_DATA_ERROR; x += ((uLong)c)<<24; return x; } /* =========================================================================== Flushes all pending output if necessary, closes the compressed file and deallocates all the (de)compression state. */ int ZEXPORT gzclose (file) gzFile file; { int err; gz_stream *s = (gz_stream*)file; if (s == NULL) return Z_STREAM_ERROR; if (s->mode == 'w') { #ifdef NO_GZCOMPRESS return Z_STREAM_ERROR; #else err = do_flush (file, Z_FINISH); if (err != Z_OK) return destroy((gz_stream*)file); putLong (s->file, s->crc); putLong (s->file, (uLong)(s->in & 0xffffffff)); #endif } return destroy((gz_stream*)file); } /* =========================================================================== Returns the error message for the last error which occured on the given compressed file. errnum is set to zlib error number. If an error occured in the file system and not in the compression library, errnum is set to Z_ERRNO and the application may consult errno to get the exact error code. */ const char * ZEXPORT gzerror (file, errnum) gzFile file; int *errnum; { char *m; gz_stream *s = (gz_stream*)file; if (s == NULL) { *errnum = Z_STREAM_ERROR; return (const char*)ERR_MSG(Z_STREAM_ERROR); } *errnum = s->z_err; if (*errnum == Z_OK) return (const char*)""; m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); TRYFREE(s->msg); s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); strcpy(s->msg, s->path); strcat(s->msg, ": "); strcat(s->msg, m); return (const char*)s->msg; } /* =========================================================================== Clear the error and end-of-file flags, and do the same for the real file. */ void ZEXPORT gzclearerr (file) gzFile file; { gz_stream *s = (gz_stream*)file; if (s == NULL) return; if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; s->z_eof = 0; /* klibc hack */ /* clearerr(s->file); */ } syslinux-legacy-3.63+dfsg/com32/lib/zlib/inffast.c0000664000175000017500000002764010777447272020453 0ustar evanevan/* inffast.c -- fast decoding * Copyright (C) 1995-2003 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" #ifndef ASMINF /* Allow machine dependent optimization for post-increment or pre-increment. Based on testing to date, Pre-increment preferred for: - PowerPC G3 (Adler) - MIPS R5000 (Randers-Pehrson) Post-increment preferred for: - none No measurable difference: - Pentium III (Anderson) - 68060 (Nikl) */ #ifdef POSTINC # define OFF 0 # define PUP(a) *(a)++ #else # define OFF 1 # define PUP(a) *++(a) #endif /* Decode literal, length, and distance codes and write out the resulting literal and match bytes until either not enough input or output is available, an end-of-block is encountered, or a data error is encountered. When large enough input and output buffers are supplied to inflate(), for example, a 16K input buffer and a 64K output buffer, more than 95% of the inflate execution time is spent in this routine. Entry assumptions: state->mode == LEN strm->avail_in >= 6 strm->avail_out >= 258 start >= strm->avail_out state->bits < 8 On return, state->mode is one of: LEN -- ran out of enough output space or enough available input TYPE -- reached end of block code, inflate() to interpret next block BAD -- error in block data Notes: - The maximum input bits used by a length/distance pair is 15 bits for the length code, 5 bits for the length extra, 15 bits for the distance code, and 13 bits for the distance extra. This totals 48 bits, or six bytes. Therefore if strm->avail_in >= 6, then there is enough input to avoid checking for available input while decoding. - The maximum bytes that a single length/distance pair can output is 258 bytes, which is the maximum length that can be coded. inflate_fast() requires strm->avail_out >= 258 for each loop to avoid checking for output space. */ void inflate_fast(strm, start) z_streamp strm; unsigned start; /* inflate()'s starting value for strm->avail_out */ { struct inflate_state FAR *state; unsigned char FAR *in; /* local strm->next_in */ unsigned char FAR *last; /* while in < last, enough input available */ unsigned char FAR *out; /* local strm->next_out */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ unsigned char FAR *end; /* while out < end, enough space available */ unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned write; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ unsigned long hold; /* local strm->hold */ unsigned bits; /* local strm->bits */ code const FAR *lcode; /* local strm->lencode */ code const FAR *dcode; /* local strm->distcode */ unsigned lmask; /* mask for first level of length codes */ unsigned dmask; /* mask for first level of distance codes */ code this; /* retrieved table entry */ unsigned op; /* code bits, operation, extra bits, or */ /* window position, window bytes to copy */ unsigned len; /* match length, unused bytes */ unsigned dist; /* match distance */ unsigned char FAR *from; /* where to copy match from */ /* copy state to local variables */ state = (struct inflate_state FAR *)strm->state; in = strm->next_in - OFF; last = in + (strm->avail_in - 5); out = strm->next_out - OFF; beg = out - (start - strm->avail_out); end = out + (strm->avail_out - 257); wsize = state->wsize; whave = state->whave; write = state->write; window = state->window; hold = state->hold; bits = state->bits; lcode = state->lencode; dcode = state->distcode; lmask = (1U << state->lenbits) - 1; dmask = (1U << state->distbits) - 1; /* decode literals and length/distances until end-of-block or not enough input data or output space */ do { if (bits < 15) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; hold += (unsigned long)(PUP(in)) << bits; bits += 8; } this = lcode[hold & lmask]; dolen: op = (unsigned)(this.bits); hold >>= op; bits -= op; op = (unsigned)(this.op); if (op == 0) { /* literal */ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", this.val)); PUP(out) = (unsigned char)(this.val); } else if (op & 16) { /* length base */ len = (unsigned)(this.val); op &= 15; /* number of extra bits */ if (op) { if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; } len += (unsigned)hold & ((1U << op) - 1); hold >>= op; bits -= op; } Tracevv((stderr, "inflate: length %u\n", len)); if (bits < 15) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; hold += (unsigned long)(PUP(in)) << bits; bits += 8; } this = dcode[hold & dmask]; dodist: op = (unsigned)(this.bits); hold >>= op; bits -= op; op = (unsigned)(this.op); if (op & 16) { /* distance base */ dist = (unsigned)(this.val); op &= 15; /* number of extra bits */ if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; } } dist += (unsigned)hold & ((1U << op) - 1); hold >>= op; bits -= op; Tracevv((stderr, "inflate: distance %u\n", dist)); op = (unsigned)(out - beg); /* max distance in output */ if (dist > op) { /* see if copy from window */ op = dist - op; /* distance back in window */ if (op > whave) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } from = window - OFF; if (write == 0) { /* very common case */ from += wsize - op; if (op < len) { /* some from window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } else if (write < op) { /* wrap around window */ from += wsize + write - op; op -= write; if (op < len) { /* some from end of window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = window - OFF; if (write < len) { /* some from start of window */ op = write; len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } } else { /* contiguous in window */ from += write - op; if (op < len) { /* some from window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } while (len > 2) { PUP(out) = PUP(from); PUP(out) = PUP(from); PUP(out) = PUP(from); len -= 3; } if (len) { PUP(out) = PUP(from); if (len > 1) PUP(out) = PUP(from); } } else { from = out - dist; /* copy direct from output */ do { /* minimum length is three */ PUP(out) = PUP(from); PUP(out) = PUP(from); PUP(out) = PUP(from); len -= 3; } while (len > 2); if (len) { PUP(out) = PUP(from); if (len > 1) PUP(out) = PUP(from); } } } else if ((op & 64) == 0) { /* 2nd level distance code */ this = dcode[this.val + (hold & ((1U << op) - 1))]; goto dodist; } else { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } } else if ((op & 64) == 0) { /* 2nd level length code */ this = lcode[this.val + (hold & ((1U << op) - 1))]; goto dolen; } else if (op & 32) { /* end-of-block */ Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } else { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } } while (in < last && out < end); /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ len = bits >> 3; in -= len; bits -= len << 3; hold &= (1U << bits) - 1; /* update state and return */ strm->next_in = in + OFF; strm->next_out = out + OFF; strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); strm->avail_out = (unsigned)(out < end ? 257 + (end - out) : 257 - (out - end)); state->hold = hold; state->bits = bits; return; } /* inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - Using bit fields for code structure - Different op definition to avoid & for extra bits (do & for table bits) - Three separate decoding do-loops for direct, window, and write == 0 - Special case for distance > 1 copies to do overlapped load and store copy - Explicit branch predictions (based on measured branch probabilities) - Deferring match copy and interspersed it with decoding subsequent codes - Swapping literal/length else - Swapping window/direct else - Larger unrolled copy loops (three is about right) - Moving len -= 3 statement into middle of loop */ #endif /* !ASMINF */ syslinux-legacy-3.63+dfsg/com32/lib/zlib/inflate.c0000664000175000017500000013045310777447272020440 0ustar evanevan/* inflate.c -- zlib decompression * Copyright (C) 1995-2003 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* * Change history: * * 1.2.beta0 24 Nov 2002 * - First version -- complete rewrite of inflate to simplify code, avoid * creation of window when not needed, minimize use of window when it is * needed, make inffast.c even faster, implement gzip decoding, and to * improve code readability and style over the previous zlib inflate code * * 1.2.beta1 25 Nov 2002 * - Use pointers for available input and output checking in inffast.c * - Remove input and output counters in inffast.c * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 * - Remove unnecessary second byte pull from length extra in inffast.c * - Unroll direct copy to three copies per loop in inffast.c * * 1.2.beta2 4 Dec 2002 * - Change external routine names to reduce potential conflicts * - Correct filename to inffixed.h for fixed tables in inflate.c * - Make hbuf[] unsigned char to match parameter type in inflate.c * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) * to avoid negation problem on Alphas (64 bit) in inflate.c * * 1.2.beta3 22 Dec 2002 * - Add comments on state->bits assertion in inffast.c * - Add comments on op field in inftrees.h * - Fix bug in reuse of allocated window after inflateReset() * - Remove bit fields--back to byte structure for speed * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths * - Change post-increments to pre-increments in inflate_fast(), PPC biased? * - Add compile time option, POSTINC, to use post-increments instead (Intel?) * - Make MATCH copy in inflate() much faster for when inflate_fast() not used * - Use local copies of stream next and avail values, as well as local bit * buffer and bit count in inflate()--for speed when inflate_fast() not used * * 1.2.beta4 1 Jan 2003 * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings * - Move a comment on output buffer sizes from inffast.c to inflate.c * - Add comments in inffast.c to introduce the inflate_fast() routine * - Rearrange window copies in inflate_fast() for speed and simplification * - Unroll last copy for window match in inflate_fast() * - Use local copies of window variables in inflate_fast() for speed * - Pull out common write == 0 case for speed in inflate_fast() * - Make op and len in inflate_fast() unsigned for consistency * - Add FAR to lcode and dcode declarations in inflate_fast() * - Simplified bad distance check in inflate_fast() * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new * source file infback.c to provide a call-back interface to inflate for * programs like gzip and unzip -- uses window as output buffer to avoid * window copying * * 1.2.beta5 1 Jan 2003 * - Improved inflateBack() interface to allow the caller to provide initial * input in strm. * - Fixed stored blocks bug in inflateBack() * * 1.2.beta6 4 Jan 2003 * - Added comments in inffast.c on effectiveness of POSTINC * - Typecasting all around to reduce compiler warnings * - Changed loops from while (1) or do {} while (1) to for (;;), again to * make compilers happy * - Changed type of window in inflateBackInit() to unsigned char * * * 1.2.beta7 27 Jan 2003 * - Changed many types to unsigned or unsigned short to avoid warnings * - Added inflateCopy() function * * 1.2.0 9 Mar 2003 * - Changed inflateBack() interface to provide separate opaque descriptors * for the in() and out() functions * - Changed inflateBack() argument and in_func typedef to swap the length * and buffer address return values for the input function * - Check next_in and next_out for Z_NULL on entry to inflate() * * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" #ifdef MAKEFIXED # ifndef BUILDFIXED # define BUILDFIXED # endif #endif /* function prototypes */ local void fixedtables OF((struct inflate_state FAR *state)); local int updatewindow OF((z_streamp strm, unsigned out)); #ifdef BUILDFIXED void makefixed OF((void)); #endif local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, unsigned len)); int ZEXPORT inflateReset(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; strm->total_in = strm->total_out = state->total = 0; strm->msg = Z_NULL; state->mode = HEAD; state->last = 0; state->havedict = 0; state->wsize = 0; state->whave = 0; state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; Tracev((stderr, "inflate: reset\n")); return Z_OK; } int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) z_streamp strm; int windowBits; const char *version; int stream_size; { struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) return Z_VERSION_ERROR; if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { strm->zalloc = zcalloc; strm->opaque = (voidpf)0; } if (strm->zfree == (free_func)0) strm->zfree = zcfree; state = (struct inflate_state FAR *) ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (voidpf)state; if (windowBits < 0) { state->wrap = 0; windowBits = -windowBits; } else { state->wrap = (windowBits >> 4) + 1; #ifdef GUNZIP if (windowBits < 48) windowBits &= 15; #endif } if (windowBits < 8 || windowBits > 15) { ZFREE(strm, state); strm->state = Z_NULL; return Z_STREAM_ERROR; } state->wbits = (unsigned)windowBits; state->window = Z_NULL; return inflateReset(strm); } int ZEXPORT inflateInit_(strm, version, stream_size) z_streamp strm; const char *version; int stream_size; { return inflateInit2_(strm, DEF_WBITS, version, stream_size); } /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. If BUILDFIXED is defined, then instead this routine builds the tables the first time it's called, and returns those tables the first time and thereafter. This reduces the size of the code by about 2K bytes, in exchange for a little execution time. However, BUILDFIXED should not be used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ local void fixedtables(state) struct inflate_state FAR *state; { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; static code fixed[544]; /* build fixed huffman tables if first call (may not be thread safe) */ if (virgin) { unsigned sym, bits; static code *next; /* literal/length table */ sym = 0; while (sym < 144) state->lens[sym++] = 8; while (sym < 256) state->lens[sym++] = 9; while (sym < 280) state->lens[sym++] = 7; while (sym < 288) state->lens[sym++] = 8; next = fixed; lenfix = next; bits = 9; inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); /* distance table */ sym = 0; while (sym < 32) state->lens[sym++] = 5; distfix = next; bits = 5; inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); /* do this just once */ virgin = 0; } #else /* !BUILDFIXED */ # include "inffixed.h" #endif /* BUILDFIXED */ state->lencode = lenfix; state->lenbits = 9; state->distcode = distfix; state->distbits = 5; } #ifdef MAKEFIXED #include /* Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also defines BUILDFIXED, so the tables are built on the fly. makefixed() writes those tables to stdout, which would be piped to inffixed.h. A small program can simply call makefixed to do this: void makefixed(void); int main(void) { makefixed(); return 0; } Then that can be linked with zlib built with MAKEFIXED defined and run: a.out > inffixed.h */ void makefixed() { unsigned low, size; struct inflate_state state; fixedtables(&state); puts(" /* inffixed.h -- table for decoding fixed codes"); puts(" * Generated automatically by makefixed()."); puts(" */"); puts(""); puts(" /* WARNING: this file should *not* be used by applications."); puts(" It is part of the implementation of this library and is"); puts(" subject to change. Applications should only use zlib.h."); puts(" */"); puts(""); size = 1U << 9; printf(" static const code lenfix[%u] = {", size); low = 0; for (;;) { if ((low % 7) == 0) printf("\n "); printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, state.lencode[low].val); if (++low == size) break; putchar(','); } puts("\n };"); size = 1U << 5; printf("\n static const code distfix[%u] = {", size); low = 0; for (;;) { if ((low % 6) == 0) printf("\n "); printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, state.distcode[low].val); if (++low == size) break; putchar(','); } puts("\n };"); } #endif /* MAKEFIXED */ /* Update the window with the last wsize (normally 32K) bytes written before returning. If window does not exist yet, create it. This is only called when a window is already in use, or when output has been written during this inflate call, but the end of the deflate stream has not been reached yet. It is also called to create a window for dictionary data when a dictionary is loaded. Providing output buffers larger than 32K to inflate() should provide a speed advantage, since only the last 32K of output is copied to the sliding window upon return from inflate(), and since all distances after the first 32K of output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ local int updatewindow(strm, out) z_streamp strm; unsigned out; { struct inflate_state FAR *state; unsigned copy, dist; state = (struct inflate_state FAR *)strm->state; /* if it hasn't been done already, allocate space for the window */ if (state->window == Z_NULL) { state->window = (unsigned char FAR *) ZALLOC(strm, 1U << state->wbits, sizeof(unsigned char)); if (state->window == Z_NULL) return 1; } /* if window not in use yet, initialize */ if (state->wsize == 0) { state->wsize = 1U << state->wbits; state->write = 0; state->whave = 0; } /* copy state->wsize or less output bytes into the circular window */ copy = out - strm->avail_out; if (copy >= state->wsize) { zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); state->write = 0; state->whave = state->wsize; } else { dist = state->wsize - state->write; if (dist > copy) dist = copy; zmemcpy(state->window + state->write, strm->next_out - copy, dist); copy -= dist; if (copy) { zmemcpy(state->window, strm->next_out - copy, copy); state->write = copy; state->whave = state->wsize; } else { state->write += dist; if (state->write == state->wsize) state->write = 0; if (state->whave < state->wsize) state->whave += dist; } } return 0; } /* Macros for inflate(): */ /* check function to use adler32() for zlib or crc32() for gzip */ #ifdef GUNZIP # define UPDATE(check, buf, len) \ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) #else # define UPDATE(check, buf, len) adler32(check, buf, len) #endif /* check macros for header crc */ #ifdef GUNZIP # define CRC2(check, word) \ do { \ hbuf[0] = (unsigned char)(word); \ hbuf[1] = (unsigned char)((word) >> 8); \ check = crc32(check, hbuf, 2); \ } while (0) # define CRC4(check, word) \ do { \ hbuf[0] = (unsigned char)(word); \ hbuf[1] = (unsigned char)((word) >> 8); \ hbuf[2] = (unsigned char)((word) >> 16); \ hbuf[3] = (unsigned char)((word) >> 24); \ check = crc32(check, hbuf, 4); \ } while (0) #endif /* Load registers with state in inflate() for speed */ #define LOAD() \ do { \ put = strm->next_out; \ left = strm->avail_out; \ next = strm->next_in; \ have = strm->avail_in; \ hold = state->hold; \ bits = state->bits; \ } while (0) /* Restore state from registers in inflate() */ #define RESTORE() \ do { \ strm->next_out = put; \ strm->avail_out = left; \ strm->next_in = next; \ strm->avail_in = have; \ state->hold = hold; \ state->bits = bits; \ } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ do { \ hold = 0; \ bits = 0; \ } while (0) /* Get a byte of input into the bit accumulator, or return from inflate() if there is no input available. */ #define PULLBYTE() \ do { \ if (have == 0) goto inf_leave; \ have--; \ hold += (unsigned long)(*next++) << bits; \ bits += 8; \ } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflate(). */ #define NEEDBITS(n) \ do { \ while (bits < (unsigned)(n)) \ PULLBYTE(); \ } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ ((unsigned)hold & ((1U << (n)) - 1)) /* Remove n bits from the bit accumulator */ #define DROPBITS(n) \ do { \ hold >>= (n); \ bits -= (unsigned)(n); \ } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ #define BYTEBITS() \ do { \ hold >>= bits & 7; \ bits -= bits & 7; \ } while (0) /* Reverse the bytes in a 32-bit value */ #define REVERSE(q) \ ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) /* inflate() uses a state machine to process as much input data and generate as much output data as possible before returning. The state machine is structured roughly as follows: for (;;) switch (state) { ... case STATEn: if (not enough input data or output space to make progress) return; ... make progress ... state = STATEm; break; ... } so when inflate() is called again, the same case is attempted again, and if the appropriate resources are provided, the machine proceeds to the next state. The NEEDBITS() macro is usually the way the state evaluates whether it can proceed or should return. NEEDBITS() does the return if the requested bits are not available. The typical use of the BITS macros is: NEEDBITS(n); ... do something with BITS(n) ... DROPBITS(n); where NEEDBITS(n) either returns from inflate() if there isn't enough input left to load n bits into the accumulator, or it continues. BITS(n) gives the low n bits in the accumulator. When done, DROPBITS(n) drops the low n bits off the accumulator. INITBITS() clears the accumulator and sets the number of available bits to zero. BYTEBITS() discards just enough bits to put the accumulator on a byte boundary. After BYTEBITS() and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return if there is no input available. The decoding of variable length codes uses PULLBYTE() directly in order to pull just enough bytes to decode the next code, and no more. Some states loop until they get enough input, making sure that enough state information is maintained to continue the loop where it left off if NEEDBITS() returns in the loop. For example, want, need, and keep would all have to actually be part of the saved state in case NEEDBITS() returns: case STATEw: while (want < need) { NEEDBITS(n); keep[want++] = BITS(n); DROPBITS(n); } state = STATEx; case STATEx: As shown above, if the next state is also the next case, then the break is omitted. A state may also return if there is not enough output space available to complete that state. Those states are copying stored data, writing a literal byte, and copying a matching string. When returning, a "goto inf_leave" is used to update the total counters, update the check value, and determine whether any progress has been made during that inflate() call in order to return the proper return code. Progress is defined as a change in either strm->avail_in or strm->avail_out. When there is a window, goto inf_leave will update the window with the last output written. If a goto inf_leave occurs in the middle of decompression and there is no window currently, goto inf_leave will create one and copy output to the window for the next call of inflate(). In this implementation, the flush parameter of inflate() only affects the return code (per zlib.h). inflate() always writes as much as possible to strm->next_out, given the space available and the provided input--the effect documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers the allocation of and copying into a sliding window until necessary, which provides the effect documented in zlib.h for Z_FINISH when the entire input stream available. So the only thing the flush parameter actually does is: when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it will return Z_BUF_ERROR if it has not reached the end of the stream. */ int ZEXPORT inflate(strm, flush) z_streamp strm; int flush; { struct inflate_state FAR *state; unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned in, out; /* save starting available input and output */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ code this; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ #ifdef GUNZIP unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ #endif static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ LOAD(); in = have; out = left; ret = Z_OK; for (;;) switch (state->mode) { case HEAD: if (state->wrap == 0) { state->mode = TYPEDO; break; } NEEDBITS(16); #ifdef GUNZIP if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ state->check = crc32(0L, Z_NULL, 0); CRC2(state->check, hold); INITBITS(); state->mode = FLAGS; break; } state->flags = 0; /* expect zlib header */ if (!(state->wrap & 1) || /* check if zlib header allowed */ #else if ( #endif ((BITS(8) << 8) + (hold >> 8)) % 31) { strm->msg = (char *)"incorrect header check"; state->mode = BAD; break; } if (BITS(4) != Z_DEFLATED) { strm->msg = (char *)"unknown compression method"; state->mode = BAD; break; } DROPBITS(4); if (BITS(4) + 8 > state->wbits) { strm->msg = (char *)"invalid window size"; state->mode = BAD; break; } Tracev((stderr, "inflate: zlib header ok\n")); strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = hold & 0x200 ? DICTID : TYPE; INITBITS(); break; #ifdef GUNZIP case FLAGS: NEEDBITS(16); state->flags = (int)(hold); if ((state->flags & 0xff) != Z_DEFLATED) { strm->msg = (char *)"unknown compression method"; state->mode = BAD; break; } if (state->flags & 0xe000) { strm->msg = (char *)"unknown header flags set"; state->mode = BAD; break; } if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = TIME; case TIME: NEEDBITS(32); if (state->flags & 0x0200) CRC4(state->check, hold); INITBITS(); state->mode = OS; case OS: NEEDBITS(16); if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; case EXLEN: if (state->flags & 0x0400) { NEEDBITS(16); state->length = (unsigned)(hold); if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); } state->mode = EXTRA; case EXTRA: if (state->flags & 0x0400) { copy = state->length; if (copy > have) copy = have; if (copy) { if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; state->length -= copy; } if (state->length) goto inf_leave; } state->mode = NAME; case NAME: if (state->flags & 0x0800) { if (have == 0) goto inf_leave; copy = 0; do { len = (unsigned)(next[copy++]); } while (len && copy < have); if (state->flags & 0x02000) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } state->mode = COMMENT; case COMMENT: if (state->flags & 0x1000) { if (have == 0) goto inf_leave; copy = 0; do { len = (unsigned)(next[copy++]); } while (len && copy < have); if (state->flags & 0x02000) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } state->mode = HCRC; case HCRC: if (state->flags & 0x0200) { NEEDBITS(16); if (hold != (state->check & 0xffff)) { strm->msg = (char *)"header crc mismatch"; state->mode = BAD; break; } INITBITS(); } strm->adler = state->check = crc32(0L, Z_NULL, 0); state->mode = TYPE; break; #endif case DICTID: NEEDBITS(32); strm->adler = state->check = REVERSE(hold); INITBITS(); state->mode = DICT; case DICT: if (state->havedict == 0) { RESTORE(); return Z_NEED_DICT; } strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; case TYPE: if (flush == Z_BLOCK) goto inf_leave; case TYPEDO: if (state->last) { BYTEBITS(); state->mode = CHECK; break; } NEEDBITS(3); state->last = BITS(1); DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN; /* decode codes */ break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; case 3: strm->msg = (char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); break; case STORED: BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { strm->msg = (char *)"invalid stored block lengths"; state->mode = BAD; break; } state->length = (unsigned)hold & 0xffff; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); state->mode = COPY; case COPY: copy = state->length; if (copy) { if (copy > have) copy = have; if (copy > left) copy = left; if (copy == 0) goto inf_leave; zmemcpy(put, next, copy); have -= copy; next += copy; left -= copy; put += copy; state->length -= copy; break; } Tracev((stderr, "inflate: stored end\n")); state->mode = TYPE; break; case TABLE: NEEDBITS(14); state->nlen = BITS(5) + 257; DROPBITS(5); state->ndist = BITS(5) + 1; DROPBITS(5); state->ncode = BITS(4) + 4; DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { strm->msg = (char *)"too many length or distance symbols"; state->mode = BAD; break; } #endif Tracev((stderr, "inflate: table sizes ok\n")); state->have = 0; state->mode = LENLENS; case LENLENS: while (state->have < state->ncode) { NEEDBITS(3); state->lens[order[state->have++]] = (unsigned short)BITS(3); DROPBITS(3); } while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid code lengths set"; state->mode = BAD; break; } Tracev((stderr, "inflate: code lengths ok\n")); state->have = 0; state->mode = CODELENS; case CODELENS: while (state->have < state->nlen + state->ndist) { for (;;) { this = state->lencode[BITS(state->lenbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if (this.val < 16) { NEEDBITS(this.bits); DROPBITS(this.bits); state->lens[state->have++] = this.val; } else { if (this.val == 16) { NEEDBITS(this.bits + 2); DROPBITS(this.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } len = state->lens[state->have - 1]; copy = 3 + BITS(2); DROPBITS(2); } else if (this.val == 17) { NEEDBITS(this.bits + 3); DROPBITS(this.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { NEEDBITS(this.bits + 7); DROPBITS(this.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } while (copy--) state->lens[state->have++] = (unsigned short)len; } } /* build code tables */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid literal/lengths set"; state->mode = BAD; break; } state->distcode = (code const FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { strm->msg = (char *)"invalid distances set"; state->mode = BAD; break; } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN; case LEN: if (have >= 6 && left >= 258) { RESTORE(); inflate_fast(strm, out); LOAD(); break; } for (;;) { this = state->lencode[BITS(state->lenbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if (this.op && (this.op & 0xf0) == 0) { last = this; for (;;) { this = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + this.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(this.bits); state->length = (unsigned)this.val; if ((int)(this.op) == 0) { Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", this.val)); state->mode = LIT; break; } if (this.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } if (this.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } state->extra = (unsigned)(this.op) & 15; state->mode = LENEXT; case LENEXT: if (state->extra) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); } Tracevv((stderr, "inflate: length %u\n", state->length)); state->mode = DIST; case DIST: for (;;) { this = state->distcode[BITS(state->distbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if ((this.op & 0xf0) == 0) { last = this; for (;;) { this = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + this.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(this.bits); if (this.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } state->offset = (unsigned)this.val; state->extra = (unsigned)(this.op) & 15; state->mode = DISTEXT; case DISTEXT: if (state->extra) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); } if (state->offset > state->whave + out - left) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } Tracevv((stderr, "inflate: distance %u\n", state->offset)); state->mode = MATCH; case MATCH: if (left == 0) goto inf_leave; copy = out - left; if (state->offset > copy) { /* copy from window */ copy = state->offset - copy; if (copy > state->write) { copy -= state->write; from = state->window + (state->wsize - copy); } else from = state->window + (state->write - copy); if (copy > state->length) copy = state->length; } else { /* copy from output */ from = put - state->offset; copy = state->length; } if (copy > left) copy = left; left -= copy; state->length -= copy; do { *put++ = *from++; } while (--copy); if (state->length == 0) state->mode = LEN; break; case LIT: if (left == 0) goto inf_leave; *put++ = (unsigned char)(state->length); left--; state->mode = LEN; break; case CHECK: if (state->wrap) { NEEDBITS(32); out -= left; strm->total_out += out; state->total += out; if (out) strm->adler = state->check = UPDATE(state->check, put - out, out); out = left; if (( #ifdef GUNZIP state->flags ? hold : #endif REVERSE(hold)) != state->check) { strm->msg = (char *)"incorrect data check"; state->mode = BAD; break; } INITBITS(); Tracev((stderr, "inflate: check matches trailer\n")); } #ifdef GUNZIP state->mode = LENGTH; case LENGTH: if (state->wrap && state->flags) { NEEDBITS(32); if (hold != (state->total & 0xffffffffUL)) { strm->msg = (char *)"incorrect length check"; state->mode = BAD; break; } INITBITS(); Tracev((stderr, "inflate: length matches trailer\n")); } #endif state->mode = DONE; case DONE: ret = Z_STREAM_END; goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; case MEM: return Z_MEM_ERROR; case SYNC: default: return Z_STREAM_ERROR; } /* Return from inflate(), updating the total counts and the check value. If there was no progress during the inflate() call, return a buffer error. Call updatewindow() to create and/or update the window state. Note: a memory error from inflate() is non-recoverable. */ inf_leave: RESTORE(); if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) if (updatewindow(strm, out)) { state->mode = MEM; return Z_MEM_ERROR; } in -= strm->avail_in; out -= strm->avail_out; strm->total_in += in; strm->total_out += out; state->total += out; if (state->wrap && out) strm->adler = state->check = UPDATE(state->check, strm->next_out - out, out); strm->data_type = state->bits + (state->last ? 64 : 0) + (state->mode == TYPE ? 128 : 0); if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) ret = Z_BUF_ERROR; return ret; } int ZEXPORT inflateEnd(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->window != Z_NULL) ZFREE(strm, state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; } int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; { struct inflate_state FAR *state; unsigned long id; /* check state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->mode != DICT) return Z_STREAM_ERROR; /* check for correct dictionary id */ id = adler32(0L, Z_NULL, 0); id = adler32(id, dictionary, dictLength); if (id != state->check) return Z_DATA_ERROR; /* copy dictionary to window */ if (updatewindow(strm, strm->avail_out)) { state->mode = MEM; return Z_MEM_ERROR; } if (dictLength > state->wsize) { zmemcpy(state->window, dictionary + dictLength - state->wsize, state->wsize); state->whave = state->wsize; } else { zmemcpy(state->window + state->wsize - dictLength, dictionary, dictLength); state->whave = dictLength; } state->havedict = 1; Tracev((stderr, "inflate: dictionary set\n")); return Z_OK; } /* Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found or when out of input. When called, *have is the number of pattern bytes found in order so far, in 0..3. On return *have is updated to the new state. If on return *have equals four, then the pattern was found and the return value is how many bytes were read including the last byte of the pattern. If *have is less than four, then the pattern has not been found yet and the return value is len. In the latter case, syncsearch() can be called again with more data and the *have state. *have is initialized to zero for the first call. */ local unsigned syncsearch(have, buf, len) unsigned FAR *have; unsigned char FAR *buf; unsigned len; { unsigned got; unsigned next; got = *have; next = 0; while (next < len && got < 4) { if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) got++; else if (buf[next]) got = 0; else got = 4 - got; next++; } *have = got; return next; } int ZEXPORT inflateSync(strm) z_streamp strm; { unsigned len; /* number of bytes to look at or looked at */ unsigned long in, out; /* temporary to save total_in and total_out */ unsigned char buf[4]; /* to restore bit buffer to byte string */ struct inflate_state FAR *state; /* check parameters */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; state->hold <<= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { buf[len++] = (unsigned char)(state->hold); state->hold >>= 8; state->bits -= 8; } state->have = 0; syncsearch(&(state->have), buf, len); } /* search available input */ len = syncsearch(&(state->have), strm->next_in, strm->avail_in); strm->avail_in -= len; strm->next_in += len; strm->total_in += len; /* return no joy or set up to restart inflate() on a new block */ if (state->have != 4) return Z_DATA_ERROR; in = strm->total_in; out = strm->total_out; inflateReset(strm); strm->total_in = in; strm->total_out = out; state->mode = TYPE; return Z_OK; } /* Returns true if inflate is currently at the end of a block generated by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored block. When decompressing, PPP checks that at the end of input packet, inflate is waiting for these length bytes. */ int ZEXPORT inflateSyncPoint(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; return state->mode == STORED && state->bits == 0; } int ZEXPORT inflateCopy(dest, source) z_streamp dest; z_streamp source; { struct inflate_state FAR *state; struct inflate_state FAR *copy; unsigned char FAR *window; /* check input */ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)source->state; /* allocate space */ copy = (struct inflate_state FAR *) ZALLOC(source, 1, sizeof(struct inflate_state)); if (copy == Z_NULL) return Z_MEM_ERROR; window = Z_NULL; if (state->window != Z_NULL) { window = (unsigned char FAR *) ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); if (window == Z_NULL) { ZFREE(source, copy); return Z_MEM_ERROR; } } /* copy state */ *dest = *source; *copy = *state; copy->lencode = copy->codes + (state->lencode - state->codes); copy->distcode = copy->codes + (state->distcode - state->codes); copy->next = copy->codes + (state->next - state->codes); if (window != Z_NULL) zmemcpy(window, state->window, 1U << state->wbits); copy->window = window; dest->state = (voidpf)copy; return Z_OK; } syslinux-legacy-3.63+dfsg/com32/lib/vsprintf.c0000664000175000017500000000026110777447272017722 0ustar evanevan/* * vsprintf.c */ #include #include int vsprintf(char *buffer, const char *format, va_list ap) { return vsnprintf(buffer, ~(size_t)0, format, ap); } syslinux-legacy-3.63+dfsg/com32/lib/seed48.c0000664000175000017500000000053110777447272017143 0ustar evanevan/* * seed48.c */ #include #include #include extern unsigned short __rand48_seed[3]; unsigned short *seed48(const unsigned short xsubi[3]) { static unsigned short oldseed[3]; memcpy(oldseed, __rand48_seed, sizeof __rand48_seed); memcpy(__rand48_seed, xsubi, sizeof __rand48_seed); return oldseed; } syslinux-legacy-3.63+dfsg/com32/lib/memcmp.c0000664000175000017500000000037010777447272017326 0ustar evanevan/* * memcmp.c */ #include int memcmp(const void *s1, const void *s2, size_t n) { const unsigned char *c1 = s1, *c2 = s2; int d = 0; while ( n-- ) { d = (int)*c1++ - (int)*c2++; if ( d ) break; } return d; } syslinux-legacy-3.63+dfsg/com32/lib/strtoll.c0000664000175000017500000000010710777447272017551 0ustar evanevan#define TYPE signed long long #define NAME strtoll #include "strtox.c" syslinux-legacy-3.63+dfsg/com32/lib/fputc.c0000664000175000017500000000030510777447272017167 0ustar evanevan/* * fputc.c * * gcc "printf decompilation" expects this to exist... */ #include int fputc(int c, FILE *f) { unsigned char ch = c; return _fwrite(&ch, 1, f) == 1 ? ch : EOF; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/0000775000175000017500000000000010777447344017602 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/lib/syslinux/adv.c0000664000175000017500000000335110777447272020522 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/adv.c * * Access the syslinux auxilliary data vector */ #include #include #include void *__syslinux_adv_ptr; size_t __syslinux_adv_size; void __constructor __syslinux_get_adv(void) { static com32sys_t reg; reg.eax.w[0] = 0x001c; __intcall(0x22, ®, ®); __syslinux_adv_ptr = MK_PTR(reg.es, reg.ebx.w[0]); __syslinux_adv_size = reg.ecx.w[0]; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/initramfs.c0000664000175000017500000000427110777447272021746 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * initramfs.c * * Utility functions for initramfs manipulation */ #include #include struct initramfs *initramfs_init(void) { struct initramfs *ir; ir = calloc(sizeof(*ir), 1); if (!ir) return NULL; ir->prev = ir->next = ir; return ir; } int initramfs_add_data(struct initramfs *ihead, const void *data, size_t data_len, size_t len, size_t align) { struct initramfs *in; if (!len) return 0; /* Nothing to add... */ /* Alignment must be a power of 2, and <= INITRAMFS_MAX_ALIGN */ if (!align || (align & (align-1)) || align > INITRAMFS_MAX_ALIGN) return -1; in = malloc(sizeof(*in)); if (!in) return -1; in->len = len; in->data = data; in->data_len = data_len; in->align = align; in->next = ihead; in->prev = ihead->prev; ihead->prev->next = in; ihead->prev = in; return 0; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/pxe_get_cached.c0000664000175000017500000000462310777447272022675 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * pxe_get_cached.c * * PXE call "get cached info" */ #include #include #include #include #include /* Returns the status code from PXE (0 on success), or -1 on invocation failure */ int pxe_get_cached_info(int level, void **buf, size_t *len) { com32sys_t regs; t_PXENV_GET_CACHED_INFO *gci = __com32.cs_bounce; void *bbuf, *nbuf; memset(®s, 0, sizeof regs); regs.eax.w[0] = 0x0009; regs.ebx.w[0] = PXENV_GET_CACHED_INFO; regs.es = SEG(gci); regs.edi.w[0] = OFFS(gci); bbuf = &gci[1]; gci->Status = PXENV_STATUS_FAILURE; gci->PacketType = level; gci->BufferSize = gci->BufferLimit = 65536-sizeof(*gci); gci->Buffer.seg = SEG(bbuf); gci->Buffer.offs = OFFS(bbuf); __intcall(0x22, ®s, ®s); if (regs.eflags.l & EFLAGS_CF) return -1; if (gci->Status) return gci->Status; nbuf = malloc(gci->BufferSize); /* malloc() does not use the bounce buffer */ if (!nbuf) return -1; memcpy(nbuf, bbuf, gci->BufferSize); *buf = nbuf; *len = gci->BufferSize; return 0; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/movebits.c0000664000175000017500000003563610777447272021613 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * movebits.c * * Utility function to take a list of memory areas to shuffle and * convert it to a set of shuffle operations. * * Note: a lot of the functions in this file deal with "parent pointers", * which are pointers to a pointer to a list, or part of the list. * They can be pointers to a variable holding the list root pointer, * or pointers to a next field of a previous entry. */ #include #include #include #include #include #include #include #ifndef DEBUG # ifdef TEST # define DEBUG 1 # else # define DEBUG 0 # endif #endif #if DEBUG # include # define dprintf printf #else # define dprintf(...) ((void)0) #endif #define min(x,y) ((x) < (y) ? (x) : (y)) #define max(x,y) ((x) > (y) ? (x) : (y)) static jmp_buf new_movelist_bail; static struct syslinux_movelist * new_movelist(addr_t dst, addr_t src, addr_t len) { struct syslinux_movelist *ml = malloc(sizeof(struct syslinux_movelist)); if ( !ml ) longjmp(new_movelist_bail, 1); ml->dst = dst; ml->src = src; ml->len = len; ml->next = NULL; return ml; } static struct syslinux_movelist * dup_movelist(struct syslinux_movelist *src) { struct syslinux_movelist *dst = NULL, **dstp = &dst, *ml; while (src) { ml = new_movelist(src->dst, src->src, src->len); *dstp = ml; dstp = &ml->next; src = src->next; } return dst; } static void add_freelist(struct syslinux_memmap **mmap, addr_t start, addr_t len, enum syslinux_memmap_types type) { if (syslinux_add_memmap(mmap, start, len, type)) longjmp(new_movelist_bail, 1); } /* * Take a chunk, entirely confined in **parentptr, and split it off so that * it has its own structure. */ static struct syslinux_movelist ** split_movelist(addr_t start, addr_t len, struct syslinux_movelist **parentptr) { struct syslinux_movelist *m, *ml = *parentptr; assert(start >= ml->src); assert(start < ml->src+ml->len); /* Split off the beginning */ if ( start > ml->src ) { addr_t l = start - ml->src; m = new_movelist(ml->dst+l, start, ml->len-l); m->next = ml->next; ml->len = l; ml->next = m; parentptr = &ml->next; ml = m; /* Continue processing the new node */ } /* Split off the end */ if ( ml->len > len ) { addr_t l = ml->len - len; m = new_movelist(ml->dst+len, ml->src+len, l); m->next = ml->next; ml->len = len; ml->next = m; } return parentptr; } static void delete_movelist(struct syslinux_movelist **parentptr) { struct syslinux_movelist *o = *parentptr; *parentptr = o->next; free(o); } static void free_movelist(struct syslinux_movelist **parentptr) { while (*parentptr) delete_movelist(parentptr); } /* * Scan the freelist looking for a particular chunk of memory */ static const struct syslinux_memmap * is_free_zone(const struct syslinux_memmap *list, addr_t start, addr_t len) { dprintf("f: 0x%08x bytes at 0x%08x\n", len, start); addr_t last, llast; last = start+len-1; while (list->type != SMT_END) { llast = list->next->start-1; if (list->start <= start) { if (llast >= last) { /* Chunk has a single, well-defined type */ if (list->type == SMT_FREE) { dprintf("F: 0x%08x bytes at 0x%08x\n", list->next->start, list->start); return list; /* It's free */ } return NULL; /* Not free */ } else if (llast >= start) { return NULL; /* Crosses region boundary */ } } list = list->next; } return NULL; /* Internal error? */ } /* * Scan the freelist looking for the smallest chunk of memory which * can fit X bytes; returns the length of the block on success. */ static addr_t free_area(const struct syslinux_memmap *mmap, addr_t len, addr_t *start) { const struct syslinux_memmap *best = NULL; const struct syslinux_memmap *s; addr_t slen, best_len = -1; for (s = mmap; s->type != SMT_END; s = s->next) { slen = s->next->start - s->start; if (slen >= len) { if (!best || best_len > slen) { best = s; best_len = slen; } } } if (best) { *start = best->start; return best_len; } else { return 0; } } /* * Remove a chunk from the freelist */ static void allocate_from(struct syslinux_memmap **mmap, addr_t start, addr_t len) { syslinux_add_memmap(mmap, start, len, SMT_ALLOC); } /* * The code to actually emit moving of a chunk into its final place. */ static void move_chunk(struct syslinux_movelist ***moves, struct syslinux_memmap **mmap, struct syslinux_movelist **fp, addr_t copylen) { addr_t copydst, copysrc; addr_t freebase, freelen; addr_t needlen; int reverse; struct syslinux_movelist *f = *fp, *mv; if ( f->src < f->dst && (f->dst - f->src) < f->len ) { /* "Shift up" type overlap */ needlen = f->dst - f->src; reverse = 1; } else if ( f->src > f->dst && (f->src - f->dst) < f->len ) { /* "Shift down" type overlap */ needlen = f->src - f->dst; reverse = 0; } else { needlen = f->len; reverse = 0; } copydst = f->dst; copysrc = f->src; dprintf("Q: copylen = 0x%08x, needlen = 0x%08x\n", copylen, needlen); if ( copylen < needlen ) { if (reverse) { copydst += (f->len-copylen); copysrc += (f->len-copylen); } dprintf("X: 0x%08x bytes at 0x%08x -> 0x%08x\n", copylen, copysrc, copydst); /* Didn't get all we wanted, so we have to split the chunk */ fp = split_movelist(copysrc, copylen, fp); /* Is this right? */ f = *fp; } mv = new_movelist(f->dst, f->src, f->len); dprintf("A: 0x%08x bytes at 0x%08x -> 0x%08x\n", mv->len, mv->src, mv->dst); **moves = mv; *moves = &mv->next; /* Figure out what memory we just freed up */ if ( f->dst > f->src ) { freebase = f->src; freelen = min(f->len, f->dst-f->src); } else if ( f->src >= f->dst+f->len ) { freebase = f->src; freelen = f->len; } else { freelen = f->src-f->dst; freebase = f->dst+f->len; } dprintf("F: 0x%08x bytes at 0x%08x\n", freelen, freebase); add_freelist(mmap, freebase, freelen, SMT_FREE); delete_movelist(fp); } /* * moves is computed from "frags" and "freemem". "space" lists * free memory areas at our disposal, and is (src, cnt) only. */ int syslinux_compute_movelist(struct syslinux_movelist **moves, struct syslinux_movelist *ifrags, struct syslinux_memmap *memmap) { struct syslinux_memmap *mmap = NULL; const struct syslinux_memmap *mm, *ep; struct syslinux_movelist *frags = NULL; struct syslinux_movelist *mv; struct syslinux_movelist *f, **fp; struct syslinux_movelist *o, **op; addr_t needbase, needlen, copysrc, copydst, copylen; addr_t avail; addr_t fstart, flen; addr_t cbyte; addr_t ep_len; int rv = -1; int reverse; dprintf("entering syslinux_compute_movelist()...\n"); if (setjmp(new_movelist_bail)) { nomem: dprintf("Out of working memory!\n"); goto bail; } *moves = NULL; /* Create our memory map. Anything that is SMT_FREE or SMT_ZERO is fair game, but mark anything used by source material as SMT_ALLOC. */ mmap = syslinux_init_memmap(); if (!mmap) goto nomem; frags = dup_movelist(ifrags); for (mm = memmap; mm->type != SMT_END; mm = mm->next) add_freelist(&mmap, mm->start, mm->next->start - mm->start, mm->type == SMT_ZERO ? SMT_FREE : mm->type); for (f = frags; f; f = f->next) add_freelist(&mmap, f->src, f->len, SMT_ALLOC); /* As long as there are unprocessed fragments in the chain... */ while ( (fp = &frags, f = *fp) ) { #if DEBUG dprintf("Current free list:\n"); syslinux_dump_memmap(stdout, mmap); dprintf("Current frag list:\n"); syslinux_dump_movelist(stdout, frags); #endif /* Scan for fragments which can be discarded without action. */ if ( f->src == f->dst ) { delete_movelist(fp); continue; } op = &f->next; while ( (o = *op) ) { if ( o->src == o->dst ) delete_movelist(op); else op = &o->next; } /* Scan for fragments which can be immediately moved to their final destination, if so handle them now */ for ( op = fp; (o = *op); op = &o->next ) { if ( o->src < o->dst && (o->dst - o->src) < o->len ) { /* "Shift up" type overlap */ needlen = o->dst - o->src; needbase = o->dst + (o->len - needlen); reverse = 1; cbyte = o->dst + o->len - 1; } else if ( o->src > o->dst && (o->src - o->dst) < o->len ) { /* "Shift down" type overlap */ needlen = o->src - o->dst; needbase = o->dst; reverse = 0; cbyte = o->dst; /* "Critical byte" */ } else { needlen = o->len; needbase = o->dst; reverse = 0; cbyte = o->dst; /* "Critical byte" */ } if (is_free_zone(mmap, needbase, needlen)) { fp = op, f = o; dprintf("!: 0x%08x bytes at 0x%08x -> 0x%08x\n", f->len, f->src, f->dst); copysrc = f->src; copylen = needlen; allocate_from(&mmap, needbase, copylen); goto move_chunk; } } /* Ok, bother. Need to do real work at least with one chunk. */ dprintf("@: 0x%08x bytes at 0x%08x -> 0x%08x\n", f->len, f->src, f->dst); /* See if we can move this chunk into place by claiming the destination, or in the case of partial overlap, the missing portion. */ if ( f->src < f->dst && (f->dst - f->src) < f->len ) { /* "Shift up" type overlap */ needlen = f->dst - f->src; needbase = f->dst + (f->len - needlen); reverse = 1; cbyte = f->dst + f->len - 1; } else if ( f->src > f->dst && (f->src - f->dst) < f->len ) { /* "Shift down" type overlap */ needlen = f->src - f->dst; needbase = f->dst; reverse = 0; cbyte = f->dst; /* "Critical byte" */ } else { needlen = f->len; needbase = f->dst; reverse = 0; cbyte = f->dst; } dprintf("need: base = 0x%08x, len = 0x%08x, " "reverse = %d, cbyte = 0x%08x\n", needbase, needlen, reverse, cbyte); ep = is_free_zone(mmap, cbyte, 1); if (ep) { ep_len = ep->next->start - ep->start; if (reverse) avail = needbase+needlen - ep->start; else avail = ep_len - (needbase - ep->start); } else { avail = 0; } if (avail) { /* We can move at least part of this chunk into place without further ado */ dprintf("space: start 0x%08x, len 0x%08x, free 0x%08x\n", ep->start, ep_len, avail); copylen = min(needlen, avail); if (reverse) allocate_from(&mmap, needbase+needlen-copylen, copylen); else allocate_from(&mmap, needbase, copylen); goto move_chunk; } /* At this point, we need to evict something out of our space. Find the object occupying the critical byte of our target space, and move it out (the whole object if we can, otherwise a subset.) Then move a chunk of ourselves into place. */ for ( op = &f->next, o = *op ; o ; op = &o->next, o = *op ) { dprintf("O: 0x%08x bytes at 0x%08x -> 0x%08x\n", o->len, o->src, o->dst); if ( !(o->src <= cbyte && o->src+o->len > cbyte) ) continue; /* Not what we're looking for... */ /* Find somewhere to put it... */ if ( is_free_zone(mmap, o->dst, o->len) ) { /* Score! We can move it into place directly... */ copydst = o->dst; copysrc = o->src; copylen = o->len; } else if ( free_area(mmap, o->len, &fstart) ) { /* We can move the whole chunk */ copydst = fstart; copysrc = o->src; copylen = o->len; } else { /* Well, copy as much as we can... */ if (syslinux_memmap_largest(mmap, SMT_FREE, &fstart, &flen)) { dprintf("No free memory at all!\n"); goto bail; /* Stuck! */ } /* Make sure we include the critical byte */ copydst = fstart; if (reverse) { copysrc = max(o->src, cbyte+1 - flen); copylen = cbyte+1 - copysrc; } else { copysrc = cbyte; copylen = min(flen, o->len - (cbyte-o->src)); } } allocate_from(&mmap, copydst, copylen); if ( copylen < o->len ) { op = split_movelist(copysrc, copylen, op); o = *op; } mv = new_movelist(copydst, copysrc, copylen); dprintf("C: 0x%08x bytes at 0x%08x -> 0x%08x\n", mv->len, mv->src, mv->dst); *moves = mv; moves = &mv->next; o->src = copydst; if ( copylen > needlen ) { /* We don't need all the memory we freed up. Mark it free. */ if ( copysrc < needbase ) { add_freelist(&mmap, copysrc, needbase-copysrc, SMT_FREE); copylen -= (needbase-copysrc); } if ( copylen > needlen ) { add_freelist(&mmap, copysrc+needlen, copylen-needlen, SMT_FREE); copylen = needlen; } } reverse = 0; goto move_chunk; } dprintf("Cannot find the chunk containing the critical byte\n"); goto bail; /* Stuck! */ move_chunk: move_chunk(&moves, &mmap, fp, copylen); } rv = 0; bail: if (mmap) syslinux_free_memmap(mmap); if (frags) free_movelist(&frags); return rv; } #ifdef TEST #include int main(int argc, char *argv[]) { FILE *f; unsigned long d, s, l; struct syslinux_movelist *frags; struct syslinux_movelist **fep = &frags; struct syslinux_movelist *space; struct syslinux_movelist **sep = &space; struct syslinux_movelist *mv, *moves; f = fopen(argv[1], "r"); while ( fscanf(f, "%lx %lx %lx", &d, &s, &l) == 3 ) { if ( d ) { mv = new_movelist(d, s, l); *fep = mv; fep = &mv->next; } else { mv = new_movelist(0, s, l); *sep = mv; sep = &mv->next; } } fclose(f); if ( syslinux_compute_movelist(&moves, frags, space) ) { printf("Failed to compute a move sequence\n"); return 1; } else { for ( mv = moves ; mv ; mv = mv->next ) { printf("0x%08x bytes at 0x%08x -> 0x%08x\n", mv->len, mv->src, mv->dst); } return 0; } } #endif /* TEST */ syslinux-legacy-3.63+dfsg/com32/lib/syslinux/localboot.c0000664000175000017500000000310310777447272021721 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include /* This returns only on failure */ void syslinux_local_boot(uint16_t flags) { static com32sys_t ireg; ireg.eax.w[0] = 0x0014; ireg.edx.w[0] = flags; __intcall(0x22, &ireg, NULL); } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/initramfs_file.c0000664000175000017500000001147510777447272022751 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * initramfs_file.c * * Utility functions to add arbitrary files including cpio header */ #include #include #include #include #include #define CPIO_MAGIC "070701" struct cpio_header { char c_magic[6]; /* 070701 */ char c_ino[8]; /* Inode number */ char c_mode[8]; /* File mode and permissions */ char c_uid[8]; /* uid */ char c_gid[8]; /* gid */ char c_nlink[8]; /* Number of links */ char c_mtime[8]; /* Modification time */ char c_filesize[8]; /* Size of data field */ char c_maj[8]; /* File device major number */ char c_min[8]; /* File device minor number */ char c_rmaj[8]; /* Device node reference major number */ char c_rmin[8]; /* Device node reference minor number */ char c_namesize[8]; /* Length of filename including final \0 */ char c_chksum[8]; /* Checksum if c_magic ends in 2 */ }; static uint32_t next_ino = 1; /* Create cpio headers for the directory entries leading up to a file. Returns the number of bytes; doesn't touch the buffer if too small. */ static size_t initramfs_mkdirs(const char *filename, void *buffer, size_t buflen) { const char *p = filename; char *bp = buffer; int len; size_t bytes = 0; int pad; while ((p = strchr(p, '/'))) { if (p != filename && p[-1] != '/') { len = p-filename; bytes += ((sizeof(struct cpio_header)+len+1)+3) & ~3; } p++; } if (buflen >= bytes) { p = filename; while ((p = strchr(p, '/'))) { if (p != filename && p[-1] != '/') { len = p-filename; bp += sprintf(bp, "070701%08x%08x%08x%08x%08x%08x%08x%08x%08x" "%08x%08x%08x%08x", next_ino++, S_IFDIR|0755, 0, 0, 1, 0, 0, 0, 1, 0, 1, len+1, 0); memcpy(bp, filename, len); bp += len; pad = (-(sizeof(struct cpio_header)+len) & 3) + 1; memset(bp, 0, pad); bp += pad; } } } return bytes; } /* * Create a file header (with optional parent directory entries) * and add it to an initramfs chain */ int initramfs_mknod(struct initramfs *ihead, const char *filename, int do_mkdir, uint16_t mode, size_t len, uint32_t major, uint32_t minor) { size_t bytes; int namelen = strlen(filename); int pad; char *buffer, *bp; if (do_mkdir) bytes = initramfs_mkdirs(filename, NULL, 0); else bytes = 0; bytes += ((sizeof(struct cpio_header)+namelen+1)+3) & ~3; bp = buffer = malloc(bytes); if (!buffer) return -1; if (do_mkdir) bp += initramfs_mkdirs(filename, bp, bytes); bp += sprintf(bp, "070701%08x%08x%08x%08x%08x%08x%08x%08x%08x" "%08x%08x%08x%08x", next_ino++, mode, 0, 0, 1, 0, len, 0, 1, major, minor, namelen+1, 0); memcpy(bp, filename, namelen); bp += len; pad = (-(sizeof(struct cpio_header)+namelen) & 3) + 1; memset(bp, 0, pad); if (initramfs_add_data(ihead, buffer, bytes, bytes, 4)) { free(buffer); return -1; } return 0; } /* * Add a file given data in memory to an initramfs chain. This * can be used to create nonfiles like symlinks by specifying an * appropriate mode. */ int initramfs_add_file(struct initramfs *ihead, const void *data, size_t data_len, size_t len, const char *filename, int do_mkdir, uint32_t mode) { if (initramfs_mknod(ihead, filename, do_mkdir, (mode & S_IFMT) ? mode : mode|S_IFREG, len, 0, 1)) return -1; return initramfs_add_data(ihead, data, data_len, len, 4); } int initramfs_add_trailer(struct initramfs *ihead) { return initramfs_mknod(ihead, "TRAILER!!!", 0, 0, 0, 0, 0); } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/cleanup.c0000664000175000017500000000304210777447272021374 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include void syslinux_final_cleanup(uint16_t flags) { static com32sys_t ireg; ireg.eax.w[0] = 0x000c; ireg.edx.w[0] = flags; __intcall(0x22, &ireg, NULL); } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/run_command.c0000664000175000017500000000332210777447272022250 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include #include __noreturn syslinux_run_command(const char *command) { static com32sys_t ireg; strcpy(__com32.cs_bounce, command); ireg.eax.w[0] = 0x0003; ireg.es = SEG(__com32.cs_bounce); ireg.ebx.w[0] = OFFS(__com32.cs_bounce); __intcall(0x22, &ireg, NULL); /* Should not return even on failure */ for(;;); } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/shuffle.c0000664000175000017500000001510310777447272021402 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * shuffle.c * * Common code for "shuffle and boot" operation; generates a shuffle list * and puts it in the bounce buffer. Returns the number of shuffle * descriptors. */ #include #include #include #include #include #include #include #ifndef DEBUG # define DEBUG 0 #endif #if DEBUG # include # define dprintf printf #else # define dprintf(f, ...) ((void)0) #endif struct shuffle_descriptor { uint32_t dst, src, len; }; static int desc_block_size; static void __constructor __syslinux_get_desc_block_size(void) { static com32sys_t reg; reg.eax.w[0] = 0x0011; __intcall(0x22, ®, ®); desc_block_size = (reg.eflags.l & EFLAGS_CF) ? 64 : reg.ecx.w[0]; } /* Allocate descriptor memory in these chunks */ #define DESC_BLOCK_SIZE desc_block_size int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist, struct syslinux_memmap *memmap) { struct syslinux_movelist *moves = NULL, *mp; struct syslinux_memmap *rxmap = NULL, *ml; struct shuffle_descriptor *dp, *dbuf; int np, nb, rv = -1; int desc_blocks, need_blocks; addr_t desczone, descfree, descaddr, descoffs; int nmoves, nzero; struct shuffle_descriptor primaries[2]; /* Count the number of zero operations */ nzero = 0; for (ml = memmap; ml->type != SMT_END; ml = ml->next) { if (ml->type == SMT_ZERO) nzero++; } /* Find the larges contiguous region unused by input *and* output; this is where we put the move descriptor list */ rxmap = syslinux_dup_memmap(memmap); if (!rxmap) goto bail; for (mp = fraglist; mp; mp = mp->next) { if (syslinux_add_memmap(&rxmap, mp->src, mp->len, SMT_ALLOC) || syslinux_add_memmap(&rxmap, mp->dst, mp->len, SMT_ALLOC)) goto bail; } if (syslinux_memmap_largest(rxmap, SMT_FREE, &desczone, &descfree)) goto bail; syslinux_free_memmap(rxmap); dprintf("desczone = 0x%08x, descfree = 0x%08x\n", desczone, descfree); rxmap = syslinux_dup_memmap(memmap); if (!rxmap) goto bail; desc_blocks = (nzero+DESC_BLOCK_SIZE)/(DESC_BLOCK_SIZE-1); for (;;) { addr_t descmem = desc_blocks* sizeof(struct shuffle_descriptor)*DESC_BLOCK_SIZE; if (descfree < descmem) goto bail; /* No memory block large enough */ /* Mark memory used by shuffle descriptors as reserved */ descaddr = desczone + descfree - descmem; if (syslinux_add_memmap(&rxmap, descaddr, descmem, SMT_RESERVED)) goto bail; #if DEBUG syslinux_dump_movelist(stdout, fraglist); #endif if (syslinux_compute_movelist(&moves, fraglist, rxmap)) goto bail; nmoves = 0; for (mp = moves; mp; mp = mp->next) nmoves++; need_blocks = (nmoves+nzero)/(DESC_BLOCK_SIZE-1); if (desc_blocks >= need_blocks) break; /* Sufficient memory, yay */ desc_blocks = need_blocks; /* Try again... */ } #if DEBUG dprintf("Final movelist:\n"); syslinux_dump_movelist(stdout, moves); #endif syslinux_free_memmap(rxmap); rxmap = NULL; dbuf = malloc((nmoves+nzero+desc_blocks)*sizeof(struct shuffle_descriptor)); if (!dbuf) goto bail; descoffs = descaddr - (addr_t)dbuf; #if DEBUG dprintf("nmoves = %d, nzero = %d, dbuf = %p, offs = 0x%08x\n", nmoves, nzero, dbuf, descoffs); #endif /* Copy the move sequence into the descriptor buffer */ np = 0; nb = 0; dp = dbuf; for (mp = moves; mp; mp = mp->next) { if (nb == DESC_BLOCK_SIZE-1) { dp->dst = -1; /* Load new descriptors */ dp->src = (addr_t)(dp+1) + descoffs; dp->len = sizeof(*dp)*min(nmoves, DESC_BLOCK_SIZE); dprintf("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len); dp++; np++; nb = 0; } dp->dst = mp->dst; dp->src = mp->src; dp->len = mp->len; dprintf("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len); dp++; np++; nb++; } /* Copy bzero operations into the descriptor buffer */ for (ml = memmap; ml->type != SMT_END; ml = ml->next) { if (ml->type == SMT_ZERO) { if (nb == DESC_BLOCK_SIZE-1) { dp->dst = (addr_t)-1; /* Load new descriptors */ dp->src = (addr_t)(dp+1) + descoffs; dp->len = sizeof(*dp)*min(nmoves, DESC_BLOCK_SIZE); dprintf("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len); dp++; np++; nb = 0; } dp->dst = ml->start; dp->src = (addr_t)-1; /* bzero region */ dp->len = ml->next->start - ml->start; dprintf("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len); dp++; np++; nb++; } } /* Set up the primary descriptors in the bounce buffer. The first one moves the descriptor list into its designated safe zone, the second one loads the first descriptor block. */ dp = primaries; dp->dst = descaddr; dp->src = (addr_t)dbuf; dp->len = np*sizeof(*dp); dprintf("< %08x %08x %08x >\n", dp->dst, dp->src, dp->len); dp++; dp->dst = (addr_t)-1; dp->src = descaddr; dp->len = sizeof(*dp)*min(np, DESC_BLOCK_SIZE); dprintf("< %08x %08x %08x >\n", dp->dst, dp->src, dp->len); dp++; memcpy(__com32.cs_bounce, primaries, 2*sizeof(*dp)); rv = 2; /* Always two primaries */ bail: /* This is safe only because free() doesn't use the bounce buffer!!!! */ if (moves) syslinux_free_movelist(moves); if (rxmap) syslinux_free_memmap(rxmap); return rv; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/getadv.c0000664000175000017500000000401110777447272021214 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/getadv.c * * Get a data item from the auxilliary data vector. Returns a pointer * and sets *size on success; NULL on failure. */ #include #include #include const void *syslinux_getadv(int tag, size_t *size) { const uint8_t *p; size_t left, len; p = syslinux_adv_ptr(); left = syslinux_adv_size(); while (left >= 2) { uint8_t ptag = *p++; size_t plen = *p++; left -= 2; if (ptag == ADV_END) return NULL; /* Not found */ if (left < plen) return NULL; /* Item overrun */ if (ptag == tag) { *size = plen; return p; } p += plen; left -= plen; } return NULL; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/features.c0000664000175000017500000000346710777447272021576 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/features.c * * SYSLINUX feature flag query */ #include #include #include #include struct __syslinux_feature_flags __syslinux_feature_flags; void __constructor __syslinux_detect_features(void) { static com32sys_t reg; memset(®, 0, sizeof reg); reg.eax.w[0] = 0x0015; __intcall(0x22, ®, ®); __syslinux_feature_flags.len = reg.ecx.w[0]; __syslinux_feature_flags.ptr = MK_PTR(reg.es, reg.ebx.w[0]); } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/dump_mmap.c0000664000175000017500000000352010777447272021725 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * dump_mmap.c * * Writes a syslinux_memmap out to a specified file. This is * intended for debugging. */ #include #include void syslinux_dump_memmap(FILE *file, struct syslinux_memmap *memmap) { fprintf(file, "%10s %10s %10s\n" "--------------------------------\n", "Start", "Length", "Type"); while (memmap->type != SMT_END) { fprintf(file, "0x%08x 0x%08x %10d\n", memmap->start, memmap->next->start - memmap->start, memmap->type); memmap = memmap->next; } } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/idle.c0000664000175000017500000000353110777447272020665 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2005-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * idle.c * * What to do in a busy loop... */ #include #include #include #include void syslinux_idle(void) { static int do_idle = 1; static const com32sys_t sys_idle = { .eax.l = 0x0013, }; com32sys_t idle_result; /* This call isn't supported on SYSLINUX < 3.08, but all it does is return an error, so we don't care. */ if ( do_idle ) { __intcall(0x22, &sys_idle, &idle_result); do_idle = ~idle_result.eflags.l & EFLAGS_CF; } cpu_relax(); } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/config.c0000664000175000017500000000317210777447272021216 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include const char *__syslinux_config_file; void __constructor __syslinux_get_config_file_name(void) { static com32sys_t reg; reg.eax.w[0] = 0x000e; __intcall(0x22, ®, ®); __syslinux_config_file = MK_PTR(reg.es, reg.ebx.w[0]); } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/advwrite.c0000664000175000017500000000314310777447272021574 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/advwrite.c * * Write back the ADV */ #include #include #include int syslinux_adv_write(void) { static com32sys_t reg; reg.eax.w[0] = 0x001d; __intcall(0x22, ®, ®); return (reg.eflags.l & EFLAGS_CF) ? -1 : 0; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/zonelist.c0000664000175000017500000001353410777447272021623 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * zonelist.c * * Deal with syslinux_memmap's, which are data structures designed to * hold memory maps. A zonelist is a sorted linked list of memory * ranges, with the guarantee that no two adjacent blocks have the * same range type. Additionally, all unspecified memory have a range * type of zero. */ #include #include /* * Create an empty syslinux_memmap list. */ struct syslinux_memmap *syslinux_init_memmap(void) { struct syslinux_memmap *sp, *ep; sp = malloc(sizeof(*sp)); if (!sp) return NULL; ep = malloc(sizeof(*ep)); if (!ep) { free(sp); return NULL; } sp->start = 0; sp->type = SMT_UNDEFINED; sp->next = ep; ep->start = 0; /* Wrap around... */ ep->type = SMT_END; /* End of chain */ ep->next = NULL; return sp; } /* * Add an item to a syslinux_memmap list, potentially overwriting * what is already there. */ int syslinux_add_memmap(struct syslinux_memmap **list, addr_t start, addr_t len, enum syslinux_memmap_types type) { addr_t last; struct syslinux_memmap *mp, **mpp; struct syslinux_memmap *mpi; struct syslinux_memmap *range; enum syslinux_memmap_types oldtype; /* Remove this to make len == 0 mean all of memory */ if (len == 0) return 0; /* Last byte -- to avoid rollover */ last = start+len-1; mpp = list; oldtype = SMT_ERROR; while (mp = *mpp, start > mp->start && mp->type != SMT_END) { oldtype = mp->type; mpp = &mp->next; } if (start < mp->start || mp->type == SMT_END) { range = malloc(sizeof(*range)); if (!range) return -1; range->start = start; range->type = type; *mpp = range; range->next = mp; mpp = &range->next; } while (mp = *mpp, last > mp->start-1) { oldtype = mp->type; mp->type = type; mpp = &mp->next; } if (last < mp->start-1) { range = malloc(sizeof(*range)); if (!range) return -1; range->start = last+1; range->type = oldtype; *mpp = range; range->next = mp; } /* Now the map is correct, but quite possibly not optimal. Scan the map for ranges which are redundant and remove them. This is technically excessive, since we scan the list to the end even though only part of it could have changed. In particular, the first entry that could change is one earlier than the first one changed above, and once we stop changing things, there shouldn't be any more changes. */ mpi = *list; while (mpi->type != SMT_END) { mp = mpi->next; if (mpi->type == mp->type) { mpi->next = mp->next; free(mp); } else { /* Go on to the next one */ mpi = mp; } } return 0; } /* * Verify what type a certain memory region is. This function returns * SMT_ERROR if the memory region has multiple types. */ enum syslinux_memmap_types syslinux_memmap_type(struct syslinux_memmap *list, addr_t start, addr_t len) { addr_t last, llast; last = start+len-1; while (list->type != SMT_END) { llast = list->next->start-1; if (list->start <= start) { if (llast >= last) return list->type; /* Region has a well-defined type */ else if (llast >= start) return SMT_ERROR; /* Crosses region boundary */ } list = list->next; } return SMT_ERROR; /* Internal error? */ } /* * Find the largest zone of a specific type. Returns -1 on failure. */ int syslinux_memmap_largest(struct syslinux_memmap *list, enum syslinux_memmap_types type, addr_t *start, addr_t *len) { addr_t size, best_size = 0; struct syslinux_memmap *best = NULL; while (list->type != SMT_END) { size = list->next->start - list->start; if (list->type == type && size > best_size) { best = list; best_size = size; } list = list->next; } if (!best) return -1; *start = best->start; *len = best_size; return 0; } /* * Free a zonelist. */ void syslinux_free_memmap(struct syslinux_memmap *list) { struct syslinux_memmap *ml; while (list) { ml = list; list = list->next; free(ml); } } /* * Duplicate a zonelist. Returns NULL on failure. */ struct syslinux_memmap *syslinux_dup_memmap(struct syslinux_memmap *list) { struct syslinux_memmap *newlist = NULL, **nlp = &newlist; struct syslinux_memmap *ml; while (list) { ml = malloc(sizeof(*ml)); if (!ml) { syslinux_free_memmap(newlist); return NULL; } ml->start = list->start; ml->type = list->type; ml->next = NULL; *nlp = ml; nlp = &ml->next; list = list->next; } return newlist; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/reboot.c0000664000175000017500000000322510777447272021242 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * reboot.c * * Provoke a system reboot */ #include #include #include __noreturn syslinux_reboot(int warm) { uint16_t * const reboot_flag = (uint16_t *)0x472; *reboot_flag = warm ? 0x1234 : 0; __farcall(0xf000, 0xfff0, &__com32_zero_regs, NULL); while(1) asm volatile("hlt"); } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/loadfile.c0000664000175000017500000000276510777447272021537 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2005-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * loadfile.c * * Read the contents of a data file into a malloc'd buffer */ #include #include #include #include #include #include #include int loadfile(const char *filename, void **ptr, size_t *len) { int fd; struct stat st; void *data; FILE *f; size_t xlen; fd = open(filename, O_RDONLY); if ( fd < 0 ) return -1; f = fdopen(fd, "rb"); if ( !f ) { close(fd); return -1; } if ( fstat(fd, &st) ) goto err_fclose; *len = st.st_size; xlen = (st.st_size + LOADFILE_ZERO_PAD-1) & ~(LOADFILE_ZERO_PAD-1); *ptr = data = malloc(xlen); if ( !data ) goto err_fclose; if ( (off_t)fread(data, 1, st.st_size, f) != st.st_size ) goto err_free; memset((char *)data + st.st_size, 0, xlen-st.st_size); fclose(f); return 0; err_free: free(data); err_fclose: fclose(f); return -1; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/ipappend.c0000664000175000017500000000402210777447272021544 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/ipappend.c * * Get ipappend strings */ #include #include #include struct syslinux_ipappend_strings __syslinux_ipappend_strings; static const char *syslinux_ipappend_string_list[32]; void __constructor __syslinux_get_ipappend_strings(void) { static com32sys_t reg; int i; reg.eax.w[0] = 0x000f; __intcall(0x22, ®, ®); if (!(reg.eflags.l & EFLAGS_CF)) { __syslinux_ipappend_strings.count = reg.ecx.w[0]; __syslinux_ipappend_strings.ptr = syslinux_ipappend_string_list; for (i = 0; i < reg.ecx.w[0]; i++) { syslinux_ipappend_string_list[i] = MK_PTR(reg.es, *(uint16_t *)MK_PTR(reg.es, reg.ebx.w[0]+i*2)); } } } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/dump_movelist.c0000664000175000017500000000341510777447272022640 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * dump_movelist.c * * Writes a syslinux_movelist out to a specified file. This is * intended for debugging. */ #include #include void syslinux_dump_movelist(FILE *file, struct syslinux_movelist *ml) { fprintf(file, "%10s %10s %10s\n" "--------------------------------\n", "Dest", "Src", "Length"); while (ml) { fprintf(file, "0x%08x 0x%08x 0x%08x\n", ml->dst, ml->src, ml->len); ml = ml->next; } } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/setadv.c0000664000175000017500000000604210777447272021236 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/setadv.c * * (Over)write a data item in the auxilliary data vector. To * delete an item, set its length to zero. * * Return 0 on success, -1 on error, and set errno. * * NOTE: Data is not written to disk unless * syslinux_adv_write() is called. */ #include #include #include #include #include #include int syslinux_setadv(int tag, size_t size, const void *data) { uint8_t *p, *advtmp; size_t left; if ((unsigned)tag-1 > 254) { errno = EINVAL; return -1; /* Impossible tag value */ } if (size > 255) { errno = ENOSPC; /* Max 255 bytes for a data item */ return -1; } left = syslinux_adv_size(); p = advtmp = alloca(left); memcpy(p, syslinux_adv_ptr(), left); /* Make working copy */ while (left >= 2) { uint8_t ptag = p[0]; size_t plen = p[1]+2; if (ptag == ADV_END) break; if (ptag == tag) { /* Found our tag. Delete it. */ if (plen >= left) { /* Entire remainder is our tag */ break; } memmove(p, p+plen, left-plen); } else { /* Not our tag */ if (plen > left) break; /* Corrupt tag (overrun) - overwrite it */ left -= plen; p += plen; } } /* Now (p, left) reflects the position to write in and how much space we have for our data. */ if (size) { if (left < size+2) { errno = ENOSPC; /* Not enough space for data */ return -1; } *p++ = tag; *p++ = size; memcpy(p, data, size); left -= size+2; } memset(p, 0, left); /* If we got here, everything went OK, commit the write to low memory */ memcpy(syslinux_adv_ptr(), advtmp, syslinux_adv_size()); return 0; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/runimage.c0000664000175000017500000000415210777447272021557 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * runimage.c * * Load and run a syslinux image. */ #include #include #include #include void syslinux_run_kernel_image(const char *filename, const char *cmdline, uint32_t ipappend_flags, uint32_t type) { static com32sys_t ireg; char *bbfilename, *bbcmdline, *bbptr; int bytes; bbptr = __com32.cs_bounce; bytes = strlen(filename)+1; memcpy(bbfilename = bbptr, filename, bytes); bbptr += bytes; bytes = strlen(cmdline)+1; memcpy(bbcmdline = bbptr, filename, bytes); bbptr += bytes; ireg.eax.w[0] = 0x0016; ireg.ds = SEG(bbfilename); ireg.esi.w[0] = OFFS(bbfilename); ireg.es = SEG(bbcmdline); ireg.ebx.w[0] = OFFS(bbcmdline); ireg.ecx.l = ipappend_flags; ireg.edx.l = type; __intcall(0x22, &ireg, 0); } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/initramfs_archive.c0000664000175000017500000000327510777447272023452 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * initramfs_archive.c * * Utility function to load an initramfs archive. */ #include #include #include int initramfs_load_archive(struct initramfs *ihead, const char *filename) { void *data; size_t len; if (loadfile(filename, &data, &len)) return -1; return initramfs_add_data(ihead, data, len, len, 4); } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/memmap.c0000664000175000017500000001000510777447272021216 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * memmap.c * * Create initial memory map for "shuffle and boot" operation */ #include #include #include #include #include #include #include #include #include struct e820_entry { uint64_t start; uint64_t len; uint32_t type; }; struct syslinux_memmap *syslinux_memory_map(void) { static com32sys_t ireg, zireg; com32sys_t oreg; struct e820_entry *e820buf = __com32.cs_bounce; uint64_t start, len, maxlen; int memfound = 0; struct syslinux_memmap *mmap; enum syslinux_memmap_types type; mmap = syslinux_init_memmap(); if (!mmap) goto bail; /* Use INT 12h to get DOS memory above 0x7c00 */ __intcall(0x12, &zireg, &oreg); if (oreg.eax.w[0] > 31 && oreg.eax.w[0] <= 640) { addr_t dosmem = (oreg.eax.w[0] << 10) - 0x7c00; if (syslinux_add_memmap(&mmap, 0x7c00, dosmem, SMT_FREE)) goto bail; } /* First try INT 15h AX=E820h */ ireg.eax.l = 0xe820; ireg.edx.l = 0x534d4150; ireg.ebx.l = 0; ireg.ecx.l = 20; ireg.es = SEG(e820buf); ireg.edi.w[0] = OFFS(e820buf); do { __intcall(0x15, &ireg, &oreg); if ((oreg.eflags.l & EFLAGS_CF) || (oreg.eax.l != 0x534d4150) || (oreg.ecx.l < 20)) break; type = e820buf->type == 1 ? SMT_FREE : SMT_RESERVED; start = e820buf->start; len = e820buf->len; if (start < 0x100000000ULL) { /* Don't rely on E820 being valid for low memory. Doing so could mean stuff like overwriting the PXE stack even when using "keeppxe", etc. */ if (start < 0x100000ULL) { if (len > 0x100000ULL-start) len -= 0x100000ULL-start; else len = 0; start = 0x100000ULL; } maxlen = 0x100000000ULL-start; if (len > maxlen) len = maxlen; if (len) { if (syslinux_add_memmap(&mmap, (addr_t)start, (addr_t)len, type)) goto bail; memfound = 1; } } ireg.ebx.l = oreg.ebx.l; } while (oreg.ebx.l); if (memfound) return mmap; /* Next try INT 15h AX=E801h */ ireg.eax.w[0] = 0xe801; __intcall(0x15, &ireg, &oreg); if (!(oreg.eflags.l & EFLAGS_CF) && oreg.ecx.w[0]) { if (syslinux_add_memmap(&mmap, (addr_t)1 << 20, oreg.ecx.w[0] << 10, SMT_FREE)) goto bail; if (oreg.edx.w[0]) { if (syslinux_add_memmap(&mmap, (addr_t)16 << 20, oreg.edx.w[0] << 16, SMT_FREE)) goto bail; } return mmap; } /* Finally try INT 15h AH=88h */ ireg.eax.w[0] = 0x8800; if (!(oreg.eflags.l & EFLAGS_CF) && oreg.eax.w[0]) { if (syslinux_add_memmap(&mmap, (addr_t)1 << 20, oreg.ecx.w[0] << 10, SMT_FREE)) goto bail; } return mmap; bail: syslinux_free_memmap(mmap); return NULL; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/freelist.c0000664000175000017500000000312110777447272021560 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * freelist.c * * Frees a syslinux_movelist */ #include #include void syslinux_free_movelist(struct syslinux_movelist *list) { struct syslinux_movelist *m; while (list) { m = list; list = list->next; free(m); } } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/addlist.c0000664000175000017500000000324710777447272021400 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include int syslinux_add_movelist(struct syslinux_movelist **list, addr_t dst, addr_t src, addr_t len) { struct syslinux_movelist *ml = malloc(sizeof(struct syslinux_movelist)); if (!ml) return -1; ml->dst = dst; ml->src = src; ml->len = len; ml->next = *list; *list = ml; return 0; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/serial.c0000664000175000017500000000360410777447272021230 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/serial.c * * SYSLINUX serial console query */ #include #include #include #include struct syslinux_serial_console_info __syslinux_serial_console_info; void __constructor __syslinux_get_serial_console_info(void) { static com32sys_t reg; memset(®, 0, sizeof reg); reg.eax.w[0] = 0x000b; __intcall(0x22, ®, ®); __syslinux_serial_console_info.iobase = reg.edx.w[0]; __syslinux_serial_console_info.divisor = reg.ecx.w[0]; __syslinux_serial_console_info.flowctl = reg.ebx.w[0]; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/load_linux.c0000664000175000017500000002275210777447272022114 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * load_linux.c * * Load a Linux kernel (Image/zImage/bzImage). */ #include #include #include #include #include #include #ifndef DEBUG # define DEBUG 0 #endif #if DEBUG # include # define dprintf printf #else # define dprintf(f, ...) ((void)0) #endif struct linux_header { uint8_t boot_sector_1[0x0020]; uint16_t old_cmd_line_magic; uint16_t old_cmd_line_offset; uint8_t boot_sector_2[0x01f1-0x0024]; uint8_t setup_sects; uint16_t root_flags; uint32_t syssize; uint16_t ram_size; uint16_t vid_mode; uint16_t root_dev; uint16_t boot_flag; uint16_t jump; uint32_t header; uint16_t version; uint32_t realmode_swtch; uint16_t start_sys; uint16_t kernel_version; uint8_t type_of_loader; uint8_t loadflags; uint16_t setup_move_size; uint32_t code32_start; uint32_t ramdisk_image; uint32_t ramdisk_size; uint32_t bootsect_kludge; uint16_t heap_end_ptr; uint16_t pad1; uint32_t cmd_line_ptr; uint32_t initrd_addr_max; uint32_t kernel_alignment; uint8_t relocatable_kernel; uint8_t pad2[3]; uint32_t cmdline_max_len; } __packed; #define BOOT_MAGIC 0xAA55 #define LINUX_MAGIC ('H' + ('d' << 8) + ('r' << 16) + ('S' << 24)) #define OLD_CMDLINE_MAGIC 0xA33F /* loadflags */ #define LOAD_HIGH 0x01 #define CAN_USE_HEAP 0x80 /* Get the combined size of the initramfs */ static addr_t initramfs_size(struct initramfs *initramfs) { struct initramfs *ip; addr_t size = 0; if (!initramfs) return 0; for (ip = initramfs->next; ip->len; ip = ip->next) { size = (size+ip->align-1) & ~(ip->align-1); /* Alignment */ size += ip->len; } return size; } /* Create the appropriate mappings for the initramfs */ static int map_initramfs(struct syslinux_movelist **fraglist, struct syslinux_memmap **mmap, struct initramfs *initramfs, addr_t addr) { struct initramfs *ip; addr_t next_addr, len, pad; for (ip = initramfs->next; ip->len; ip = ip->next) { len = ip->len; next_addr = addr+len; /* If this isn't the last entry, extend the zero-pad region to enforce the alignment of the next chunk. */ if (ip->next->len) { pad = -next_addr & (ip->next->align-1); len += pad; next_addr += pad; } if (ip->data_len) { if (syslinux_add_movelist(fraglist, addr, (addr_t)ip->data, len)) return -1; } if (len > ip->data_len) { if (syslinux_add_memmap(mmap, addr+ip->data_len, len-ip->data_len, SMT_ZERO)) return -1; } addr = next_addr; } return 0; } int syslinux_boot_linux(void *kernel_buf, size_t kernel_size, struct initramfs *initramfs, char *cmdline, uint16_t video_mode, uint32_t memlimit) { struct linux_header hdr, *whdr; size_t real_mode_size, prot_mode_size; addr_t real_mode_base, prot_mode_base; addr_t irf_size; size_t cmdline_size, cmdline_offset; struct syslinux_rm_regs regs; struct syslinux_movelist *fraglist = NULL; struct syslinux_memmap *mmap = NULL; struct syslinux_memmap *amap = NULL; cmdline_size = strlen(cmdline)+1; if (kernel_size < 2*512) goto bail; /* Copy the header into private storage */ /* Use whdr to modify the actual kernel header */ memcpy(&hdr, kernel_buf, sizeof hdr); whdr = (struct linux_header *)kernel_buf; if (hdr.boot_flag != BOOT_MAGIC) goto bail; if (hdr.header != LINUX_MAGIC) { hdr.version = 0x0100; /* Very old kernel */ hdr.loadflags = 0; } whdr->vid_mode = video_mode; if (!hdr.setup_sects) hdr.setup_sects = 4; if (hdr.version < 0x0203) hdr.initrd_addr_max = 0x37ffffff; if (!memlimit || memlimit-1 > hdr.initrd_addr_max) memlimit = hdr.initrd_addr_max+1; /* Zero for no limit */ if (hdr.version < 0x0206) hdr.cmdline_max_len = 256; if (cmdline_size > hdr.cmdline_max_len) { cmdline_size = hdr.cmdline_max_len; cmdline[cmdline_size-1] = '\0'; } if (hdr.version < 0x0202 || !(hdr.loadflags & 0x01)) cmdline_offset = (0x9ff0 - cmdline_size) & ~15; else cmdline_offset = 0x10000; real_mode_size = (hdr.setup_sects+1) << 9; real_mode_base = (hdr.loadflags & LOAD_HIGH) ? 0x10000 : 0x90000; prot_mode_base = (hdr.loadflags & LOAD_HIGH) ? 0x100000 : 0x10000; prot_mode_size = kernel_size - real_mode_size; if (!(hdr.loadflags & LOAD_HIGH) && prot_mode_size > 512*1024) goto bail; /* Kernel cannot be loaded low */ if (initramfs && hdr.version < 0x0200) goto bail; /* initrd/initramfs not supported */ if (hdr.version >= 0x0200) { whdr->type_of_loader = 0x30; /* SYSLINUX unknown module */ if (hdr.version >= 0x0201) { whdr->heap_end_ptr = cmdline_offset - 0x0200; whdr->loadflags |= CAN_USE_HEAP; } if (hdr.version >= 0x0202) { whdr->cmd_line_ptr = real_mode_base+cmdline_offset; } else { whdr->old_cmd_line_magic = OLD_CMDLINE_MAGIC; whdr->old_cmd_line_offset = cmdline_offset; /* Be paranoid and round up to a multiple of 16 */ whdr->setup_move_size = (cmdline_offset+cmdline_size+15) & ~15; } } /* Get the memory map */ mmap = syslinux_memory_map(); /* Memory map for shuffle_boot */ amap = syslinux_dup_memmap(mmap); /* Keep track of available memory */ if (!mmap || !amap) goto bail; #if DEBUG dprintf("Initial memory map:\n"); syslinux_dump_memmap(stdout, mmap); #endif /* If the user has specified a memory limit, mark that as unavailable. Question: should we mark this off-limit in the mmap as well (meaning it's unavailable to the boot loader, which probably has already touched some of it), or just in the amap? */ if (memlimit) if (syslinux_add_memmap(&amap, memlimit, -memlimit, SMT_RESERVED)) goto bail; /* Place the kernel in memory */ /* Real mode code */ if (syslinux_add_movelist(&fraglist, real_mode_base, (addr_t)kernel_buf, real_mode_size)) goto bail; if (syslinux_add_memmap(&amap, real_mode_base, cmdline_offset+cmdline_size, SMT_ALLOC)) goto bail; /* Zero region between real mode code and cmdline */ if (syslinux_add_memmap(&mmap, real_mode_base+real_mode_size, cmdline_offset-real_mode_size, SMT_ZERO)) goto bail; /* Command line */ if (syslinux_add_movelist(&fraglist, real_mode_base+cmdline_offset, (addr_t)cmdline, cmdline_size)) goto bail; /* Protected-mode code */ if (syslinux_add_movelist(&fraglist, prot_mode_base, (addr_t)kernel_buf + real_mode_size, prot_mode_size)) goto bail; if (syslinux_add_memmap(&amap, prot_mode_base, prot_mode_size, SMT_ALLOC)) goto bail; /* Figure out the size of the initramfs, and where to put it. We should put it at the highest possible address which is <= hdr.initrd_addr_max, which fits the entire initramfs. */ irf_size = initramfs_size(initramfs); /* Handles initramfs == NULL */ if (irf_size) { addr_t best_addr = 0; struct syslinux_memmap *ml; const addr_t align_mask = INITRAMFS_MAX_ALIGN-1; if (irf_size) { for (ml = amap; ml->type != SMT_END; ml = ml->next) { addr_t adj_start = (ml->start+align_mask) & ~align_mask; if (ml->type == SMT_FREE && ml->next->start - adj_start >= irf_size) best_addr = (ml->next->start - irf_size) & ~align_mask; } if (!best_addr) goto bail; /* Insufficient memory for initramfs */ whdr->ramdisk_image = best_addr; whdr->ramdisk_size = irf_size; if (syslinux_add_memmap(&amap, best_addr, irf_size, SMT_ALLOC)) goto bail; if (map_initramfs(&fraglist, &mmap, initramfs, best_addr)) goto bail; } } /* Set up the registers on entry */ memset(®s, 0, sizeof regs); regs.es = regs.ds = regs.ss = regs.fs = regs.gs = real_mode_base >> 4; regs.cs = (real_mode_base >> 4)+0x20; /* regs.ip = 0; */ regs.esp.w[0] = cmdline_offset; #if DEBUG dprintf("Final memory map:\n"); syslinux_dump_memmap(stdout, mmap); dprintf("Final available map:\n"); syslinux_dump_memmap(stdout, amap); dprintf("Initial movelist:\n"); syslinux_dump_movelist(stdout, fraglist); #endif syslinux_shuffle_boot_rm(fraglist, mmap, 0, ®s); bail: syslinux_free_movelist(fraglist); syslinux_free_memmap(mmap); syslinux_free_memmap(amap); return -1; } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/initramfs_loadfile.c0000664000175000017500000000341010777447272023577 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * initramfs_loadfile.c * * Load a single file into an initramfs image. */ #include #include int initramfs_load_file(struct initramfs *ihead, const char *src_filename, const char *dst_filename, int do_mkdir, uint32_t mode) { void *data; size_t len; if (loadfile(src_filename, &data, &len)) return -1; return initramfs_add_file(ihead, data, len, len, dst_filename, do_mkdir, mode); } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/shuffle_pm.c0000664000175000017500000000435210777447272022102 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * shuffle_pm.c * * Shuffle and boot to protected mode code */ #include #include #include #include #include #include int syslinux_shuffle_boot_pm(struct syslinux_movelist *fraglist, struct syslinux_memmap *memmap, uint16_t bootflags, struct syslinux_pm_regs *regs) { int nd; com32sys_t ireg; char *regbuf; nd = syslinux_prepare_shuffle(fraglist, memmap); if (nd < 0) return -1; regbuf = (char *)__com32.cs_bounce + (12*nd); memcpy(regbuf, regs, sizeof(*regs)); memset(&ireg, 0, sizeof ireg); ireg.eax.w[0] = 0x001a; ireg.edx.w[0] = bootflags; ireg.es = SEG(__com32.cs_bounce); ireg.edi.l = OFFS(__com32.cs_bounce); ireg.ecx.l = nd; ireg.ds = SEG(regbuf); ireg.esi.l = OFFS(regbuf); __intcall(0x22, &ireg, NULL); return -1; /* Too many descriptors? */ } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/shuffle_rm.c0000664000175000017500000000435210777447272022104 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * shuffle_rm.c * * Shuffle and boot to protected mode code */ #include #include #include #include #include #include int syslinux_shuffle_boot_rm(struct syslinux_movelist *fraglist, struct syslinux_memmap *memmap, uint16_t bootflags, struct syslinux_rm_regs *regs) { int nd; com32sys_t ireg; char *regbuf; nd = syslinux_prepare_shuffle(fraglist, memmap); if (nd < 0) return -1; regbuf = (char *)__com32.cs_bounce + (12*nd); memcpy(regbuf, regs, sizeof(*regs)); memset(&ireg, 0, sizeof ireg); ireg.eax.w[0] = 0x001b; ireg.edx.w[0] = bootflags; ireg.es = SEG(__com32.cs_bounce); ireg.edi.l = OFFS(__com32.cs_bounce); ireg.ecx.l = nd; ireg.ds = SEG(regbuf); ireg.esi.l = OFFS(regbuf); __intcall(0x22, &ireg, NULL); return -1; /* Too many descriptors? */ } syslinux-legacy-3.63+dfsg/com32/lib/syslinux/run_default.c0000664000175000017500000000307010777447272022256 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include __noreturn syslinux_run_default(void) { static com32sys_t ireg; ireg.eax.w[0] = 0x0004; __intcall(0x22, &ireg, NULL); /* Should not return even on failure */ for(;;); } syslinux-legacy-3.63+dfsg/com32/lib/fwrite2.c0000664000175000017500000000036010777447272017431 0ustar evanevan/* * fwrite2.c * * The actual fwrite() function as a non-inline */ #define __NO_FREAD_FWRITE_INLINES #include size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *f) { return _fwrite(ptr, size*nmemb, f)/size; } syslinux-legacy-3.63+dfsg/com32/lib/fgetc.c0000664000175000017500000000056410777447272017145 0ustar evanevan/* * fgetc.c * * Extremely slow fgetc implementation, using _fread(). If people * actually need character-oriented input to be fast, we may actually * have to implement buffering. Sigh. */ #include #include #include #include int fgetc(FILE *f) { unsigned char ch; return (_fread(&ch, 1, f) == 1) ? (int)ch : EOF; } syslinux-legacy-3.63+dfsg/com32/lib/atexit.h0000664000175000017500000000035410777447272017355 0ustar evanevan/* * atexit.h * * atexit()/on_exit() internal definitions */ #ifndef ATEXIT_H #define ATEXIT_H struct atexit { void (*fctn)(int, void *); void *arg; /* on_exit() parameter */ struct atexit *next; }; #endif /* ATEXIT_H */ syslinux-legacy-3.63+dfsg/com32/lib/fopendev.c0000664000175000017500000000123110777447272017653 0ustar evanevan/* * fopendev.c */ #include #include #include FILE *fopendev(const struct dev_info *dev, const char *mode) { int flags = O_RDONLY; int plus = 0; int fd; while ( *mode ) { switch ( *mode ) { case 'r': flags = O_RDONLY; break; case 'w': flags = O_WRONLY|O_CREAT|O_TRUNC; break; case 'a': flags = O_WRONLY|O_CREAT|O_APPEND; break; case '+': plus = 1; break; } mode++; } if ( plus ) { flags = (flags & ~(O_RDONLY|O_WRONLY)) | O_RDWR; } fd = opendev(file, flags); if ( fd < 0 ) return NULL; else return fdopen(fd, mode); } syslinux-legacy-3.63+dfsg/com32/lib/setjmp.S0000664000175000017500000000203510777447272017332 0ustar evanevan# # arch/i386/setjmp.S # # setjmp/longjmp for the i386 architecture # # # The jmp_buf is assumed to contain the following, in order: # %ebx # %esp # %ebp # %esi # %edi # # .text .align 4 .globl _setjmp .type _setjmp, @function _setjmp: # gcc 4.0.1 wants this as an alias? .globl setjmp .type setjmp, @function setjmp: #ifdef REGPARM movl %eax,%edx #else movl 4(%esp),%edx #endif popl %ecx # Return address, and adjust the stack xorl %eax,%eax # Return value movl %ebx,(%edx) movl %esp,4(%edx) # Post-return %esp! pushl %ecx # Make the call/return stack happy movl %ebp,8(%edx) movl %esi,12(%edx) movl %edi,16(%edx) movl %ecx,20(%edx) # Return address ret .size setjmp,.-setjmp .text .align 4 .globl longjmp .type longjmp, @function longjmp: #ifdef REGPARM xchgl %eax,%edx #else movl 4(%esp),%edx # jmp_ptr address movl 8(%esp),%eax # Return value #endif movl (%edx),%ebx movl 4(%edx),%esp movl 8(%edx),%ebp movl 12(%edx),%esi movl 16(%edx),%edi jmp *20(%edx) .size longjmp,.-longjmp syslinux-legacy-3.63+dfsg/com32/lib/strcasecmp.c0000664000175000017500000000067110777447272020220 0ustar evanevan/* * strcasecmp.c */ #include #include int strcasecmp(const char *s1, const char *s2) { const unsigned char *c1 = s1, *c2 = s2; unsigned char ch; int d = 0; while ( 1 ) { /* toupper() expects an unsigned char (implicitly cast to int) as input, and returns an int, which is exactly what we want. */ d = toupper(ch = *c1++) - toupper(*c2++); if ( d || !ch ) break; } return d; } syslinux-legacy-3.63+dfsg/com32/lib/fopen.c0000664000175000017500000000121410777447272017155 0ustar evanevan/* * fopen.c */ #include #include #include FILE *fopen(const char *file, const char *mode) { int flags = O_RDONLY; int plus = 0; int fd; while ( *mode ) { switch ( *mode ) { case 'r': flags = O_RDONLY; break; case 'w': flags = O_WRONLY|O_CREAT|O_TRUNC; break; case 'a': flags = O_WRONLY|O_CREAT|O_APPEND; break; case '+': plus = 1; break; } mode++; } if ( plus ) { flags = (flags & ~(O_RDONLY|O_WRONLY)) | O_RDWR; } fd = open(file, flags, 0666); if ( fd < 0 ) return NULL; else return fdopen(fd, mode); } syslinux-legacy-3.63+dfsg/com32/lib/vprintf.c0000664000175000017500000000022410777447272017536 0ustar evanevan/* * vprintf.c */ #include #include int vprintf(const char *format, va_list ap) { return vfprintf(stdout, format, ap); } syslinux-legacy-3.63+dfsg/com32/lib/strtox.c0000664000175000017500000000034510777447272017415 0ustar evanevan/* * strtox.c * * strto...() functions, by macro definition */ #include #include TYPE NAME (const char *nptr, char **endptr, int base) { return (TYPE) strntoumax(nptr, endptr, base, ~(size_t)0); } syslinux-legacy-3.63+dfsg/com32/lib/memmem.c0000664000175000017500000000141410777447272017325 0ustar evanevan/* * memmem.c * * Find a byte string inside a longer byte string * * This uses the "Not So Naive" algorithm, a very simple but * usually effective algorithm, see: * * http://www-igm.univ-mlv.fr/~lecroq/string/ */ #include void *memmem(const void *haystack, size_t n, const void *needle, size_t m) { const unsigned char *y = (const unsigned char *)haystack; const unsigned char *x = (const unsigned char *)needle; size_t j, k, l; if ( m > n ) return NULL; if ( x[0] == x[1] ) { k = 2; l = 1; } else { k = 1; l = 2; } j = 0; while ( j <= n-m ) { if (x[1] != y[j+1]) { j += k; } else { if ( !memcmp(x+2, y+j+2, m-2) && x[0] == y[j] ) return (void *)&y[j]; j += l; } } return NULL; } syslinux-legacy-3.63+dfsg/com32/lib/strnlen.c0000664000175000017500000000023410777447272017534 0ustar evanevan/* * strnlen() */ #include size_t strnlen(const char *s, size_t n) { const char *ss = s; while ( n-- && *ss ) ss++; return ss-s; } syslinux-legacy-3.63+dfsg/com32/lib/strtok.c0000664000175000017500000000025310777447272017376 0ustar evanevan/* * strtok.c */ #include char *strtok(char *s, const char *delim) { static char *holder; if ( s ) holder = s; return strsep(&holder, delim); } syslinux-legacy-3.63+dfsg/com32/lib/onexit.c0000664000175000017500000000117710777447272017364 0ustar evanevan/* * onexit.c */ #include #include #include "atexit.h" extern __noreturn (*__exit_handler)(int); static struct atexit *__atexit_list; static __noreturn on_exit_exit(int rv) { struct atexit *ap; for ( ap = __atexit_list ; ap ; ap = ap->next ) { ap->fctn(rv, ap->arg); /* This assumes extra args are harmless */ } _exit(rv); } int on_exit(void (*fctn)(int, void *), void *arg) { struct atexit *as = malloc(sizeof(struct atexit)); if ( !as ) return -1; as->fctn = fctn; as->arg = arg; as->next = __atexit_list; __atexit_list = as; __exit_handler = on_exit_exit; return 0; } syslinux-legacy-3.63+dfsg/com32/lib/strtoumax.c0000664000175000017500000000010210777447272020107 0ustar evanevan#define TYPE uintmax_t #define NAME strtoumax #include "strtox.c" syslinux-legacy-3.63+dfsg/com32/LICENCE0000664000175000017500000000276210777447272016132 0ustar evanevanlibcom32 and libutil are licensed under the MIT license: ## ----------------------------------------------------------------------- ## ## Copyright 2004-2008 H. Peter Anvin - All Rights Reserved ## ## Permission is hereby granted, free of charge, to any person ## obtaining a copy of this software and associated documentation ## files (the "Software"), to deal in the Software without ## restriction, including without limitation the rights to use, ## copy, modify, merge, publish, distribute, sublicense, and/or ## sell copies of the Software, and to permit persons to whom ## the Software is furnished to do so, subject to the following ## conditions: ## ## The above copyright notice and this permission notice shall ## be included in all copies or substantial portions of the Software. ## ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ## OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ## HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ## WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ## FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ## OTHER DEALINGS IN THE SOFTWARE. ## ## ----------------------------------------------------------------------- The files in the samples and modules directories are mostly under the GNU GPL (see the file COPYING in the directory above.) syslinux-legacy-3.63+dfsg/com32/include/0000775000175000017500000000000010777447272016561 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/include/dev.h0000664000175000017500000000347410777447272017520 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * console.h * * Alternative consoles */ #ifndef _DEV_H #define _DEV_H #include #include struct input_dev; struct output_dev; __extern int opendev(const struct input_dev *, const struct output_dev *, int); /* Common generic devices */ /* Null device */ extern const struct input_dev dev_null_r; extern const struct output_dev dev_null_w; /* Error device */ extern const struct input_dev dev_error_r; extern const struct output_dev dev_error_w; #endif /* _DEV_H */ syslinux-legacy-3.63+dfsg/com32/include/setjmp.h0000664000175000017500000000061010777447272020231 0ustar evanevan/* * setjmp.h */ #ifndef _SETJMP_H #define _SETJMP_H #include #include #include #include __extern int setjmp(jmp_buf); __extern __noreturn longjmp(jmp_buf, int); typedef jmp_buf sigjmp_buf; #define sigsetjmp(__env, __save) setjmp(__env) #define siglongjmp(__env, __val) longjmp(__env, __val) #endif /* _SETJMP_H */ syslinux-legacy-3.63+dfsg/com32/include/unistd.h0000664000175000017500000000106310777447272020240 0ustar evanevan/* * unistd.h */ #ifndef _UNISTD_H #define _UNISTD_H #include #include #include #include __extern __noreturn _exit(int); __extern int open(const char *, int, ...); __extern int close(int); __extern ssize_t read(int, void *, size_t); __extern ssize_t write(int, const void *, size_t); __extern int isatty(int); __extern int getscreensize(int, int *, int *); /* Standard file descriptor numbers. */ #define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2 #endif /* _UNISTD_H */ syslinux-legacy-3.63+dfsg/com32/include/limits.h0000664000175000017500000000130510777447272020232 0ustar evanevan/* * limits.h */ #ifndef _LIMITS_H #define _LIMITS_H #define CHAR_BIT 8 #define SHRT_BIT 16 #define INT_BIT 32 #define LONGLONG_BIT 64 #define SCHAR_MIN (-128) #define SCHAR_MAX 127 #define UCHAR_MAX 255 #ifdef __CHAR_UNSIGNED__ # define CHAR_MIN 0 # define CHAR_MAX UCHAR_MAX #else # define CHAR_MIN SCHAR_MIN # define CHAR_MAX SCHAR_MAX #endif #define SHRT_MIN (-32768) #define SHRT_MAX 32767 #define USHRT_MAX 65535 #define INT_MIN (-2147483647-1) #define INT_MAX 2147483647 #define UINT_MAX 4294967295U #define LONGLONG_MIN (-9223372036854775807LL-1) #define LONGLONG_MAX 9223372036854775807LL #define ULONGLONG_MAX 18446744073709551615ULL #include #endif /* _LIMITS_H */ syslinux-legacy-3.63+dfsg/com32/include/endian.h0000664000175000017500000000036510777447272020174 0ustar evanevan/* * endian.h */ #ifndef _ENDIAN_H #define _ENDIAN_H #include #define LITTLE_ENDIAN __LITTLE_ENDIAN #define BIG_ENDIAN __BIG_ENDIAN #define PDP_ENDIAN __PDP_ENDIAN #define BYTE_ORDER __BYTE_ORDER #endif /* _ENDIAN_H */ syslinux-legacy-3.63+dfsg/com32/include/klibc/0000775000175000017500000000000010777447272017645 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/include/klibc/extern.h0000664000175000017500000000027510777447272021327 0ustar evanevan/* * klibc/extern.h */ #ifndef _KLIBC_EXTERN_H #define _KLIBC_EXTERN_H #ifdef __cplusplus #define __extern extern "C" #else #define __extern extern #endif #endif /* _KLIBC_EXTERN_H */ syslinux-legacy-3.63+dfsg/com32/include/klibc/endian.h0000664000175000017500000000176110777447272021261 0ustar evanevan/* * klibc/endian.h * * Like , but export only double-underscore symbols */ #ifndef _KLIBC_ENDIAN_H #define _KLIBC_ENDIAN_H #define __LITTLE_ENDIAN /* we're on i386, littleendian */ /* Linux' asm/byteorder.h defines either __LITTLE_ENDIAN or __BIG_ENDIAN, but the glibc/BSD-ish macros expect both to be defined with __BYTE_ORDER defining which is actually used... */ #if defined(__LITTLE_ENDIAN) # undef __LITTLE_ENDIAN # define __LITTLE_ENDIAN 1234 # define __BIG_ENDIAN 4321 # define __PDP_ENDIAN 3412 # define __BYTE_ORDER __LITTLE_ENDIAN #elif defined(__BIG_ENDIAN) # undef __BIG_ENDIAN # define __LITTLE_ENDIAN 1234 # define __BIG_ENDIAN 4321 # define __PDP_ENDIAN 3412 # define __BYTE_ORDER __BIG_ENDIAN #elif defined(__PDP_ENDIAN) # undef __PDP_ENDIAN # define __LITTLE_ENDIAN 1234 # define __BIG_ENDIAN 4321 # define __PDP_ENDIAN 3412 # define __BYTE_ORDER __PDP_ENDIAN #else # error "Unknown byte order!" #endif #endif /* _KLIBC_ENDIAN_H */ syslinux-legacy-3.63+dfsg/com32/include/klibc/diverr.h0000664000175000017500000000013310777447272021306 0ustar evanevanstatic inline void __divide_error(void) { asm volatile("int $0"); /* Divide by zero */ } syslinux-legacy-3.63+dfsg/com32/include/klibc/archsetjmp.h0000664000175000017500000000050110777447272022152 0ustar evanevan/* * arch/i386/include/klibc/archsetjmp.h */ #ifndef _KLIBC_ARCHSETJMP_H #define _KLIBC_ARCHSETJMP_H struct __jmp_buf { unsigned int __ebx; unsigned int __esp; unsigned int __ebp; unsigned int __esi; unsigned int __edi; unsigned int __eip; }; typedef struct __jmp_buf jmp_buf[1]; #endif /* _SETJMP_H */ syslinux-legacy-3.63+dfsg/com32/include/klibc/sysconfig.h0000664000175000017500000000161210777447272022022 0ustar evanevan/* * klibc/sysconfig.h * * Allows for definitions of some things which may be system-dependent */ #ifndef _KLIBC_SYSCONFIG_H #define _KLIBC_SYSCONFIG_H /* * Define this to obtain memory using sbrk() instead * of mmap(). This should make it friendlier on * non-MMU architectures. This should become a * per-architecture configurable. */ #define MALLOC_USING_SBRK /* * This is the minimum chunk size we will ask the kernel for using * malloc(); this should be a multiple of the page size on all * architectures. */ #define MALLOC_CHUNK_SIZE 4096 #define MALLOC_CHUNK_MASK (MALLOC_CHUNK_SIZE-1) /* * This is the minimum alignment for the memory returned by sbrk(). * It must be a power of 2. If MALLOC_USING_SBRK is defined it should * be no smaller than the size of struct arena_header in malloc.h (4 * pointers.) */ #define SBRK_ALIGNMENT 32 #endif /* _KLIBC_SYSCONFIG_H */ syslinux-legacy-3.63+dfsg/com32/include/klibc/compiler.h0000664000175000017500000000635510777447272021641 0ustar evanevan/* * klibc/compiler.h * * Various compiler features */ #ifndef _KLIBC_COMPILER_H #define _KLIBC_COMPILER_H #define __user /* Specific calling conventions */ /* __cdecl is used when we want varadic and non-varadic functions to have the same binary calling convention. */ #ifdef __i386__ # ifdef __GNUC__ # define __cdecl __attribute__((cdecl,regparm(0))) # else /* Most other C compilers have __cdecl as a keyword */ # endif #else # define __cdecl /* Meaningless on non-i386 */ #endif /* How to declare a function that *must* be inlined */ #ifdef __GNUC__ # if __GNUC_MAJOR__ >= 3 # define __must_inline static __inline__ __attribute__((always_inline)) # else # define __must_inline extern __inline__ # endif #else # define __must_inline inline /* Just hope this works... */ #endif /* How to declare a function that does not return */ #ifdef __GNUC__ # define __noreturn void __attribute__((noreturn)) #else # define __noreturn void #endif /* "const" function: Many functions do not examine any values except their arguments, and have no effects except the return value. Basically this is just slightly more strict class than the `pure' attribute above, since function is not allowed to read global memory. Note that a function that has pointer arguments and examines the data pointed to must _not_ be declared `const'. Likewise, a function that calls a non-`const' function usually must not be `const'. It does not make sense for a `const' function to return `void'. */ #ifdef __GNUC__ # define __constfunc __attribute__((const)) #else # define __constfunc #endif #undef __attribute_const__ #define __attribute_const__ __constfunc /* "pure" function: Many functions have no effects except the return value and their return value depends only on the parameters and/or global variables. Such a function can be subject to common subexpression elimination and loop optimization just as an arithmetic operator would be. These functions should be declared with the attribute `pure'. */ #ifdef __GNUC__ # define __purefunc __attribute__((pure)) #else # define __purefunc #endif #undef __attribute_pure__ #define __attribute_pure__ __purefunc /* Format attribute */ #ifdef __GNUC__ # define __formatfunc(t,f,a) __attribute__((format(t,f,a))) #else # define __formatfunc(t,f,a) #endif /* malloc() function (returns unaliased pointer) */ #if defined(__GNUC__) && (__GNUC_MAJOR__ >= 3) # define __mallocfunc __attribute__((malloc)) #else # define __mallocfunc #endif /* likely/unlikely */ #if defined(__GNUC__) && (__GNUC_MAJOR__ > 2 || (__GNUC_MAJOR__ == 2 && __GNUC_MINOR__ >= 95)) # define __likely(x) __builtin_expect((x), 1) # define __unlikely(x) __builtin_expect((x), 0) #else # define __likely(x) (x) # define __unlikely(x) (x) #endif /* Possibly unused function */ #ifdef __GNUC__ # define __unusedfunc __attribute__((unused)) #else # define __unusedfunc #endif /* Constructors and destructors */ #define __constructor __attribute__((constructor)) #define __destructor __attribute__((destructor)) /* Packed structures */ #define __packed __attribute__((packed)) /* Alignment */ #define __aligned(x) __attribute__((aligned(x))) #define __alignas(x) __attribute__((aligned(__alignof__(x)))) #endif syslinux-legacy-3.63+dfsg/com32/include/bitsize/0000775000175000017500000000000010777447272020232 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/include/bitsize/limits.h0000664000175000017500000000034310777447272021704 0ustar evanevan/* * bits32/limits.h */ #ifndef _BITSIZE_LIMITS_H #define _BITSIZE_LIMITS_H #define LONG_BIT 32 #define LONG_MIN (-2147483647L-1) #define LONG_MAX 2147483647L #define ULONG_MAX 4294967295UL #endif /* _BITSIZE_LIMITS_H */ syslinux-legacy-3.63+dfsg/com32/include/bitsize/stdintlimits.h0000664000175000017500000000075110777447272023135 0ustar evanevan/* * bits32/stdintlimits.h */ #ifndef _BITSIZE_STDINTLIMITS_H #define _BITSIZE_STDINTLIMITS_H #define INT_FAST16_MIN INT32_MIN #define INT_FAST32_MIN INT32_MIN #define INT_FAST16_MAX INT32_MAX #define INT_FAST32_MAX INT32_MAX #define UINT_FAST16_MAX UINT32_MAX #define UINT_FAST32_MAX UINT32_MAX #define INTPTR_MIN INT32_MIN #define INTPTR_MAX INT32_MAX #define UINTPTR_MAX UINT32_MAX #define PTRDIFF_MIN INT32_MIN #define PTRDIFF_MAX INT32_MAX #endif /* _BITSIZE_STDINTLIMITS_H */ syslinux-legacy-3.63+dfsg/com32/include/bitsize/stdint.h0000664000175000017500000000127610777447272021716 0ustar evanevan/* * bits32/stdint.h */ #ifndef _BITSIZE_STDINT_H #define _BITSIZE_STDINT_H typedef signed char int8_t; typedef short int int16_t; typedef int int32_t; typedef long long int int64_t; typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef unsigned long long int uint64_t; typedef int int_fast16_t; typedef int int_fast32_t; typedef unsigned int uint_fast16_t; typedef unsigned int uint_fast32_t; typedef int intptr_t; typedef unsigned int uintptr_t; #define __INT64_C(c) c ## LL #define __UINT64_C(c) c ## ULL #define __PRI64_RANK "ll" #define __PRIFAST_RANK "" #define __PRIPTR_RANK "" #endif /* _BITSIZE_STDINT_H */ syslinux-legacy-3.63+dfsg/com32/include/bitsize/stdintconst.h0000664000175000017500000000057610777447272022767 0ustar evanevan/* * bits32/stdintconst.h */ #ifndef _BITSIZE_STDINTCONST_H #define _BITSIZE_STDINTCONST_H #define INT_FAST16_C(c) INT32_C(c) #define INT_FAST32_C(c) INT32_C(c) #define UINT_FAST16_C(c) UINT32_C(c) #define UINT_FAST32_C(c) UINT32_C(c) #define INTPTR_C(c) INT32_C(c) #define UINTPTR_C(c) UINT32_C(c) #define PTRDIFF_C(c) INT32_C(c) #endif /* _BITSIZE_STDINTCONST_H */ syslinux-legacy-3.63+dfsg/com32/include/bitsize/stddef.h0000664000175000017500000000047410777447272021661 0ustar evanevan/* * bits32/stddef.h */ #ifndef _BITSIZE_STDDEF_H #define _BITSIZE_STDDEF_H #define _SIZE_T #if defined(__s390__) || defined(__hppa__) || defined(__cris__) typedef unsigned long size_t; #else typedef unsigned int size_t; #endif #define _PTRDIFF_T typedef signed int ptrdiff_t; #endif /* _BITSIZE_STDDEF_H */ syslinux-legacy-3.63+dfsg/com32/include/pngconf.h0000664000175000017500000012520210777447272020366 0ustar evanevan /* pngconf.h - machine configurable file for libpng * * libpng version 1.2.8 - December 3, 2004 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ /* Any machine specific code is near the front of this file, so if you * are configuring libpng for a machine, you may want to read the section * starting here down to where it starts to typedef png_color, png_text, * and png_info. */ #ifndef PNGCONF_H #define PNGCONF_H #define PNG_1_2_X /* * PNG_USER_CONFIG has to be defined on the compiler command line. This * includes the resource compiler for Windows DLL configurations. */ #ifdef PNG_USER_CONFIG #include "pngusr.h" #endif /* * Added at libpng-1.2.8 * * If you create a private DLL you need to define in "pngusr.h" the followings: * #define PNG_USER_PRIVATEBUILD * e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons." * #define PNG_USER_DLLFNAME_POSTFIX * e.g. // private DLL "libpng13gx.dll" * #define PNG_USER_DLLFNAME_POSTFIX "gx" * * The following macros are also at your disposal if you want to complete the * DLL VERSIONINFO structure. * - PNG_USER_VERSIONINFO_COMMENTS * - PNG_USER_VERSIONINFO_COMPANYNAME * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS */ #ifdef __STDC__ #ifdef SPECIALBUILD # pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\ are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.") #endif #ifdef PRIVATEBUILD # pragma message("PRIVATEBUILD is deprecated. Use\ PNG_USER_PRIVATEBUILD instead.") # define PNG_USER_PRIVATEBUILD PRIVATEBUILD #endif #endif /* __STDC__ */ #ifndef PNG_VERSION_INFO_ONLY /* End of material added to libpng-1.2.8 */ /* This is the size of the compression buffer, and thus the size of * an IDAT chunk. Make this whatever size you feel is best for your * machine. One of these will be allocated per png_struct. When this * is full, it writes the data to the disk, and does some other * calculations. Making this an extremely small size will slow * the library down, but you may want to experiment to determine * where it becomes significant, if you are concerned with memory * usage. Note that zlib allocates at least 32Kb also. For readers, * this describes the size of the buffer available to read the data in. * Unless this gets smaller than the size of a row (compressed), * it should not make much difference how big this is. */ #ifndef PNG_ZBUF_SIZE # define PNG_ZBUF_SIZE 8192 #endif /* Enable if you want a write-only libpng */ #ifndef PNG_NO_READ_SUPPORTED # define PNG_READ_SUPPORTED #endif /* Enable if you want a read-only libpng */ #ifndef PNG_NO_WRITE_SUPPORTED # define PNG_WRITE_SUPPORTED #endif /* Enabled by default in 1.2.0. You can disable this if you don't need to support PNGs that are embedded in MNG datastreams */ #if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES) # ifndef PNG_MNG_FEATURES_SUPPORTED # define PNG_MNG_FEATURES_SUPPORTED # endif #endif #ifndef PNG_NO_FLOATING_POINT_SUPPORTED # ifndef PNG_FLOATING_POINT_SUPPORTED # define PNG_FLOATING_POINT_SUPPORTED # endif #endif /* If you are running on a machine where you cannot allocate more * than 64K of memory at once, uncomment this. While libpng will not * normally need that much memory in a chunk (unless you load up a very * large file), zlib needs to know how big of a chunk it can use, and * libpng thus makes sure to check any memory allocation to verify it * will fit into memory. #define PNG_MAX_MALLOC_64K */ #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) # define PNG_MAX_MALLOC_64K #endif /* Special munging to support doing things the 'cygwin' way: * 'Normal' png-on-win32 defines/defaults: * PNG_BUILD_DLL -- building dll * PNG_USE_DLL -- building an application, linking to dll * (no define) -- building static library, or building an * application and linking to the static lib * 'Cygwin' defines/defaults: * PNG_BUILD_DLL -- (ignored) building the dll * (no define) -- (ignored) building an application, linking to the dll * PNG_STATIC -- (ignored) building the static lib, or building an * application that links to the static lib. * ALL_STATIC -- (ignored) building various static libs, or building an * application that links to the static libs. * Thus, * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and * this bit of #ifdefs will define the 'correct' config variables based on * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but * unnecessary. * * Also, the precedence order is: * ALL_STATIC (since we can't #undef something outside our namespace) * PNG_BUILD_DLL * PNG_STATIC * (nothing) == PNG_USE_DLL * * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent * of auto-import in binutils, we no longer need to worry about * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore, * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes * to __declspec() stuff. However, we DO need to worry about * PNG_BUILD_DLL and PNG_STATIC because those change some defaults * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed. */ #if defined(__CYGWIN__) # if defined(ALL_STATIC) # if defined(PNG_BUILD_DLL) # undef PNG_BUILD_DLL # endif # if defined(PNG_USE_DLL) # undef PNG_USE_DLL # endif # if defined(PNG_DLL) # undef PNG_DLL # endif # if !defined(PNG_STATIC) # define PNG_STATIC # endif # else # if defined (PNG_BUILD_DLL) # if defined(PNG_STATIC) # undef PNG_STATIC # endif # if defined(PNG_USE_DLL) # undef PNG_USE_DLL # endif # if !defined(PNG_DLL) # define PNG_DLL # endif # else # if defined(PNG_STATIC) # if defined(PNG_USE_DLL) # undef PNG_USE_DLL # endif # if defined(PNG_DLL) # undef PNG_DLL # endif # else # if !defined(PNG_USE_DLL) # define PNG_USE_DLL # endif # if !defined(PNG_DLL) # define PNG_DLL # endif # endif # endif # endif #endif /* This protects us against compilers that run on a windowing system * and thus don't have or would rather us not use the stdio types: * stdin, stdout, and stderr. The only one currently used is stderr * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will * prevent these from being compiled and used. #defining PNG_NO_STDIO * will also prevent these, plus will prevent the entire set of stdio * macros and functions (FILE *, printf, etc.) from being compiled and used, * unless (PNG_DEBUG > 0) has been #defined. * * #define PNG_NO_CONSOLE_IO * #define PNG_NO_STDIO */ #if defined(_WIN32_WCE) # include /* Console I/O functions are not supported on WindowsCE */ # define PNG_NO_CONSOLE_IO # ifdef PNG_DEBUG # undef PNG_DEBUG # endif #endif #ifdef PNG_BUILD_DLL # ifndef PNG_CONSOLE_IO_SUPPORTED # ifndef PNG_NO_CONSOLE_IO # define PNG_NO_CONSOLE_IO # endif # endif #endif # ifdef PNG_NO_STDIO # ifndef PNG_NO_CONSOLE_IO # define PNG_NO_CONSOLE_IO # endif # ifdef PNG_DEBUG # if (PNG_DEBUG > 0) # include # endif # endif # else # if !defined(_WIN32_WCE) /* "stdio.h" functions are not supported on WindowsCE */ # include # endif # endif /* This macro protects us against machines that don't have function * prototypes (ie K&R style headers). If your compiler does not handle * function prototypes, define this macro and use the included ansi2knr. * I've always been able to use _NO_PROTO as the indicator, but you may * need to drag the empty declaration out in front of here, or change the * ifdef to suit your own needs. */ #ifndef PNGARG #ifdef OF /* zlib prototype munger */ # define PNGARG(arglist) OF(arglist) #else #ifdef _NO_PROTO # define PNGARG(arglist) () # ifndef PNG_TYPECAST_NULL # define PNG_TYPECAST_NULL # endif #else # define PNGARG(arglist) arglist #endif /* _NO_PROTO */ #endif /* OF */ #endif /* PNGARG */ /* Try to determine if we are compiling on a Mac. Note that testing for * just __MWERKS__ is not good enough, because the Codewarrior is now used * on non-Mac platforms. */ #ifndef MACOS # if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) # define MACOS # endif #endif /* enough people need this for various reasons to include it here */ #if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE) # include #endif #if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED) # define PNG_SETJMP_SUPPORTED #endif #ifdef PNG_SETJMP_SUPPORTED /* This is an attempt to force a single setjmp behaviour on Linux. If * the X config stuff didn't define _BSD_SOURCE we wouldn't need this. */ # ifdef __linux__ # ifdef _BSD_SOURCE # define PNG_SAVE_BSD_SOURCE # undef _BSD_SOURCE # endif # ifdef _SETJMP_H /* If you encounter a compiler error here, see the explanation * near the end of INSTALL. */ __png.h__ already includes setjmp.h; __dont__ include it again.; # endif # endif /* __linux__ */ /* include setjmp.h for error handling */ # include # ifdef __linux__ # ifdef PNG_SAVE_BSD_SOURCE # define _BSD_SOURCE # undef PNG_SAVE_BSD_SOURCE # endif # endif /* __linux__ */ #endif /* PNG_SETJMP_SUPPORTED */ #ifdef BSD # include #else # include #endif /* Other defines for things like memory and the like can go here. */ #ifdef PNG_INTERNAL #include /* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which * aren't usually used outside the library (as far as I know), so it is * debatable if they should be exported at all. In the future, when it is * possible to have run-time registry of chunk-handling functions, some of * these will be made available again. #define PNG_EXTERN extern */ #define PNG_EXTERN /* Other defines specific to compilers can go here. Try to keep * them inside an appropriate ifdef/endif pair for portability. */ #if defined(PNG_FLOATING_POINT_SUPPORTED) # if defined(MACOS) /* We need to check that hasn't already been included earlier * as it seems it doesn't agree with , yet we should really use * if possible. */ # if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) # include # endif # else # include # endif # if defined(_AMIGA) && defined(__SASC) && defined(_M68881) /* Amiga SAS/C: We must include builtin FPU functions when compiling using * MATH=68881 */ # include # endif #endif /* Codewarrior on NT has linking problems without this. */ #if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__) # define PNG_ALWAYS_EXTERN #endif /* This provides the non-ANSI (far) memory allocation routines. */ #if defined(__TURBOC__) && defined(__MSDOS__) # include # include #endif /* I have no idea why is this necessary... */ #if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \ defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__)) # include #endif /* This controls how fine the dithering gets. As this allocates * a largish chunk of memory (32K), those who are not as concerned * with dithering quality can decrease some or all of these. */ #ifndef PNG_DITHER_RED_BITS # define PNG_DITHER_RED_BITS 5 #endif #ifndef PNG_DITHER_GREEN_BITS # define PNG_DITHER_GREEN_BITS 5 #endif #ifndef PNG_DITHER_BLUE_BITS # define PNG_DITHER_BLUE_BITS 5 #endif /* This controls how fine the gamma correction becomes when you * are only interested in 8 bits anyway. Increasing this value * results in more memory being used, and more pow() functions * being called to fill in the gamma tables. Don't set this value * less then 8, and even that may not work (I haven't tested it). */ #ifndef PNG_MAX_GAMMA_8 # define PNG_MAX_GAMMA_8 11 #endif /* This controls how much a difference in gamma we can tolerate before * we actually start doing gamma conversion. */ #ifndef PNG_GAMMA_THRESHOLD # define PNG_GAMMA_THRESHOLD 0.05 #endif #endif /* PNG_INTERNAL */ /* The following uses const char * instead of char * for error * and warning message functions, so some compilers won't complain. * If you do not want to use const, define PNG_NO_CONST here. */ #ifndef PNG_NO_CONST # define PNG_CONST const #else # define PNG_CONST #endif /* The following defines give you the ability to remove code from the * library that you will not be using. I wish I could figure out how to * automate this, but I can't do that without making it seriously hard * on the users. So if you are not using an ability, change the #define * to and #undef, and that part of the library will not be compiled. If * your linker can't find a function, you may want to make sure the * ability is defined here. Some of these depend upon some others being * defined. I haven't figured out all the interactions here, so you may * have to experiment awhile to get everything to compile. If you are * creating or using a shared library, you probably shouldn't touch this, * as it will affect the size of the structures, and this will cause bad * things to happen if the library and/or application ever change. */ /* Any features you will not be using can be undef'ed here */ /* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS * on the compile line, then pick and choose which ones to define without * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED * if you only want to have a png-compliant reader/writer but don't need * any of the extra transformations. This saves about 80 kbytes in a * typical installation of the library. (PNG_NO_* form added in version * 1.0.1c, for consistency) */ /* The size of the png_text structure changed in libpng-1.0.6 when * iTXt is supported. It is turned off by default, to support old apps * that malloc the png_text structure instead of calling png_set_text() * and letting libpng malloc it. It will be turned on by default in * libpng-1.3.0. */ #ifndef PNG_iTXt_SUPPORTED # if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt) # define PNG_NO_READ_iTXt # endif # if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt) # define PNG_NO_WRITE_iTXt # endif #endif /* The following support, added after version 1.0.0, can be turned off here en * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility * with old applications that require the length of png_struct and png_info * to remain unchanged. */ #ifdef PNG_LEGACY_SUPPORTED # define PNG_NO_FREE_ME # define PNG_NO_READ_UNKNOWN_CHUNKS # define PNG_NO_WRITE_UNKNOWN_CHUNKS # define PNG_NO_READ_USER_CHUNKS # define PNG_NO_READ_iCCP # define PNG_NO_WRITE_iCCP # define PNG_NO_READ_iTXt # define PNG_NO_WRITE_iTXt # define PNG_NO_READ_sCAL # define PNG_NO_WRITE_sCAL # define PNG_NO_READ_sPLT # define PNG_NO_WRITE_sPLT # define PNG_NO_INFO_IMAGE # define PNG_NO_READ_RGB_TO_GRAY # define PNG_NO_READ_USER_TRANSFORM # define PNG_NO_WRITE_USER_TRANSFORM # define PNG_NO_USER_MEM # define PNG_NO_READ_EMPTY_PLTE # define PNG_NO_MNG_FEATURES # define PNG_NO_FIXED_POINT_SUPPORTED #endif /* Ignore attempt to turn off both floating and fixed point support */ #if !defined(PNG_FLOATING_POINT_SUPPORTED) || \ !defined(PNG_NO_FIXED_POINT_SUPPORTED) # define PNG_FIXED_POINT_SUPPORTED #endif #ifndef PNG_NO_FREE_ME # define PNG_FREE_ME_SUPPORTED #endif #if defined(PNG_READ_SUPPORTED) #if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \ !defined(PNG_NO_READ_TRANSFORMS) # define PNG_READ_TRANSFORMS_SUPPORTED #endif #ifdef PNG_READ_TRANSFORMS_SUPPORTED # ifndef PNG_NO_READ_EXPAND # define PNG_READ_EXPAND_SUPPORTED # endif # ifndef PNG_NO_READ_SHIFT # define PNG_READ_SHIFT_SUPPORTED # endif # ifndef PNG_NO_READ_PACK # define PNG_READ_PACK_SUPPORTED # endif # ifndef PNG_NO_READ_BGR # define PNG_READ_BGR_SUPPORTED # endif # ifndef PNG_NO_READ_SWAP # define PNG_READ_SWAP_SUPPORTED # endif # ifndef PNG_NO_READ_PACKSWAP # define PNG_READ_PACKSWAP_SUPPORTED # endif # ifndef PNG_NO_READ_INVERT # define PNG_READ_INVERT_SUPPORTED # endif # ifndef PNG_NO_READ_DITHER # define PNG_READ_DITHER_SUPPORTED # endif # ifndef PNG_NO_READ_BACKGROUND # define PNG_READ_BACKGROUND_SUPPORTED # endif # ifndef PNG_NO_READ_16_TO_8 # define PNG_READ_16_TO_8_SUPPORTED # endif # ifndef PNG_NO_READ_FILLER # define PNG_READ_FILLER_SUPPORTED # endif # ifndef PNG_NO_READ_GAMMA # define PNG_READ_GAMMA_SUPPORTED # endif # ifndef PNG_NO_READ_GRAY_TO_RGB # define PNG_READ_GRAY_TO_RGB_SUPPORTED # endif # ifndef PNG_NO_READ_SWAP_ALPHA # define PNG_READ_SWAP_ALPHA_SUPPORTED # endif # ifndef PNG_NO_READ_INVERT_ALPHA # define PNG_READ_INVERT_ALPHA_SUPPORTED # endif # ifndef PNG_NO_READ_STRIP_ALPHA # define PNG_READ_STRIP_ALPHA_SUPPORTED # endif # ifndef PNG_NO_READ_USER_TRANSFORM # define PNG_READ_USER_TRANSFORM_SUPPORTED # endif # ifndef PNG_NO_READ_RGB_TO_GRAY # define PNG_READ_RGB_TO_GRAY_SUPPORTED # endif #endif /* PNG_READ_TRANSFORMS_SUPPORTED */ #if !defined(PNG_NO_PROGRESSIVE_READ) && \ !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED) /* if you don't do progressive */ # define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */ #endif /* about interlacing capability! You'll */ /* still have interlacing unless you change the following line: */ #define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */ #ifndef PNG_NO_READ_COMPOSITE_NODIV # ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */ # define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */ # endif #endif /* Deprecated, will be removed from version 2.0.0. Use PNG_MNG_FEATURES_SUPPORTED instead. */ #ifndef PNG_NO_READ_EMPTY_PLTE # define PNG_READ_EMPTY_PLTE_SUPPORTED #endif #endif /* PNG_READ_SUPPORTED */ #if defined(PNG_WRITE_SUPPORTED) # if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \ !defined(PNG_NO_WRITE_TRANSFORMS) # define PNG_WRITE_TRANSFORMS_SUPPORTED #endif #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED # ifndef PNG_NO_WRITE_SHIFT # define PNG_WRITE_SHIFT_SUPPORTED # endif # ifndef PNG_NO_WRITE_PACK # define PNG_WRITE_PACK_SUPPORTED # endif # ifndef PNG_NO_WRITE_BGR # define PNG_WRITE_BGR_SUPPORTED # endif # ifndef PNG_NO_WRITE_SWAP # define PNG_WRITE_SWAP_SUPPORTED # endif # ifndef PNG_NO_WRITE_PACKSWAP # define PNG_WRITE_PACKSWAP_SUPPORTED # endif # ifndef PNG_NO_WRITE_INVERT # define PNG_WRITE_INVERT_SUPPORTED # endif # ifndef PNG_NO_WRITE_FILLER # define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */ # endif # ifndef PNG_NO_WRITE_SWAP_ALPHA # define PNG_WRITE_SWAP_ALPHA_SUPPORTED # endif # ifndef PNG_NO_WRITE_INVERT_ALPHA # define PNG_WRITE_INVERT_ALPHA_SUPPORTED # endif # ifndef PNG_NO_WRITE_USER_TRANSFORM # define PNG_WRITE_USER_TRANSFORM_SUPPORTED # endif #endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ #define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant encoders, but can cause trouble if left undefined */ #if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \ defined(PNG_FLOATING_POINT_SUPPORTED) # define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED #endif #ifndef PNG_NO_WRITE_FLUSH # define PNG_WRITE_FLUSH_SUPPORTED #endif /* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */ #ifndef PNG_NO_WRITE_EMPTY_PLTE # define PNG_WRITE_EMPTY_PLTE_SUPPORTED #endif #endif /* PNG_WRITE_SUPPORTED */ #ifndef PNG_1_0_X # ifndef PNG_NO_ERROR_NUMBERS # define PNG_ERROR_NUMBERS_SUPPORTED # endif #endif /* PNG_1_0_X */ #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) # ifndef PNG_NO_USER_TRANSFORM_PTR # define PNG_USER_TRANSFORM_PTR_SUPPORTED # endif #endif #ifndef PNG_NO_STDIO # define PNG_TIME_RFC1123_SUPPORTED #endif /* This adds extra functions in pngget.c for accessing data from the * info pointer (added in version 0.99) * png_get_image_width() * png_get_image_height() * png_get_bit_depth() * png_get_color_type() * png_get_compression_type() * png_get_filter_type() * png_get_interlace_type() * png_get_pixel_aspect_ratio() * png_get_pixels_per_meter() * png_get_x_offset_pixels() * png_get_y_offset_pixels() * png_get_x_offset_microns() * png_get_y_offset_microns() */ #if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED) # define PNG_EASY_ACCESS_SUPPORTED #endif /* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0 even when PNG_USE_PNGVCRD or PNG_USE_PNGGCCRD is not defined */ #if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE) # ifndef PNG_ASSEMBLER_CODE_SUPPORTED # define PNG_ASSEMBLER_CODE_SUPPORTED # endif # if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) # define PNG_MMX_CODE_SUPPORTED # endif #endif /* If you are sure that you don't need thread safety and you are compiling with PNG_USE_PNGCCRD for an MMX application, you can define this for faster execution. See pnggccrd.c. #define PNG_THREAD_UNSAFE_OK */ #if !defined(PNG_1_0_X) #if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED) # define PNG_USER_MEM_SUPPORTED #endif #endif /* PNG_1_0_X */ /* Added at libpng-1.2.6 */ #if !defined(PNG_1_0_X) #ifndef PNG_SET_USER_LIMITS_SUPPORTED #if !defined(PNG_NO_SET_USER_LIMITS) && !defined(PNG_SET_USER_LIMITS_SUPPORTED) # define PNG_SET_USER_LIMITS_SUPPORTED #endif #endif #endif /* PNG_1_0_X */ /* Added at libpng-1.0.16 and 1.2.6. To accept all valid PNGS no matter * how large, set these limits to 0x7fffffffL */ #ifndef PNG_USER_WIDTH_MAX # define PNG_USER_WIDTH_MAX 1000000L #endif #ifndef PNG_USER_HEIGHT_MAX # define PNG_USER_HEIGHT_MAX 1000000L #endif /* These are currently experimental features, define them if you want */ /* very little testing */ /* #ifdef PNG_READ_SUPPORTED # ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED # define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED # endif #endif */ /* This is only for PowerPC big-endian and 680x0 systems */ /* some testing */ /* #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED # define PNG_READ_BIG_ENDIAN_SUPPORTED #endif */ /* Buggy compilers (e.g., gcc 2.7.2.2) need this */ /* #define PNG_NO_POINTER_INDEXING */ /* These functions are turned off by default, as they will be phased out. */ /* #define PNG_USELESS_TESTS_SUPPORTED #define PNG_CORRECT_PALETTE_SUPPORTED */ /* Any chunks you are not interested in, you can undef here. The * ones that allocate memory may be expecially important (hIST, * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info * a bit smaller. */ #if defined(PNG_READ_SUPPORTED) && \ !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ !defined(PNG_NO_READ_ANCILLARY_CHUNKS) # define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED #endif #if defined(PNG_WRITE_SUPPORTED) && \ !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS) # define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED #endif #ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED #ifdef PNG_NO_READ_TEXT # define PNG_NO_READ_iTXt # define PNG_NO_READ_tEXt # define PNG_NO_READ_zTXt #endif #ifndef PNG_NO_READ_bKGD # define PNG_READ_bKGD_SUPPORTED # define PNG_bKGD_SUPPORTED #endif #ifndef PNG_NO_READ_cHRM # define PNG_READ_cHRM_SUPPORTED # define PNG_cHRM_SUPPORTED #endif #ifndef PNG_NO_READ_gAMA # define PNG_READ_gAMA_SUPPORTED # define PNG_gAMA_SUPPORTED #endif #ifndef PNG_NO_READ_hIST # define PNG_READ_hIST_SUPPORTED # define PNG_hIST_SUPPORTED #endif #ifndef PNG_NO_READ_iCCP # define PNG_READ_iCCP_SUPPORTED # define PNG_iCCP_SUPPORTED #endif #ifndef PNG_NO_READ_iTXt # ifndef PNG_READ_iTXt_SUPPORTED # define PNG_READ_iTXt_SUPPORTED # endif # ifndef PNG_iTXt_SUPPORTED # define PNG_iTXt_SUPPORTED # endif #endif #ifndef PNG_NO_READ_oFFs # define PNG_READ_oFFs_SUPPORTED # define PNG_oFFs_SUPPORTED #endif #ifndef PNG_NO_READ_pCAL # define PNG_READ_pCAL_SUPPORTED # define PNG_pCAL_SUPPORTED #endif #ifndef PNG_NO_READ_sCAL # define PNG_READ_sCAL_SUPPORTED # define PNG_sCAL_SUPPORTED #endif #ifndef PNG_NO_READ_pHYs # define PNG_READ_pHYs_SUPPORTED # define PNG_pHYs_SUPPORTED #endif #ifndef PNG_NO_READ_sBIT # define PNG_READ_sBIT_SUPPORTED # define PNG_sBIT_SUPPORTED #endif #ifndef PNG_NO_READ_sPLT # define PNG_READ_sPLT_SUPPORTED # define PNG_sPLT_SUPPORTED #endif #ifndef PNG_NO_READ_sRGB # define PNG_READ_sRGB_SUPPORTED # define PNG_sRGB_SUPPORTED #endif #ifndef PNG_NO_READ_tEXt # define PNG_READ_tEXt_SUPPORTED # define PNG_tEXt_SUPPORTED #endif #ifndef PNG_NO_READ_tIME # define PNG_READ_tIME_SUPPORTED # define PNG_tIME_SUPPORTED #endif #ifndef PNG_NO_READ_tRNS # define PNG_READ_tRNS_SUPPORTED # define PNG_tRNS_SUPPORTED #endif #ifndef PNG_NO_READ_zTXt # define PNG_READ_zTXt_SUPPORTED # define PNG_zTXt_SUPPORTED #endif #ifndef PNG_NO_READ_UNKNOWN_CHUNKS # define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED # ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED # define PNG_UNKNOWN_CHUNKS_SUPPORTED # endif # ifndef PNG_NO_HANDLE_AS_UNKNOWN # define PNG_HANDLE_AS_UNKNOWN_SUPPORTED # endif #endif #if !defined(PNG_NO_READ_USER_CHUNKS) && \ defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) # define PNG_READ_USER_CHUNKS_SUPPORTED # define PNG_USER_CHUNKS_SUPPORTED # ifdef PNG_NO_READ_UNKNOWN_CHUNKS # undef PNG_NO_READ_UNKNOWN_CHUNKS # endif # ifdef PNG_NO_HANDLE_AS_UNKNOWN # undef PNG_NO_HANDLE_AS_UNKNOWN # endif #endif #ifndef PNG_NO_READ_OPT_PLTE # define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */ #endif /* optional PLTE chunk in RGB and RGBA images */ #if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \ defined(PNG_READ_zTXt_SUPPORTED) # define PNG_READ_TEXT_SUPPORTED # define PNG_TEXT_SUPPORTED #endif #endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */ #ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED #ifdef PNG_NO_WRITE_TEXT # define PNG_NO_WRITE_iTXt # define PNG_NO_WRITE_tEXt # define PNG_NO_WRITE_zTXt #endif #ifndef PNG_NO_WRITE_bKGD # define PNG_WRITE_bKGD_SUPPORTED # ifndef PNG_bKGD_SUPPORTED # define PNG_bKGD_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_cHRM # define PNG_WRITE_cHRM_SUPPORTED # ifndef PNG_cHRM_SUPPORTED # define PNG_cHRM_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_gAMA # define PNG_WRITE_gAMA_SUPPORTED # ifndef PNG_gAMA_SUPPORTED # define PNG_gAMA_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_hIST # define PNG_WRITE_hIST_SUPPORTED # ifndef PNG_hIST_SUPPORTED # define PNG_hIST_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_iCCP # define PNG_WRITE_iCCP_SUPPORTED # ifndef PNG_iCCP_SUPPORTED # define PNG_iCCP_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_iTXt # ifndef PNG_WRITE_iTXt_SUPPORTED # define PNG_WRITE_iTXt_SUPPORTED # endif # ifndef PNG_iTXt_SUPPORTED # define PNG_iTXt_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_oFFs # define PNG_WRITE_oFFs_SUPPORTED # ifndef PNG_oFFs_SUPPORTED # define PNG_oFFs_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_pCAL # define PNG_WRITE_pCAL_SUPPORTED # ifndef PNG_pCAL_SUPPORTED # define PNG_pCAL_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_sCAL # define PNG_WRITE_sCAL_SUPPORTED # ifndef PNG_sCAL_SUPPORTED # define PNG_sCAL_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_pHYs # define PNG_WRITE_pHYs_SUPPORTED # ifndef PNG_pHYs_SUPPORTED # define PNG_pHYs_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_sBIT # define PNG_WRITE_sBIT_SUPPORTED # ifndef PNG_sBIT_SUPPORTED # define PNG_sBIT_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_sPLT # define PNG_WRITE_sPLT_SUPPORTED # ifndef PNG_sPLT_SUPPORTED # define PNG_sPLT_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_sRGB # define PNG_WRITE_sRGB_SUPPORTED # ifndef PNG_sRGB_SUPPORTED # define PNG_sRGB_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_tEXt # define PNG_WRITE_tEXt_SUPPORTED # ifndef PNG_tEXt_SUPPORTED # define PNG_tEXt_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_tIME # define PNG_WRITE_tIME_SUPPORTED # ifndef PNG_tIME_SUPPORTED # define PNG_tIME_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_tRNS # define PNG_WRITE_tRNS_SUPPORTED # ifndef PNG_tRNS_SUPPORTED # define PNG_tRNS_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_zTXt # define PNG_WRITE_zTXt_SUPPORTED # ifndef PNG_zTXt_SUPPORTED # define PNG_zTXt_SUPPORTED # endif #endif #ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS # define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED # ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED # define PNG_UNKNOWN_CHUNKS_SUPPORTED # endif # ifndef PNG_NO_HANDLE_AS_UNKNOWN # ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED # define PNG_HANDLE_AS_UNKNOWN_SUPPORTED # endif # endif #endif #if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ defined(PNG_WRITE_zTXt_SUPPORTED) # define PNG_WRITE_TEXT_SUPPORTED # ifndef PNG_TEXT_SUPPORTED # define PNG_TEXT_SUPPORTED # endif #endif #endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */ /* Turn this off to disable png_read_png() and * png_write_png() and leave the row_pointers member * out of the info structure. */ #ifndef PNG_NO_INFO_IMAGE # define PNG_INFO_IMAGE_SUPPORTED #endif /* need the time information for reading tIME chunks */ #if defined(PNG_tIME_SUPPORTED) # if !defined(_WIN32_WCE) && !defined(__COM32__) /* "time.h" functions are not supported on WindowsCE */ # include # endif #endif /* Some typedefs to get us started. These should be safe on most of the * common platforms. The typedefs should be at least as large as the * numbers suggest (a png_uint_32 must be at least 32 bits long), but they * don't have to be exactly that size. Some compilers dislike passing * unsigned shorts as function parameters, so you may be better off using * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may * want to have unsigned int for png_uint_32 instead of unsigned long. */ typedef unsigned long png_uint_32; typedef long png_int_32; typedef unsigned short png_uint_16; typedef short png_int_16; typedef unsigned char png_byte; /* This is usually size_t. It is typedef'ed just in case you need it to change (I'm not sure if you will or not, so I thought I'd be safe) */ #ifdef PNG_SIZE_T typedef PNG_SIZE_T png_size_t; # define png_sizeof(x) png_convert_size(sizeof (x)) #else typedef size_t png_size_t; # define png_sizeof(x) sizeof (x) #endif /* The following is needed for medium model support. It cannot be in the * PNG_INTERNAL section. Needs modification for other compilers besides * MSC. Model independent support declares all arrays and pointers to be * large using the far keyword. The zlib version used must also support * model independent data. As of version zlib 1.0.4, the necessary changes * have been made in zlib. The USE_FAR_KEYWORD define triggers other * changes that are needed. (Tim Wegner) */ /* Separate compiler dependencies (problem here is that zlib.h always defines FAR. (SJT) */ #ifdef __BORLANDC__ # if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) # define LDATA 1 # else # define LDATA 0 # endif /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ # if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__) # define PNG_MAX_MALLOC_64K # if (LDATA != 1) # ifndef FAR # define FAR __far # endif # define USE_FAR_KEYWORD # endif /* LDATA != 1 */ /* Possibly useful for moving data out of default segment. * Uncomment it if you want. Could also define FARDATA as * const if your compiler supports it. (SJT) # define FARDATA FAR */ # endif /* __WIN32__, __FLAT__, __CYGWIN__ */ #endif /* __BORLANDC__ */ /* Suggest testing for specific compiler first before testing for * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM, * making reliance oncertain keywords suspect. (SJT) */ /* MSC Medium model */ #if defined(FAR) # if defined(M_I86MM) # define USE_FAR_KEYWORD # define FARDATA FAR # include # endif #endif /* SJT: default case */ #ifndef FAR # define FAR #endif /* At this point FAR is always defined */ #ifndef FARDATA # define FARDATA #endif /* Typedef for floating-point numbers that are converted to fixed-point with a multiple of 100,000, e.g., int_gamma */ typedef png_int_32 png_fixed_point; /* Add typedefs for pointers */ typedef void FAR * png_voidp; typedef png_byte FAR * png_bytep; typedef png_uint_32 FAR * png_uint_32p; typedef png_int_32 FAR * png_int_32p; typedef png_uint_16 FAR * png_uint_16p; typedef png_int_16 FAR * png_int_16p; typedef PNG_CONST char FAR * png_const_charp; typedef char FAR * png_charp; typedef png_fixed_point FAR * png_fixed_point_p; #ifndef PNG_NO_STDIO #if defined(_WIN32_WCE) typedef HANDLE png_FILE_p; #else typedef FILE * png_FILE_p; #endif #endif #ifdef PNG_FLOATING_POINT_SUPPORTED typedef double FAR * png_doublep; #endif /* Pointers to pointers; i.e. arrays */ typedef png_byte FAR * FAR * png_bytepp; typedef png_uint_32 FAR * FAR * png_uint_32pp; typedef png_int_32 FAR * FAR * png_int_32pp; typedef png_uint_16 FAR * FAR * png_uint_16pp; typedef png_int_16 FAR * FAR * png_int_16pp; typedef PNG_CONST char FAR * FAR * png_const_charpp; typedef char FAR * FAR * png_charpp; typedef png_fixed_point FAR * FAR * png_fixed_point_pp; #ifdef PNG_FLOATING_POINT_SUPPORTED typedef double FAR * FAR * png_doublepp; #endif /* Pointers to pointers to pointers; i.e., pointer to array */ typedef char FAR * FAR * FAR * png_charppp; #if defined(PNG_1_0_X) || defined(PNG_1_2_X) /* SPC - Is this stuff deprecated? */ /* It'll be removed as of libpng-1.3.0 - GR-P */ /* libpng typedefs for types in zlib. If zlib changes * or another compression library is used, then change these. * Eliminates need to change all the source files. */ typedef charf * png_zcharp; typedef charf * FAR * png_zcharpp; typedef z_stream FAR * png_zstreamp; #endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */ /* * Define PNG_BUILD_DLL if the module being built is a Windows * LIBPNG DLL. * * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL. * It is equivalent to Microsoft predefined macro _DLL that is * automatically defined when you compile using the share * version of the CRT (C Run-Time library) * * The cygwin mods make this behavior a little different: * Define PNG_BUILD_DLL if you are building a dll for use with cygwin * Define PNG_STATIC if you are building a static library for use with cygwin, * -or- if you are building an application that you want to link to the * static library. * PNG_USE_DLL is defined by default (no user action needed) unless one of * the other flags is defined. */ #if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL)) # define PNG_DLL #endif /* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib. * When building a static lib, default to no GLOBAL ARRAYS, but allow * command-line override */ #if defined(__CYGWIN__) # if !defined(PNG_STATIC) # if defined(PNG_USE_GLOBAL_ARRAYS) # undef PNG_USE_GLOBAL_ARRAYS # endif # if !defined(PNG_USE_LOCAL_ARRAYS) # define PNG_USE_LOCAL_ARRAYS # endif # else # if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS) # if defined(PNG_USE_GLOBAL_ARRAYS) # undef PNG_USE_GLOBAL_ARRAYS # endif # endif # endif # if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) # define PNG_USE_LOCAL_ARRAYS # endif #endif /* Do not use global arrays (helps with building DLL's) * They are no longer used in libpng itself, since version 1.0.5c, * but might be required for some pre-1.0.5c applications. */ #if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) # if defined(PNG_NO_GLOBAL_ARRAYS) || (defined(__GNUC__) && defined(PNG_DLL)) # define PNG_USE_LOCAL_ARRAYS # else # define PNG_USE_GLOBAL_ARRAYS # endif #endif #if defined(__CYGWIN__) # undef PNGAPI # define PNGAPI __cdecl # undef PNG_IMPEXP # define PNG_IMPEXP #endif /* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall", * you may get warnings regarding the linkage of png_zalloc and png_zfree. * Don't ignore those warnings; you must also reset the default calling * convention in your compiler to match your PNGAPI, and you must build * zlib and your applications the same way you build libpng. */ #if defined(__MINGW32__) && !defined(PNG_MODULEDEF) # ifndef PNG_NO_MODULEDEF # define PNG_NO_MODULEDEF # endif #endif #if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF) # define PNG_IMPEXP #endif #if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \ (( defined(_Windows) || defined(_WINDOWS) || \ defined(WIN32) || defined(_WIN32) || defined(__WIN32__) )) # ifndef PNGAPI # if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) # define PNGAPI __cdecl # else # define PNGAPI _cdecl # endif # endif # if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \ 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */) # define PNG_IMPEXP # endif # if !defined(PNG_IMPEXP) # define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol # define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol /* Borland/Microsoft */ # if defined(_MSC_VER) || defined(__BORLANDC__) # if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500) # define PNG_EXPORT PNG_EXPORT_TYPE1 # else # define PNG_EXPORT PNG_EXPORT_TYPE2 # if defined(PNG_BUILD_DLL) # define PNG_IMPEXP __export # else # define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in VC++ */ # endif /* Exists in Borland C++ for C++ classes (== huge) */ # endif # endif # if !defined(PNG_IMPEXP) # if defined(PNG_BUILD_DLL) # define PNG_IMPEXP __declspec(dllexport) # else # define PNG_IMPEXP __declspec(dllimport) # endif # endif # endif /* PNG_IMPEXP */ #else /* !(DLL || non-cygwin WINDOWS) */ # if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) # ifndef PNGAPI # define PNGAPI _System # endif # else # if 0 /* ... other platforms, with other meanings */ # endif # endif #endif #ifndef PNGAPI # define PNGAPI #endif #ifndef PNG_IMPEXP # define PNG_IMPEXP #endif #ifdef PNG_BUILDSYMS # ifndef PNG_EXPORT # define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END # endif # ifdef PNG_USE_GLOBAL_ARRAYS # ifndef PNG_EXPORT_VAR # define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT # endif # endif #endif #ifndef PNG_EXPORT # define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol #endif #ifdef PNG_USE_GLOBAL_ARRAYS # ifndef PNG_EXPORT_VAR # define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type # endif #endif /* User may want to use these so they are not in PNG_INTERNAL. Any library * functions that are passed far data must be model independent. */ #ifndef PNG_ABORT # define PNG_ABORT() abort() #endif #ifdef PNG_SETJMP_SUPPORTED # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) #else # define png_jmpbuf(png_ptr) \ (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED) #endif #if defined(USE_FAR_KEYWORD) /* memory model independent fns */ /* use this to make far-to-near assignments */ # define CHECK 1 # define NOCHECK 0 # define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) # define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) # define png_strcpy _fstrcpy # define png_strncpy _fstrncpy /* Added to v 1.2.6 */ # define png_strlen _fstrlen # define png_memcmp _fmemcmp /* SJT: added */ # define png_memcpy _fmemcpy # define png_memset _fmemset #else /* use the usual functions */ # define CVT_PTR(ptr) (ptr) # define CVT_PTR_NOCHECK(ptr) (ptr) # define png_strcpy strcpy # define png_strncpy strncpy /* Added to v 1.2.6 */ # define png_strlen strlen # define png_memcmp memcmp /* SJT: added */ # define png_memcpy memcpy # define png_memset memset #endif /* End of memory model independent support */ /* Just a little check that someone hasn't tried to define something * contradictory. */ #if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) # undef PNG_ZBUF_SIZE # define PNG_ZBUF_SIZE 65536L #endif #ifdef PNG_READ_SUPPORTED /* Prior to libpng-1.0.9, this block was in pngasmrd.h */ #if defined(PNG_INTERNAL) /* These are the default thresholds before the MMX code kicks in; if either * rowbytes or bitdepth is below the threshold, plain C code is used. These * can be overridden at runtime via the png_set_mmx_thresholds() call in * libpng 1.2.0 and later. The values below were chosen by Intel. */ #ifndef PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT # define PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT 128 /* >= */ #endif #ifndef PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT # define PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT 9 /* >= */ #endif /* Set this in the makefile for VC++ on Pentium, not here. */ /* Platform must be Pentium. Makefile must assemble and load pngvcrd.c . * MMX will be detected at run time and used if present. */ #ifdef PNG_USE_PNGVCRD # define PNG_HAVE_ASSEMBLER_COMBINE_ROW # define PNG_HAVE_ASSEMBLER_READ_INTERLACE # define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW #endif /* Set this in the makefile for gcc/as on Pentium, not here. */ /* Platform must be Pentium. Makefile must assemble and load pnggccrd.c . * MMX will be detected at run time and used if present. */ #ifdef PNG_USE_PNGGCCRD # define PNG_HAVE_ASSEMBLER_COMBINE_ROW # define PNG_HAVE_ASSEMBLER_READ_INTERLACE # define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW #endif /* - see pnggccrd.c for info about what is currently enabled */ #endif /* PNG_INTERNAL */ #endif /* PNG_READ_SUPPORTED */ /* Added at libpng-1.2.8 */ #endif /* PNG_VERSION_INFO_ONLY */ #endif /* PNGCONF_H */ syslinux-legacy-3.63+dfsg/com32/include/stdlib.h0000664000175000017500000000434410777447272020220 0ustar evanevan/* * stdlib.h */ #ifndef _STDLIB_H #define _STDLIB_H #include #include #include #define EXIT_FAILURE 1 #define EXIT_SUCCESS 0 static __inline__ __noreturn _Exit(int __n) { __extern __noreturn _exit(int); _exit(__n); for(;;); /* Some gcc versions are stupid */ } __extern __noreturn abort(void); static __inline__ int abs(int __n) { return (__n < 0) ? -__n : __n; } __extern int atexit(void (*)(void)); __extern int on_exit(void (*)(int, void *), void *); __extern int atoi(const char *); __extern long atol(const char *); __extern long long atoll(const char *); __extern __noreturn exit(int); __extern void free(void *); static __inline__ long labs(long __n) { return (__n < 0L) ? -__n : __n; } static __inline__ long long llabs(long long __n) { return (__n < 0LL) ? -__n : __n; } __extern __mallocfunc void *malloc(size_t); __extern __mallocfunc void *calloc(size_t, size_t); __extern __mallocfunc void *realloc(void *, size_t); __extern long strtol(const char *, char **, int); __extern long long strtoll(const char *, char **, int); __extern unsigned long strtoul(const char *, char **, int); __extern unsigned long long strtoull(const char *, char **, int); __extern char *getenv(const char *); __extern int putenv(const char *); __extern int setenv(const char *, const char *, int); __extern int unsetenv(const char *); __extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); __extern long jrand48(unsigned short *); __extern long mrand48(void); __extern long nrand48(unsigned short *); __extern long lrand48(void); __extern unsigned short *seed48(const unsigned short *); __extern void srand48(long); #define RAND_MAX 0x7fffffff static __inline__ int rand(void) { return (int)lrand48(); } static __inline__ void srand(unsigned int __s) { srand48(__s); } static __inline__ long random(void) { return lrand48(); } static __inline__ void srandom(unsigned int __s) { srand48(__s); } /* Basic PTY functions. These only work if devpts is mounted! */ __extern int unlockpt(int); __extern char *ptsname(int); __extern int getpt(void); static __inline__ int grantpt(int __fd) { (void)__fd; return 0; /* devpts does this all for us! */ } #endif /* _STDLIB_H */ syslinux-legacy-3.63+dfsg/com32/include/stdio.h0000664000175000017500000000566210777447272020065 0ustar evanevan/* * stdio.h */ #ifndef _STDIO_H #define _STDIO_H #include #include #include /* This structure doesn't really exist, but it gives us something to define FILE * with */ struct _IO_file; typedef struct _IO_file FILE; #ifndef EOF # define EOF (-1) #endif #ifndef BUFSIZ # define BUFSIZ 4096 #endif #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 /* * Convert between a FILE * and a file descriptor. We don't actually * have any in-memory data, so we just abuse the pointer itself to * hold the data. Note, however, that for file descriptors, -1 is * error and 0 is a valid value; for FILE *, NULL (0) is error and * non-NULL are valid. */ static __inline__ int fileno(FILE *__f) { /* This should really be intptr_t, but size_t should be the same size */ return (int)(size_t)__f - 1; } /* This is a macro so it can be used as initializer */ #define __create_file(__fd) ((FILE *)(size_t)((__fd) + 1)) #define stdin __create_file(0) #define stdout __create_file(1) #define stderr __create_file(2) __extern FILE *fopen(const char *, const char *); struct dev_info; __extern FILE *fopendev(const struct dev_info *, const char *); static __inline__ FILE *fdopen(int __fd, const char *__m) { (void)__m; return __create_file(__fd); } static __inline__ int fclose(FILE *__f) { extern int close(int); return close(fileno(__f)); } __extern int fputs(const char *, FILE *); __extern int puts(const char *); __extern int fputc(int, FILE *); #define putc(c,f) fputc((c),(f)) #define putchar(c) fputc((c),stdout) __extern int fgetc(FILE *); __extern char * fgets(char *, int, FILE *); #define getc(f) fgetc(f) __extern size_t _fread(void *, size_t, FILE *); __extern size_t _fwrite(const void *, size_t, FILE *); #ifndef __NO_FREAD_FWRITE_INLINES extern __inline__ size_t fread(void *__p, size_t __s, size_t __n, FILE *__f) { return _fread(__p, __s*__n, __f)/__s; } extern __inline__ size_t fwrite(void *__p, size_t __s, size_t __n, FILE *__f) { return _fwrite(__p, __s*__n, __f)/__s; } #endif /* No seek, but we can tell */ __extern long ftell(FILE *); __extern int printf(const char *, ...); __extern int vprintf(const char *, va_list); __extern int fprintf(FILE *, const char *, ...); __extern int vfprintf(FILE *, const char *, va_list); __extern int sprintf(char *, const char *, ...); __extern int vsprintf(char *, const char *, va_list); __extern int snprintf(char *, size_t n, const char *, ...); __extern int vsnprintf(char *, size_t n, const char *, va_list); __extern int asprintf(char **, const char *, ...); __extern int vasprintf(char **, const char *, va_list); /* No buffering, so no flushing needed */ extern __inline__ int fflush(FILE *__f) { (void)__f; return 0; } __extern int sscanf(const char *, const char *, ...); __extern int vsscanf(const char *, const char *, va_list); __extern void perror(const char *); __extern int rename(const char *, const char *); #endif /* _STDIO_H */ syslinux-legacy-3.63+dfsg/com32/include/zconf.h0000664000175000017500000002132610777447272020055 0ustar evanevan/* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-2003 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ #ifndef ZCONF_H #define ZCONF_H /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. */ #ifdef Z_PREFIX # define deflateInit_ z_deflateInit_ # define deflate z_deflate # define deflateEnd z_deflateEnd # define inflateInit_ z_inflateInit_ # define inflate z_inflate # define inflateEnd z_inflateEnd # define deflateInit2_ z_deflateInit2_ # define deflateSetDictionary z_deflateSetDictionary # define deflateCopy z_deflateCopy # define deflateReset z_deflateReset # define deflatePrime z_deflatePrime # define deflateParams z_deflateParams # define deflateBound z_deflateBound # define inflateInit2_ z_inflateInit2_ # define inflateSetDictionary z_inflateSetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateCopy z_inflateCopy # define inflateReset z_inflateReset # define compress z_compress # define compress2 z_compress2 # define compressBound z_compressBound # define uncompress z_uncompress # define adler32 z_adler32 # define crc32 z_crc32 # define get_crc_table z_get_crc_table # define Byte z_Byte # define uInt z_uInt # define uLong z_uLong # define Bytef z_Bytef # define charf z_charf # define intf z_intf # define uIntf z_uIntf # define uLongf z_uLongf # define voidpf z_voidpf # define voidp z_voidp #endif #if defined(__MSDOS__) && !defined(MSDOS) # define MSDOS #endif #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) # define OS2 #endif #if defined(_WINDOWS) && !defined(WINDOWS) # define WINDOWS #endif #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) # define WIN32 #endif #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) # ifndef SYS16BIT # define SYS16BIT # endif # endif #endif /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). */ #ifdef SYS16BIT # define MAXSEG_64K #endif #ifdef MSDOS # define UNALIGNED_OK #endif #ifdef __STDC_VERSION__ # ifndef STDC # define STDC # endif # if __STDC_VERSION__ >= 199901L # ifndef STDC99 # define STDC99 # endif # endif #endif #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) # define STDC #endif #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) # define STDC #endif #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) # define STDC #endif #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) # define STDC #endif #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ # define STDC #endif #ifndef STDC # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # define const /* note: need a more gentle solution here */ # endif #endif /* Some Mac compilers merge all .h files incorrectly: */ #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) # define NO_DUMMY_DECL #endif /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # ifdef MAXSEG_64K # define MAX_MEM_LEVEL 8 # else # define MAX_MEM_LEVEL 9 # endif #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files * created by gzip. (Files created by minigzip can still be extracted by * gzip.) */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Type declarations */ #ifndef OF /* function prototypes */ # ifdef STDC # define OF(args) args # else # define OF(args) () # endif #endif /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * just define FAR to be empty. */ #ifdef SYS16BIT # if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */ # define SMALL_MEDIUM # ifdef _MSC_VER # define FAR _far # else # define FAR far # endif # endif # if (defined(__SMALL__) || defined(__MEDIUM__)) /* Turbo C small or medium model */ # define SMALL_MEDIUM # ifdef __BORLANDC__ # define FAR _far # else # define FAR far # endif # endif #endif #if defined(WINDOWS) || defined(WIN32) /* If building or using zlib as a DLL, define ZLIB_DLL. * This is not mandatory, but it offers a little performance increase. */ # ifdef ZLIB_DLL # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) # ifdef ZLIB_INTERNAL # define ZEXTERN extern __declspec(dllexport) # else # define ZEXTERN extern __declspec(dllimport) # endif # endif # endif /* ZLIB_DLL */ /* If building or using zlib with the WINAPI/WINAPIV calling convention, * define ZLIB_WINAPI. * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. */ # ifdef ZLIB_WINAPI # ifdef FAR # undef FAR # endif # include /* No need for _export, use ZLIB.DEF instead. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */ # define ZEXPORT WINAPI # ifdef WIN32 # define ZEXPORTVA WINAPIV # else # define ZEXPORTVA FAR CDECL # endif # endif #endif #if defined (__BEOS__) # ifdef ZLIB_DLL # ifdef ZLIB_INTERNAL # define ZEXPORT __declspec(dllexport) # define ZEXPORTVA __declspec(dllexport) # else # define ZEXPORT __declspec(dllimport) # define ZEXPORTVA __declspec(dllimport) # endif # endif #endif #ifndef ZEXTERN # define ZEXTERN extern #endif #ifndef ZEXPORT # define ZEXPORT #endif #ifndef ZEXPORTVA # define ZEXPORTVA #endif #ifndef FAR # define FAR #endif #if !defined(__MACTYPES__) typedef unsigned char Byte; /* 8 bits */ #endif typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ #ifdef SMALL_MEDIUM /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ # define Bytef Byte FAR #else typedef Byte FAR Bytef; #endif typedef char FAR charf; typedef int FAR intf; typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC typedef void const *voidpc; typedef void FAR *voidpf; typedef void *voidp; #else typedef Byte const *voidpc; typedef Byte FAR *voidpf; typedef Byte *voidp; #endif #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ # include /* for off_t */ # include /* for SEEK_* and off_t */ # ifdef VMS # include /* for off_t */ # endif # define z_off_t off_t #endif #ifndef SEEK_SET # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif #ifndef z_off_t # define z_off_t long #endif #if defined(__OS400__) #define NO_vsnprintf #endif #if defined(__MVS__) # define NO_vsnprintf # ifdef FAR # undef FAR # endif #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) # pragma map(deflateInit_,"DEIN") # pragma map(deflateInit2_,"DEIN2") # pragma map(deflateEnd,"DEEND") # pragma map(deflateBound,"DEBND") # pragma map(inflateInit_,"ININ") # pragma map(inflateInit2_,"ININ2") # pragma map(inflateEnd,"INEND") # pragma map(inflateSync,"INSY") # pragma map(inflateSetDictionary,"INSEDI") # pragma map(compressBound,"CMBND") # pragma map(inflate_table,"INTABL") # pragma map(inflate_fast,"INFA") # pragma map(inflate_copyright,"INCOPY") #endif #endif /* ZCONF_H */ syslinux-legacy-3.63+dfsg/com32/include/elf.h0000664000175000017500000000016610777447272017503 0ustar evanevan/* * elf.h */ #ifndef _ELF_H #define _ELF_H #include #include #endif /* _ELF_H */ syslinux-legacy-3.63+dfsg/com32/include/console.h0000664000175000017500000000444510777447272020403 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * console.h * * Alternative consoles */ #ifndef _CONSOLE_H #define _CONSOLE_H #include #include __extern int openconsole(const struct input_dev *, const struct output_dev *); /* Standard line-oriented console */ extern const struct input_dev dev_stdcon_r; extern const struct output_dev dev_stdcon_w; /* Raw character-oriented console */ extern const struct input_dev dev_rawcon_r; extern const struct output_dev dev_rawcon_w; /* These are output-only consoles; combine with one of the input methods */ /* Serial port only */ extern const struct output_dev dev_serial_w; /* ANSI console (output only; combine with one of the input methods) */ extern const struct output_dev dev_ansicon_w; /* ANSI plus serial port */ extern const struct output_dev dev_ansiserial_w; /* VESA graphics console (output only) */ extern const struct output_dev dev_vesacon_w; /* VESA plus serial port */ extern const struct output_dev dev_vesaserial_w; #endif /* _CONSOLE_H */ syslinux-legacy-3.63+dfsg/com32/include/alloca.h0000664000175000017500000000025610777447272020170 0ustar evanevan/* * alloca.h * * Just call the builtin alloca() function */ #ifndef _ALLOCA_H #define _ALLOCA_H #define alloca(size) __builtin_alloca(size) #endif /* _ALLOCA_H */ syslinux-legacy-3.63+dfsg/com32/include/fcntl.h0000664000175000017500000000074110777447272020042 0ustar evanevan/* * fcntl.h */ #ifndef _FCNTL_H #define _FCNTL_H #include #include #include /* None of these are actually supported, although O_RDONLY works */ /* Note this is different from the classical Unix way of doing it */ #define O_RDONLY 1 #define O_WRONLY 2 #define O_RDWR 3 #define O_CREAT 0100 #define O_EXCL 0200 #define O_TRUNC 01000 #define O_APPEND 02000 __extern int open(const char *, int, ...); #endif /* _FCNTL_H */ syslinux-legacy-3.63+dfsg/com32/include/sys/0000775000175000017500000000000010777447272017377 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/include/sys/pci.h0000664000175000017500000000375210777447272020332 0ustar evanevan#ifndef _SYS_PCI_H #define _SYS_PCI_H #include #include #define MAX_PCI_DEVICES 32 #define MAX_PCI_BUSES 255 typedef uint32_t pciaddr_t; /* a structure for extended pci information */ struct pci_dev_info { char vendor_name[255]; char product_name[255]; char linux_kernel_module[64]; }; /* a struct to represent a pci device */ struct pci_device { uint16_t vendor; uint16_t product; uint16_t sub_vendor; uint16_t sub_product; uint8_t revision; struct pci_dev_info *pci_dev_info; }; struct pci_bus { uint16_t id; struct pci_device *pci_device[MAX_PCI_DEVICES]; uint8_t pci_device_count; }; struct pci_device_list { struct pci_device pci_device[MAX_PCI_DEVICES]; uint8_t count; }; struct pci_bus_list { struct pci_bus pci_bus[MAX_PCI_BUSES]; uint8_t count; }; struct match { struct match *next; uint32_t did; uint32_t did_mask; uint32_t sid; uint32_t sid_mask; uint8_t rid_min, rid_max; char *filename; }; static inline pciaddr_t pci_mkaddr(uint32_t bus, uint32_t dev, uint32_t func, uint32_t reg) { return 0x80000000 | ((bus & 0xff) << 16) | ((dev & 0x1f) << 11) | ((func & 0x07) << 8) | (reg & 0xff); } enum pci_config_type { PCI_CFG_NONE = -1, /* badness */ PCI_CFG_AUTO = 0, /* autodetect */ PCI_CFG_TYPE1 = 1, PCI_CFG_TYPE2 = 2, PCI_CFG_BIOS = 3, }; enum pci_config_type pci_set_config_type(enum pci_config_type); uint8_t pci_readb(pciaddr_t); uint16_t pci_readw(pciaddr_t); uint32_t pci_readl(pciaddr_t); void pci_writeb(uint8_t, pciaddr_t); void pci_writew(uint16_t, pciaddr_t); void pci_writel(uint32_t, pciaddr_t); extern int pci_scan(struct pci_bus_list *pci_bus_list, struct pci_device_list *pci_device_list); extern struct match * find_pci_device(struct pci_device_list *pci_device_list, struct match *list); extern void get_name_from_pci_ids(struct pci_device_list *pci_device_list); extern void get_module_name_from_pci_ids(struct pci_device_list *pci_device_list); #endif /* _SYS_PCI_H */ syslinux-legacy-3.63+dfsg/com32/include/sys/elf64.h0000664000175000017500000000421010777447272020465 0ustar evanevan/* * sys/elf64.h */ #ifndef _SYS_ELF64_H #define _SYS_ELF64_H #include /* ELF standard typedefs (yet more proof that was way overdue) */ typedef uint16_t Elf64_Half; typedef int16_t Elf64_SHalf; typedef uint32_t Elf64_Word; typedef int32_t Elf64_Sword; typedef uint64_t Elf64_Xword; typedef int64_t Elf64_Sxword; typedef uint64_t Elf64_Off; typedef uint64_t Elf64_Addr; typedef uint16_t Elf64_Section; /* Dynamic header */ typedef struct elf64_dyn { Elf64_Sxword d_tag; union { Elf64_Xword d_val; Elf64_Addr d_ptr; } d_un; } Elf64_Dyn; /* Relocations */ #define ELF64_R_SYM(x) ((x) >> 32) #define ELF64_R_TYPE(x) ((x) & 0xffffffff) typedef struct elf64_rel { Elf64_Addr r_offset; Elf64_Xword r_info; } Elf64_Rel; typedef struct elf64_rela { Elf64_Addr r_offset; Elf64_Xword r_info; Elf64_Sxword r_addend; } Elf64_Rela; /* Symbol */ typedef struct elf64_sym { Elf64_Word st_name; unsigned char st_info; unsigned char st_other; Elf64_Half st_shndx; Elf64_Addr st_value; Elf64_Xword st_size; } Elf64_Sym; /* Main file header */ typedef struct elf64_hdr { unsigned char e_ident[EI_NIDENT]; Elf64_Half e_type; Elf64_Half e_machine; Elf64_Word e_version; Elf64_Addr e_entry; Elf64_Off e_phoff; Elf64_Off e_shoff; Elf64_Word e_flags; Elf64_Half e_ehsize; Elf64_Half e_phentsize; Elf64_Half e_phnum; Elf64_Half e_shentsize; Elf64_Half e_shnum; Elf64_Half e_shstrndx; } Elf64_Ehdr; /* Program header */ typedef struct elf64_phdr { Elf64_Word p_type; Elf64_Word p_flags; Elf64_Off p_offset; Elf64_Addr p_vaddr; Elf64_Addr p_paddr; Elf64_Xword p_filesz; Elf64_Xword p_memsz; Elf64_Xword p_align; } Elf64_Phdr; /* Section header */ typedef struct elf64_shdr { Elf64_Word sh_name; Elf64_Word sh_type; Elf64_Xword sh_flags; Elf64_Addr sh_addr; Elf64_Off sh_offset; Elf64_Xword sh_size; Elf64_Word sh_link; Elf64_Word sh_info; Elf64_Xword sh_addralign; Elf64_Xword sh_entsize; } Elf64_Shdr; /* Note header */ typedef struct elf64_note { Elf64_Word n_namesz; /* Name size */ Elf64_Word n_descsz; /* Content size */ Elf64_Word n_type; /* Content type */ } Elf64_Nhdr; #endif /* _SYS_ELF64_H */ syslinux-legacy-3.63+dfsg/com32/include/sys/cpu.h0000664000175000017500000000241410777447272020340 0ustar evanevan#ifndef _CPU_H #define _CPU_H #include static inline uint64_t rdtsc(void) { uint64_t v; asm volatile("rdtsc" : "=A" (v)); return v; } static inline uint32_t rdtscl(void) { uint32_t v; asm volatile("rdtsc" : "=a" (v) : : "edx"); return v; } static inline uint32_t cpuid_eax(uint32_t level) { uint32_t v; asm("cpuid" : "=a" (v) : "a" (level) : "ebx", "ecx", "edx"); return v; } static inline uint32_t cpuid_ebx(uint32_t level) { uint32_t v; asm("cpuid" : "=b" (v), "+a" (level) : : "ecx", "edx"); return v; } static inline uint32_t cpuid_ecx(uint32_t level) { uint32_t v; asm("cpuid" : "=c" (v), "+a" (level) : : "ebx", "edx"); return v; } static inline uint32_t cpuid_edx(uint32_t level) { uint32_t v; asm("cpuid" : "=d" (v), "+a" (level) : : "ebx", "ecx"); return v; } static inline uint64_t rdmsr(uint32_t msr) { uint64_t v; asm volatile("rdmsr" : "=A" (v) : "c" (msr)); return v; } static inline void wrmsr(uint64_t v, uint32_t msr) { asm volatile("wrmsr" : : "A" (v), "c" (msr)); } static inline void cpu_relax(void) { asm volatile("rep ; nop"); } /* These are local cli/sti; not SMP-safe!!! */ static inline void cli(void) { asm volatile("cli"); } static inline void sti(void) { asm volatile("sti"); } #endif syslinux-legacy-3.63+dfsg/com32/include/sys/time.h0000664000175000017500000000007510777447272020510 0ustar evanevan#ifndef _SYS_TIME_H #define _SYS_TIME_H /* empty */ #endif syslinux-legacy-3.63+dfsg/com32/include/sys/types.h0000664000175000017500000000032610777447272020715 0ustar evanevan/* * sys/types.h */ #ifndef _SYS_TYPES_H #define _SYS_TYPES_H #include #include #include typedef ptrdiff_t ssize_t; typedef int mode_t; typedef size_t off_t; #endif syslinux-legacy-3.63+dfsg/com32/include/sys/elfcommon.h0000664000175000017500000001153710777447272021536 0ustar evanevan/* * sys/elfcommon.h */ #ifndef _SYS_ELFCOMMON_H #define _SYS_ELFCOMMON_H #include /* Segment types */ #define PT_NULL 0 #define PT_LOAD 1 #define PT_DYNAMIC 2 #define PT_INTERP 3 #define PT_NOTE 4 #define PT_SHLIB 5 #define PT_PHDR 6 #define PT_LOOS 0x60000000 #define PT_HIOS 0x6fffffff #define PT_LOPROC 0x70000000 #define PT_HIPROC 0x7fffffff #define PT_GNU_EH_FRAME 0x6474e550 /* Extension, eh? */ /* ELF file types */ #define ET_NONE 0 #define ET_REL 1 #define ET_EXEC 2 #define ET_DYN 3 #define ET_CORE 4 #define ET_LOPROC 0xff00 #define ET_HIPROC 0xffff /* ELF machine types */ #define EM_NONE 0 #define EM_M32 1 #define EM_SPARC 2 #define EM_386 3 #define EM_68K 4 #define EM_88K 5 #define EM_486 6 /* Not used in Linux at least */ #define EM_860 7 #define EM_MIPS 8 /* R3k, bigendian(?) */ #define EM_MIPS_RS4_BE 10 /* R4k BE */ #define EM_PARISC 15 #define EM_SPARC32PLUS 18 #define EM_PPC 20 #define EM_PPC64 21 #define EM_S390 22 #define EM_SH 42 #define EM_SPARCV9 43 /* v9 = SPARC64 */ #define EM_H8_300H 47 #define EM_H8S 48 #define EM_IA_64 50 /* Itanic */ #define EM_X86_64 62 #define EM_CRIS 76 #define EM_V850 87 #define EM_ALPHA 0x9026 /* Interrim Alpha that stuck around */ #define EM_CYGNUS_V850 0x9080 /* Old v850 ID used by Cygnus */ #define EM_S390_OLD 0xA390 /* Obsolete interrim value for S/390 */ /* Dynamic type values */ #define DT_NULL 0 #define DT_NEEDED 1 #define DT_PLTRELSZ 2 #define DT_PLTGOT 3 #define DT_HASH 4 #define DT_STRTAB 5 #define DT_SYMTAB 6 #define DT_RELA 7 #define DT_RELASZ 8 #define DT_RELAENT 9 #define DT_STRSZ 10 #define DT_SYMENT 11 #define DT_INIT 12 #define DT_FINI 13 #define DT_SONAME 14 #define DT_RPATH 15 #define DT_SYMBOLIC 16 #define DT_REL 17 #define DT_RELSZ 18 #define DT_RELENT 19 #define DT_PLTREL 20 #define DT_DEBUG 21 #define DT_TEXTREL 22 #define DT_JMPREL 23 #define DT_LOPROC 0x70000000 #define DT_HIPROC 0x7fffffff /* Auxilliary table entries */ #define AT_NULL 0 /* end of vector */ #define AT_IGNORE 1 /* entry should be ignored */ #define AT_EXECFD 2 /* file descriptor of program */ #define AT_PHDR 3 /* program headers for program */ #define AT_PHENT 4 /* size of program header entry */ #define AT_PHNUM 5 /* number of program headers */ #define AT_PAGESZ 6 /* system page size */ #define AT_BASE 7 /* base address of interpreter */ #define AT_FLAGS 8 /* flags */ #define AT_ENTRY 9 /* entry point of program */ #define AT_NOTELF 10 /* program is not ELF */ #define AT_UID 11 /* real uid */ #define AT_EUID 12 /* effective uid */ #define AT_GID 13 /* real gid */ #define AT_EGID 14 /* effective gid */ #define AT_PLATFORM 15 /* string identifying CPU for optimizations */ #define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ #define AT_CLKTCK 17 /* frequency at which times() increments */ /* 18..22 = ? */ #define AT_SECURE 23 /* secure mode boolean */ /* Program header permission flags */ #define PF_X 0x1 #define PF_W 0x2 #define PF_R 0x4 /* Section header types */ #define SHT_NULL 0 #define SHT_PROGBITS 1 #define SHT_SYMTAB 2 #define SHT_STRTAB 3 #define SHT_RELA 4 #define SHT_HASH 5 #define SHT_DYNAMIC 6 #define SHT_NOTE 7 #define SHT_NOBITS 8 #define SHT_REL 9 #define SHT_SHLIB 10 #define SHT_DYNSYM 11 #define SHT_NUM 12 #define SHT_LOPROC 0x70000000 #define SHT_HIPROC 0x7fffffff #define SHT_LOUSER 0x80000000 #define SHT_HIUSER 0xffffffff /* Section header flags */ #define SHF_WRITE 0x1 #define SHF_ALLOC 0x2 #define SHF_EXECINSTR 0x4 #define SHF_MASKPROC 0xf0000000 /* Special section numbers */ #define SHN_UNDEF 0 #define SHN_LORESERVE 0xff00 #define SHN_LOPROC 0xff00 #define SHN_HIPROC 0xff1f #define SHN_ABS 0xfff1 #define SHN_COMMON 0xfff2 #define SHN_HIRESERVE 0xffff /* Lenght of magic at the start of a file */ #define EI_NIDENT 16 /* Magic number constants... */ #define EI_MAG0 0 /* e_ident[] indexes */ #define EI_MAG1 1 #define EI_MAG2 2 #define EI_MAG3 3 #define EI_CLASS 4 #define EI_DATA 5 #define EI_VERSION 6 #define EI_OSABI 7 #define EI_PAD 8 #define ELFMAG0 0x7f /* EI_MAG */ #define ELFMAG1 'E' #define ELFMAG2 'L' #define ELFMAG3 'F' #define ELFMAG "\177ELF" #define SELFMAG 4 #define ELFCLASSNONE 0 /* EI_CLASS */ #define ELFCLASS32 1 #define ELFCLASS64 2 #define ELFCLASSNUM 3 #define ELFDATANONE 0 /* e_ident[EI_DATA] */ #define ELFDATA2LSB 1 #define ELFDATA2MSB 2 #define EV_NONE 0 /* e_version, EI_VERSION */ #define EV_CURRENT 1 #define EV_NUM 2 #define ELFOSABI_NONE 0 #define ELFOSABI_LINUX 3 #endif /* _SYS_ELFCOMMON_H */ syslinux-legacy-3.63+dfsg/com32/include/sys/io.h0000664000175000017500000000136610777447272020165 0ustar evanevan#ifndef _SYS_IO_H #define _SYS_IO_H #include static inline uint8_t inb(uint16_t p) { uint8_t v; asm volatile("inb %1,%0" : "=a" (v) : "Nd" (p)); return v; } static inline uint16_t inw(uint16_t p) { uint16_t v; asm volatile("inw %1,%0" : "=a" (v) : "Nd" (p)); return v; } static inline uint32_t inl(uint16_t p) { uint32_t v; asm volatile("inl %1,%0" : "=a" (v) : "Nd" (p)); return v; } static inline void outb(uint8_t v, uint16_t p) { asm volatile("outb %0,%1" : : "a" (v), "Nd" (p)); } static inline void outw(uint16_t v, uint16_t p) { asm volatile("outw %0,%1" : : "a" (v), "Nd" (p)); } static inline void outl(uint32_t v, uint16_t p) { asm volatile("outl %0,%1" : : "a" (v), "Nd" (p)); } #endif /* _SYS_IO_H */ syslinux-legacy-3.63+dfsg/com32/include/sys/stat.h0000664000175000017500000000234110777447272020523 0ustar evanevan/* * sys/stat.h */ #ifndef _SYS_STAT_H #define _SYS_STAT_H #include /* We don't use this, but it's there for compatibility */ #define S_IFMT 00170000 #define S_IFSOCK 0140000 #define S_IFLNK 0120000 #define S_IFREG 0100000 #define S_IFBLK 0060000 #define S_IFDIR 0040000 #define S_IFCHR 0020000 #define S_IFIFO 0010000 #define S_ISUID 0004000 #define S_ISGID 0002000 #define S_ISVTX 0001000 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) #define S_IRWXU 00700 #define S_IRUSR 00400 #define S_IWUSR 00200 #define S_IXUSR 00100 #define S_IRWXG 00070 #define S_IRGRP 00040 #define S_IWGRP 00020 #define S_IXGRP 00010 #define S_IRWXO 00007 #define S_IROTH 00004 #define S_IWOTH 00002 #define S_IXOTH 00001 /* These are the only fields in struct stat we emulate */ struct stat { mode_t st_mode; off_t st_size; }; /* Only fstat() supported */ int fstat(int, struct stat *); #endif /* _SYS_STAT_H */ syslinux-legacy-3.63+dfsg/com32/include/sys/fpu.h0000664000175000017500000000013710777447272020343 0ustar evanevan#ifndef _SYS_FPU_H #define _SYS_FPU_H extern int x86_init_fpu(void); #endif /* _SYS_FPU_H */ syslinux-legacy-3.63+dfsg/com32/include/sys/times.h0000664000175000017500000000041010777447272020664 0ustar evanevan/* * sys/times.h */ #ifndef _SYS_TIMES_H #define _SYS_TIMES_H #include struct tms { /* Empty */ }; #define HZ 18 /* Piddly resolution... */ #define CLK_TCK HZ typedef uint16_t clock_t; clock_t times(struct tms *); #endif /* _SYS_TIMES_H */ syslinux-legacy-3.63+dfsg/com32/include/sys/elf32.h0000664000175000017500000000416510777447272020471 0ustar evanevan/* * sys/elf32.h */ #ifndef _SYS_ELF32_H #define _SYS_ELF32_H #include /* ELF standard typedefs (yet more proof that was way overdue) */ typedef uint16_t Elf32_Half; typedef int16_t Elf32_SHalf; typedef uint32_t Elf32_Word; typedef int32_t Elf32_Sword; typedef uint64_t Elf32_Xword; typedef int64_t Elf32_Sxword; typedef uint32_t Elf32_Off; typedef uint32_t Elf32_Addr; typedef uint16_t Elf32_Section; /* Dynamic header */ typedef struct elf32_dyn { Elf32_Sword d_tag; union { Elf32_Sword d_val; Elf32_Addr d_ptr; } d_un; } Elf32_Dyn; /* Relocations */ #define ELF32_R_SYM(x) ((x) >> 8) #define ELF32_R_TYPE(x) ((x) & 0xff) typedef struct elf32_rel { Elf32_Addr r_offset; Elf32_Word r_info; } Elf32_Rel; typedef struct elf32_rela { Elf32_Addr r_offset; Elf32_Word r_info; Elf32_Sword r_addend; } Elf32_Rela; /* Symbol */ typedef struct elf32_sym { Elf32_Word st_name; Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info; unsigned char st_other; Elf32_Half st_shndx; } Elf32_Sym; /* Main file header */ typedef struct elf32_hdr { unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; } Elf32_Ehdr; /* Program header */ typedef struct elf32_phdr { Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; } Elf32_Phdr; /* Section header */ typedef struct elf32_shdr { Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; Elf32_Word sh_addralign; Elf32_Word sh_entsize; } Elf32_Shdr; /* Note header */ typedef struct elf32_note { Elf32_Word n_namesz; /* Name size */ Elf32_Word n_descsz; /* Content size */ Elf32_Word n_type; /* Content type */ } Elf32_Nhdr; #endif /* _SYS_ELF32_H */ syslinux-legacy-3.63+dfsg/com32/include/ctype.h0000664000175000017500000000421510777447272020060 0ustar evanevan/* * ctype.h * * This assumes ISO 8859-1, being a reasonable superset of ASCII. */ #ifndef _CTYPE_H #define _CTYPE_H #ifndef __CTYPE_NO_INLINE # define __ctype_inline extern __inline__ #else # define __ctype_inline #endif /* * This relies on the following definitions: * * cntrl = !print * alpha = upper|lower * graph = punct|alpha|digit * blank = '\t' || ' ' (per POSIX requirement) */ enum { __ctype_upper = (1 << 0), __ctype_lower = (1 << 1), __ctype_digit = (1 << 2), __ctype_xdigit = (1 << 3), __ctype_space = (1 << 4), __ctype_print = (1 << 5), __ctype_punct = (1 << 6), __ctype_cntrl = (1 << 7), }; extern const unsigned char __ctypes[]; __ctype_inline int isalnum(int __c) { return __ctypes[__c+1] & (__ctype_upper|__ctype_lower|__ctype_digit); } __ctype_inline int isalpha(int __c) { return __ctypes[__c+1] & (__ctype_upper|__ctype_lower); } __ctype_inline int isascii(int __c) { return !(__c & ~0x7f); } __ctype_inline int isblank(int __c) { return (__c == '\t') || (__c == ' '); } __ctype_inline int iscntrl(int __c) { return __ctypes[__c+1] & __ctype_cntrl; } __ctype_inline int isdigit(int __c) { return ((unsigned)__c - '0') <= 9; } __ctype_inline int isgraph(int __c) { return __ctypes[__c+1] & (__ctype_upper|__ctype_lower|__ctype_digit|__ctype_punct); } __ctype_inline int islower(int __c) { return __ctypes[__c+1] & __ctype_lower; } __ctype_inline int isprint(int __c) { return __ctypes[__c+1] & __ctype_print; } __ctype_inline int ispunct(int __c) { return __ctypes[__c+1] & __ctype_punct; } __ctype_inline int isspace(int __c) { return __ctypes[__c+1] & __ctype_space; } __ctype_inline int isupper(int __c) { return __ctypes[__c+1] & __ctype_upper; } __ctype_inline int isxdigit(int __c) { return __ctypes[__c+1] & __ctype_xdigit; } /* Note: this is decimal, not hex, to avoid accidental promotion to unsigned */ #define _toupper(__c) ((__c) & ~32) #define _tolower(__c) ((__c) | 32) __ctype_inline int toupper(int __c) { return islower(__c) ? _toupper(__c) : __c; } __ctype_inline int tolower(int __c) { return isupper(__c) ? _tolower(__c) : __c; } #endif /* _CTYPE_H */ syslinux-legacy-3.63+dfsg/com32/include/stdarg.h0000664000175000017500000000051410777447272020216 0ustar evanevan/* * stdarg.h * * This is just a wrapper for the gcc one, but defines va_copy() * even if gcc doesn't. */ /* Note: the _STDARG_H macro belongs to the gcc header... */ #include_next /* Older gcc considers this an extension, so it's double underbar only */ #ifndef va_copy #define va_copy(d,s) __va_copy(d,s) #endif syslinux-legacy-3.63+dfsg/com32/include/string.h0000664000175000017500000000336310777447272020245 0ustar evanevan/* * string.h */ #ifndef _STRING_H #define _STRING_H #include #include __extern void *memccpy(void *, const void *, int, size_t); __extern void *memchr(const void *, int, size_t); __extern int memcmp(const void *, const void *, size_t); __extern void *memcpy(void *, const void *, size_t); __extern void *mempcpy(void *, const void *, size_t); __extern void *memmove(void *, const void *, size_t); __extern void *memset(void *, int, size_t); __extern void *memmem(const void *, size_t, const void *, size_t); __extern void memswap(void *, void *, size_t); __extern int strcasecmp(const char *, const char *); __extern int strncasecmp(const char *, const char *, size_t); __extern char *strcat(char *, const char *); __extern char *strchr(const char *, int); __extern int strcmp(const char *, const char *); __extern char *strcpy(char *, const char *); __extern size_t strcspn(const char *, const char *); __extern char *strdup(const char *); __extern char *strndup(const char *, size_t); __extern char *strerror(int); __extern size_t strlen(const char *); __extern size_t strnlen(const char *, size_t); __extern char *strncat(char *, const char *, size_t); __extern size_t strlcat(char *, const char *, size_t); __extern int strncmp(const char *, const char *, size_t); __extern char *strncpy(char *, const char *, size_t); __extern char *stpncpy(char *, const char *, size_t); __extern size_t strlcpy(char *, const char *, size_t); __extern char *strpbrk(const char *, const char *); __extern char *strrchr(const char *, int); __extern char *strsep(char **, const char *); __extern size_t strspn(const char *, const char *); __extern char *strstr(const char *, const char *); __extern char *strtok(char *, const char *); #endif /* _STRING_H */ syslinux-legacy-3.63+dfsg/com32/include/tinyjpeg.h0000664000175000017500000000602310777447272020564 0ustar evanevan/* * Small jpeg decoder library (header file) * * Copyright (c) 2006, Luc Saillard * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __JPEGDEC_H__ #define __JPEGDEC_H__ #ifdef __cplusplus extern "C" { #endif struct jdec_private; /* Flags that can be set by any applications */ #define TINYJPEG_FLAGS_MJPEG_TABLE (1<<1) /* Format accepted in outout */ struct tinyjpeg_colorspace; typedef const struct tinyjpeg_colorspace *tinyjpeg_colorspace_t; extern const tinyjpeg_colorspace_t TINYJPEG_FMT_GREY, TINYJPEG_FMT_BGR24, TINYJPEG_FMT_RGB24, TINYJPEG_FMT_YUV420P, TINYJPEG_FMT_BGRA32, TINYJPEG_FMT_RGBA32; struct jdec_private *tinyjpeg_init(void); void tinyjpeg_free(struct jdec_private *priv); int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size); int tinyjpeg_decode(struct jdec_private *priv, tinyjpeg_colorspace_t pixel_format); const char *tinyjpeg_get_errorstring(struct jdec_private *priv); void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height); int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components, unsigned int ncomponents); int tinyjpeg_set_components(struct jdec_private *priv, unsigned char * const *components, unsigned int ncomponents); int tinyjpeg_get_bytes_per_row(struct jdec_private *priv, unsigned int *bytes, unsigned int ncomponents); int tinyjpeg_set_bytes_per_row(struct jdec_private *priv, const unsigned int *bytes, unsigned int ncomponents); int tinyjpeg_set_flags(struct jdec_private *priv, int flags); #ifdef __cplusplus } #endif #endif syslinux-legacy-3.63+dfsg/com32/include/colortbl.h0000664000175000017500000000400610777447272020552 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #ifndef _COLORTBL_H #define _COLORTBL_H /* Attribute/color table used by ansicon and vesacon to abstract out the color selection. */ /* Note: vesacon relies on the encoding of these numbers */ enum color_table_shadow { SHADOW_NONE = 0, SHADOW_ALL = 1, SHADOW_NORMAL = 2, SHADOW_REVERSE = 3, }; struct color_table { const char *name; /* Attribute name (used for customization) */ const char *ansi; /* ANSI attribute */ unsigned int argb_fg; /* ARGB for foreground */ unsigned int argb_bg; /* ARGB for background */ enum color_table_shadow shadow; /* Shadow mode */ }; extern struct color_table *console_color_table; extern int console_color_table_size; #endif /* _COLORTBL_H */ syslinux-legacy-3.63+dfsg/com32/include/assert.h0000664000175000017500000000017610777447272020237 0ustar evanevan#ifndef _ASSERT_H #define _ASSERT_H /* Assert not currently supported */ #define assert(X) ((void)0) #endif /* _ASSERT_H */ syslinux-legacy-3.63+dfsg/com32/include/time.h0000664000175000017500000000006510777447272017671 0ustar evanevan#ifndef _TIME_H #define _TIME_H /* empty */ #endif syslinux-legacy-3.63+dfsg/com32/include/zlib.h0000664000175000017500000016061310777447272017701 0ustar evanevan/* zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.1, November 17th, 2003 Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ #ifndef ZLIB_H #define ZLIB_H #include "zconf.h" #ifdef __cplusplus extern "C" { #endif #define ZLIB_VERSION "1.2.1" #define ZLIB_VERNUM 0x1210 /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms will be added later and will have the same stream interface. Compression can be done in a single step if the buffers are large enough (for example if an input file is mmap'ed), or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. The compressed data format used by the in-memory functions is the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped around a deflate stream, which is itself documented in RFC 1951. The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- file compression on file systems, has a larger header than zlib to maintain directory information, and uses a different, slower check method than zlib. This library does not provide any functions to write gzip files in memory. However such functions could be easily written using zlib's deflate function, the documentation in the gzip RFC, and the examples in gzio.c. The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); typedef void (*free_func) OF((voidpf opaque, voidpf address)); struct internal_state; typedef struct z_stream_s { Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total nb of input bytes read so far */ Bytef *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ free_func zfree; /* used to free the internal state */ voidpf opaque; /* private data object passed to zalloc and zfree */ int data_type; /* best guess about the data type: ascii or binary */ uLong adler; /* adler32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; typedef z_stream FAR *z_streamp; /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the compression library and must not be updated by the application. The opaque value provided by the application will be passed as the first parameter for calls of zalloc and zfree. This can be useful for custom memory management. The compression library attaches no meaning to the opaque value. zalloc must return Z_NULL if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be thread safe. On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers returned by zalloc for objects of exactly 65536 bytes *must* have their offset normalized to zero. The default allocation function provided by this library ensures this (see zutil.c). To reduce memory requirements and avoid any allocation of 64K objects, at the expense of compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ #define Z_SYNC_FLUSH 2 #define Z_FULL_FLUSH 3 #define Z_FINISH 4 #define Z_BLOCK 5 /* Allowed flush values; see deflate() and inflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_RLE 3 #define Z_DEFAULT_STRATEGY 0 /* compression strategy; see deflateInit2() below for details */ #define Z_BINARY 0 #define Z_ASCII 1 #define Z_UNKNOWN 2 /* Possible values of the data_type field (though see inflate()) */ #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ /* basic functions */ ZEXTERN const char * ZEXPORT zlibVersion OF((void)); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ /* ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default allocation functions. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION requests a default compromise between speed and compression (currently equivalent to level 6). deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if level is not a valid compression level, Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. deflate performs one or both of the following actions: - Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary (in interactive applications). Some output may be provided even if flush is not set. Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating avail_in or avail_out accordingly; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. (In particular avail_in is zero after the call if enough output space has been provided before the call.) Flushing may degrade compression for some compression algorithms and so it should be used only when necessary. If flush is set to Z_FULL_FLUSH, all output is flushed as with Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using Z_FULL_FLUSH too often can seriously degrade the compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out is greater than six to avoid repeated flush markers due to avail_out == 0 on return. If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was enough output space; if deflate returns with Z_OK, this function must be called again with Z_FINISH and more output space (updated avail_out) but no more input data, until it returns with Z_STREAM_END or an error. After deflate has returned Z_STREAM_END, the only possible operations on the stream are deflateReset or deflateEnd. Z_FINISH can be used immediately after deflateInit if all the compression is to be done in a single step. In this case, avail_out must be at least the value returned by deflateBound (see below). If deflate does not return Z_STREAM_END, then it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). deflate() may update data_type if it can make a good guess about the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered binary. This field is only for information purposes and does not affect the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and deflate() can be called again with more input and more output space to continue compressing. */ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. If next_in is not Z_NULL and avail_in is large enough (the exact value depends on the compression method), inflateInit determines the compression method from the zlib header and allocates all data structures accordingly; otherwise the allocation will be deferred to the first call of inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller. msg is set to null if there is no error message. inflateInit does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) */ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. inflate performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in is updated and processing will resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating the next_* and avail_* values accordingly. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If inflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much output as possible to the output buffer. Z_BLOCK requests that inflate() stop if and when it get to the next deflate block boundary. When decoding the zlib or gzip format, this will cause inflate() to return immediately after the header and before the first block. When doing a raw inflate, inflate() will go ahead and process the first block, and will return when it gets to the end of that block, or when it runs out of data. The Z_BLOCK option assists in appending to or combining deflate streams. Also to assist in this, on return inflate() will set strm->data_type to the number of unused bits in the last byte taken from strm->next_in, plus 64 if inflate() is currently decoding the last block in the deflate stream, plus 128 if inflate() returned immediately after decoding an end-of-block code or decoding the complete header up to just before the first byte of the deflate stream. The end-of-block will not be indicated until all of the uncompressed data from that block has been written to strm->next_out. The number of unused bits may in general be greater than seven, except when bit 7 of data_type is set, in which case the number of unused bits will be less than eight. inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all the uncompressed data. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The next operation on this stream must be inflateEnd to deallocate the decompression state. The use of Z_FINISH is never required, but can be used to inform inflate that a faster approach may be used for the single inflate() call. In this implementation, inflate() always flushes as much output as possible to the output buffer, and always uses the faster approach on the first call. So the only effect of the flush parameter in this implementation is on the return value of inflate(), as noted below, or when it returns early because Z_BLOCK is used. If a preset dictionary is needed after this call (see inflateSetDictionary below), inflate sets strm-adler to the adler32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the adler32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described below. At the end of the stream, inflate() checks that its computed adler32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. inflate() will decompress and check either zlib-wrapped or gzip-wrapped deflate data. The header type is detected automatically. Any information contained in the gzip header is not retained, so applications that need that information should instead use raw inflate, see inflateInit2() below, or inflateBack() and perform their own processing of the gzip header and trailer. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect check value), Z_STREAM_ERROR if the stream structure was inconsistent (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress is possible or if there was not enough room in the output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and inflate() can be called again with more input and more output space to continue decompressing. If Z_DATA_ERROR is returned, the application may then call inflateSync() to look for a good compression block if a partial recovery of the data is desired. */ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* Advanced functions */ /* The following functions are needed only in some special applications. */ /* ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy)); This is another version of deflateInit with more compression options. The fields next_in, zalloc, zfree and opaque must be initialized before by the caller. The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. The windowBits parameter is the base two logarithm of the window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. windowBits can also be -8..-15 for raw deflate. In this case, -windowBits determines the window size. deflate() will then generate raw deflate data with no zlib header or trailer, and will not compute an adler32 check value. windowBits can also be greater than 15 for optional gzip encoding. Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper. The gzip header will have no file name, no extra data, no comment, no modification time (set to zero), no header crc, and the operating system will be set to 255 (unknown). The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel. The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no string match), or Z_RLE to limit match distances to one (run-length encoding). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid method). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. This function must be called immediately after deflateInit, deflateInit2 or deflateReset, before any call of deflate. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary. Depending on the size of the compression data structures selected by deflateInit or deflateInit2, a part of the dictionary may in effect be discarded, for example if the dictionary is larger than the window size in deflate or deflate2. Thus the strings most likely to be useful should be put at the end of the dictionary, not at the front. Upon return of this function, strm->adler is set to the adler32 value of the dictionary; the decompressor may later use this value to determine which dictionary has been used by the compressor. (The adler32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) If a raw deflate was requested, then the adler32 value is not computed and strm->adler is not set. deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is inconsistent (for example if deflate has already been called for this stream or if the compression method is bsort). deflateSetDictionary does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory. deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. The stream will keep the same compression level and any other attributes that may have been set by deflateInit2. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). */ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, int level, int strategy)); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression level is changed, the input available so far is compressed with the old level (and may be flushed); the new level will take effect only at the next call of deflate(). Before the call of deflateParams, the stream state must be set as for a call of deflate(), since the currently available input may have to be compressed and flushed. In particular, strm->avail_out must be non-zero. deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if strm->avail_out was zero. */ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, uLong sourceLen)); /* deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() or deflateInit2(). This would be used to allocate an output buffer for deflation in a single pass, and so would be called before deflate(). */ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, int bits, int value)); /* deflatePrime() inserts bits in the deflate output stream. The intent is that this function is used to start off the deflate output with the bits leftover from a previous deflate stream when appending to it. As such, this function can only be used for raw deflate, and must be used before the first deflate() call after a deflateInit2() or deflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the output. deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, int windowBits)); This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. The default value is 15 if inflateInit is used instead. windowBits must be greater than or equal to the windowBits value provided to deflateInit2() while compressing, or it must be equal to 15 if deflateInit2() was not used. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. windowBits can also be -8..-15 for raw inflate. In this case, -windowBits determines the window size. inflate() will then process raw deflate data, not looking for a zlib or gzip header, not generating a check value, and not looking for any check values for comparison at the end of the stream. This is for use with other formats that use the deflate compressed data format such as zip. Those formats provide their own check values. If a custom format is developed using the raw deflate format for compressed data, it is recommended that a check value such as an adler32 or a crc32 be applied to the uncompressed data as is done in the zlib, gzip, and zip formats. For most applications, the zlib format should be used as is. Note that comments above on the use in deflateInit2() applies to the magnitude of windowBits. windowBits can also be greater than 15 for optional gzip decoding. Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (the zlib format will return a Z_DATA_ERROR). inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative memLevel). msg is set to null if there is no error message. inflateInit2 does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) */ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the adler32 value returned by this call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the expected one (incorrect adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); /* Skips invalid compressed data until a full flush point (see above the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided. inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the success case, the application may save the current current value of total_in which indicates where valid compressed data was found. In the error case, the application may repeatedly call inflateSync, providing more input each time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when randomly accessing a large stream. The first pass through the stream can periodically record the inflate state, allowing restarting inflate at those points when randomly accessing the stream. inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). */ /* ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits, unsigned char FAR *window)); Initialize the internal stream state for decompression using inflateBack() calls. The fields zalloc, zfree and opaque in strm must be initialized before the call. If zalloc and zfree are Z_NULL, then the default library- derived memory allocation routines are used. windowBits is the base two logarithm of the window size, in the range 8..15. window is a caller supplied buffer of that size. Except for special applications where it is assured that deflate was used with small window sizes, windowBits must be 15 and a 32K byte window must be supplied to be able to decompress general deflate streams. See inflateBack() for the usage of these routines. inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of the paramaters are invalid, Z_MEM_ERROR if the internal state could not be allocated, or Z_VERSION_ERROR if the version of the library does not match the version of the header file. */ typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc)); /* inflateBack() does a raw inflate with a single call using a call-back interface for input and output. This is more efficient than inflate() for file i/o applications in that it avoids copying between the output and the sliding window by simply making the window itself the output buffer. This function trusts the application to not change the output buffer passed by the output function, at least until inflateBack() returns. inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. inflateBack() may then be used multiple times to inflate a complete, raw deflate stream with each call. inflateBackEnd() is then called to free the allocated state. A raw deflate stream is one with no zlib or gzip header or trailer. This routine would normally be used in a utility that reads zip or gzip files and writes out uncompressed files. The utility would decode the header and process the trailer on its own, hence this routine expects only the raw deflate stream to decompress. This is different from the normal behavior of inflate(), which expects either a zlib or gzip header and trailer around the deflate stream. inflateBack() uses two subroutines supplied by the caller that are then called by inflateBack() for input and output. inflateBack() calls those routines until it reads a complete deflate stream and writes out all of the uncompressed data, or until it encounters an error. The function's parameters and return types are defined above in the in_func and out_func typedefs. inflateBack() will call in(in_desc, &buf) which should return the number of bytes of provided input, and a pointer to that input in buf. If there is no input available, in() must return zero--buf is ignored in that case--and inflateBack() will return a buffer error. inflateBack() will call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() should return zero on success, or non-zero on failure. If out() returns non-zero, inflateBack() will return with an error. Neither in() nor out() are permitted to change the contents of the window provided to inflateBackInit(), which is also the buffer that out() uses to write from. The length written by out() will be at most the window size. Any non-zero amount of input may be provided by in(). For convenience, inflateBack() can be provided input on the first call by setting strm->next_in and strm->avail_in. If that input is exhausted, then in() will be called. Therefore strm->next_in must be initialized before calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in must also be initialized, and then if strm->avail_in is not zero, input will initially be taken from strm->next_in[0 .. strm->avail_in - 1]. The in_desc and out_desc parameters of inflateBack() is passed as the first parameter of in() and out() respectively when they are called. These descriptors can be optionally used to pass any information that the caller- supplied in() and out() functions need to do their job. On return, inflateBack() will set strm->next_in and strm->avail_in to pass back any unused input that was provided by the last in() call. The return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR if in() or out() returned an error, Z_DATA_ERROR if there was a format error in the deflate stream (in which case strm->msg is set to indicate the nature of the error), or Z_STREAM_ERROR if the stream was not properly initialized. In the case of Z_BUF_ERROR, an input or output error can be distinguished using strm->next_in which will be Z_NULL only if in() returned an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to out() returning non-zero. (in() will always be called before out(), so strm->next_in is assured to be defined if out() returns non-zero.) Note that inflateBack() cannot return Z_OK. */ ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm)); /* All memory allocated by inflateBackInit() is freed. inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream state was inconsistent. */ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); /* Return flags indicating compile-time options. Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: 1.0: size of uInt 3.2: size of uLong 5.4: size of voidpf (pointer) 7.6: size of z_off_t Compiler, assembler, and debug options: 8: DEBUG 9: ASMV or ASMINF -- use ASM code 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention 11: 0 (reserved) One-time table building (smaller code, but not thread-safe if true): 12: BUILDFIXED -- build static block decoding tables when needed 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed 14,15: 0 (reserved) Library content (indicates missing functionality): 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking deflate code when not needed) 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect and decode gzip streams (to avoid linking crc code) 18-19: 0 (reserved) Operation variations (changes in library functionality): 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate 21: FASTEST -- deflate algorithm with only one, lowest compression level 22,23: 0 (reserved) The sprintf variant used by gzprintf (zero is best): 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! 26: 0 = returns value, 1 = void -- 1 means inferred string length returned Remainder: 27-31: 0 (reserved) */ /* utility functions */ /* The following utility functions are implemented on top of the basic stream-oriented functions. To simplify the interface, some default options are assumed (compression level and memory usage, standard memory allocation functions). The source code of these utility functions can easily be modified if you need special options. */ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. This function can be used to compress a whole file at once if the input file is mmap'ed. compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer. */ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); /* compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer. */ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the compressed buffer. This function can be used to decompress a whole file at once if the input file is mmap'ed. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. */ typedef voidp gzFile; ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); /* Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb") but can also include a compression level ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman only compression as in "wb1h", or 'R' for run-length encoding as in "wb1R". (See the description of deflateInit2 for more information about the strategy parameter.) gzopen can be used to read a file which is not in gzip format; in this case gzread will directly read from the file without decompression. gzopen returns NULL if the file could not be opened or if there was insufficient memory to allocate the (de)compression state; errno can be checked to distinguish the two cases (if errno is zero, the zlib error is Z_MEM_ERROR). */ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); /* gzdopen() associates a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or fileno (in the file has been previously opened with fopen). The mode parameter is as in gzopen. The next call of gzclose on the returned gzFile will also close the file descriptor fd, just like fclose(fdopen(fd), mode) closes the file descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). gzdopen returns NULL if there was insufficient memory to allocate the (de)compression state. */ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); /* Dynamically update the compression level or strategy. See the description of deflateInit2 for the meaning of these parameters. gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not opened for writing. */ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); /* Reads the given number of uncompressed bytes from the compressed file. If the input file was not in gzip format, gzread copies the given number of bytes into the buffer. gzread returns the number of uncompressed bytes actually read (0 for end of file, -1 for error). */ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len)); /* Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of uncompressed bytes actually written (0 in case of error). */ ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); /* Converts, formats, and writes the args to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of uncompressed bytes actually written (0 in case of error). The number of uncompressed bytes written is limited to 4095. The caller should assure that this limit is not exceeded. If it is exceeded, then gzprintf() will return return an error (0) with nothing written. In this case, there may also be a buffer overflow with unpredictable consequences, which is possible only if zlib was compiled with the insecure functions sprintf() or vsprintf() because the secure snprintf() or vsnprintf() functions were not available. */ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); /* Writes the given null-terminated string to the compressed file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. */ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); /* Reads bytes from the compressed file until len-1 characters are read, or a newline character is read and transferred to buf, or an end-of-file condition is encountered. The string is then terminated with a null character. gzgets returns buf, or Z_NULL in case of error. */ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); /* Writes c, converted to an unsigned char, into the compressed file. gzputc returns the value that was written, or -1 in case of error. */ ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); /* Reads one byte from the compressed file. gzgetc returns this byte or -1 in case of end of file or error. */ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); /* Push one character back onto the stream to be read again later. Only one character of push-back is allowed. gzungetc() returns the character pushed, or -1 on failure. gzungetc() will fail if a character has been pushed but not read yet, or if c is -1. The pushed character will be discarded if the stream is repositioned with gzseek() or gzrewind(). */ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); /* Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function gzerror below). gzflush returns Z_OK if the flush parameter is Z_FINISH and all output could be flushed. gzflush should be called only when strictly necessary because it can degrade compression. */ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, z_off_t offset, int whence)); /* Sets the starting position for the next gzread or gzwrite on the given compressed file. The offset represents a number of bytes in the uncompressed data stream. The whence parameter is defined as in lseek(2); the value SEEK_END is not supported. If the file is opened for reading, this function is emulated but can be extremely slow. If the file is opened for writing, only forward seeks are supported; gzseek then compresses a sequence of zeroes up to the new starting position. gzseek returns the resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position would be before the current position. */ ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); /* Rewinds the given file. This function is supported only for reading. gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) */ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); /* Returns the starting position for the next gzread or gzwrite on the given compressed file. This position represents a number of bytes in the uncompressed data stream. gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) */ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); /* Returns 1 when EOF has previously been detected reading the given input stream, otherwise zero. */ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); /* Flushes all pending output if necessary, closes the compressed file and deallocates all the (de)compression state. The return value is the zlib error number (see function gzerror below). */ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); /* Returns the error message for the last error which occurred on the given compressed file. errnum is set to zlib error number. If an error occurred in the file system and not in the compression library, errnum is set to Z_ERRNO and the application may consult errno to get the exact error code. */ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); /* Clears the error and end-of-file flags for file. This is analogous to the clearerr() function in stdio. This is useful for continuing to read a gzip file that is being written concurrently. */ /* checksum functions */ /* These functions are not related to compression but are exported anyway because they might be useful in applications using the compression library. */ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is NULL, this function returns the required initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much faster. Usage example: uLong adler = adler32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { adler = adler32(adler, buffer, length); } if (adler != original_adler) error(); */ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); /* Update a running crc with the bytes buf[0..len-1] and return the updated crc. If buf is NULL, this function returns the required initial value for the crc. Pre- and post-conditioning (one's complement) is performed within this function so it shouldn't be done by the application. Usage example: uLong crc = crc32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { crc = crc32(crc, buffer, length); } if (crc != original_crc) error(); */ /* various hacks, don't look :) */ /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, const char *version, int stream_size)); ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size)); #define deflateInit(strm, level) \ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) #define inflateInit(strm) \ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ (strategy), ZLIB_VERSION, sizeof(z_stream)) #define inflateInit2(strm, windowBits) \ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) #define inflateBackInit(strm, windowBits, window) \ inflateBackInit_((strm), (windowBits), (window), \ ZLIB_VERSION, sizeof(z_stream)) #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) struct internal_state {int dummy;}; /* hack for buggy compilers */ #endif ZEXTERN const char * ZEXPORT zError OF((int err)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); #ifdef __cplusplus } #endif #endif /* ZLIB_H */ syslinux-legacy-3.63+dfsg/com32/include/stdint.h0000664000175000017500000000760210777447272020244 0ustar evanevan/* * stdint.h */ #ifndef _STDINT_H #define _STDINT_H /* Exact types */ typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef signed long long int64_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; /* Small types */ typedef signed char int_least8_t; typedef signed short int_least16_t; typedef signed int int_least32_t; typedef signed long long int_least64_t; typedef unsigned char uint_least8_t; typedef unsigned short uint_least16_t; typedef unsigned int uint_least32_t; typedef unsigned long long uint_least64_t; /* Fast types */ typedef signed char int_fast8_t; typedef signed short int_fast16_t; typedef signed int int_fast32_t; typedef signed long long int_fast64_t; typedef unsigned char uint_fast8_t; typedef unsigned short uint_fast16_t; typedef unsigned int uint_fast32_t; typedef unsigned long long uint_fast64_t; /* Pointer types */ typedef int32_t intptr_t; typedef uint32_t uintptr_t; /* Maximal types */ typedef int64_t intmax_t; typedef uint64_t uintmax_t; /* * To be strictly correct... */ #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) # define INT8_MIN (-128) # define INT16_MIN (-32767-1) # define INT32_MIN (-2147483647-1) # define INT64_MIN (-9223372036854775807LL-1) # define INT8_MAX (127) # define INT16_MAX (32767) # define INT32_MAX (2147483647) # define INT64_MAX (9223372036854775807LL) # define UINT8_MAX (255U) # define UINT16_MAX (65535U) # define UINT32_MAX (4294967295U) # define UINT64_MAX (18446744073709551615ULL) # define INT_LEAST8_MIN (-128) # define INT_LEAST16_MIN (-32767-1) # define INT_LEAST32_MIN (-2147483647-1) # define INT_LEAST64_MIN (-9223372036854775807LL-1) # define INT_LEAST8_MAX (127) # define INT_LEAST16_MAX (32767) # define INT_LEAST32_MAX (2147483647) # define INT_LEAST64_MAX (9223372036854775807LL) # define UINT_LEAST8_MAX (255U) # define UINT_LEAST16_MAX (65535U) # define UINT_LEAST32_MAX (4294967295U) # define UINT_LEAST64_MAX (18446744073709551615ULL) # define INT_FAST8_MIN (-128) # define INT_FAST16_MIN (-32767-1) # define INT_FAST32_MIN (-2147483647-1) # define INT_FAST64_MIN (-9223372036854775807LL-1) # define INT_FAST8_MAX (127) # define INT_FAST16_MAX (32767) # define INT_FAST32_MAX (2147483647) # define INT_FAST64_MAX (9223372036854775807LL) # define UINT_FAST8_MAX (255U) # define UINT_FAST16_MAX (65535U) # define UINT_FAST32_MAX (4294967295U) # define UINT_FAST64_MAX (18446744073709551615ULL) # define INTPTR_MIN (-2147483647-1) # define INTPTR_MAX (2147483647) # define UINTPTR_MAX (4294967295U) # define INTMAX_MIN (-9223372036854775807LL-1) # define INTMAX_MAX (9223372036854775807LL) # define UINTMAX_MAX (18446744073709551615ULL) /* ptrdiff_t limit */ # define PTRDIFF_MIN (-2147483647-1) # define PTRDIFF_MAX (2147483647) /* sig_atomic_t limit */ # define SIG_ATOMIC_MIN (-2147483647-1) # define SIG_ATOMIC_MAX (2147483647) /* size_t limit */ # define SIZE_MAX (4294967295U) #endif /* STDC_LIMIT_MACROS */ #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) # define INT8_C(n) n # define INT16_C(n) n # define INT32_C(n) n # define INT64_C(n) n ## LL # define UINT8_C(n) n ## U # define UINT16_C(n) n ## U # define UINT32_C(n) n ## U # define UINT64_C(n) n ## ULL # define INTMAX_C(n) n ## LL # define UINTMAX_C(n) n ## ULL #endif /* STDC_CONSTANT_MACROS */ #endif /* _STDINT_H */ syslinux-legacy-3.63+dfsg/com32/include/png.h0000664000175000017500000042573610777447272017537 0ustar evanevan/* png.h - header file for PNG reference library * * libpng version 1.2.8 - December 3, 2004 * Copyright (c) 1998-2004 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * * Authors and maintainers: * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.97, January 1998, through 1.2.8 - December 3, 2004: Glenn * See also "Contributing Authors", below. * * Note about libpng version numbers: * * Due to various miscommunications, unforeseen code incompatibilities * and occasional factors outside the authors' control, version numbering * on the library has not always been consistent and straightforward. * The following table summarizes matters since version 0.89c, which was * the first widely used release: * * source png.h png.h shared-lib * version string int version * ------- ------ ----- ---------- * 0.89c "1.0 beta 3" 0.89 89 1.0.89 * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] * 0.97c 0.97 97 2.0.97 * 0.98 0.98 98 2.0.98 * 0.99 0.99 98 2.0.99 * 0.99a-m 0.99 99 2.0.99 * 1.00 1.00 100 2.1.0 [100 should be 10000] * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] * 1.0.1 png.h string is 10001 2.1.0 * 1.0.1a-e identical to the 10002 from here on, the shared library * 1.0.2 source version) 10002 is 2.V where V is the source code * 1.0.2a-b 10003 version, except as noted. * 1.0.3 10003 * 1.0.3a-d 10004 * 1.0.4 10004 * 1.0.4a-f 10005 * 1.0.5 (+ 2 patches) 10005 * 1.0.5a-d 10006 * 1.0.5e-r 10100 (not source compatible) * 1.0.5s-v 10006 (not binary compatible) * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) * 1.0.6d-f 10007 (still binary incompatible) * 1.0.6g 10007 * 1.0.6h 10007 10.6h (testing xy.z so-numbering) * 1.0.6i 10007 10.6i * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) * 1.0.7 1 10007 (still compatible) * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 * 1.0.8rc1 1 10008 2.1.0.8rc1 * 1.0.8 1 10008 2.1.0.8 * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 * 1.0.9rc1 1 10009 2.1.0.9rc1 * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 * 1.0.9rc2 1 10009 2.1.0.9rc2 * 1.0.9 1 10009 2.1.0.9 * 1.0.10beta1 1 10010 2.1.0.10beta1 * 1.0.10rc1 1 10010 2.1.0.10rc1 * 1.0.10 1 10010 2.1.0.10 * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 * 1.0.11rc1 1 10011 2.1.0.11rc1 * 1.0.11 1 10011 2.1.0.11 * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 * 1.0.12rc1 2 10012 2.1.0.12rc1 * 1.0.12 2 10012 2.1.0.12 * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 * 1.2.0rc1 3 10200 3.1.2.0rc1 * 1.2.0 3 10200 3.1.2.0 * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 * 1.2.1 3 10201 3.1.2.1 * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 * 1.0.13 10 10013 10.so.0.1.0.13 * 1.2.2 12 10202 12.so.0.1.2.2 * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 * 1.2.3 12 10203 12.so.0.1.2.3 * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 * 1.0.14 10 10014 10.so.0.1.0.14 * 1.2.4 13 10204 12.so.0.1.2.4 * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 * 1.0.15 10 10015 10.so.0.1.0.15 * 1.2.5 13 10205 12.so.0.1.2.5 * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 * 1.0.16 10 10016 10.so.0.1.0.16 * 1.2.6 13 10206 12.so.0.1.2.6 * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 * 1.0.17rc1 10 10017 12.so.0.1.0.17rc1 * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 * 1.0.17 10 10017 12.so.0.1.0.17 * 1.2.7 13 10207 12.so.0.1.2.7 * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 * 1.0.18rc1-5 10 10018 12.so.0.1.0.18rc1-5 * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 * 1.0.18 10 10018 12.so.0.1.0.18 * 1.2.8 13 10208 12.so.0.1.2.8 * * Henceforth the source version will match the shared-library major * and minor numbers; the shared-library major version number will be * used for changes in backward compatibility, as it is intended. The * PNG_LIBPNG_VER macro, which is not used within libpng but is available * for applications, is an unsigned integer of the form xyyzz corresponding * to the source version x.y.z (leading zeros in y and z). Beta versions * were given the previous public release number plus a letter, until * version 1.0.6j; from then on they were given the upcoming public * release number plus "betaNN" or "rcN". * * Binary incompatibility exists only when applications make direct access * to the info_ptr or png_ptr members through png.h, and the compiled * application is loaded with a different version of the library. * * DLLNUM will change each time there are forward or backward changes * in binary compatibility (e.g., when a new feature is added). * * See libpng.txt or libpng.3 for more information. The PNG specification * is available as a W3C Recommendation and as an ISO Specification, * defines should NOT be changed. */ #define PNG_INFO_gAMA 0x0001 #define PNG_INFO_sBIT 0x0002 #define PNG_INFO_cHRM 0x0004 #define PNG_INFO_PLTE 0x0008 #define PNG_INFO_tRNS 0x0010 #define PNG_INFO_bKGD 0x0020 #define PNG_INFO_hIST 0x0040 #define PNG_INFO_pHYs 0x0080 #define PNG_INFO_oFFs 0x0100 #define PNG_INFO_tIME 0x0200 #define PNG_INFO_pCAL 0x0400 #define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ #define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ #define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ #define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ #define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */ /* This is used for the transformation routines, as some of them * change these values for the row. It also should enable using * the routines for other purposes. */ typedef struct png_row_info_struct { png_uint_32 width; /* width of row */ png_uint_32 rowbytes; /* number of bytes in row */ png_byte color_type; /* color type of row */ png_byte bit_depth; /* bit depth of row */ png_byte channels; /* number of channels (1, 2, 3, or 4) */ png_byte pixel_depth; /* bits per pixel (depth * channels) */ } png_row_info; typedef png_row_info FAR * png_row_infop; typedef png_row_info FAR * FAR * png_row_infopp; /* These are the function types for the I/O functions and for the functions * that allow the user to override the default I/O functions with his or her * own. The png_error_ptr type should match that of user-supplied warning * and error functions, while the png_rw_ptr type should match that of the * user read/write data functions. */ typedef struct png_struct_def png_struct; typedef png_struct FAR * png_structp; typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp)); typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t)); typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp)); typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32, int)); typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32, int)); #ifdef PNG_PROGRESSIVE_READ_SUPPORTED typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop)); typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop)); typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep, png_uint_32, int)); #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_LEGACY_SUPPORTED) typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp, png_row_infop, png_bytep)); #endif #if defined(PNG_USER_CHUNKS_SUPPORTED) typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp)); #endif #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp)); #endif /* Transform masks for the high-level interface */ #define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ #define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ #define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ #define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ #define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ #define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ #define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ #define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ #define PNG_TRANSFORM_BGR 0x0080 /* read and write */ #define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ #define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ #define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ #define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* WRITE only */ /* Flags for MNG supported features */ #define PNG_FLAG_MNG_EMPTY_PLTE 0x01 #define PNG_FLAG_MNG_FILTER_64 0x04 #define PNG_ALL_MNG_FEATURES 0x05 typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t)); typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp)); /* The structure that holds the information to read and write PNG files. * The only people who need to care about what is inside of this are the * people who will be modifying the library for their own special needs. * It should NOT be accessed directly by an application, except to store * the jmp_buf. */ struct png_struct_def { #ifdef PNG_SETJMP_SUPPORTED jmp_buf jmpbuf; /* used in png_error */ #endif png_error_ptr error_fn; /* function for printing errors and aborting */ png_error_ptr warning_fn; /* function for printing warnings */ png_voidp error_ptr; /* user supplied struct for error functions */ png_rw_ptr write_data_fn; /* function for writing output data */ png_rw_ptr read_data_fn; /* function for reading input data */ png_voidp io_ptr; /* ptr to application struct for I/O functions */ #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) png_user_transform_ptr read_user_transform_fn; /* user read transform */ #endif #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) png_user_transform_ptr write_user_transform_fn; /* user write transform */ #endif /* These were added in libpng-1.0.2 */ #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) png_voidp user_transform_ptr; /* user supplied struct for user transform */ png_byte user_transform_depth; /* bit depth of user transformed pixels */ png_byte user_transform_channels; /* channels in user transformed pixels */ #endif #endif png_uint_32 mode; /* tells us where we are in the PNG file */ png_uint_32 flags; /* flags indicating various things to libpng */ png_uint_32 transformations; /* which transformations to perform */ z_stream zstream; /* pointer to decompression structure (below) */ png_bytep zbuf; /* buffer for zlib */ png_size_t zbuf_size; /* size of zbuf */ int zlib_level; /* holds zlib compression level */ int zlib_method; /* holds zlib compression method */ int zlib_window_bits; /* holds zlib compression window bits */ int zlib_mem_level; /* holds zlib compression memory level */ int zlib_strategy; /* holds zlib compression strategy */ png_uint_32 width; /* width of image in pixels */ png_uint_32 height; /* height of image in pixels */ png_uint_32 num_rows; /* number of rows in current pass */ png_uint_32 usr_width; /* width of row at start of write */ png_uint_32 rowbytes; /* size of row in bytes */ png_uint_32 irowbytes; /* size of current interlaced row in bytes */ png_uint_32 iwidth; /* width of current interlaced row in pixels */ png_uint_32 row_number; /* current row in interlace pass */ png_bytep prev_row; /* buffer to save previous (unfiltered) row */ png_bytep row_buf; /* buffer to save current (unfiltered) row */ png_bytep sub_row; /* buffer to save "sub" row when filtering */ png_bytep up_row; /* buffer to save "up" row when filtering */ png_bytep avg_row; /* buffer to save "avg" row when filtering */ png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ png_row_info row_info; /* used for transformation routines */ png_uint_32 idat_size; /* current IDAT size for read */ png_uint_32 crc; /* current chunk CRC value */ png_colorp palette; /* palette from the input file */ png_uint_16 num_palette; /* number of color entries in palette */ png_uint_16 num_trans; /* number of transparency values */ png_byte chunk_name[5]; /* null-terminated name of current chunk */ png_byte compression; /* file compression type (always 0) */ png_byte filter; /* file filter type (always 0) */ png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ png_byte pass; /* current interlace pass (0 - 6) */ png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ png_byte color_type; /* color type of file */ png_byte bit_depth; /* bit depth of file */ png_byte usr_bit_depth; /* bit depth of users row */ png_byte pixel_depth; /* number of bits per pixel */ png_byte channels; /* number of channels in file */ png_byte usr_channels; /* channels at start of write */ png_byte sig_bytes; /* magic bytes read/written from start of file */ #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) #ifdef PNG_LEGACY_SUPPORTED png_byte filler; /* filler byte for pixel expansion */ #else png_uint_16 filler; /* filler bytes for pixel expansion */ #endif #endif #if defined(PNG_bKGD_SUPPORTED) png_byte background_gamma_type; # ifdef PNG_FLOATING_POINT_SUPPORTED float background_gamma; # endif png_color_16 background; /* background color in screen gamma space */ #if defined(PNG_READ_GAMMA_SUPPORTED) png_color_16 background_1; /* background normalized to gamma 1.0 */ #endif #endif /* PNG_bKGD_SUPPORTED */ #if defined(PNG_WRITE_FLUSH_SUPPORTED) png_flush_ptr output_flush_fn;/* Function for flushing output */ png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ png_uint_32 flush_rows; /* number of rows written since last flush */ #endif #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) int gamma_shift; /* number of "insignificant" bits 16-bit gamma */ #ifdef PNG_FLOATING_POINT_SUPPORTED float gamma; /* file gamma value */ float screen_gamma; /* screen gamma value (display_exponent) */ #endif #endif #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) png_bytep gamma_table; /* gamma table for 8-bit depth files */ png_bytep gamma_from_1; /* converts from 1.0 to screen */ png_bytep gamma_to_1; /* converts from file to 1.0 */ png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ #endif #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) png_color_8 sig_bit; /* significant bits in each available channel */ #endif #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) png_color_8 shift; /* shift for significant bit tranformation */ #endif #if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) png_bytep trans; /* transparency values for paletted files */ png_color_16 trans_values; /* transparency values for non-paletted files */ #endif png_read_status_ptr read_row_fn; /* called after each row is decoded */ png_write_status_ptr write_row_fn; /* called after each row is encoded */ #ifdef PNG_PROGRESSIVE_READ_SUPPORTED png_progressive_info_ptr info_fn; /* called after header data fully read */ png_progressive_row_ptr row_fn; /* called after each prog. row is decoded */ png_progressive_end_ptr end_fn; /* called after image is complete */ png_bytep save_buffer_ptr; /* current location in save_buffer */ png_bytep save_buffer; /* buffer for previously read data */ png_bytep current_buffer_ptr; /* current location in current_buffer */ png_bytep current_buffer; /* buffer for recently used data */ png_uint_32 push_length; /* size of current input chunk */ png_uint_32 skip_length; /* bytes to skip in input data */ png_size_t save_buffer_size; /* amount of data now in save_buffer */ png_size_t save_buffer_max; /* total size of save_buffer */ png_size_t buffer_size; /* total amount of available input data */ png_size_t current_buffer_size; /* amount of data now in current_buffer */ int process_mode; /* what push library is currently doing */ int cur_palette; /* current push library palette index */ # if defined(PNG_TEXT_SUPPORTED) png_size_t current_text_size; /* current size of text input data */ png_size_t current_text_left; /* how much text left to read in input */ png_charp current_text; /* current text chunk buffer */ png_charp current_text_ptr; /* current location in current_text */ # endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */ #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) /* for the Borland special 64K segment handler */ png_bytepp offset_table_ptr; png_bytep offset_table; png_uint_16 offset_table_number; png_uint_16 offset_table_count; png_uint_16 offset_table_count_free; #endif #if defined(PNG_READ_DITHER_SUPPORTED) png_bytep palette_lookup; /* lookup table for dithering */ png_bytep dither_index; /* index translation for palette files */ #endif #if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED) png_uint_16p hist; /* histogram */ #endif #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) png_byte heuristic_method; /* heuristic for row filter selection */ png_byte num_prev_filters; /* number of weights for previous rows */ png_bytep prev_filters; /* filter type(s) of previous row(s) */ png_uint_16p filter_weights; /* weight(s) for previous line(s) */ png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */ png_uint_16p filter_costs; /* relative filter calculation cost */ png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ #endif #if defined(PNG_TIME_RFC1123_SUPPORTED) png_charp time_buffer; /* String to hold RFC 1123 time text */ #endif /* New members added in libpng-1.0.6 */ #ifdef PNG_FREE_ME_SUPPORTED png_uint_32 free_me; /* flags items libpng is responsible for freeing */ #endif #if defined(PNG_USER_CHUNKS_SUPPORTED) png_voidp user_chunk_ptr; png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ #endif #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) int num_chunk_list; png_bytep chunk_list; #endif /* New members added in libpng-1.0.3 */ #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) png_byte rgb_to_gray_status; /* These were changed from png_byte in libpng-1.0.6 */ png_uint_16 rgb_to_gray_red_coeff; png_uint_16 rgb_to_gray_green_coeff; png_uint_16 rgb_to_gray_blue_coeff; #endif /* New member added in libpng-1.0.4 (renamed in 1.0.9) */ #if defined(PNG_MNG_FEATURES_SUPPORTED) || \ defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) /* changed from png_byte to png_uint_32 at version 1.2.0 */ #ifdef PNG_1_0_X png_byte mng_features_permitted; #else png_uint_32 mng_features_permitted; #endif /* PNG_1_0_X */ #endif /* New member added in libpng-1.0.7 */ #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) png_fixed_point int_gamma; #endif /* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ #if defined(PNG_MNG_FEATURES_SUPPORTED) png_byte filter_type; #endif #if defined(PNG_1_0_X) || (defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)) /* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */ png_uint_32 row_buf_size; #endif /* New members added in libpng-1.2.0 */ #if !defined(PNG_1_0_X) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) png_byte mmx_bitdepth_threshold; png_uint_32 mmx_rowbytes_threshold; png_uint_32 asm_flags; #endif /* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ #ifdef PNG_USER_MEM_SUPPORTED png_voidp mem_ptr; /* user supplied struct for mem functions */ png_malloc_ptr malloc_fn; /* function for allocating memory */ png_free_ptr free_fn; /* function for freeing memory */ #endif /* New member added in libpng-1.0.13 and 1.2.0 */ png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ #if defined(PNG_READ_DITHER_SUPPORTED) /* The following three members were added at version 1.0.14 and 1.2.4 */ png_bytep dither_sort; /* working sort array */ png_bytep index_to_palette; /* where the original index currently is */ /* in the palette */ png_bytep palette_to_index; /* which original index points to this */ /* palette color */ #endif /* New members added in libpng-1.0.16 and 1.2.6 */ png_byte compression_type; #ifdef PNG_SET_USER_LIMITS_SUPPORTED png_uint_32 user_width_max; png_uint_32 user_height_max; #endif }; /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ typedef png_structp version_1_2_8; typedef png_struct FAR * FAR * png_structpp; /* Here are the function definitions most commonly used. This is not * the place to find out how to use libpng. See libpng.txt for the * full explanation, see example.c for the summary. This just provides * a simple one line description of the use of each function. */ /* Returns the version number of the library */ extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void)); /* Tell lib we have already handled the first magic bytes. * Handling more than 8 bytes from the beginning of the file is an error. */ extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr, int num_bytes)); /* Check sig[start] through sig[start + num_to_check - 1] to see if it's a * PNG file. Returns zero if the supplied bytes match the 8-byte PNG * signature, and non-zero otherwise. Having num_to_check == 0 or * start > 7 will always fail (ie return non-zero). */ extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start, png_size_t num_to_check)); /* Simple signature checking function. This is the same as calling * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). */ extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num)); /* Allocate and initialize png_ptr struct for reading, and any other memory. */ extern PNG_EXPORT(png_structp,png_create_read_struct) PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn)); /* Allocate and initialize png_ptr struct for writing, and any other memory */ extern PNG_EXPORT(png_structp,png_create_write_struct) PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn)); #ifdef PNG_WRITE_SUPPORTED extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size) PNGARG((png_structp png_ptr)); #endif #ifdef PNG_WRITE_SUPPORTED extern PNG_EXPORT(void,png_set_compression_buffer_size) PNGARG((png_structp png_ptr, png_uint_32 size)); #endif /* Reset the compression stream */ extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr)); /* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ #ifdef PNG_USER_MEM_SUPPORTED extern PNG_EXPORT(png_structp,png_create_read_struct_2) PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn)); extern PNG_EXPORT(png_structp,png_create_write_struct_2) PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn)); #endif /* Write a PNG chunk - size, type, (optional) data, CRC. */ extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr, png_bytep chunk_name, png_bytep data, png_size_t length)); /* Write the start of a PNG chunk - length and chunk name. */ extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr, png_bytep chunk_name, png_uint_32 length)); /* Write the data of a PNG chunk started with png_write_chunk_start(). */ extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr, png_bytep data, png_size_t length)); /* Finish a chunk started with png_write_chunk_start() (includes CRC). */ extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr)); /* Allocate and initialize the info structure */ extern PNG_EXPORT(png_infop,png_create_info_struct) PNGARG((png_structp png_ptr)); /* Initialize the info structure (old interface - DEPRECATED) */ extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr)); #undef png_info_init #define png_info_init(info_ptr) png_info_init_3(&info_ptr,\ png_sizeof(png_info)); extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr, png_size_t png_info_struct_size)); /* Writes all the PNG information before the image. */ extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr, png_infop info_ptr)); extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr, png_infop info_ptr)); #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED /* read the information before the actual image data. */ extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr, png_infop info_ptr)); #endif #if defined(PNG_TIME_RFC1123_SUPPORTED) extern PNG_EXPORT(png_charp,png_convert_to_rfc1123) PNGARG((png_structp png_ptr, png_timep ptime)); #endif #if !defined(_WIN32_WCE) /* "time.h" functions are not supported on WindowsCE */ #if defined(PNG_WRITE_tIME_SUPPORTED) /* convert from a struct tm to png_time */ extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime, struct tm FAR * ttime)); /* convert from time_t to png_time. Uses gmtime() */ extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime, time_t ttime)); #endif /* PNG_WRITE_tIME_SUPPORTED */ #endif /* _WIN32_WCE */ #if defined(PNG_READ_EXPAND_SUPPORTED) /* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) /* Use blue, green, red order for pixels. */ extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) /* Expand the grayscale to 24-bit RGB if necessary. */ extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) /* Reduce RGB to grayscale. */ #ifdef PNG_FLOATING_POINT_SUPPORTED extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr, int error_action, double red, double green )); #endif extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr, int error_action, png_fixed_point red, png_fixed_point green )); extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp png_ptr)); #endif extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth, png_colorp palette)); #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) /* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr, png_uint_32 filler, int flags)); /* The values of the PNG_FILLER_ defines should NOT be changed */ #define PNG_FILLER_BEFORE 0 #define PNG_FILLER_AFTER 1 /* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ #if !defined(PNG_1_0_X) extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr, png_uint_32 filler, int flags)); #endif #endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) /* Swap bytes in 16-bit depth files. */ extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) /* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) /* Swap packing order of pixels in bytes. */ extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) /* Converts files to legal bit depths. */ extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr, png_color_8p true_bits)); #endif #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ defined(PNG_WRITE_INTERLACING_SUPPORTED) /* Have the code handle the interlacing. Returns the number of passes. */ extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) /* Invert monochrome files */ extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) /* Handle alpha and tRNS by replacing with a background color. */ #ifdef PNG_FLOATING_POINT_SUPPORTED extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr, png_color_16p background_color, int background_gamma_code, int need_expand, double background_gamma)); #endif #define PNG_BACKGROUND_GAMMA_UNKNOWN 0 #define PNG_BACKGROUND_GAMMA_SCREEN 1 #define PNG_BACKGROUND_GAMMA_FILE 2 #define PNG_BACKGROUND_GAMMA_UNIQUE 3 #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) /* strip the second byte of information from a 16-bit depth file. */ extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_DITHER_SUPPORTED) /* Turn on dithering, and reduce the palette to the number of colors available. */ extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr, png_colorp palette, int num_palette, int maximum_colors, png_uint_16p histogram, int full_dither)); #endif #if defined(PNG_READ_GAMMA_SUPPORTED) /* Handle gamma correction. Screen_gamma=(display_exponent) */ #ifdef PNG_FLOATING_POINT_SUPPORTED extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr, double screen_gamma, double default_file_gamma)); #endif #endif #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) /* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */ /* Deprecated and will be removed. Use png_permit_mng_features() instead. */ extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr, int empty_plte_permitted)); #endif #if defined(PNG_WRITE_FLUSH_SUPPORTED) /* Set how many lines between output flushes - 0 for no flushing */ extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows)); /* Flush the current PNG output buffer */ extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr)); #endif /* optional update palette with requested transformations */ extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr)); /* optional call to update the users info structure */ extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr, png_infop info_ptr)); #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED /* read one or more rows of image data. */ extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr, png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)); #endif #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED /* read a row of data. */ extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr, png_bytep row, png_bytep display_row)); #endif #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED /* read the whole image into memory at once. */ extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr, png_bytepp image)); #endif /* write a row of image data */ extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr, png_bytep row)); /* write a few rows of image data */ extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr, png_bytepp row, png_uint_32 num_rows)); /* write the image data */ extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr, png_bytepp image)); /* writes the end of the PNG file. */ extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr, png_infop info_ptr)); #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED /* read the end of the PNG file. */ extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr, png_infop info_ptr)); #endif /* free any memory associated with the png_info_struct */ extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr, png_infopp info_ptr_ptr)); /* free any memory associated with the png_struct and the png_info_structs */ extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); /* free all memory used by the read (old method - NOT DLL EXPORTED) */ extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)); /* free any memory associated with the png_struct and the png_info_structs */ extern PNG_EXPORT(void,png_destroy_write_struct) PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)); /* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ extern void png_write_destroy PNGARG((png_structp png_ptr)); /* set the libpng method of handling chunk CRC errors */ extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr, int crit_action, int ancil_action)); /* Values for png_set_crc_action() to say how to handle CRC errors in * ancillary and critical chunks, and whether to use the data contained * therein. Note that it is impossible to "discard" data in a critical * chunk. For versions prior to 0.90, the action was always error/quit, * whereas in version 0.90 and later, the action for CRC errors in ancillary * chunks is warn/discard. These values should NOT be changed. * * value action:critical action:ancillary */ #define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ #define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ #define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ #define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ #define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ #define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ /* These functions give the user control over the scan-line filtering in * libpng and the compression methods used by zlib. These functions are * mainly useful for testing, as the defaults should work with most users. * Those users who are tight on memory or want faster performance at the * expense of compression can modify them. See the compression library * header file (zlib.h) for an explination of the compression functions. */ /* set the filtering method(s) used by libpng. Currently, the only valid * value for "method" is 0. */ extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method, int filters)); /* Flags for png_set_filter() to say which filters to use. The flags * are chosen so that they don't conflict with real filter types * below, in case they are supplied instead of the #defined constants. * These values should NOT be changed. */ #define PNG_NO_FILTERS 0x00 #define PNG_FILTER_NONE 0x08 #define PNG_FILTER_SUB 0x10 #define PNG_FILTER_UP 0x20 #define PNG_FILTER_AVG 0x40 #define PNG_FILTER_PAETH 0x80 #define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ PNG_FILTER_AVG | PNG_FILTER_PAETH) /* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. * These defines should NOT be changed. */ #define PNG_FILTER_VALUE_NONE 0 #define PNG_FILTER_VALUE_SUB 1 #define PNG_FILTER_VALUE_UP 2 #define PNG_FILTER_VALUE_AVG 3 #define PNG_FILTER_VALUE_PAETH 4 #define PNG_FILTER_VALUE_LAST 5 #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */ /* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ * defines, either the default (minimum-sum-of-absolute-differences), or * the experimental method (weighted-minimum-sum-of-absolute-differences). * * Weights are factors >= 1.0, indicating how important it is to keep the * filter type consistent between rows. Larger numbers mean the current * filter is that many times as likely to be the same as the "num_weights" * previous filters. This is cumulative for each previous row with a weight. * There needs to be "num_weights" values in "filter_weights", or it can be * NULL if the weights aren't being specified. Weights have no influence on * the selection of the first row filter. Well chosen weights can (in theory) * improve the compression for a given image. * * Costs are factors >= 1.0 indicating the relative decoding costs of a * filter type. Higher costs indicate more decoding expense, and are * therefore less likely to be selected over a filter with lower computational * costs. There needs to be a value in "filter_costs" for each valid filter * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't * setting the costs. Costs try to improve the speed of decompression without * unduly increasing the compressed image size. * * A negative weight or cost indicates the default value is to be used, and * values in the range [0.0, 1.0) indicate the value is to remain unchanged. * The default values for both weights and costs are currently 1.0, but may * change if good general weighting/cost heuristics can be found. If both * the weights and costs are set to 1.0, this degenerates the WEIGHTED method * to the UNWEIGHTED method, but with added encoding time/computation. */ #ifdef PNG_FLOATING_POINT_SUPPORTED extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr, int heuristic_method, int num_weights, png_doublep filter_weights, png_doublep filter_costs)); #endif #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ /* Heuristic used for row filter selection. These defines should NOT be * changed. */ #define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ #define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ #define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ #define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ /* Set the library compression level. Currently, valid values range from * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 * (0 - no compression, 9 - "maximal" compression). Note that tests have * shown that zlib compression levels 3-6 usually perform as well as level 9 * for PNG images, and do considerably fewer caclulations. In the future, * these values may not correspond directly to the zlib compression levels. */ extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr, int level)); extern PNG_EXPORT(void,png_set_compression_mem_level) PNGARG((png_structp png_ptr, int mem_level)); extern PNG_EXPORT(void,png_set_compression_strategy) PNGARG((png_structp png_ptr, int strategy)); extern PNG_EXPORT(void,png_set_compression_window_bits) PNGARG((png_structp png_ptr, int window_bits)); extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr, int method)); /* These next functions are called for input/output, memory, and error * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, * and call standard C I/O routines such as fread(), fwrite(), and * fprintf(). These functions can be made to use other I/O routines * at run time for those applications that need to handle I/O in a * different manner by calling png_set_???_fn(). See libpng.txt for * more information. */ #if !defined(PNG_NO_STDIO) /* Initialize the input/output for the PNG file to the default functions. */ extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp)); #endif /* Replace the (error and abort), and warning functions with user * supplied functions. If no messages are to be printed you must still * write and use replacement functions. The replacement error_fn should * still do a longjmp to the last setjmp location if you are using this * method of error handling. If error_fn or warning_fn is NULL, the * default function will be used. */ extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); /* Return the user pointer associated with the error functions */ extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr)); /* Replace the default data output functions with a user supplied one(s). * If buffered output is not used, then output_flush_fn can be set to NULL. * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time * output_flush_fn will be ignored (and thus can be NULL). */ extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr, png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); /* Replace the default data input function with a user supplied one. */ extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn)); /* Return the user pointer associated with the I/O functions */ extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr, png_read_status_ptr read_row_fn)); extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr, png_write_status_ptr write_row_fn)); #ifdef PNG_USER_MEM_SUPPORTED /* Replace the default memory allocation functions with user supplied one(s). */ extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn)); /* Return the user pointer associated with the memory functions */ extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_LEGACY_SUPPORTED) extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp png_ptr, png_user_transform_ptr read_user_transform_fn)); #endif #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_LEGACY_SUPPORTED) extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp png_ptr, png_user_transform_ptr write_user_transform_fn)); #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_LEGACY_SUPPORTED) extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp png_ptr, png_voidp user_transform_ptr, int user_transform_depth, int user_transform_channels)); /* Return the user pointer associated with the user transform functions */ extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr) PNGARG((png_structp png_ptr)); #endif #ifdef PNG_USER_CHUNKS_SUPPORTED extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr, png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp png_ptr)); #endif #ifdef PNG_PROGRESSIVE_READ_SUPPORTED /* Sets the function callbacks for the push reader, and a pointer to a * user-defined structure available to the callback functions. */ extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr, png_voidp progressive_ptr, png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); /* returns the user pointer associated with the push read functions */ extern PNG_EXPORT(png_voidp,png_get_progressive_ptr) PNGARG((png_structp png_ptr)); /* function to be called when data becomes available */ extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr, png_infop info_ptr, png_bytep buffer, png_size_t buffer_size)); /* function that combines rows. Not very much different than the * png_combine_row() call. Is this even used????? */ extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr, png_bytep old_row, png_bytep new_row)); #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr, png_uint_32 size)); #if defined(PNG_1_0_X) # define png_malloc_warn png_malloc #else /* Added at libpng version 1.2.4 */ extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr, png_uint_32 size)); #endif /* frees a pointer allocated by png_malloc() */ extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr)); #if defined(PNG_1_0_X) /* Function to allocate memory for zlib. */ extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items, uInt size)); /* Function to free memory for zlib */ extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr)); #endif /* Free data that was allocated internally */ extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 free_me, int num)); #ifdef PNG_FREE_ME_SUPPORTED /* Reassign responsibility for freeing existing data, whether allocated * by libpng or by the application */ extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr, png_infop info_ptr, int freer, png_uint_32 mask)); #endif /* assignments for png_data_freer */ #define PNG_DESTROY_WILL_FREE_DATA 1 #define PNG_SET_WILL_FREE_DATA 1 #define PNG_USER_WILL_FREE_DATA 2 /* Flags for png_ptr->free_me and info_ptr->free_me */ #define PNG_FREE_HIST 0x0008 #define PNG_FREE_ICCP 0x0010 #define PNG_FREE_SPLT 0x0020 #define PNG_FREE_ROWS 0x0040 #define PNG_FREE_PCAL 0x0080 #define PNG_FREE_SCAL 0x0100 #define PNG_FREE_UNKN 0x0200 #define PNG_FREE_LIST 0x0400 #define PNG_FREE_PLTE 0x1000 #define PNG_FREE_TRNS 0x2000 #define PNG_FREE_TEXT 0x4000 #define PNG_FREE_ALL 0x7fff #define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ #ifdef PNG_USER_MEM_SUPPORTED extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr, png_uint_32 size)); extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr, png_voidp ptr)); #endif extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr, png_voidp s1, png_voidp s2, png_uint_32 size)); extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr, png_voidp s1, int value, png_uint_32 size)); #if defined(USE_FAR_KEYWORD) /* memory model conversion function */ extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr, int check)); #endif /* USE_FAR_KEYWORD */ /* Fatal error in PNG image of libpng - can't continue */ extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr, png_const_charp error_message)); /* The same, but the chunk name is prepended to the error string. */ extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr, png_const_charp error_message)); /* Non-fatal error in libpng. Can continue, but may have a problem. */ extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr, png_const_charp warning_message)); /* Non-fatal error in libpng, chunk name is prepended to message. */ extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr, png_const_charp warning_message)); /* The png_set_ functions are for storing values in the png_info_struct. * Similarly, the png_get_ calls are used to read values from the * png_info_struct, either storing the parameters in the passed variables, or * setting pointers into the png_info_struct where the data is stored. The * png_get_ functions return a non-zero value if the data was available * in info_ptr, or return zero and do not change any of the parameters if the * data was not available. * * These functions should be used instead of directly accessing png_info * to avoid problems with future changes in the size and internal layout of * png_info_struct. */ /* Returns "flag" if chunk data is valid in info_ptr. */ extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)); /* Returns number of bytes needed to hold a transformed row. */ extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr, png_infop info_ptr)); #if defined(PNG_INFO_IMAGE_SUPPORTED) /* Returns row_pointers, which is an array of pointers to scanlines that was returned from png_read_png(). */ extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr, png_infop info_ptr)); /* Set row_pointers, which is an array of pointers to scanlines for use by png_write_png(). */ extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)); #endif /* Returns number of color channels in image. */ extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr, png_infop info_ptr)); #ifdef PNG_EASY_ACCESS_SUPPORTED /* Returns image width in pixels. */ extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp png_ptr, png_infop info_ptr)); /* Returns image height in pixels. */ extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp png_ptr, png_infop info_ptr)); /* Returns image bit_depth. */ extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp png_ptr, png_infop info_ptr)); /* Returns image color_type. */ extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp png_ptr, png_infop info_ptr)); /* Returns image filter_type. */ extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp png_ptr, png_infop info_ptr)); /* Returns image interlace_type. */ extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp png_ptr, png_infop info_ptr)); /* Returns image compression_type. */ extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp png_ptr, png_infop info_ptr)); /* Returns image resolution in pixels per meter, from pHYs chunk data. */ extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp png_ptr, png_infop info_ptr)); extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp png_ptr, png_infop info_ptr)); extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp png_ptr, png_infop info_ptr)); /* Returns pixel aspect ratio, computed from pHYs chunk data. */ #ifdef PNG_FLOATING_POINT_SUPPORTED extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp png_ptr, png_infop info_ptr)); #endif /* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp png_ptr, png_infop info_ptr)); extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp png_ptr, png_infop info_ptr)); extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp png_ptr, png_infop info_ptr)); extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp png_ptr, png_infop info_ptr)); #endif /* PNG_EASY_ACCESS_SUPPORTED */ /* Returns pointer to signature string read from PNG header */ extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr, png_infop info_ptr)); #if defined(PNG_bKGD_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr, png_infop info_ptr, png_color_16p *background)); #endif #if defined(PNG_bKGD_SUPPORTED) extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr, png_infop info_ptr, png_color_16p background)); #endif #if defined(PNG_cHRM_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr, png_infop info_ptr, double *white_x, double *white_y, double *red_x, double *red_y, double *green_x, double *green_y, double *blue_x, double *blue_y)); #endif #ifdef PNG_FIXED_POINT_SUPPORTED extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr, png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y, png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point *int_blue_x, png_fixed_point *int_blue_y)); #endif #endif #if defined(PNG_cHRM_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr, png_infop info_ptr, double white_x, double white_y, double red_x, double red_y, double green_x, double green_y, double blue_x, double blue_y)); #endif #ifdef PNG_FIXED_POINT_SUPPORTED extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr, png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y, png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, png_fixed_point int_blue_y)); #endif #endif #if defined(PNG_gAMA_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr, png_infop info_ptr, double *file_gamma)); #endif extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr, png_infop info_ptr, png_fixed_point *int_file_gamma)); #endif #if defined(PNG_gAMA_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr, png_infop info_ptr, double file_gamma)); #endif extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr, png_infop info_ptr, png_fixed_point int_file_gamma)); #endif #if defined(PNG_hIST_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)); #endif #if defined(PNG_hIST_SUPPORTED) extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)); #endif extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 *width, png_uint_32 *height, int *bit_depth, int *color_type, int *interlace_method, int *compression_method, int *filter_method)); extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, int interlace_method, int compression_method, int filter_method)); #if defined(PNG_oFFs_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr, png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)); #endif #if defined(PNG_oFFs_SUPPORTED) extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr, png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y, int unit_type)); #endif #if defined(PNG_pCAL_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr, png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, png_charp *units, png_charpp *params)); #endif #if defined(PNG_pCAL_SUPPORTED) extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr, png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)); #endif #if defined(PNG_pHYs_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); #endif #if defined(PNG_pHYs_SUPPORTED) extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); #endif extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr, png_infop info_ptr, png_colorp *palette, int *num_palette)); extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr, png_infop info_ptr, png_colorp palette, int num_palette)); #if defined(PNG_sBIT_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)); #endif #if defined(PNG_sBIT_SUPPORTED) extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr, png_infop info_ptr, png_color_8p sig_bit)); #endif #if defined(PNG_sRGB_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr, png_infop info_ptr, int *intent)); #endif #if defined(PNG_sRGB_SUPPORTED) extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr, png_infop info_ptr, int intent)); extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr, png_infop info_ptr, int intent)); #endif #if defined(PNG_iCCP_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr, png_infop info_ptr, png_charpp name, int *compression_type, png_charpp profile, png_uint_32 *proflen)); /* Note to maintainer: profile should be png_bytepp */ #endif #if defined(PNG_iCCP_SUPPORTED) extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr, png_infop info_ptr, png_charp name, int compression_type, png_charp profile, png_uint_32 proflen)); /* Note to maintainer: profile should be png_bytep */ #endif #if defined(PNG_sPLT_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr, png_infop info_ptr, png_sPLT_tpp entries)); #endif #if defined(PNG_sPLT_SUPPORTED) extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr, png_infop info_ptr, png_sPLT_tp entries, int nentries)); #endif #if defined(PNG_TEXT_SUPPORTED) /* png_get_text also returns the number of text chunks in *num_text */ extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr, int *num_text)); #endif /* * Note while png_set_text() will accept a structure whose text, * language, and translated keywords are NULL pointers, the structure * returned by png_get_text will always contain regular * zero-terminated C strings. They might be empty strings but * they will never be NULL pointers. */ #if defined(PNG_TEXT_SUPPORTED) extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, int num_text)); #endif #if defined(PNG_tIME_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)); #endif #if defined(PNG_tIME_SUPPORTED) extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr, png_infop info_ptr, png_timep mod_time)); #endif #if defined(PNG_tRNS_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr, png_infop info_ptr, png_bytep *trans, int *num_trans, png_color_16p *trans_values)); #endif #if defined(PNG_tRNS_SUPPORTED) extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr, png_infop info_ptr, png_bytep trans, int num_trans, png_color_16p trans_values)); #endif #if defined(PNG_tRNS_SUPPORTED) #endif #if defined(PNG_sCAL_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr, png_infop info_ptr, int *unit, double *width, double *height)); #else #ifdef PNG_FIXED_POINT_SUPPORTED extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr, png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight)); #endif #endif #endif /* PNG_sCAL_SUPPORTED */ #if defined(PNG_sCAL_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr, png_infop info_ptr, int unit, double width, double height)); #endif #ifdef PNG_FIXED_POINT_SUPPORTED extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr, png_infop info_ptr, int unit, png_charp swidth, png_charp sheight)); #endif #endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) /* provide a list of chunks and how they are to be handled, if the built-in handling or default unknown chunk handling is not desired. Any chunks not listed will be handled in the default manner. The IHDR and IEND chunks must not be listed. keep = 0: follow default behavour = 1: do not keep = 2: keep only if safe-to-copy = 3: keep even if unsafe-to-copy */ extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp png_ptr, int keep, png_bytep chunk_list, int num_chunks)); extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr, png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)); extern PNG_EXPORT(void, png_set_unknown_chunk_location) PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location)); extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp png_ptr, png_infop info_ptr, png_unknown_chunkpp entries)); #endif #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep chunk_name)); #endif /* Png_free_data() will turn off the "valid" flag for anything it frees. If you need to turn it off for a chunk that your application has freed, you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */ extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr, png_infop info_ptr, int mask)); #if defined(PNG_INFO_IMAGE_SUPPORTED) /* The "params" pointer is currently not used and is for future expansion. */ extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr, png_infop info_ptr, int transforms, png_voidp params)); extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr, png_infop info_ptr, int transforms, png_voidp params)); #endif /* Define PNG_DEBUG at compile time for debugging information. Higher * numbers for PNG_DEBUG mean more debugging information. This has * only been added since version 0.95 so it is not implemented throughout * libpng yet, but more support will be added as needed. */ #ifdef PNG_DEBUG #if (PNG_DEBUG > 0) #if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) #include #if (PNG_DEBUG > 1) #define png_debug(l,m) _RPT0(_CRT_WARN,m) #define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m,p1) #define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2) #endif #else /* PNG_DEBUG_FILE || !_MSC_VER */ #ifndef PNG_DEBUG_FILE #define PNG_DEBUG_FILE stderr #endif /* PNG_DEBUG_FILE */ #if (PNG_DEBUG > 1) #define png_debug(l,m) \ { \ int num_tabs=l; \ fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ } #define png_debug1(l,m,p1) \ { \ int num_tabs=l; \ fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ } #define png_debug2(l,m,p1,p2) \ { \ int num_tabs=l; \ fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ } #endif /* (PNG_DEBUG > 1) */ #endif /* _MSC_VER */ #endif /* (PNG_DEBUG > 0) */ #endif /* PNG_DEBUG */ #ifndef png_debug #define png_debug(l, m) #endif #ifndef png_debug1 #define png_debug1(l, m, p1) #endif #ifndef png_debug2 #define png_debug2(l, m, p1, p2) #endif extern PNG_EXPORT(png_bytep,png_sig_bytes) PNGARG((void)); extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr)); #ifdef PNG_MNG_FEATURES_SUPPORTED extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp png_ptr, png_uint_32 mng_features_permitted)); #endif /* For use in png_set_keep_unknown, added to version 1.2.6 */ #define PNG_HANDLE_CHUNK_AS_DEFAULT 0 #define PNG_HANDLE_CHUNK_NEVER 1 #define PNG_HANDLE_CHUNK_IF_SAFE 2 #define PNG_HANDLE_CHUNK_ALWAYS 3 /* Added to version 1.2.0 */ #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) #define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */ #define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */ #define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04 #define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08 #define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10 #define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20 #define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40 #define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80 #define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */ #define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ | PNG_ASM_FLAG_MMX_READ_INTERLACE \ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ) #define PNG_MMX_WRITE_FLAGS ( 0 ) #define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \ | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \ | PNG_MMX_READ_FLAGS \ | PNG_MMX_WRITE_FLAGS ) #define PNG_SELECT_READ 1 #define PNG_SELECT_WRITE 2 #if !defined(PNG_1_0_X) /* pngget.c */ extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask) PNGARG((int flag_select, int *compilerID)); /* pngget.c */ extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask) PNGARG((int flag_select)); /* pngget.c */ extern PNG_EXPORT(png_uint_32,png_get_asm_flags) PNGARG((png_structp png_ptr)); /* pngget.c */ extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold) PNGARG((png_structp png_ptr)); /* pngget.c */ extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold) PNGARG((png_structp png_ptr)); /* pngset.c */ extern PNG_EXPORT(void,png_set_asm_flags) PNGARG((png_structp png_ptr, png_uint_32 asm_flags)); /* pngset.c */ extern PNG_EXPORT(void,png_set_mmx_thresholds) PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold, png_uint_32 mmx_rowbytes_threshold)); #endif /* PNG_1_0_X */ #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ #if !defined(PNG_1_0_X) /* png.c, pnggccrd.c, or pngvcrd.c */ extern PNG_EXPORT(int,png_mmx_support) PNGARG((void)); /* Strip the prepended error numbers ("#nnn ") from error and warning * messages before passing them to the error or warning handler. */ #ifdef PNG_ERROR_NUMBERS_SUPPORTED extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp png_ptr, png_uint_32 strip_mode)); #endif #endif /* PNG_1_0_X */ /* Added at libpng-1.2.6 */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max)); extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp png_ptr)); #endif /* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */ #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED /* With these routines we avoid an integer divide, which will be slower on * most machines. However, it does take more operations than the corresponding * divide method, so it may be slower on a few RISC systems. There are two * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. * * Note that the rounding factors are NOT supposed to be the same! 128 and * 32768 are correct for the NODIV code; 127 and 32767 are correct for the * standard method. * * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] */ /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ # define png_composite(composite, fg, alpha, bg) \ { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \ + (png_uint_16)(bg)*(png_uint_16)(255 - \ (png_uint_16)(alpha)) + (png_uint_16)128); \ (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } # define png_composite_16(composite, fg, alpha, bg) \ { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \ + (png_uint_32)(bg)*(png_uint_32)(65535L - \ (png_uint_32)(alpha)) + (png_uint_32)32768L); \ (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } #else /* standard method using integer division */ # define png_composite(composite, fg, alpha, bg) \ (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ (png_uint_16)127) / 255) # define png_composite_16(composite, fg, alpha, bg) \ (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \ (png_uint_32)32767) / (png_uint_32)65535L) #endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ /* These next functions are used internally in the code. They generally * shouldn't be used unless you are writing code to add or replace some * functionality in libpng. More information about most functions can * be found in the files where the functions are located. */ #if defined(PNG_INTERNAL) /* Various modes of operation. Note that after an init, mode is set to * zero automatically when the structure is created. */ #define PNG_HAVE_IHDR 0x01 #define PNG_HAVE_PLTE 0x02 #define PNG_HAVE_IDAT 0x04 #define PNG_AFTER_IDAT 0x08 #define PNG_HAVE_IEND 0x10 #define PNG_HAVE_gAMA 0x20 #define PNG_HAVE_cHRM 0x40 #define PNG_HAVE_sRGB 0x80 #define PNG_HAVE_CHUNK_HEADER 0x100 #define PNG_WROTE_tIME 0x200 #define PNG_WROTE_INFO_BEFORE_PLTE 0x400 #define PNG_BACKGROUND_IS_GRAY 0x800 #define PNG_HAVE_PNG_SIGNATURE 0x1000 /* flags for the transformations the PNG library does on the image data */ #define PNG_BGR 0x0001 #define PNG_INTERLACE 0x0002 #define PNG_PACK 0x0004 #define PNG_SHIFT 0x0008 #define PNG_SWAP_BYTES 0x0010 #define PNG_INVERT_MONO 0x0020 #define PNG_DITHER 0x0040 #define PNG_BACKGROUND 0x0080 #define PNG_BACKGROUND_EXPAND 0x0100 /* 0x0200 unused */ #define PNG_16_TO_8 0x0400 #define PNG_RGBA 0x0800 #define PNG_EXPAND 0x1000 #define PNG_GAMMA 0x2000 #define PNG_GRAY_TO_RGB 0x4000 #define PNG_FILLER 0x8000L #define PNG_PACKSWAP 0x10000L #define PNG_SWAP_ALPHA 0x20000L #define PNG_STRIP_ALPHA 0x40000L #define PNG_INVERT_ALPHA 0x80000L #define PNG_USER_TRANSFORM 0x100000L #define PNG_RGB_TO_GRAY_ERR 0x200000L #define PNG_RGB_TO_GRAY_WARN 0x400000L #define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */ /* 0x800000L Unused */ #define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */ /* 0x2000000L unused */ /* 0x4000000L unused */ /* 0x8000000L unused */ /* 0x10000000L unused */ /* 0x20000000L unused */ /* 0x40000000L unused */ /* flags for png_create_struct */ #define PNG_STRUCT_PNG 0x0001 #define PNG_STRUCT_INFO 0x0002 /* Scaling factor for filter heuristic weighting calculations */ #define PNG_WEIGHT_SHIFT 8 #define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT)) #define PNG_COST_SHIFT 3 #define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT)) /* flags for the png_ptr->flags rather than declaring a byte for each one */ #define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 #define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002 #define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004 #define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008 #define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010 #define PNG_FLAG_ZLIB_FINISHED 0x0020 #define PNG_FLAG_ROW_INIT 0x0040 #define PNG_FLAG_FILLER_AFTER 0x0080 #define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 #define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 #define PNG_FLAG_CRC_CRITICAL_USE 0x0400 #define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 #define PNG_FLAG_FREE_PLTE 0x1000 #define PNG_FLAG_FREE_TRNS 0x2000 #define PNG_FLAG_FREE_HIST 0x4000 #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L #define PNG_FLAG_LIBRARY_MISMATCH 0x20000L #define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L #define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L #define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L #define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */ #define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */ /* 0x800000L unused */ /* 0x1000000L unused */ /* 0x2000000L unused */ /* 0x4000000L unused */ /* 0x8000000L unused */ /* 0x10000000L unused */ /* 0x20000000L unused */ /* 0x40000000L unused */ #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ PNG_FLAG_CRC_ANCILLARY_NOWARN) #define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \ PNG_FLAG_CRC_CRITICAL_IGNORE) #define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ PNG_FLAG_CRC_CRITICAL_MASK) /* save typing and make code easier to understand */ #define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ abs((int)((c1).green) - (int)((c2).green)) + \ abs((int)((c1).blue) - (int)((c2).blue))) /* Added to libpng-1.2.6 JB */ #define PNG_ROWBYTES(pixel_bits, width) \ ((pixel_bits) >= 8 ? \ ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \ (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) ) /* PNG_OUT_OF_RANGE returns true if value is outside the range ideal-delta..ideal+delta. Each argument is evaluated twice. "ideal" and "delta" should be constants, normally simple integers, "value" a variable. Added to libpng-1.2.6 JB */ #define PNG_OUT_OF_RANGE(value, ideal, delta) \ ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) /* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ #if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) /* place to hold the signature string for a PNG file. */ #ifdef PNG_USE_GLOBAL_ARRAYS PNG_EXPORT_VAR (const png_byte FARDATA) png_sig[8]; #else #define png_sig png_sig_bytes(NULL) #endif #endif /* PNG_NO_EXTERN */ /* Constant strings for known chunk types. If you need to add a chunk, * define the name here, and add an invocation of the macro in png.c and * wherever it's needed. */ #define PNG_IHDR const png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} #define PNG_IDAT const png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} #define PNG_IEND const png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} #define PNG_PLTE const png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} #define PNG_bKGD const png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} #define PNG_cHRM const png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} #define PNG_gAMA const png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} #define PNG_hIST const png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} #define PNG_iCCP const png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} #define PNG_iTXt const png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} #define PNG_oFFs const png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} #define PNG_pCAL const png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} #define PNG_sCAL const png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} #define PNG_pHYs const png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} #define PNG_sBIT const png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} #define PNG_sPLT const png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} #define PNG_sRGB const png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} #define PNG_tEXt const png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} #define PNG_tIME const png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} #define PNG_tRNS const png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} #define PNG_zTXt const png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} #ifdef PNG_USE_GLOBAL_ARRAYS PNG_EXPORT_VAR (const png_byte FARDATA) png_IHDR[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_IDAT[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_IEND[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_PLTE[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_bKGD[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_cHRM[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_gAMA[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_hIST[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_iCCP[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_iTXt[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_oFFs[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_pCAL[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_sCAL[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_pHYs[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_sBIT[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_sPLT[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_sRGB[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_tEXt[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_tIME[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_tRNS[5]; PNG_EXPORT_VAR (const png_byte FARDATA) png_zTXt[5]; #endif /* PNG_USE_GLOBAL_ARRAYS */ /* Inline macros to do direct reads of bytes from the input buffer. These * require that you are using an architecture that uses PNG byte ordering * (MSB first) and supports unaligned data storage. I think that PowerPC * in big-endian mode and 680x0 are the only ones that will support this. * The x86 line of processors definitely do not. The png_get_int_32() * routine also assumes we are using two's complement format for negative * values, which is almost certainly true. */ #if defined(PNG_READ_BIG_ENDIAN_SUPPORTED) # if defined(PNG_pCAL_SUPPORTED) || defined(PNG_oFFs_SUPPORTED) # define png_get_int_32(buf) ( *((png_int_32p) (buf))) # endif # define png_get_uint_32(buf) ( *((png_uint_32p) (buf))) # define png_get_uint_16(buf) ( *((png_uint_16p) (buf))) #else # if defined(PNG_pCAL_SUPPORTED) || defined(PNG_oFFs_SUPPORTED) PNG_EXTERN png_int_32 png_get_int_32 PNGARG((png_bytep buf)); # endif PNG_EXTERN png_uint_32 png_get_uint_32 PNGARG((png_bytep buf)); PNG_EXTERN png_uint_16 png_get_uint_16 PNGARG((png_bytep buf)); #endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */ PNG_EXTERN png_uint_32 png_get_uint_31 PNGARG((png_structp png_ptr, png_bytep buf)); /* Initialize png_ptr struct for reading, and allocate any other memory. * (old interface - DEPRECATED - use png_create_read_struct instead). */ extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr)); #undef png_read_init #define png_read_init(png_ptr) png_read_init_3(&png_ptr, \ PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr, png_const_charp user_png_ver, png_size_t png_struct_size)); extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr, png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t png_info_size)); /* Initialize png_ptr struct for writing, and allocate any other memory. * (old interface - DEPRECATED - use png_create_write_struct instead). */ extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr)); #undef png_write_init #define png_write_init(png_ptr) png_write_init_3(&png_ptr, \ PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr, png_const_charp user_png_ver, png_size_t png_struct_size)); extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr, png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t png_info_size)); /* Allocate memory for an internal libpng struct */ PNG_EXTERN png_voidp png_create_struct PNGARG((int type)); /* Free memory from internal libpng struct */ PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)); PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)); PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, png_free_ptr free_fn, png_voidp mem_ptr)); /* Free any memory that info_ptr points to and reset struct. */ PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, png_infop info_ptr)); #ifndef PNG_1_0_X /* Function to allocate memory for zlib. */ PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size)); /* Function to free memory for zlib */ PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); #ifdef PNG_SIZE_T /* Function to convert a sizeof an item to png_sizeof item */ PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)); #endif /* Next four functions are used internally as callbacks. PNGAPI is required * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */ PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr, png_bytep data, png_size_t length)); #ifdef PNG_PROGRESSIVE_READ_SUPPORTED PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr, png_bytep buffer, png_size_t length)); #endif PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr, png_bytep data, png_size_t length)); #if defined(PNG_WRITE_FLUSH_SUPPORTED) #if !defined(PNG_NO_STDIO) PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr)); #endif #endif #else /* PNG_1_0_X */ #ifdef PNG_PROGRESSIVE_READ_SUPPORTED PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr, png_bytep buffer, png_size_t length)); #endif #endif /* PNG_1_0_X */ /* Reset the CRC variable */ PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)); /* Write the "data" buffer to whatever output you are using. */ PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data, png_size_t length)); /* Read data from whatever input you are using into the "data" buffer */ PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, png_size_t length)); /* Read bytes into buf, and update png_ptr->crc */ PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, png_size_t length)); /* Decompress data in a chunk that uses compression */ #if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \ defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr, int comp_type, png_charp chunkdata, png_size_t chunklength, png_size_t prefix_length, png_size_t *data_length)); #endif /* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)); /* Read the CRC from the file and compare it to the libpng calculated CRC */ PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)); /* Calculate the CRC over a section of data. Note that we are only * passing a maximum of 64K on systems that have this as a memory limit, * since this is the maximum buffer size we can specify. */ PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr, png_size_t length)); #if defined(PNG_WRITE_FLUSH_SUPPORTED) PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); #endif /* Place a 32-bit number into a buffer in PNG byte order (big-endian). * The only currently known PNG chunks that use signed numbers are * the ancillary extension chunks, oFFs and pCAL. */ PNG_EXTERN void png_save_uint_32 PNGARG((png_bytep buf, png_uint_32 i)); #if defined(PNG_WRITE_pCAL_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) PNG_EXTERN void png_save_int_32 PNGARG((png_bytep buf, png_int_32 i)); #endif /* Place a 16-bit number into a buffer in PNG byte order. * The parameter is declared unsigned int, not png_uint_16, * just to avoid potential problems on pre-ANSI C compilers. */ PNG_EXTERN void png_save_uint_16 PNGARG((png_bytep buf, unsigned int i)); /* simple function to write the signature */ PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr)); /* write various chunks */ /* Write the IHDR chunk, and update the png_struct with the necessary * information. */ PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, int compression_method, int filter_method, int interlace_method)); PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)); PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, png_size_t length)); PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)); #if defined(PNG_WRITE_gAMA_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma)); #endif #ifdef PNG_FIXED_POINT_SUPPORTED PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point file_gamma)); #endif #endif #if defined(PNG_WRITE_sBIT_SUPPORTED) PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit, int color_type)); #endif #if defined(PNG_WRITE_cHRM_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr, double white_x, double white_y, double red_x, double red_y, double green_x, double green_y, double blue_x, double blue_y)); #endif #ifdef PNG_FIXED_POINT_SUPPORTED PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y, png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, png_fixed_point int_blue_y)); #endif #endif #if defined(PNG_WRITE_sRGB_SUPPORTED) PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, int intent)); #endif #if defined(PNG_WRITE_iCCP_SUPPORTED) PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, png_charp name, int compression_type, png_charp profile, int proflen)); /* Note to maintainer: profile should be png_bytep */ #endif #if defined(PNG_WRITE_sPLT_SUPPORTED) PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, png_sPLT_tp palette)); #endif #if defined(PNG_WRITE_tRNS_SUPPORTED) PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans, png_color_16p values, int number, int color_type)); #endif #if defined(PNG_WRITE_bKGD_SUPPORTED) PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, png_color_16p values, int color_type)); #endif #if defined(PNG_WRITE_hIST_SUPPORTED) PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist, int num_hist)); #endif #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr, png_charp key, png_charpp new_key)); #endif #if defined(PNG_WRITE_tEXt_SUPPORTED) PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key, png_charp text, png_size_t text_len)); #endif #if defined(PNG_WRITE_zTXt_SUPPORTED) PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key, png_charp text, png_size_t text_len, int compression)); #endif #if defined(PNG_WRITE_iTXt_SUPPORTED) PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, int compression, png_charp key, png_charp lang, png_charp lang_key, png_charp text)); #endif #if defined(PNG_TEXT_SUPPORTED) /* Added at version 1.0.14 and 1.2.4 */ PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, int num_text)); #endif #if defined(PNG_WRITE_oFFs_SUPPORTED) PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, int unit_type)); #endif #if defined(PNG_WRITE_pCAL_SUPPORTED) PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)); #endif #if defined(PNG_WRITE_pHYs_SUPPORTED) PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr, png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, int unit_type)); #endif #if defined(PNG_WRITE_tIME_SUPPORTED) PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, png_timep mod_time)); #endif #if defined(PNG_WRITE_sCAL_SUPPORTED) #if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr, int unit, double width, double height)); #else #ifdef PNG_FIXED_POINT_SUPPORTED PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, int unit, png_charp width, png_charp height)); #endif #endif #endif /* Called when finished processing a row of data */ PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); /* Internal use only. Called before first row of data */ PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); #if defined(PNG_READ_GAMMA_SUPPORTED) PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr)); #endif /* combine a row of data, dealing with alpha, etc. if requested */ PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, int mask)); #if defined(PNG_READ_INTERLACING_SUPPORTED) /* expand an interlaced row */ /* OLD pre-1.0.9 interface: PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, png_bytep row, int pass, png_uint_32 transformations)); */ PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)); #endif /* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ #if defined(PNG_WRITE_INTERLACING_SUPPORTED) /* grab pixels out of a row for an interlaced pass */ PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, png_bytep row, int pass)); #endif /* unfilter a row */ PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr, png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter)); /* Choose the best filter to use and filter the row data */ PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, png_row_infop row_info)); /* Write out the filtered row. */ PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr, png_bytep filtered_row)); /* finish a row while reading, dealing with interlacing passes, etc. */ PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); /* initialize the row buffers, etc. */ PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)); /* optional call to update the users info structure */ PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, png_infop info_ptr)); /* these are the functions that do the transformations */ #if defined(PNG_READ_FILLER_SUPPORTED) PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, png_bytep row, png_uint_32 filler, png_uint_32 flags)); #endif #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ defined(PNG_READ_STRIP_ALPHA_SUPPORTED) PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info, png_bytep row, png_uint_32 flags)); #endif #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_READ_PACK_SUPPORTED) PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_READ_SHIFT_SUPPORTED) PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row, png_color_8p sig_bits)); #endif #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_READ_DITHER_SUPPORTED) PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info, png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup)); # if defined(PNG_CORRECT_PALETTE_SUPPORTED) PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr, png_colorp palette, int num_palette)); # endif #endif #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_WRITE_PACK_SUPPORTED) PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)); #endif #if defined(PNG_WRITE_SHIFT_SUPPORTED) PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row, png_color_8p bit_depth)); #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) #if defined(PNG_READ_GAMMA_SUPPORTED) PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, png_color_16p trans_values, png_color_16p background, png_color_16p background_1, png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, png_uint_16pp gamma_16_to_1, int gamma_shift)); #else PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, png_color_16p trans_values, png_color_16p background)); #endif #endif #if defined(PNG_READ_GAMMA_SUPPORTED) PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row, png_bytep gamma_table, png_uint_16pp gamma_16_table, int gamma_shift)); #endif #if defined(PNG_READ_EXPAND_SUPPORTED) PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, png_bytep row, png_colorp palette, png_bytep trans, int num_trans)); PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, png_bytep row, png_color_16p trans_value)); #endif /* The following decodes the appropriate chunks, and does error correction, * then calls the appropriate callback for the chunk if it is valid. */ /* decode the IHDR chunk */ PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #if defined(PNG_READ_bKGD_SUPPORTED) PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_cHRM_SUPPORTED) PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_gAMA_SUPPORTED) PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_hIST_SUPPORTED) PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_iCCP_SUPPORTED) extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif /* PNG_READ_iCCP_SUPPORTED */ #if defined(PNG_READ_iTXt_SUPPORTED) PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_oFFs_SUPPORTED) PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_pCAL_SUPPORTED) PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_pHYs_SUPPORTED) PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_sBIT_SUPPORTED) PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_sCAL_SUPPORTED) PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_sPLT_SUPPORTED) extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif /* PNG_READ_sPLT_SUPPORTED */ #if defined(PNG_READ_sRGB_SUPPORTED) PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_tEXt_SUPPORTED) PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_tIME_SUPPORTED) PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_tRNS_SUPPORTED) PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif #if defined(PNG_READ_zTXt_SUPPORTED) PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, png_bytep chunk_name)); /* handle the transformations for reading and writing */ PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr)); PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr)); PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr)); #ifdef PNG_PROGRESSIVE_READ_SUPPORTED PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr, png_infop info_ptr)); PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr, png_infop info_ptr)); PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)); PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, png_uint_32 length)); PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)); PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)); PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, png_bytep buffer, png_size_t buffer_length)); PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)); PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr, png_bytep buffer, png_size_t buffer_length)); PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)); PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr, png_infop info_ptr)); PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr, png_infop info_ptr)); PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row)); PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr, png_infop info_ptr)); PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr, png_infop info_ptr)); PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr)); #if defined(PNG_READ_tEXt_SUPPORTED) PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr)); #endif #if defined(PNG_READ_zTXt_SUPPORTED) PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr)); #endif #if defined(PNG_READ_iTXt_SUPPORTED) PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr)); #endif #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ #ifdef PNG_MNG_FEATURES_SUPPORTED PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info, png_bytep row)); PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) /* png.c */ /* PRIVATE */ PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr)); #endif /* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ #endif /* PNG_INTERNAL */ #ifdef __cplusplus } #endif #endif /* PNG_VERSION_INFO_ONLY */ /* do not put anything past this line */ #endif /* PNG_H */ syslinux-legacy-3.63+dfsg/com32/include/minmax.h0000664000175000017500000000327310777447272020230 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #ifndef _MINMAX_H #define _MINMAX_H /* * minmax.h: Type-independent safe min/max macros */ #define min(x,y) ({ __typeof(x) xx = (x); \ __typeof(y) yy = (y); \ xx < yy ? xx : yy; }) #define max(x,y) ({ __typeof(x) xx = (x); \ __typeof(y) yy = (y); \ xx > yy ? xx : yy; }) #endif /* _MINMAX_H */ syslinux-legacy-3.63+dfsg/com32/include/netinet/0000775000175000017500000000000010777447272020227 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/include/netinet/in.h0000664000175000017500000000163410777447272021012 0ustar evanevan#ifndef _NETINET_IN_H #define _NETINET_IN_H /* COM32 will be running on an i386 platform */ #include static inline uint16_t __htons(uint16_t v) { return ((v) << 8) | ((v) >> 8); } #define htons(x) __htons(x) #define ntohs(x) __htons(x) static inline uint32_t __htonl(uint32_t v) { if ( __builtin_constant_p(v) ) { return (((v) & 0x000000ff) << 24) | (((v) & 0x0000ff00) << 8) | (((v) & 0x00ff0000) >> 8) | (((v) & 0xff000000) >> 24); } else { asm("xchgb %h0,%b0 ; roll $16,%0 ; xchgb %h0,%b0" : "+abcd" (v)); return v; } } #define htonl(x) __htonl(x) #define ntohl(x) __htonl(x) static inline uint64_t __htonq(uint64_t v) { return ((uint64_t) __htonl(v) << 32) | __htonl(v >> 32); } #define htonq(x) __htonq(x) #define ntohq(x) __htonq(x) typedef uint32_t in_addr_t; typedef uint16_t in_port_t; struct in_addr { in_addr_t s_addr; }; #endif /* _NETINET_IN_H */ syslinux-legacy-3.63+dfsg/com32/include/dmi/0000775000175000017500000000000010777447272017332 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/include/dmi/dmi_base_board.h0000664000175000017500000000357510777447272022427 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef DMI_BASE_BOARD_H #define DMI_BASE_BOARD_H #include "stdbool.h" #define BASE_BOARD_MANUFACTURER_SIZE 32 #define BASE_BOARD_PRODUCT_NAME_SIZE 32 #define BASE_BOARD_VERSION_SIZE 16 #define BASE_BOARD_SERIAL_SIZE 32 #define BASE_BOARD_ASSET_TAG_SIZE 32 #define BASE_BOARD_LOCATION_SIZE 32 #define BASE_BOARD_FEATURES_SIZE 32 #define BASE_BOARD_TYPE_SIZE 32 #define BASE_BOARD_NB_ELEMENTS 5 static const char *base_board_features_strings[]={ "Board is a hosting board", /* 0 */ "Board requires at least one daughter board", "Board is removable", "Board is replaceable", "Board is hot swappable" /* 4 */ }; /* this struct have BASE_BOARD_NB_ELEMENTS */ /* each bool is associated to the relevant message above */ typedef struct { bool hosting; bool board_needs_daughter; bool removable; bool replaceable; bool hot_swappable; } __attribute__((__packed__)) s_base_board_features; typedef struct { char manufacturer[BASE_BOARD_MANUFACTURER_SIZE]; char product_name[BASE_BOARD_PRODUCT_NAME_SIZE]; char version[BASE_BOARD_VERSION_SIZE]; char serial[BASE_BOARD_SERIAL_SIZE]; char asset_tag[BASE_BOARD_ASSET_TAG_SIZE]; char location[BASE_BOARD_LOCATION_SIZE]; char type[BASE_BOARD_TYPE_SIZE]; s_base_board_features features; } s_base_board; #endif syslinux-legacy-3.63+dfsg/com32/include/dmi/dmi.h0000664000175000017500000000413610777447272020260 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef DMI_H #define DMI_H #define u32 unsigned int #define u16 unsigned short #define u8 unsigned char #define PAGE_SIZE 4096 typedef struct { u32 l; u32 h; } u64; static const char *out_of_spec = ""; static const char *bad_index = ""; #define WORD(x) (u16)(*(const u16 *)(x)) #define DWORD(x) (u32)(*(const u32 *)(x)) #define QWORD(x) (*(const u64 *)(x)) #include "dmi_bios.h" #include "dmi_system.h" #include "dmi_base_board.h" #include "dmi_chassis.h" #include "dmi_processor.h" extern char display_line; #define moreprintf(...) do { display_line++; if (display_line == 24) { char tempbuf[10]; display_line=0; printf("Press enter to continue"); fgets(tempbuf, sizeof tempbuf, stdin);} printf ( __VA_ARGS__); } while (0); typedef struct { u16 num; u16 len; u16 ver; u32 base; } dmi_table; static dmi_table dmitable; struct dmi_header { u8 type; u8 length; u16 handle; u8 *data; }; typedef struct { s_bios bios; s_system system; s_base_board base_board; s_chassis chassis; s_processor processor; } s_dmi; void to_dmi_header(struct dmi_header *h, u8 *data); void dmi_bios_runtime_size(u32 code, s_dmi *dmi); const char *dmi_string(struct dmi_header *dm, u8 s); inline int dmi_checksum(u8 *buf); void parse_dmitable(s_dmi *dmi); void dmi_decode(struct dmi_header *h, u16 ver, s_dmi *dmi); int dmi_interate(); /* dmi_utils.c */ void display_bios_characteristics(s_dmi *dmi); void display_base_board_features(s_dmi *dmi); void display_processor_flags(s_dmi *dmi); #endif syslinux-legacy-3.63+dfsg/com32/include/dmi/dmi_system.h0000664000175000017500000000231210777447272021656 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef DMI_SYSTEM_H #define DMI_SYSTEM_H #define SYSTEM_MANUFACTURER_SIZE 32 #define SYSTEM_PRODUCT_NAME_SIZE 32 #define SYSTEM_VERSION_SIZE 16 #define SYSTEM_SERIAL_SIZE 32 #define SYSTEM_UUID_SIZE 40 #define SYSTEM_WAKEUP_TYPE_SIZE 32 #define SYSTEM_SKU_NUMBER_SIZE 32 #define SYSTEM_FAMILY_SIZE 32 typedef struct { char manufacturer[SYSTEM_MANUFACTURER_SIZE]; char product_name[SYSTEM_PRODUCT_NAME_SIZE]; char version[SYSTEM_VERSION_SIZE]; char serial[SYSTEM_SERIAL_SIZE]; char uuid[SYSTEM_UUID_SIZE]; char wakeup_type[SYSTEM_WAKEUP_TYPE_SIZE]; char sku_number[SYSTEM_SKU_NUMBER_SIZE]; char family[SYSTEM_FAMILY_SIZE]; } s_system; #endif syslinux-legacy-3.63+dfsg/com32/include/dmi/dmi_chassis.h0000664000175000017500000000717610777447272022004 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef DMI_CHASSIS_H #define DMI_CHASSIS_H #define CHASSIS_MANUFACTURER_SIZE 32 #define CHASSIS_TYPE_SIZE 16 #define CHASSIS_LOCK_SIZE 16 #define CHASSIS_VERSION_SIZE 16 #define CHASSIS_SERIAL_SIZE 32 #define CHASSIS_ASSET_TAG_SIZE 32 #define CHASSIS_BOOT_UP_STATE_SIZE 32 #define CHASSIS_POWER_SUPPLY_STATE_SIZE 32 #define CHASSIS_THERMAL_STATE_SIZE 32 #define CHASSIS_SECURITY_STATUS_SIZE 32 #define CHASSIS_OEM_INFORMATION_SIZE 32 typedef struct { char manufacturer[CHASSIS_MANUFACTURER_SIZE]; char type[CHASSIS_TYPE_SIZE]; char lock[CHASSIS_LOCK_SIZE]; char version[CHASSIS_VERSION_SIZE]; char serial[CHASSIS_SERIAL_SIZE]; char asset_tag[CHASSIS_ASSET_TAG_SIZE]; char boot_up_state[CHASSIS_BOOT_UP_STATE_SIZE]; char power_supply_state[CHASSIS_POWER_SUPPLY_STATE_SIZE]; char thermal_state[CHASSIS_THERMAL_STATE_SIZE]; char security_status[CHASSIS_SECURITY_STATUS_SIZE]; char oem_information[CHASSIS_OEM_INFORMATION_SIZE]; u16 height; u16 nb_power_cords; } s_chassis; static const char *dmi_chassis_type(u8 code) { /* 3.3.4.1 */ static const char *type[]={ "Other", /* 0x01 */ "Unknown", "Desktop", "Low Profile Desktop", "Pizza Box", "Mini Tower", "Tower", "Portable", "Laptop", "Notebook", "Hand Held", "Docking Station", "All In One", "Sub Notebook", "Space-saving", "Lunch Box", "Main Server Chassis", /* master.mif says System */ "Expansion Chassis", "Sub Chassis", "Bus Expansion Chassis", "Peripheral Chassis", "RAID Chassis", "Rack Mount Chassis", "Sealed-case PC", "Multi-system" /* 0x19 */ }; if(code>=0x01 && code<=0x19) return type[code-0x01]; return out_of_spec; } static const char *dmi_chassis_lock(u8 code) { static const char *lock[]={ "Not Present", /* 0x00 */ "Present" /* 0x01 */ }; return lock[code]; } static const char *dmi_chassis_state(u8 code) { /* 3.3.4.2 */ static const char *state[]={ "Other", /* 0x01 */ "Unknown", "Safe", /* master.mif says OK */ "Warning", "Critical", "Non-recoverable" /* 0x06 */ }; if(code>=0x01 && code<=0x06) return(state[code-0x01]); return out_of_spec; } static const char *dmi_chassis_security_status(u8 code) { /* 3.3.4.3 */ static const char *status[]={ "Other", /* 0x01 */ "Unknown", "None", "External Interface Locked Out", "External Interface Enabled" /* 0x05 */ }; if(code>=0x01 && code<=0x05) return(status[code-0x01]); return out_of_spec; } #endif syslinux-legacy-3.63+dfsg/com32/include/dmi/dmi_processor.h0000664000175000017500000002242110777447272022354 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef DMI_PROCESSOR_H #define DMI_PROCESSOR_H #include "stdbool.h" #define PROCESSOR_SOCKET_DESIGNATION_SIZE 32 #define PROCESSOR_TYPE_SIZE 32 #define PROCESSOR_FAMILY_SIZE 32 #define PROCESSOR_MANUFACTURER_SIZE 64 #define PROCESSOR_VERSION_SIZE 32 #define PROCESSOR_VOLTAGE_SIZE 16 #define PROCESSOR_STATUS_SIZE 16 #define PROCESSOR_UPGRADE_SIZE 16 #define PROCESSOR_CACHE_SIZE 16 #define PROCESSOR_SERIAL_SIZE 32 #define PROCESSOR_ASSET_TAG_SIZE 32 #define PROCESSOR_PART_NUMBER_SIZE 32 #define PROCESSOR_ID_SIZE 32 #define PROCESSOR_FLAGS_ELEMENTS 32 /* Intel AP-485 revision 28, table 5 */ static const char *cpu_flags_strings[32]={ "FPU (Floating-point unit on-chip)", /* 0 */ "VME (Virtual mode extension)", "DE (Debugging extension)", "PSE (Page size extension)", "TSC (Time stamp counter)", "MSR (Model specific registers)", "PAE (Physical address extension)", "MCE (Machine check exception)", "CX8 (CMPXCHG8 instruction supported)", "APIC (On-chip APIC hardware supported)", NULL, /* 10 */ "SEP (Fast system call)", "MTRR (Memory type range registers)", "PGE (Page global enable)", "MCA (Machine check architecture)", "CMOV (Conditional move instruction supported)", "PAT (Page attribute table)", "PSE-36 (36-bit page size extension)", "PSN (Processor serial number present and enabled)", "CLFSH (CLFLUSH instruction supported)", NULL, /* 20 */ "DS (Debug store)", "ACPI (ACPI supported)", "MMX (MMX technology supported)", "FXSR (Fast floating-point save and restore)", "SSE (Streaming SIMD extensions)", "SSE2 (Streaming SIMD extensions 2)", "SS (Self-snoop)", "HTT (Hyper-threading technology)", "TM (Thermal monitor supported)", NULL, /* 30 */ "PBE (Pending break enabled)" /* 31 */ }; /* this struct have PROCESSOR_FLAGS_ELEMENTS */ /* each bool is associated to the relevant message above */ typedef struct { bool fpu; bool vme; bool de; bool pse; bool tsc; bool msr; bool pae; bool mce; bool cx8; bool apic; bool null_10; bool sep; bool mtrr; bool pge; bool mca; bool cmov; bool pat; bool pse_36; bool psn; bool clfsh; bool null_20; bool ds; bool acpi; bool mmx; bool fxsr; bool sse; bool sse2; bool ss; bool htt; bool tm; bool null_30; bool pbe; } __attribute__((__packed__)) s_cpu_flags; typedef struct { u8 type; u8 family; u8 model; u8 stepping; u8 minor_stepping; } __attribute__((__packed__)) s_signature; typedef struct { char socket_designation[PROCESSOR_SOCKET_DESIGNATION_SIZE]; char type[PROCESSOR_TYPE_SIZE]; char family[PROCESSOR_FAMILY_SIZE]; char manufacturer[PROCESSOR_MANUFACTURER_SIZE]; char version[PROCESSOR_VERSION_SIZE]; float voltage; u16 external_clock; u16 max_speed; u16 current_speed; char status[PROCESSOR_STATUS_SIZE]; char upgrade[PROCESSOR_UPGRADE_SIZE]; char cache1[PROCESSOR_CACHE_SIZE]; char cache2[PROCESSOR_CACHE_SIZE]; char cache3[PROCESSOR_CACHE_SIZE]; char serial[PROCESSOR_SERIAL_SIZE]; char asset_tag[PROCESSOR_ASSET_TAG_SIZE]; char part_number[PROCESSOR_PART_NUMBER_SIZE]; char id[PROCESSOR_ID_SIZE]; s_cpu_flags cpu_flags; s_signature signature; } s_processor; static const char *dmi_processor_type(u8 code) { /* 3.3.5.1 */ static const char *type[]={ "Other", /* 0x01 */ "Unknown", "Central Processor", "Math Processor", "DSP Processor", "Video Processor" /* 0x06 */ }; if(code>=0x01 && code<=0x06) return type[code-0x01]; return out_of_spec; } static const char *dmi_processor_family(u8 code) { /* 3.3.5.2 */ static const char *family[]={ NULL, /* 0x00 */ "Other", "Unknown", "8086", "80286", "80386", "80486", "8087", "80287", "80387", "80487", "Pentium", "Pentium Pro", "Pentium II", "Pentium MMX", "Celeron", "Pentium II Xeon", "Pentium III", "M1", "M2", NULL, /* 0x14 */ NULL, NULL, NULL, /* 0x17 */ "Duron", "K5", "K6", "K6-2", "K6-3", "Athlon", "AMD2900", "K6-2+", "Power PC", "Power PC 601", "Power PC 603", "Power PC 603+", "Power PC 604", "Power PC 620", "Power PC x704", "Power PC 750", NULL, /* 0x28 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL,/* 0x2F */ "Alpha", "Alpha 21064", "Alpha 21066", "Alpha 21164", "Alpha 21164PC", "Alpha 21164a", "Alpha 21264", "Alpha 21364", NULL, /* 0x38 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x3F */ "MIPS", "MIPS R4000", "MIPS R4200", "MIPS R4400", "MIPS R4600", "MIPS R10000", NULL, /* 0x46 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x4F */ "SPARC", "SuperSPARC", "MicroSPARC II", "MicroSPARC IIep", "UltraSPARC", "UltraSPARC II", "UltraSPARC IIi", "UltraSPARC III", "UltraSPARC IIIi", NULL, /* 0x59 */ NULL, NULL, NULL, NULL, NULL, NULL, /* 0x5F */ "68040", "68xxx", "68000", "68010", "68020", "68030", NULL, /* 0x66 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x6F */ "Hobbit", NULL, /* 0x71 */ NULL, NULL, NULL, NULL, NULL, NULL, /* 0x77 */ "Crusoe TM5000", "Crusoe TM3000", "Efficeon TM8000", NULL, /* 0x7B */ NULL, NULL, NULL, NULL, /* 0x7F */ "Weitek", NULL, /* 0x81 */ "Itanium", "Athlon 64", "Opteron", "Sempron", NULL, /* 0x86 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x8F */ "PA-RISC", "PA-RISC 8500", "PA-RISC 8000", "PA-RISC 7300LC", "PA-RISC 7200", "PA-RISC 7100LC", "PA-RISC 7100", NULL, /* 0x97 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x9F */ "V30", NULL, /* 0xA1 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0xAF */ "Pentium III Xeon", "Pentium III Speedstep", "Pentium 4", "Xeon", "AS400", "Xeon MP", "Athlon XP", "Athlon MP", "Itanium 2", "Pentium M", NULL, /* 0xBA */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0xC7 */ "IBM390", "G4", "G5", NULL, /* 0xCB */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0xF9 */ "i860", "i960", NULL, /* 0xFC */ NULL, NULL, NULL /* 0xFF */ /* master.mif has values beyond that, but they can't be used for DMI */ }; if(family[code]!=NULL) { return family[code]; } return out_of_spec; } static const char *dmi_processor_status(u8 code) { static const char *status[]={ "Unknown", /* 0x00 */ "Enabled", "Disabled By User", "Disabled By BIOS", "Idle", /* 0x04 */ "Other" /* 0x07 */ }; if(code<=0x04) return status[code]; if(code==0x07) return status[0x05]; return out_of_spec; } static const char *dmi_processor_upgrade(u8 code) { /* 3.3.5.5 */ static const char *upgrade[]={ "Other", /* 0x01 */ "Unknown", "Daughter Board", "ZIF Socket", "Replaceable Piggy Back", "None", "LIF Socket", "Slot 1", "Slot 2", "370-pin Socket", "Slot A", "Slot M", "Socket 423", "Socket A (Socket 462)", "Socket 478", "Socket 754", "Socket 940", "Socket 939" /* 0x12 */ }; if(code>=0x01 && code<=0x11) return upgrade[code-0x01]; return out_of_spec; } static void dmi_processor_cache(u16 code, const char *level, u16 ver, char *cache) { if(code==0xFFFF) { if(ver>=0x0203) sprintf(cache,"Not Provided"); else sprintf(cache,"No %s Cache", level); } else sprintf(cache,"0x%04X", code); } #endif syslinux-legacy-3.63+dfsg/com32/include/dmi/dmi_bios.h0000664000175000017500000001064210777447272021273 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef DMI_BIOS_H #define DMI_BIOS_H #include "stdbool.h" #define BIOS_VENDOR_SIZE 32 #define BIOS_VERSION_SIZE 32 #define BIOS_RELEASE_SIZE 16 #define BIOS_RUNTIME_SIZE_UNIT_SIZE 16 #define BIOS_ROM_UNIT_SIZE 16 #define BIOS_BIOS_REVISION_SIZE 16 #define BIOS_FIRMWARE_REVISION_SIZE 16 #define BIOS_CHAR_NB_ELEMENTS 28 #define BIOS_CHAR_X1_NB_ELEMENTS 8 #define BIOS_CHAR_X2_NB_ELEMENTS 3 static const char *bios_charac_strings[]={ "BIOS characteristics not supported", /* 3 */ "ISA is supported", "MCA is supported", "EISA is supported", "PCI is supported", "PC Card (PCMCIA) is supported", "PNP is supported", "APM is supported", "BIOS is upgradeable", "BIOS shadowing is allowed", "VLB is supported", "ESCD support is available", "Boot from CD is supported", "Selectable boot is supported", "BIOS ROM is socketed", "Boot from PC Card (PCMCIA) is supported", "EDD is supported", "Japanese floppy for NEC 9800 1.2 MB is supported (int 13h)", "Japanese floppy for Toshiba 1.2 MB is supported (int 13h)", "5.25\"/360 KB floppy services are supported (int 13h)", "5.25\"/1.2 MB floppy services are supported (int 13h)", "3.5\"/720 KB floppy services are supported (int 13h)", "3.5\"/2.88 MB floppy services are supported (int 13h)", "Print screen service is supported (int 5h)", "8042 keyboard services are supported (int 9h)", "Serial services are supported (int 14h)", "Printer services are supported (int 17h)", "CGA/mono video services are supported (int 10h)", "NEC PC-98" /* 31 */ }; /* this struct has BIOS_CHAR_NB_ELEMENTS */ /* each bool is associated with the relevant message above */ typedef struct { bool bios_characteristics_not_supported; bool isa; bool mca; bool eisa; bool pci; bool pc_card; bool pnp; bool apm; bool bios_upgreadable; bool bios_shadowing; bool vlb; bool escd; bool boot_from_cd; bool selectable_boot; bool bios_rom_socketed; bool edd; bool japanese_floppy_nec_9800_1_2MB; bool japanese_floppy_toshiba_1_2MB; bool floppy_5_25_360KB; bool floppy_5_25_1_2MB; bool floppy_3_5_720KB; bool floppy_3_5_2_88MB; bool print_screen; bool keyboard_8042_support; bool serial_support; bool printer_support; bool cga_mono_support; bool nec_pc_98; } __attribute__((__packed__)) s_characteristics; static const char *bios_charac_x1_strings[]={ "ACPI is supported", /* 0 */ "USB legacy is supported", "AGP is supported", "I2O boot is supported", "LS-120 boot is supported", "ATAPI Zip drive boot is supported", "IEEE 1394 boot is supported", "Smart battery is supported" /* 7 */ }; /* this struct has BIOS_CHAR_X1_NB_ELEMENTS */ /* each bool is associated with the relevant message above */ typedef struct { bool acpi; bool usb_legacy; bool agp; bool i2o_boot; bool ls_120_boot; bool zip_drive_boot; bool ieee_1394_boot; bool smart_battery; } __attribute__((__packed__)) s_characteristics_x1; static const char *bios_charac_x2_strings[]={ "BIOS boot specification is supported", /* 0 */ "Function key-initiated network boot is supported", "Targeted content distribution is supported" /* 2 */ }; /* this struct has BIOS_CHAR_X2_NB_ELEMENTS */ /* each bool is associated with the relevant message above */ typedef struct { bool bios_boot_specification; bool bios_network_boot_by_keypress; bool target_content_distribution; } __attribute__((__packed__)) s_characteristics_x2; typedef struct { char vendor[BIOS_VENDOR_SIZE]; char version[BIOS_VERSION_SIZE]; char release_date[BIOS_RELEASE_SIZE]; u16 address; u16 runtime_size; char runtime_size_unit[BIOS_RUNTIME_SIZE_UNIT_SIZE]; u16 rom_size; char rom_size_unit[BIOS_ROM_UNIT_SIZE]; s_characteristics characteristics; s_characteristics_x1 characteristics_x1; s_characteristics_x2 characteristics_x2; char bios_revision [BIOS_BIOS_REVISION_SIZE]; char firmware_revision [BIOS_FIRMWARE_REVISION_SIZE]; } s_bios; #endif syslinux-legacy-3.63+dfsg/com32/include/inttypes.h0000664000175000017500000001170410777447272020614 0ustar evanevan/* * inttypes.h */ #ifndef _INTTYPES_H #define _INTTYPES_H #include #include #include static __inline__ intmax_t imaxabs(intmax_t __n) { return (__n < (intmax_t)0) ? -__n : __n; } __extern intmax_t strtoimax(const char *, char **, int); __extern uintmax_t strtoumax(const char *, char **, int); /* extensions */ __extern intmax_t strntoimax(const char *, char **, int, size_t); __extern uintmax_t strntoumax(const char *, char **, int, size_t); #if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) #define PRId8 "d" #define PRId16 "d" #define PRId32 "d" #define PRId64 __PRI64_RANK "d" #define PRIdLEAST8 "d" #define PRIdLEAST16 "d" #define PRIdLEAST32 "d" #define PRIdLEAST64 __PRI64_RANK "d" #define PRIdFAST8 "d" #define PRIdFAST16 __PRIFAST_RANK "d" #define PRIdFAST32 __PRIFAST_RANK "d" #define PRIdFAST64 __PRI64_RANK "d" #define PRIdMAX __PRI64_RANK "d" #define PRIdPTR __PRIPTR_RANK "d" #define PRIi8 "i" #define PRIi16 "i" #define PRIi32 "i" #define PRIi64 __PRI64_RANK "i" #define PRIiLEAST8 "i" #define PRIiLEAST16 "i" #define PRIiLEAST32 "i" #define PRIiLEAST64 __PRI64_RANK "i" #define PRIiFAST8 "i" #define PRIiFAST16 __PRIFAST_RANK "i" #define PRIiFAST32 __PRIFAST_RANK "i" #define PRIiFAST64 __PRI64_RANK "i" #define PRIiMAX __PRI64_RANK "i" #define PRIiPTR __PRIPTR_RANK "i" #define PRIo8 "o" #define PRIo16 "o" #define PRIo32 "o" #define PRIo64 __PRI64_RANK "o" #define PRIoLEAST8 "o" #define PRIoLEAST16 "o" #define PRIoLEAST32 "o" #define PRIoLEAST64 __PRI64_RANK "o" #define PRIoFAST8 "o" #define PRIoFAST16 __PRIFAST_RANK "o" #define PRIoFAST32 __PRIFAST_RANK "o" #define PRIoFAST64 __PRI64_RANK "o" #define PRIoMAX __PRI64_RANK "o" #define PRIoPTR __PRIPTR_RANK "o" #define PRIu8 "u" #define PRIu16 "u" #define PRIu32 "u" #define PRIu64 __PRI64_RANK "u" #define PRIuLEAST8 "u" #define PRIuLEAST16 "u" #define PRIuLEAST32 "u" #define PRIuLEAST64 __PRI64_RANK "u" #define PRIuFAST8 "u" #define PRIuFAST16 __PRIFAST_RANK "u" #define PRIuFAST32 __PRIFAST_RANK "u" #define PRIuFAST64 __PRI64_RANK "u" #define PRIuMAX __PRI64_RANK "u" #define PRIuPTR __PRIPTR_RANK "u" #define PRIx8 "x" #define PRIx16 "x" #define PRIx32 "x" #define PRIx64 __PRI64_RANK "x" #define PRIxLEAST8 "x" #define PRIxLEAST16 "x" #define PRIxLEAST32 "x" #define PRIxLEAST64 __PRI64_RANK "x" #define PRIxFAST8 "x" #define PRIxFAST16 __PRIFAST_RANK "x" #define PRIxFAST32 __PRIFAST_RANK "x" #define PRIxFAST64 __PRI64_RANK "x" #define PRIxMAX __PRI64_RANK "x" #define PRIxPTR __PRIPTR_RANK "x" #define PRIX8 "X" #define PRIX16 "X" #define PRIX32 "X" #define PRIX64 __PRI64_RANK "X" #define PRIXLEAST8 "X" #define PRIXLEAST16 "X" #define PRIXLEAST32 "X" #define PRIXLEAST64 __PRI64_RANK "X" #define PRIXFAST8 "X" #define PRIXFAST16 __PRIFAST_RANK "X" #define PRIXFAST32 __PRIFAST_RANK "X" #define PRIXFAST64 __PRI64_RANK "X" #define PRIXMAX __PRI64_RANK "X" #define PRIXPTR __PRIPTR_RANK "X" #define SCNd8 "hhd" #define SCNd16 "hd" #define SCNd32 "d" #define SCNd64 __PRI64_RANK "d" #define SCNdLEAST8 "hhd" #define SCNdLEAST16 "hd" #define SCNdLEAST32 "d" #define SCNdLEAST64 __PRI64_RANK "d" #define SCNdFAST8 "hhd" #define SCNdFAST16 __PRIFAST_RANK "d" #define SCNdFAST32 __PRIFAST_RANK "d" #define SCNdFAST64 __PRI64_RANK "d" #define SCNdMAX __PRI64_RANK "d" #define SCNdPTR __PRIPTR_RANK "d" #define SCNi8 "hhi" #define SCNi16 "hi" #define SCNi32 "i" #define SCNi64 __PRI64_RANK "i" #define SCNiLEAST8 "hhi" #define SCNiLEAST16 "hi" #define SCNiLEAST32 "i" #define SCNiLEAST64 __PRI64_RANK "i" #define SCNiFAST8 "hhi" #define SCNiFAST16 __PRIFAST_RANK "i" #define SCNiFAST32 __PRIFAST_RANK "i" #define SCNiFAST64 __PRI64_RANK "i" #define SCNiMAX __PRI64_RANK "i" #define SCNiPTR __PRIPTR_RANK "i" #define SCNo8 "hho" #define SCNo16 "ho" #define SCNo32 "o" #define SCNo64 __PRI64_RANK "o" #define SCNoLEAST8 "hho" #define SCNoLEAST16 "ho" #define SCNoLEAST32 "o" #define SCNoLEAST64 __PRI64_RANK "o" #define SCNoFAST8 "hho" #define SCNoFAST16 __PRIFAST_RANK "o" #define SCNoFAST32 __PRIFAST_RANK "o" #define SCNoFAST64 __PRI64_RANK "o" #define SCNoMAX __PRI64_RANK "o" #define SCNoPTR __PRIPTR_RANK "o" #define SCNu8 "hhu" #define SCNu16 "hu" #define SCNu32 "u" #define SCNu64 __PRI64_RANK "u" #define SCNuLEAST8 "hhu" #define SCNuLEAST16 "hu" #define SCNuLEAST32 "u" #define SCNuLEAST64 __PRI64_RANK "u" #define SCNuFAST8 "hhu" #define SCNuFAST16 __PRIFAST_RANK "u" #define SCNuFAST32 __PRIFAST_RANK "u" #define SCNuFAST64 __PRI64_RANK "u" #define SCNuMAX __PRI64_RANK "u" #define SCNuPTR __PRIPTR_RANK "u" #define SCNx8 "hhx" #define SCNx16 "hx" #define SCNx32 "x" #define SCNx64 __PRI64_RANK "x" #define SCNxLEAST8 "hhx" #define SCNxLEAST16 "hx" #define SCNxLEAST32 "x" #define SCNxLEAST64 __PRI64_RANK "x" #define SCNxFAST8 "hhx" #define SCNxFAST16 __PRIFAST_RANK "x" #define SCNxFAST32 __PRIFAST_RANK "x" #define SCNxFAST64 __PRI64_RANK "x" #define SCNxMAX __PRI64_RANK "x" #define SCNxPTR __PRIPTR_RANK "x" #endif #endif /* _INTTYPES_H */ syslinux-legacy-3.63+dfsg/com32/include/math.h0000664000175000017500000000041410777447272017662 0ustar evanevan#ifndef _MATH_H #define _MATH_H #ifndef __DBL_MIN_EXP__ # define __DBL_MIN_EXP__ (-1021) #endif #ifndef __DBL_MAX_EXP__ # define __DBL_MAX_EXP__ 1024 #endif double pow(double, double); double fabs(double); double strtod(const char *, char **); #endif /* _MATH_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/0000775000175000017500000000000010777447272020457 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/include/syslinux/movebits.h0000664000175000017500000000523710777447272022467 0ustar evanevan#ifndef _SYSLINUX_MOVEBITS_H #define _SYSLINUX_MOVEBITS_H #include #include typedef uint32_t addr_t; /* * A syslinux_movelist is a linked list of move operations. The ordering * is important, so no sorting requirement can be imposed. */ struct syslinux_movelist { addr_t dst; addr_t src; addr_t len; struct syslinux_movelist *next; }; /* * A syslinux_memmap is a sorted, linked list of memory regions, * guaranteed to satisfy the constraint that no adjacent zones have * the same type. Undefined memory ranges are represented with entries; * they have type SMT_UNDEFINED. * * Note that there is no length field. The length of a region is obtained * by looking at the start of the next entry in the chain. */ enum syslinux_memmap_types { SMT_ERROR = -2, /* Internal error token */ SMT_END = -1, /* End of list */ SMT_UNDEFINED = 0, /* Unknown range */ SMT_FREE = 1, /* Available memory */ SMT_RESERVED, /* Unusable memory */ SMT_ALLOC, /* Memory allocated by user */ SMT_ZERO, /* Memory that should be zeroed */ }; struct syslinux_memmap { addr_t start; enum syslinux_memmap_types type; struct syslinux_memmap *next; }; /* * moves is computed from "fraglist" and "memmap". Areas that are * to be zeroed should be marked as such in the memmap, not in the * fraglist. */ int syslinux_compute_movelist(struct syslinux_movelist **movelist, struct syslinux_movelist *fraglist, struct syslinux_memmap *memmap); struct syslinux_memmap *syslinux_memory_map(void); void syslinux_free_movelist(struct syslinux_movelist *); int syslinux_add_movelist(struct syslinux_movelist **, addr_t dst, addr_t src, addr_t len); int syslinux_allocate_from_list(struct syslinux_movelist **freelist, addr_t dst, addr_t len); int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist, struct syslinux_memmap *memmap); /* Operatons on struct syslinux_memmap */ struct syslinux_memmap *syslinux_init_memmap(void); int syslinux_add_memmap(struct syslinux_memmap **list, addr_t start, addr_t len, enum syslinux_memmap_types type); enum syslinux_memmap_types syslinux_memmap_type(struct syslinux_memmap *list, addr_t start, addr_t len); int syslinux_memmap_largest(struct syslinux_memmap *list, enum syslinux_memmap_types type, addr_t *start, addr_t *len); void syslinux_free_memmap(struct syslinux_memmap *list); struct syslinux_memmap *syslinux_dup_memmap(struct syslinux_memmap *list); /* Debugging functions */ void syslinux_dump_movelist(FILE *file, struct syslinux_movelist *ml); void syslinux_dump_memmap(FILE *file, struct syslinux_memmap *memmap); #endif /* _SYSLINUX_MOVEBITS_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/config.h0000664000175000017500000000754110777447272022104 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/config.h * * Query syslinux configuration information. */ #ifndef _SYSLINUX_CONFIG_H #define _SYSLINUX_CONFIG_H #include enum syslinux_filesystem { SYSLINUX_FS_UNKNOWN = 0x30, SYSLINUX_FS_SYSLINUX = 0x31, SYSLINUX_FS_PXELINUX = 0x32, SYSLINUX_FS_ISOLINUX = 0x33, SYSLINUX_FS_EXTLINUX = 0x34, }; struct syslinux_version { uint16_t version; /* (major << 8)+minor */ uint16_t max_api; enum syslinux_filesystem filesystem; const char *version_string; const char *copyright_string; }; extern struct syslinux_version __syslinux_version; static inline const struct syslinux_version * syslinux_version(void) { return &__syslinux_version; } union syslinux_derivative_info { struct { uint8_t filesystem; uint8_t ah; } c; /* common */ struct { uint16_t ax; uint16_t cx; uint16_t dx; uint16_t _pad; const void *esbx; const void *fssi; const void *gsdi; } r; /* raw */ struct { uint8_t filesystem; uint8_t ah; uint8_t sector_shift; uint8_t ch; uint8_t drive_number; uint8_t dh; uint16_t _pad; const void *ptab_ptr; const uint32_t *esdi_ptr; } disk; /* syslinux/extlinux */ struct { uint8_t filesystem; uint8_t ah; uint16_t cx; uint16_t apiver; uint16_t _pad; const void *pxenvptr; const void *stack; } pxe; /* pxelinux */ struct { uint8_t filesystem; uint8_t ah; uint8_t sector_shift; uint8_t ch; uint8_t drive_number; uint8_t dh; uint16_t _pad; const void *spec_packet; const uint32_t *esdi_ptr; } iso; /* isolinux */ }; union syslinux_derivative_info __syslinux_derivative_info; static inline const union syslinux_derivative_info * syslinux_derivative_info(void) { return &__syslinux_derivative_info; } struct syslinux_serial_console_info { uint16_t iobase; uint16_t divisor; uint16_t flowctl; }; extern struct syslinux_serial_console_info __syslinux_serial_console_info; static inline const struct syslinux_serial_console_info * syslinux_serial_console_info(void) { return &__syslinux_serial_console_info; } extern const char *__syslinux_config_file; static inline const char *syslinux_config_file(void) { return __syslinux_config_file; } struct syslinux_ipappend_strings { int count; const char * const *ptr; }; extern struct syslinux_ipappend_strings __syslinux_ipappend_strings; static inline const struct syslinux_ipappend_strings * syslinux_ipappend_strings(void) { return &__syslinux_ipappend_strings; } #endif /* _SYSLINUX_CONFIG_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/features.h0000664000175000017500000000356710777447272022461 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #ifndef _SYSLINUX_FEATURES_H #define _SYSLINUX_FEATURES_H #define SYSLINUX_FEATURE_LOCAL_BOOT (0*8+0) #define SYSLINUX_FEATURE_NOOP_IDLE (0*8+1) extern struct __syslinux_feature_flags { unsigned int len; const unsigned char *ptr; } __syslinux_feature_flags; static inline int syslinux_has_feature(unsigned int __flag) { unsigned int __byte = __flag >> 3; unsigned int __bit = __flag & 7; if (__byte <= __syslinux_feature_flags.len) return (__syslinux_feature_flags.ptr[__byte] >> __bit) & 1; else return 0; } #endif /* _SYSLINUX_FEATURE_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/loadfile.h0000664000175000017500000000043310777447272022407 0ustar evanevan#ifndef LIBUTIL_LOADFILE_H #define LIBUTIL_LOADFILE_H #include /* loadfile() returns the true size of the file, but will guarantee valid, zero-padded memory out to this boundary. */ #define LOADFILE_ZERO_PAD 64 int loadfile(const char *, void **, size_t *); #endif syslinux-legacy-3.63+dfsg/com32/include/syslinux/reboot.h0000664000175000017500000000302010777447272022115 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/reboot.h * * Reboot the system */ #ifndef _SYSLINUX_REBOOT_H #define _SYSLINUX_REBOOT_H #include __noreturn syslinux_reboot(int warm); #endif /* _SYSLINUX_REBOOT_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/adv.h0000664000175000017500000000356310777447272021411 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/adv.h */ #ifndef _SYSLINUX_ADV_H #define _SYSLINUX_ADV_H #include #include #include __extern void *__syslinux_adv_ptr; __extern size_t __syslinux_adv_size; static inline void *syslinux_adv_ptr(void) { return __syslinux_adv_ptr; } static inline size_t syslinux_adv_size(void) { return __syslinux_adv_size; } __extern int syslinux_adv_write(void); __extern int syslinux_setadv(int, size_t, const void *); __extern const void *syslinux_getadv(int, size_t *); #endif /* _SYSLINUX_ADV_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/boot.h0000664000175000017500000000427710777447272021605 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/boot.h * * SYSLINUX boot API invocation */ #ifndef _SYSLINUX_BOOT_H #define _SYSLINUX_BOOT_H #include #include __noreturn syslinux_run_command(const char *); __noreturn syslinux_run_default(void); void syslinux_local_boot(uint16_t flags); void syslinux_final_cleanup(uint16_t flags); void syslinux_chain_bootstrap(uint16_t flags, const void *bootstrap, uint32_t bootstrap_len, uint32_t edx, uint32_t esi, uint16_t ds); #define IMAGE_TYPE_KERNEL 0 #define IMAGE_TYPE_LINUX 1 #define IMAGE_TYPE_BOOT 2 #define IMAGE_TYPE_BSS 3 #define IMAGE_TYPE_PXE 4 #define IMAGE_TYPE_FDIMAGE 5 #define IMAGE_TYPE_COMBOOT 6 #define IMAGE_TYPE_COM32 7 #define IMAGE_TYPE_CONFIG 8 void syslinux_run_kernel_image(const char *filename, const char *cmdline, uint32_t ipappend_flags, uint32_t type); #endif /* _SYSLINUX_BOOT_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/idle.h0000664000175000017500000000266010777447272021551 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2005-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/idle.h */ #ifndef _SYSLINUX_IDLE_H #define _SYSLINUX_IDLE_H void syslinux_idle(void); #endif syslinux-legacy-3.63+dfsg/com32/include/syslinux/bootrm.h0000664000175000017500000000471010777447272022134 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/bootrm.h * * Data structures for shuffle and boot to protected mode */ #ifndef _SYSLINUX_BOOTRM_H #define _SYSLINUX_BOOTRM_H #include #include #include /* This register set is used by the shuffle and boot interface. It is a completely different structure from what the __intcall() and __farcall() interfaces use! */ struct syslinux_rm_regs { uint16_t es; /* Offset 0 */ uint16_t _unused_cs; /* Offset 2 */ uint16_t ds; /* Offset 4 */ uint16_t ss; /* Offset 6 */ uint16_t fs; /* Offset 8 */ uint16_t gs; /* Offset 10 */ reg32_t eax; /* Offset 12 */ reg32_t ecx; /* Offset 16 */ reg32_t edx; /* Offset 20 */ reg32_t ebx; /* Offset 24 */ reg32_t esp; /* Offset 28 */ reg32_t ebp; /* Offset 32 */ reg32_t esi; /* Offset 36 */ reg32_t edi; /* Offset 40 */ uint16_t ip; /* Offset 44 */ uint16_t cs; /* Offset 46 */ }; int syslinux_shuffle_boot_rm(struct syslinux_movelist *fraglist, struct syslinux_memmap *memmap, uint16_t bootflags, struct syslinux_rm_regs *regs); #endif /* _SYSLINUX_BOOTRM_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/linux.h0000664000175000017500000000554110777447272021774 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/linux.h * * Definitions used to boot a Linux kernel */ #ifndef _SYSLINUX_LINUX_H #define _SYSLINUX_LINUX_H #include #include /* A chunk of an initramfs. These are kept as a doubly-linked circular list with headnode; the headnode is distinguished by having len == 0. The data pointer can be NULL if data_len is zero; if data_len < len then the balance of the region is zeroed. */ struct initramfs { struct initramfs *prev, *next; size_t len; size_t align; const void *data; size_t data_len; }; #define INITRAMFS_MAX_ALIGN 4096 int syslinux_boot_linux(void *kernel_buf, size_t kernel_size, struct initramfs *initramfs, char *cmdline, uint16_t video_mode, uint32_t mem_limit); /* Initramfs manipulation functions */ struct initramfs *initramfs_init(void); int initramfs_add_data(struct initramfs *ihead, const void *data, size_t data_len, size_t len, size_t align); int initramfs_mknod(struct initramfs *ihead, const char *filename, int do_mkdir, uint16_t mode, size_t len, uint32_t major, uint32_t minor); int initramfs_add_file(struct initramfs *ihead, const void *data, size_t data_len, size_t len, const char *filename, int do_mkdir, uint32_t mode); int initramfs_load_file(struct initramfs *ihead, const char *src_filename, const char *dst_filename, int do_mkdir, uint32_t mode); int initramfs_add_trailer(struct initramfs *ihead); int initramfs_load_archive(struct initramfs *ihead, const char *filename); #endif /* _SYSLINUX_LINUX_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/advconst.h0000664000175000017500000000322610777447272022454 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/advconst.h * * ADV defined constants * * Defined in a separate file so it can be used by non-COM32 code. * Some of these constants are also defined in adv.inc, they better match... */ #ifndef _SYSLINUX_ADVCONST_H #define _SYSLINUX_ADVCONST_H #define ADV_END 0 #define ADV_BOOTONCE 1 #endif /* _SYSLINUX_ADVCONST_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/pxe.h0000664000175000017500000003503210777447272021427 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/pxe.h * * PXE definitions and function prototypes for SYSLINUX */ #ifndef _SYSLINUX_PXE_H #define _SYSLINUX_PXE_H #include #include #include /* PXE spec structures and definitions. These mostly follow the PXE spec, except when the PXE spec is unnecessarily stupid. Of course, that is most of the time. */ /* Basic types; use Unix-like _t convention instead of SCREAMING; also re-use types we already have, like in_addr_t. */ typedef uint16_t pxenv_status_t; #define MAC_ADDR_LEN 16 typedef uint8_t mac_addr_t[MAC_ADDR_LEN]; /* "Protected mode segment descriptor" according to PXE... */ typedef struct { uint16_t segaddr; uint32_t physaddr; uint16_t segsize; } __packed pxe_segdesc_t; typedef struct { uint16_t offs; uint16_t seg; } segoff16_t; /* Function calling structures and constants */ typedef struct s_PXENV_GET_CACHED_INFO { pxenv_status_t Status; uint16_t PacketType; #define PXENV_PACKET_TYPE_DHCP_DISCOVER 1 #define PXENV_PACKET_TYPE_DHCP_ACK 2 #define PXENV_PACKET_TYPE_CACHED_REPLY 3 uint16_t BufferSize; segoff16_t Buffer; uint16_t BufferLimit; } __packed t_PXENV_GET_CACHED_INFO; typedef struct s_PXENV_START_UNDI { pxenv_status_t Status; uint16_t AX; uint16_t BX; uint16_t DX; uint16_t DI; uint16_t ES; } __packed t_PXENV_START_UNDI; typedef struct s_PXENV_STOP_UNDI { pxenv_status_t Status; } __packed t_PXENV_STOP_UNDI; typedef struct s_PXENV_START_BASE { pxenv_status_t Status; } __packed t_PXENV_START_BASE; typedef struct s_PXENV_STOP_BASE { pxenv_status_t Status; } __packed t_PXENV_STOP_BASE; typedef struct s_PXENV_TFTP_OPEN { pxenv_status_t Status; in_addr_t ServerIPAddress; in_addr_t GatewayIPAddress; uint8_t FileName[128]; in_port_t TFTPPort; uint16_t PacketSize; } __packed t_PXENV_TFTP_OPEN; typedef struct s_PXENV_TFTP_CLOSE { pxenv_status_t Status; } __packed t_PXENV_TFTP_CLOSE; typedef struct s_PXENV_TFTP_READ { pxenv_status_t Status; uint16_t PacketNumber; uint16_t BufferSize; segoff16_t Buffer; } __packed t_PXENV_TFTP_READ; typedef struct s_PXENV_TFTP_READ_FILE { pxenv_status_t Status; uint8_t FileName[128]; uint32_t BufferSize; void * Buffer; in_addr_t ServerIPAddress; in_addr_t GatewayIPAddress; in_addr_t McastIPAddress; in_port_t TFTPClntPort; in_port_t TFTPSrvPort; uint16_t TFTPOpenTimeOut; uint16_t TFTPReopenDelay; } __packed t_PXENV_TFTP_READ_FILE; typedef struct s_PXENV_TFTP_GET_FSIZE { pxenv_status_t Status; in_addr_t ServerIPAddress; in_addr_t GatewayIPAddress; uint8_t FileName[128]; uint32_t FileSize; } __packed t_PXENV_TFTP_GET_FSIZE; typedef struct s_PXENV_UDP_OPEN { pxenv_status_t status; in_addr_t src_ip; } __packed t_PXENV_UDP_OPEN; typedef struct s_PXENV_UDP_CLOSE { pxenv_status_t status; } __packed t_PXENV_UDP_CLOSE; typedef struct s_PXENV_UDP_WRITE { pxenv_status_t status; in_addr_t ip; in_addr_t gw; in_port_t src_port; in_port_t dst_port; uint16_t buffer_size; segoff16_t buffer; } __packed t_PXENV_UDP_WRITE; typedef struct s_PXENV_UDP_READ { pxenv_status_t status; in_addr_t src_ip; in_addr_t dest_ip; in_port_t s_port; in_port_t d_port; uint16_t buffer_size; segoff16_t buffer; } __packed t_PXENV_UDP_READ; typedef struct s_PXENV_UNDI_STARTUP { pxenv_status_t Status; } __packed t_PXENV_UNDI_STARTUP; typedef struct s_PXENV_UNDI_CLEANUP { pxenv_status_t Status; } __packed t_PXENV_UNDI_CLEANUP; typedef struct s_PXENV_UNDI_INITIALIZE { pxenv_status_t Status; void * ProtocolIni; uint8_t reserved[8]; } __packed t_PXENV_UNDI_INITIALIZE; #define MAXNUM_MCADDR 8 typedef struct s_PXENV_UNDI_MCAST_ADDRESS { uint16_t MCastAddrCount; mac_addr_t McastAddr[MAXNUM_MCADDR]; } __packed t_PXENV_UNDI_MCAST_ADDRESS; typedef struct s_PXENV_UNDI_RESET { pxenv_status_t Status; t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; } __packed t_PXENV_UNDI_RESET; typedef struct s_PXENV_UNDI_SHUTDOWN { pxenv_status_t Status; } __packed t_PXENV_UNDI_SHUTDOWN; typedef struct s_PXENV_UNDI_OPEN { pxenv_status_t Status; uint16_t OpenFlag; uint16_t PktFilter; #define FLTR_DIRECTED 0x0001 #define FLTR_BRDCST 0x0002 #define FLTR_PRMSCS 0x0004 #define FLTR_SRC_RTG 0x0008 t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; } __packed t_PXENV_UNDI_OPEN; typedef struct s_PXENV_UNDI_CLOSE { pxenv_status_t Status; } __packed t_PXENV_UNDI_CLOSE; typedef struct s_PXENV_UNDI_TRANSMIT { pxenv_status_t Status; uint8_t Protocol; #define P_UNKNOWN 0 #define P_IP 1 #define P_ARP 2 #define P_RARP 3 uint8_t XmitFlag; #define XMT_DESTADDR 0x0000 #define XMT_BROADCAST 0x0001 segoff16_t DestAddr; segoff16_t TBD; uint32_t Reserved[2]; } __packed t_PXENV_UNDI_TRANSMIT; #define MAX_DATA_BLKS 8 typedef struct s_PXENV_UNDI_TBD { uint16_t ImmedLength; segoff16_t Xmit; uint16_t DataBlkCount; struct DataBlk { uint8_t TDPtrType; uint8_t TDRsvdByte; uint16_t TDDataLen; segoff16_t TDDataPtr; } DataBlock[MAX_DATA_BLKS]; } __packed t_PXENV_UNDI_TBD; typedef struct s_PXENV_UNDI_SET_MCAST_ADDRESS { pxenv_status_t Status; t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf; } __packed t_PXENV_UNDI_SET_MCAST_ADDR; typedef struct s_PXENV_UNDI_SET_STATION_ADDRESS { pxenv_status_t Status; mac_addr_t StationAddress; } __packed t_PXENV_UNDI_SET_STATION_ADDR; typedef struct s_PXENV_UNDI_SET_PACKET_FILTER { pxenv_status_t Status; uint8_t filter; } __packed t_PXENV_UNDI_SET_PACKET_FILTER; typedef struct s_PXENV_UNDI_GET_INFORMATION { pxenv_status_t Status; uint16_t BaseIo; uint16_t IntNumber; uint16_t MaxTranUnit; uint16_t HwType; #define ETHER_TYPE 1 #define EXP_ETHER_TYPE 2 #define IEEE_TYPE 6 #define ARCNET_TYPE 7 uint16_t HwAddrLen; mac_addr_t CurrentNodeAddress; mac_addr_t PermNodeAddress; uint16_t ROMAddress; uint16_t RxBufCt; uint16_t TxBufCt; } __packed t_PXENV_UNDI_GET_INFORMATION; typedef struct s_PXENV_UNDI_GET_STATISTICS { pxenv_status_t Status; uint32_t XmtGoodFrames; uint32_t RcvGoodFrames; uint32_t RcvCRCErrors; uint32_t RcvResourceErrors; } __packed t_PXENV_UNDI_GET_STATISTICS; typedef struct s_PXENV_UNDI_CLEAR_STATISTICS { pxenv_status_t Status; } __packed t_PXENV_UNDI_CLEAR_STATISTICS; typedef struct s_PXENV_UNDI_INITIATE_DIAGS { pxenv_status_t Status; } __packed t_PXENV_UNDI_INITIATE_DIAGS; typedef struct s_PXENV_UNDI_FORCE_INTERRUPT { pxenv_status_t Status; } __packed t_PXENV_UNDI_FORCE_INTERRUPT; typedef struct s_PXENV_UNDI_GET_MCAST_ADDRESS { pxenv_status_t Status; in_addr_t InetAddr; mac_addr_t MediaAddr; } __packed t_PXENV_UNDI_GET_MCAST_ADDR; typedef struct s_PXENV_UNDI_GET_NIC_TYPE { pxenv_status_t Status; uint8_t NicType; #define PCI_NIC 2 #define PnP_NIC 3 #define CardBus_NIC 4 union { struct { uint16_t Vendor_ID; uint16_t Dev_ID; uint8_t Base_Class; uint8_t Sub_Class; uint8_t Prog_Intf; uint8_t Rev; uint16_t BusDevFunc; uint16_t SubVendor_ID; uint16_t SubDevice_ID; } pci, cardbus; struct { uint32_t EISA_Dev_ID; uint8_t Base_Class; uint8_t Sub_Class; uint8_t Prog_Intf; uint16_t CardSelNum; } __packed pnp; } __packed info; } __packed t_PXENV_UNDI_GET_NIC_TYPE; typedef struct s_PXENV_UNDI_GET_IFACE_INFO { pxenv_status_t Status; uint8_t IfaceType[16]; uint32_t LinkSpeed; uint32_t ServiceFlags; uint32_t Reserved[4]; } __packed t_PXENV_UNDI_GET_NDIS_INFO; typedef struct s_PXENV_UNDI_GET_STATE { #define PXE_UNDI_GET_STATE_STARTED 1 #define PXE_UNDI_GET_STATE_INITIALIZED 2 #define PXE_UNDI_GET_STATE_OPENED 3 pxenv_status_t Status; uint8_t UNDIstate; } __packed t_PXENV_UNDI_GET_STATE; typedef struct s_PXENV_UNDI_ISR { pxenv_status_t Status; uint16_t FuncFlag; uint16_t BufferLength; uint16_t FrameLength; uint16_t FrameHeaderLength; segoff16_t Frame; uint8_t ProtType; uint8_t PktType; } __packed t_PXENV_UNDI_ISR; #define PXENV_UNDI_ISR_IN_START 1 #define PXENV_UNDI_ISR_IN_PROCESS 2 #define PXENV_UNDI_ISR_IN_GET_NEXT 3 /* One of these will be returned for PXENV_UNDI_ISR_IN_START */ #define PXENV_UNDI_ISR_OUT_OURS 0 #define PXENV_UNDI_USR_OUT_NOT_OURS 1 /* One of these will be returned for PXENV_UNDI_ISR_IN_PROCESS and PXENV_UNDI_ISR_IN_GET_NEXT */ #define PXENV_UNDI_ISR_OUT_DONE 0 #define PXENV_UNDI_ISR_OUT_TRANSMIT 2 #define PXENV_UNDI_ISR_OUT_RECEIVE 3 #define PXENV_UNDI_ISR_OUT_BUSY 4 /* Function numbers and error codes */ #define PXENV_TFTP_OPEN 0x0020 #define PXENV_TFTP_CLOSE 0x0021 #define PXENV_TFTP_READ 0x0022 #define PXENV_TFTP_READ_FILE 0x0023 #define PXENV_TFTP_READ_FILE_PMODE 0x0024 #define PXENV_TFTP_GET_FSIZE 0x0025 #define PXENV_UDP_OPEN 0x0030 #define PXENV_UDP_CLOSE 0x0031 #define PXENV_UDP_READ 0x0032 #define PXENV_UDP_WRITE 0x0033 #define PXENV_START_UNDI 0x0000 #define PXENV_UNDI_STARTUP 0x0001 #define PXENV_UNDI_CLEANUP 0x0002 #define PXENV_UNDI_INITIALIZE 0x0003 #define PXENV_UNDI_RESET_NIC 0x0004 #define PXENV_UNDI_SHUTDOWN 0x0005 #define PXENV_UNDI_OPEN 0x0006 #define PXENV_UNDI_CLOSE 0x0007 #define PXENV_UNDI_TRANSMIT 0x0008 #define PXENV_UNDI_SET_MCAST_ADDR 0x0009 #define PXENV_UNDI_SET_STATION_ADDR 0x000A #define PXENV_UNDI_SET_PACKET_FILTER 0x000B #define PXENV_UNDI_GET_INFORMATION 0x000C #define PXENV_UNDI_GET_STATISTICS 0x000D #define PXENV_UNDI_CLEAR_STATISTICS 0x000E #define PXENV_UNDI_INITIATE_DIAGS 0x000F #define PXENV_UNDI_FORCE_INTERRUPT 0x0010 #define PXENV_UNDI_GET_MCAST_ADDR 0x0011 #define PXENV_UNDI_GET_NIC_TYPE 0x0012 #define PXENV_UNDI_GET_IFACE_INFO 0x0013 #define PXENV_UNDI_ISR 0x0014 #define PXENV_STOP_UNDI 0x0015 /* Overlap...? */ #define PXENV_UNDI_GET_STATE 0x0015 /* Overlap...? */ #define PXENV_UNLOAD_STACK 0x0070 #define PXENV_GET_CACHED_INFO 0x0071 #define PXENV_RESTART_DHCP 0x0072 #define PXENV_RESTART_TFTP 0x0073 #define PXENV_MODE_SWITCH 0x0074 #define PXENV_START_BASE 0x0075 #define PXENV_STOP_BASE 0x0076 #define PXENV_EXIT_SUCCESS 0x0000 #define PXENV_EXIT_FAILURE 0x0001 #define PXENV_STATUS_SUCCESS 0x00 #define PXENV_STATUS_FAILURE 0x01 #define PXENV_STATUS_BAD_FUNC 0x02 #define PXENV_STATUS_UNSUPPORTED 0x03 #define PXENV_STATUS_KEEP_UNDI 0x04 #define PXENV_STATUS_KEEP_ALL 0x05 #define PXENV_STATUS_OUT_OF_RESOURCES 0x06 #define PXENV_STATUS_ARP_TIMEOUT 0x11 #define PXENV_STATUS_UDP_CLOSED 0x18 #define PXENV_STATUS_UDP_OPEN 0x19 #define PXENV_STATUS_TFTP_CLOSED 0x1A #define PXENV_STATUS_TFTP_OPEN 0x1B #define PXENV_STATUS_MCOPY_PROBLEM 0x20 #define PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x21 #define PXENV_STATUS_BIS_VALIDATE_FAILURE 0x22 #define PXENV_STATUS_BIS_INIT_FAILURE 0x23 #define PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x24 #define PXENV_STATUS_BIS_GBOA_FAILURE 0x25 #define PXENV_STATUS_BIS_FREE_FAILURE 0x26 #define PXENV_STATUS_BIS_GSI_FAILURE 0x27 #define PXENV_STATUS_BIS_BAD_CKSUM 0x28 #define PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x30 #define PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x32 #define PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x33 #define PXENV_STATUS_TFTP_READ_TIMEOUT 0x35 #define PXENV_STATUS_TFTP_ERROR_OPCODE 0x36 #define PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x38 #define PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x39 #define PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x3A #define PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x3B #define PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x3C #define PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x3D #define PXENV_STATUS_TFTP_NO_FILESIZE 0x3E #define PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x3F #define PXENV_STATUS_DHCP_TIMEOUT 0x51 #define PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x52 #define PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x53 #define PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x54 #define PXENV_STATUS_UNDI_INVALID_FUNCTION 0x60 #define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x61 #define PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x62 #define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x63 #define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x64 #define PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x65 #define PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x66 #define PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x67 #define PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x68 #define PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x69 #define PXENV_STATUS_UNDI_INVALID_STATE 0x6A #define PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x6B #define PXENV_STATUS_UNDI_INVALID_PARAMETER 0x6C #define PXENV_STATUS_BSTRAP_PROMPT_MENU 0x74 #define PXENV_STATUS_BSTRAP_MCAST_ADDR 0x76 #define PXENV_STATUS_BSTRAP_MISSING_LIST 0x77 #define PXENV_STATUS_BSTRAP_NO_RESPONSE 0x78 #define PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x79 #define PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0xA0 #define PXENV_STATUS_BINL_NO_PXE_SERVER 0xA1 #define PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0xA2 #define PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0xA3 #define PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0xB0 #define PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0xC0 #define PXENV_STATUS_LOADER_NO_BC_ROMID 0xC1 #define PXENV_STATUS_LOADER_BAD_BC_ROMID 0xC2 #define PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0xC3 #define PXENV_STATUS_LOADER_NO_UNDI_ROMID 0xC4 #define PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0xC5 #define PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0xC6 #define PXENV_STATUS_LOADER_NO_PXE_STRUCT 0xC8 #define PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0xC9 #define PXENV_STATUS_LOADER_UNDI_START 0xCA #define PXENV_STATUS_LOADER_BC_START 0xCB /* SYSLINUX-defined PXE utility functions */ int pxe_get_cached_info(int level, void **buf, size_t *len); #endif /* _SYSLINUX_PXE_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/io.h0000664000175000017500000000302010777447272021232 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/io.h * * SYSLINUX low-level I/O functions */ #ifndef _SYSLINUX_IO_H #define _SYSLINUX_IO_H int syslinux_read_disk(void *buf, uint32_t sector, uint16_t count); #endif /* _SYSLINUX_IO_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/resolve.h0000664000175000017500000000306310777447272022311 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/resolve.h * * Interface to the syslinux DNS query API */ #ifndef _SYSLINUX_RESOLVE_H #define _SYSLINUX_RESOLVE_H #include in_addr_t syslinux_resolve_hostname(const char *); #endif /* _SYSLINUX_RESOLVE_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/video.h0000664000175000017500000000320310777447272021734 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/video.h * * SYSLINUX video API functions. */ #ifndef _SYSLINUX_VIDEO_H #define _SYSLINUX_VIDEO_H #include void syslinux_force_text_mode(void); int syslinux_report_video_mode(uint16_t flags, uint16_t xsize, uint16_t ysize); int syslinux_font_query(void **font); #endif /* _SYSLINUX_API_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/vesacon.h0000664000175000017500000000302610777447272022267 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #ifndef _SYSLINUX_VESACON_H #define _SYSLINUX_VESACON_H int vesacon_default_background(void); int vesacon_load_background(const char *); int vesacon_set_background(unsigned int); #endif /* _SYSLINUX_VESACON_H */ syslinux-legacy-3.63+dfsg/com32/include/syslinux/bootpm.h0000664000175000017500000000404510777447272022133 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * syslinux/bootpm.h * * Data structures for shuffle and boot to protected mode */ #ifndef _SYSLINUX_BOOTPM_H #define _SYSLINUX_BOOTPM_H #include #include struct syslinux_pm_regs { uint32_t eax; /* Offset 0 */ uint32_t ecx; /* Offset 4 */ uint32_t edx; /* Offset 8 */ uint32_t ebx; /* Offset 12 */ uint32_t esp; /* Offset 16 */ uint32_t ebp; /* Offset 20 */ uint32_t esi; /* Offset 24 */ uint32_t edi; /* Offset 28 */ uint32_t eip; /* Offset 32 */ }; int syslinux_shuffle_boot_pm(struct syslinux_movelist *fraglist, struct syslinux_memmap *memmap, uint16_t bootflags, struct syslinux_pm_regs *regs); #endif /* _SYSLINUX_BOOTPM_H */ syslinux-legacy-3.63+dfsg/com32/include/errno.h0000664000175000017500000001405210777447272020061 0ustar evanevan#ifndef _ERRNO_H #define _ERRNO_H extern int errno; #define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ #define EINTR 4 /* Interrupted system call */ #define EIO 5 /* I/O error */ #define ENXIO 6 /* No such device or address */ #define E2BIG 7 /* Arg list too long */ #define ENOEXEC 8 /* Exec format error */ #define EBADF 9 /* Bad file number */ #define ECHILD 10 /* No child processes */ #define EAGAIN 11 /* Try again */ #define ENOMEM 12 /* Out of memory */ #define EACCES 13 /* Permission denied */ #define EFAULT 14 /* Bad address */ #define ENOTBLK 15 /* Block device required */ #define EBUSY 16 /* Device or resource busy */ #define EEXIST 17 /* File exists */ #define EXDEV 18 /* Cross-device link */ #define ENODEV 19 /* No such device */ #define ENOTDIR 20 /* Not a directory */ #define EISDIR 21 /* Is a directory */ #define EINVAL 22 /* Invalid argument */ #define ENFILE 23 /* File table overflow */ #define EMFILE 24 /* Too many open files */ #define ENOTTY 25 /* Not a typewriter */ #define ETXTBSY 26 /* Text file busy */ #define EFBIG 27 /* File too large */ #define ENOSPC 28 /* No space left on device */ #define ESPIPE 29 /* Illegal seek */ #define EROFS 30 /* Read-only file system */ #define EMLINK 31 /* Too many links */ #define EPIPE 32 /* Broken pipe */ #define EDOM 33 /* Math argument out of domain of func */ #define ERANGE 34 /* Math result not representable */ #define EDEADLK 35 /* Resource deadlock would occur */ #define ENAMETOOLONG 36 /* File name too long */ #define ENOLCK 37 /* No record locks available */ #define ENOSYS 38 /* Function not implemented */ #define ENOTEMPTY 39 /* Directory not empty */ #define ELOOP 40 /* Too many symbolic links encountered */ #define EWOULDBLOCK EAGAIN /* Operation would block */ #define ENOMSG 42 /* No message of desired type */ #define EIDRM 43 /* Identifier removed */ #define ECHRNG 44 /* Channel number out of range */ #define EL2NSYNC 45 /* Level 2 not synchronized */ #define EL3HLT 46 /* Level 3 halted */ #define EL3RST 47 /* Level 3 reset */ #define ELNRNG 48 /* Link number out of range */ #define EUNATCH 49 /* Protocol driver not attached */ #define ENOCSI 50 /* No CSI structure available */ #define EL2HLT 51 /* Level 2 halted */ #define EBADE 52 /* Invalid exchange */ #define EBADR 53 /* Invalid request descriptor */ #define EXFULL 54 /* Exchange full */ #define ENOANO 55 /* No anode */ #define EBADRQC 56 /* Invalid request code */ #define EBADSLT 57 /* Invalid slot */ #define EDEADLOCK EDEADLK #define EBFONT 59 /* Bad font file format */ #define ENOSTR 60 /* Device not a stream */ #define ENODATA 61 /* No data available */ #define ETIME 62 /* Timer expired */ #define ENOSR 63 /* Out of streams resources */ #define ENONET 64 /* Machine is not on the network */ #define ENOPKG 65 /* Package not installed */ #define EREMOTE 66 /* Object is remote */ #define ENOLINK 67 /* Link has been severed */ #define EADV 68 /* Advertise error */ #define ESRMNT 69 /* Srmount error */ #define ECOMM 70 /* Communication error on send */ #define EPROTO 71 /* Protocol error */ #define EMULTIHOP 72 /* Multihop attempted */ #define EDOTDOT 73 /* RFS specific error */ #define EBADMSG 74 /* Not a data message */ #define EOVERFLOW 75 /* Value too large for defined data type */ #define ENOTUNIQ 76 /* Name not unique on network */ #define EBADFD 77 /* File descriptor in bad state */ #define EREMCHG 78 /* Remote address changed */ #define ELIBACC 79 /* Can not access a needed shared library */ #define ELIBBAD 80 /* Accessing a corrupted shared library */ #define ELIBSCN 81 /* .lib section in a.out corrupted */ #define ELIBMAX 82 /* Attempting to link in too many shared libraries */ #define ELIBEXEC 83 /* Cannot exec a shared library directly */ #define EILSEQ 84 /* Illegal byte sequence */ #define ERESTART 85 /* Interrupted system call should be restarted */ #define ESTRPIPE 86 /* Streams pipe error */ #define EUSERS 87 /* Too many users */ #define ENOTSOCK 88 /* Socket operation on non-socket */ #define EDESTADDRREQ 89 /* Destination address required */ #define EMSGSIZE 90 /* Message too long */ #define EPROTOTYPE 91 /* Protocol wrong type for socket */ #define ENOPROTOOPT 92 /* Protocol not available */ #define EPROTONOSUPPORT 93 /* Protocol not supported */ #define ESOCKTNOSUPPORT 94 /* Socket type not supported */ #define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ #define EPFNOSUPPORT 96 /* Protocol family not supported */ #define EAFNOSUPPORT 97 /* Address family not supported by protocol */ #define EADDRINUSE 98 /* Address already in use */ #define EADDRNOTAVAIL 99 /* Cannot assign requested address */ #define ENETDOWN 100 /* Network is down */ #define ENETUNREACH 101 /* Network is unreachable */ #define ENETRESET 102 /* Network dropped connection because of reset */ #define ECONNABORTED 103 /* Software caused connection abort */ #define ECONNRESET 104 /* Connection reset by peer */ #define ENOBUFS 105 /* No buffer space available */ #define EISCONN 106 /* Transport endpoint is already connected */ #define ENOTCONN 107 /* Transport endpoint is not connected */ #define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ #define ETOOMANYREFS 109 /* Too many references: cannot splice */ #define ETIMEDOUT 110 /* Connection timed out */ #define ECONNREFUSED 111 /* Connection refused */ #define EHOSTDOWN 112 /* Host is down */ #define EHOSTUNREACH 113 /* No route to host */ #define EALREADY 114 /* Operation already in progress */ #define EINPROGRESS 115 /* Operation now in progress */ #define ESTALE 116 /* Stale NFS file handle */ #define EUCLEAN 117 /* Structure needs cleaning */ #define ENOTNAM 118 /* Not a XENIX named type file */ #define ENAVAIL 119 /* No XENIX semaphores available */ #define EISNAM 120 /* Is a named type file */ #define EREMOTEIO 121 /* Remote I/O error */ #define EDQUOT 122 /* Quota exceeded */ #define ENOMEDIUM 123 /* No medium found */ #define EMEDIUMTYPE 124 /* Wrong medium type */ #endif /* _ERRNO_H */ syslinux-legacy-3.63+dfsg/com32/include/stddef.h0000664000175000017500000000046110777447272020204 0ustar evanevan/* * stddef.h */ #ifndef _STDDEF_H #define _STDDEF_H #ifndef __KLIBC__ # define __KLIBC__ 1 #endif #include #undef NULL #ifdef __cplusplus # define NULL 0 #else # define NULL ((void *)0) #endif #undef offsetof #define offsetof(t,m) ((size_t)&((t *)0)->m) #endif /* _STDDEF_H */ syslinux-legacy-3.63+dfsg/com32/include/cpuid.h0000664000175000017500000001761610777447272020051 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef CPUID_H #define CPUID_H #include "stdbool.h" #include "cpufeature.h" #define u32 unsigned int #define __u32 u32 #define __u16 unsigned short #define __u8 unsigned char #define PAGE_SIZE 4096 #define CPU_MODEL_SIZE 48 #define CPU_VENDOR_SIZE 48 typedef struct { __u32 l; __u32 h; } __u64; typedef struct { bool fpu; /* Onboard FPU */ bool vme; /* Virtual Mode Extensions */ bool de; /* Debugging Extensions */ bool pse; /* Page Size Extensions */ bool tsc; /* Time Stamp Counter */ bool msr; /* Model-Specific Registers, RDMSR, WRMSR */ bool pae; /* Physical Address Extensions */ bool mce; /* Machine Check Architecture */ bool cx8; /* CMPXCHG8 instruction */ bool apic;/* Onboard APIC */ bool sep; /* SYSENTER/SYSEXIT */ bool mtrr;/* Memory Type Range Registers */ bool pge; /* Page Global Enable */ bool mca; /* Machine Check Architecture */ bool cmov;/* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */ bool pat; /* Page Attribute Table */ bool pse_36; /* 36-bit PSEs */ bool psn; /* Processor serial number */ bool clflsh; /* Supports the CLFLUSH instruction */ bool dts; /* Debug Trace Store */ bool acpi;/* ACPI via MSR */ bool mmx; /* Multimedia Extensions */ bool fxsr;/* FXSAVE and FXRSTOR instructions (fast save and restore */ /* of FPU context), and CR4.OSFXSR available */ bool sse; /* Streaming SIMD Extensions */ bool sse2;/* Streaming SIMD Extensions 2*/ bool ss; /* CPU self snoop */ bool htt; /* Hyper-Threading */ bool acc; /* Automatic clock control */ bool syscall; /* SYSCALL/SYSRET */ bool mp; /* MP Capable. */ bool nx; /* Execute Disable */ bool mmxext; /* AMD MMX extensions */ bool lm; /* Long Mode (x86-64) */ bool nowext;/* AMD 3DNow! extensions */ bool now; /* 3DNow! */ bool smp; /* A smp configuration has been found*/ } __attribute__((__packed__)) s_cpu_flags; typedef struct { char vendor[CPU_VENDOR_SIZE]; __u8 vendor_id; __u8 family; char model[CPU_MODEL_SIZE]; __u8 model_id; __u8 stepping; s_cpu_flags flags; } s_cpu; /**********************************************************************************/ /**********************************************************************************/ /* From this point this is some internal stuff mainly taken from the linux kernel */ /**********************************************************************************/ /**********************************************************************************/ /* * EFLAGS bits */ #define X86_EFLAGS_CF 0x00000001 /* Carry Flag */ #define X86_EFLAGS_PF 0x00000004 /* Parity Flag */ #define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */ #define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */ #define X86_EFLAGS_SF 0x00000080 /* Sign Flag */ #define X86_EFLAGS_TF 0x00000100 /* Trap Flag */ #define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */ #define X86_EFLAGS_DF 0x00000400 /* Direction Flag */ #define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */ #define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */ #define X86_EFLAGS_NT 0x00004000 /* Nested Task */ #define X86_EFLAGS_RF 0x00010000 /* Resume Flag */ #define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */ #define X86_EFLAGS_AC 0x00040000 /* Alignment Check */ #define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */ #define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ #define X86_VENDOR_INTEL 0 #define X86_VENDOR_CYRIX 1 #define X86_VENDOR_AMD 2 #define X86_VENDOR_UMC 3 #define X86_VENDOR_NEXGEN 4 #define X86_VENDOR_CENTAUR 5 #define X86_VENDOR_RISE 6 #define X86_VENDOR_TRANSMETA 7 #define X86_VENDOR_NSC 8 #define X86_VENDOR_NUM 9 #define X86_VENDOR_UNKNOWN 0xff static inline int test_bit(int nr, const volatile unsigned long *addr) { return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0; } #define cpu_has(c, bit) test_bit(bit, (c)->x86_capability) /* * CPU type and hardware bug flags. Kept separately for each CPU. * Members of this structure are referenced in head.S, so think twice * before touching them. [mj] */ struct cpuinfo_x86 { __u8 x86; /* CPU family */ __u8 x86_vendor; /* CPU vendor */ __u8 x86_model; __u8 x86_mask; char wp_works_ok; /* It doesn't on 386's */ char hlt_works_ok; /* Problems on some 486Dx4's and old 386's */ char hard_math; char rfu; int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */ unsigned long x86_capability[NCAPINTS]; char x86_vendor_id[16]; char x86_model_id[64]; int x86_cache_size; /* in KB - valid for CPUS which support this call */ int x86_cache_alignment; /* In bytes */ char fdiv_bug; char f00f_bug; char coma_bug; char pad0; int x86_power; unsigned long loops_per_jiffy; #ifdef CONFIG_SMP cpumask_t llc_shared_map; /* cpus sharing the last level cache */ #endif unsigned char x86_max_cores; /* cpuid returned max cores value */ unsigned char booted_cores; /* number of cores as seen by OS */ unsigned char apicid; } __attribute__((__packed__)); #endif struct cpu_model_info { int vendor; int family; char *model_names[16]; }; /* attempt to consolidate cpu attributes */ struct cpu_dev { char * c_vendor; /* some have two possibilities for cpuid string */ char * c_ident[2]; struct cpu_model_info c_models[4]; void (*c_init)(struct cpuinfo_x86 * c); void (*c_identify)(struct cpuinfo_x86 * c); unsigned int (*c_size_cache)(struct cpuinfo_x86 * c, unsigned int size); }; /* * Generic CPUID function * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx * resulting in stale register contents being returned. */ static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { __asm__("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "0" (op), "c"(0)); } /* * Structure definitions for SMP machines following the * Intel Multiprocessing Specification 1.1 and 1.4. */ /* * This tag identifies where the SMP configuration * information is. */ #define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_') struct intel_mp_floating { char mpf_signature[4]; /* "_MP_" */ unsigned long mpf_physptr; /* Configuration table address */ unsigned char mpf_length; /* Our length (paragraphs) */ unsigned char mpf_specification;/* Specification version */ unsigned char mpf_checksum; /* Checksum (makes sum 0) */ unsigned char mpf_feature1; /* Standard or configuration ? */ unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */ unsigned char mpf_feature3; /* Unused (0) */ unsigned char mpf_feature4; /* Unused (0) */ unsigned char mpf_feature5; /* Unused (0) */ }; extern void get_cpu_vendor(struct cpuinfo_x86 *c); extern void detect_cpu(s_cpu *cpu); syslinux-legacy-3.63+dfsg/com32/include/com32.h0000664000175000017500000000763210777447272017665 0ustar evanevan/* ----------------------------------------------------------------------- * * Not Copyright 2002-2008 H. Peter Anvin * This file is in the public domain. * ----------------------------------------------------------------------- */ /* * com32.h * * Common declarations for com32 programs. */ #ifndef _COM32_H #define _COM32_H #include #include /* For __cdecl */ /* * This structure defines the register frame used by the * system call interface. * * The syscall interface is: * * __intcall(interrupt_#, source_regs, return_regs) * __farcall(seg, offs, source_regs, return_regs) */ typedef union { uint32_t l; uint16_t w[2]; uint8_t b[4]; } reg32_t; typedef struct { uint16_t gs; /* Offset 0 */ uint16_t fs; /* Offset 2 */ uint16_t es; /* Offset 4 */ uint16_t ds; /* Offset 6 */ reg32_t edi; /* Offset 8 */ reg32_t esi; /* Offset 12 */ reg32_t ebp; /* Offset 16 */ reg32_t _unused_esp; /* Offset 20 */ reg32_t ebx; /* Offset 24 */ reg32_t edx; /* Offset 28 */ reg32_t ecx; /* Offset 32 */ reg32_t eax; /* Offset 36 */ reg32_t eflags; /* Offset 40 */ } com32sys_t; /* EFLAGS definitions */ #define EFLAGS_CF 0x00000001 #define EFLAGS_PF 0x00000004 #define EFLAGS_AF 0x00000010 #define EFLAGS_ZF 0x00000040 #define EFLAGS_SF 0x00000080 #define EFLAGS_TF 0x00000100 #define EFLAGS_IF 0x00000200 #define EFLAGS_DF 0x00000400 #define EFLAGS_OF 0x00000800 #define EFLAGS_IOPL 0x00003000 #define EFLAGS_NT 0x00004000 #define EFLAGS_RF 0x00010000 #define EFLAGS_VM 0x00020000 #define EFLAGS_AC 0x00040000 #define EFLAGS_VIF 0x00080000 #define EFLAGS_VIP 0x00100000 #define EFLAGS_ID 0x00200000 extern struct com32_sys_args { uint32_t cs_sysargs; char *cs_cmdline; void __cdecl (*cs_intcall)(uint8_t, const com32sys_t *, com32sys_t *); void *cs_bounce; uint32_t cs_bounce_size; void __cdecl (*cs_farcall)(uint32_t, const com32sys_t *, com32sys_t *); int __cdecl (*cs_cfarcall)(uint32_t, const void *, uint32_t); } __com32; /* * System call wrapper functions */ void __intcall(uint8_t __i, const com32sys_t *__sr, com32sys_t *__dr); void __farcall(uint16_t __cs, uint16_t __ip, const com32sys_t *__sr, com32sys_t *__dr); int __cfarcall(uint16_t __cs, uint16_t __ip, const void *__stack, uint32_t __stack_size); extern const com32sys_t __com32_zero_regs; /* * These functions convert between linear pointers in the range * 0..0xFFFFF and real-mode style SEG:OFFS pointers. Note that a * 32-bit linear pointer is not compatible with a SEG:OFFS pointer * stored in two consecutive 16-bit words. * * Use OFFS_WRT() if you want to compute an offset relative to a * specific segment. OFFS_VALID() will return whether or not the * pointer is actually reachable from the target segment. */ static inline uint16_t SEG(const volatile void *__p) { return (uint16_t)(((uintptr_t)__p) >> 4); } static inline uint16_t OFFS(const volatile void *__p) { /* The double cast here is to shut up gcc */ return (uint16_t)(uintptr_t)__p & 0x000F; } static inline uint16_t OFFS_WRT(const volatile void *__p, uint16_t seg) { return (uint16_t)((uintptr_t)__p - ((uintptr_t)seg << 4)); } static inline int OFFS_VALID(const volatile void *__p, uint16_t seg) { uintptr_t __segstart = (uintptr_t)seg << 4; uintptr_t __ptr = (uintptr_t)__p; return (__ptr >= __segstart) && (__ptr <= __segstart+0xffff); } static inline void *MK_PTR(uint16_t __seg, uint16_t __offs) { return (void *)((__seg << 4) + __offs); } /* Some tools to handle 16:16 far pointers in memory */ struct __far_ptr { uint32_t __ptr; } __attribute__((packed)); typedef struct __far_ptr far_ptr_t; static inline void *GET_PTR(far_ptr_t __fptr) { return MK_PTR(__fptr.__ptr >> 16, __fptr.__ptr); } static inline far_ptr_t FAR_PTR(void *__ptr) { far_ptr_t __fptr; __fptr.__ptr = (SEG(__ptr) << 16) + OFFS(__ptr); return __fptr; } #endif /* _COM32_H */ syslinux-legacy-3.63+dfsg/com32/include/cpufeature.h0000664000175000017500000001434010777447272021077 0ustar evanevan/* * cpufeature.h * * Defines x86 CPU feature bits */ #ifndef __ASM_I386_CPUFEATURE_H #define __ASM_I386_CPUFEATURE_H #define NCAPINTS 7 /* N 32-bit words worth of info */ /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */ #define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */ #define X86_FEATURE_VME (0*32+ 1) /* Virtual Mode Extensions */ #define X86_FEATURE_DE (0*32+ 2) /* Debugging Extensions */ #define X86_FEATURE_PSE (0*32+ 3) /* Page Size Extensions */ #define X86_FEATURE_TSC (0*32+ 4) /* Time Stamp Counter */ #define X86_FEATURE_MSR (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */ #define X86_FEATURE_PAE (0*32+ 6) /* Physical Address Extensions */ #define X86_FEATURE_MCE (0*32+ 7) /* Machine Check Architecture */ #define X86_FEATURE_CX8 (0*32+ 8) /* CMPXCHG8 instruction */ #define X86_FEATURE_APIC (0*32+ 9) /* Onboard APIC */ #define X86_FEATURE_SEP (0*32+11) /* SYSENTER/SYSEXIT */ #define X86_FEATURE_MTRR (0*32+12) /* Memory Type Range Registers */ #define X86_FEATURE_PGE (0*32+13) /* Page Global Enable */ #define X86_FEATURE_MCA (0*32+14) /* Machine Check Architecture */ #define X86_FEATURE_CMOV (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */ #define X86_FEATURE_PAT (0*32+16) /* Page Attribute Table */ #define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */ #define X86_FEATURE_PN (0*32+18) /* Processor serial number */ #define X86_FEATURE_CLFLSH (0*32+19) /* Supports the CLFLUSH instruction */ #define X86_FEATURE_DTES (0*32+21) /* Debug Trace Store */ #define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */ #define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */ #define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */ /* of FPU context), and CR4.OSFXSR available */ #define X86_FEATURE_XMM (0*32+25) /* Streaming SIMD Extensions */ #define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */ #define X86_FEATURE_SELFSNOOP (0*32+27) /* CPU self snoop */ #define X86_FEATURE_HT (0*32+28) /* Hyper-Threading */ #define X86_FEATURE_ACC (0*32+29) /* Automatic clock control */ #define X86_FEATURE_IA64 (0*32+30) /* IA-64 processor */ /* AMD-defined CPU features, CPUID level 0x80000001, word 1 */ /* Don't duplicate feature flags which are redundant with Intel! */ #define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */ #define X86_FEATURE_MP (1*32+19) /* MP Capable. */ #define X86_FEATURE_NX (1*32+20) /* Execute Disable */ #define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ #define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */ #define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */ #define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */ /* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */ #define X86_FEATURE_RECOVERY (2*32+ 0) /* CPU in recovery mode */ #define X86_FEATURE_LONGRUN (2*32+ 1) /* Longrun power control */ #define X86_FEATURE_LRTI (2*32+ 3) /* LongRun table interface */ /* Other features, Linux-defined mapping, word 3 */ /* This range is used for feature bits which conflict or are synthesized */ #define X86_FEATURE_CXMMX (3*32+ 0) /* Cyrix MMX extensions */ #define X86_FEATURE_K6_MTRR (3*32+ 1) /* AMD K6 nonstandard MTRRs */ #define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */ #define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */ /* cpu types for specific tunings: */ #define X86_FEATURE_K8 (3*32+ 4) /* Opteron, Athlon64 */ #define X86_FEATURE_K7 (3*32+ 5) /* Athlon */ #define X86_FEATURE_P3 (3*32+ 6) /* P3 */ #define X86_FEATURE_P4 (3*32+ 7) /* P4 */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ #define X86_FEATURE_MWAIT (4*32+ 3) /* Monitor/Mwait support */ #define X86_FEATURE_DSCPL (4*32+ 4) /* CPL Qualified Debug Store */ #define X86_FEATURE_EST (4*32+ 7) /* Enhanced SpeedStep */ #define X86_FEATURE_TM2 (4*32+ 8) /* Thermal Monitor 2 */ #define X86_FEATURE_CID (4*32+10) /* Context ID */ #define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */ #define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */ /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ #define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */ #define X86_FEATURE_XSTORE_EN (5*32+ 3) /* on-CPU RNG enabled */ #define X86_FEATURE_XCRYPT (5*32+ 6) /* on-CPU crypto (xcrypt insn) */ #define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* on-CPU crypto enabled */ /* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ #define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */ #define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */ #define cpu_has(c, bit) test_bit(bit, (c)->x86_capability) #define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability) #define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU) #define cpu_has_vme boot_cpu_has(X86_FEATURE_VME) #define cpu_has_de boot_cpu_has(X86_FEATURE_DE) #define cpu_has_pse boot_cpu_has(X86_FEATURE_PSE) #define cpu_has_tsc boot_cpu_has(X86_FEATURE_TSC) #define cpu_has_pae boot_cpu_has(X86_FEATURE_PAE) #define cpu_has_pge boot_cpu_has(X86_FEATURE_PGE) #define cpu_has_apic boot_cpu_has(X86_FEATURE_APIC) #define cpu_has_sep boot_cpu_has(X86_FEATURE_SEP) #define cpu_has_mtrr boot_cpu_has(X86_FEATURE_MTRR) #define cpu_has_mmx boot_cpu_has(X86_FEATURE_MMX) #define cpu_has_fxsr boot_cpu_has(X86_FEATURE_FXSR) #define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM) #define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2) #define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3) #define cpu_has_ht boot_cpu_has(X86_FEATURE_HT) #define cpu_has_mp boot_cpu_has(X86_FEATURE_MP) #define cpu_has_nx boot_cpu_has(X86_FEATURE_NX) #define cpu_has_k6_mtrr boot_cpu_has(X86_FEATURE_K6_MTRR) #define cpu_has_cyrix_arr boot_cpu_has(X86_FEATURE_CYRIX_ARR) #define cpu_has_centaur_mcr boot_cpu_has(X86_FEATURE_CENTAUR_MCR) #define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE) #define cpu_has_xstore_enabled boot_cpu_has(X86_FEATURE_XSTORE_EN) #define cpu_has_xcrypt boot_cpu_has(X86_FEATURE_XCRYPT) #define cpu_has_xcrypt_enabled boot_cpu_has(X86_FEATURE_XCRYPT_EN) #endif /* __ASM_I386_CPUFEATURE_H */ /* * Local Variables: * mode:c * comment-column:42 * End: */ syslinux-legacy-3.63+dfsg/com32/include/stdbool.h0000664000175000017500000000072110777447272020400 0ustar evanevan/* * * stdbool.h */ #ifndef _STDBOOL_H #define _STDBOOL_H #ifndef __cplusplus #if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) # if !defined(__GNUC__) ||(__GNUC__ < 3) typedef char _Bool; /* For C compilers without _Bool */ # endif #endif #define bool _Bool #define true 1 #define false 0 #else /* C++ */ #define bool bool #define true true #define false false #endif #define __bool_true_false_are_defined 1 #endif /* _STDBOOL_H */ syslinux-legacy-3.63+dfsg/com32/samples/0000775000175000017500000000000010777447345016603 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/samples/cat.c0000664000175000017500000000101510777447273017513 0ustar evanevan#include #include #include int main(int argc, char *argv[]) { FILE *f; int ch; int i; openconsole(&dev_stdcon_r, &dev_stdcon_w); printf("argv = %p\n", argv); for ( i = 0 ; i <= argc ; i++ ) printf("argv[%d] = %p = \"%s\"\n", i, argv[i], argv[i]); if ( argc < 2 ) { fprintf(stderr, "Missing file name!\n"); exit(1); } printf("File = %s\n", argv[1]); f = fopen(argv[1], "r"); while ( (ch = getc(f)) != EOF ) putchar(ch); fclose(f); return 0; } syslinux-legacy-3.63+dfsg/com32/samples/fancyhello.c0000664000175000017500000000220310777447273021070 0ustar evanevan /* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * fancyhello.c * * Hello, World! using libcom32 and ANSI console; also possible to compile * as a Linux application for testing. */ #include #include #include /* Provided by libutil */ int main(void) { char buffer[1024]; console_ansi_std(); printf("\033[1;33;44m *** \033[37mHello, World!\033[33m *** \033[0m\n"); for (;;) { printf("\033[1;36m>\033[0m "); fgets(buffer, sizeof buffer, stdin); if ( !strncmp(buffer, "exit", 4) ) break; printf("\033[1m:\033[0m %s", buffer); } return 0; } syslinux-legacy-3.63+dfsg/com32/samples/vesainfo.c320000775000175000017500000001121010777447342020721 0ustar evanevanL!1"()t$"g;vA"R P("("sXZ"L$qUWVSQ!!C "VBE2f"O؃f"f""ʸ f="OtL q;VESAt b ZfCRRPh #Sҍ<E~D$t1f"Of"f"f""ʸK f="Ou:PPF$PF"PF PFPFPFPFPPPh n0ffV1Y[^_]aÐUWVS Ӊ͉1,Eى u"t t t )ÅuЉ [^_]ÐL$$L$T$ 7Ð  x  ÐVSÍt$QѺ'x=~ى‰u [^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$!%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$,!L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$p!ЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$!T$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$D!D$D!D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u!1I|$Xt ;L$X~L$X9L$\~D<PSPh{ CD$H9s .u1Y[^_]aÐVW։ljsft_^ÐL$$L$T$ ÐVSÍt$QѺ'x=~ى‰ [^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$ %u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$ L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$ ЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$!T$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$D9!D$D(!D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u 1I|$Xt ;L$X~L$X9L$\~r|h^T"3%0:D0123456789ABCDEF0123456789abcdefB p  B'syslinux-legacy-3.63+dfsg/com32/samples/resolv.c0000664000175000017500000000272310777447273020265 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * resolv.c * * Resolve an IP address */ #include #include #include #include #include uint32_t resolv(const char *name) { com32sys_t reg; strcpy((char *)__com32.cs_bounce, name); memset(®, 0, sizeof reg); reg.eax.w[0] = 0x0010; reg.ebx.w[0] = OFFS(__com32.cs_bounce); reg.es = SEG(__com32.cs_bounce); __intcall(0x22, ®, ®); if ( reg.eflags.l & EFLAGS_CF ) return 0; else return reg.eax.l; } int main(int argc, char *argv[]) { uint32_t ip; openconsole(&dev_null_r, &dev_stdcon_w); if ( argc < 2 ) { fputs("Usage: resolv hostname\n", stderr); exit(1); } ip = resolv(argv[1]); if ( ip ) { printf("%s = %u.%u.%u.%u\n", argv[1], (ip & 0xff), (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff); } else { printf("%s not found\n", argv[1]); } return 0; } syslinux-legacy-3.63+dfsg/com32/samples/cat.c320000775000175000017500000001301410777447342017662 0ustar evanevanL!1 &c+)t$$&g;vA(&R P%%sXZ&L$qWVSQ ljֺ %$4RRVh#1PPSh#C9~O$PPvh$ $FWà uC" 1 Y[^_aÐD$HtD$VSƸ15rt +tau#wu BBB uŅtQhPV y1@Z[^ÐшD$D$HtD$UWVSƉՉ1҉وJ[^_]LUWVS Ӊ͉1,Eى u@&t t t )ÅuЉ [^_]ÐUWVS Ӊ͉1,Eى u@&t t t )ÅuЉ [^_]Ð &L$$L$T$ ÐVSÍt$QѺ'x=~ى‰M[^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$,$%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$@$L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$$ЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$$T$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$D$D$D$D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u"$1I|$Xt ;L$X~L$X9L$\~C9vNjS'|$){{ ){@D$l[^_]ÐW8fxt8D$ D$ 1|$fD$0BfD$PjD$Pj",&18_VSƉ1dډ"u8Kډ u1ډu0Z[^ÐUWVS ƉL$1E~tF@FNE u*/^ h @ډhF^uG;l$r [^_]WVS0ΉӍ|$ 1D$)1; uD$ T$1ɸ!D$ CT$1ɸ!Ouɉ0[^_ÐUWVSlT$͍|$@ 11AD$e \$t$@ى!|$8t#D$eى!D$8T$G9ul[^_]Ð@&ÐVW։ljsft_^ÐWVS$Ήiً<$$Z[^_VS։19s@A1u[^ÐQRP,&ÐlUWVS ljօu1Pu1Ft Ѕt@&1`&;u{tE t(@@&\8%CP%C CtWt҅u*;t3Vt҅t uvus@&o [^_]ÐUWVSʼn։L$@@D$1T$T$0HtT$ tuA tYu5)tONL%T$KL%T$u)딋D$H9sT$GFw $T$G[^_]Ð@&Ð<=&t!L$%"D$8Ѓ&<argv = %p argv[%d] = %p = "%s" Missing file name! File = %s r(null)z"w  */8I~0123456789ABCDEF0123456789abcdef\p B  `!  B#`+syslinux-legacy-3.63+dfsg/com32/samples/advdump.c0000664000175000017500000000226210777447273020411 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * advdump.c * * Dump the contents of the syslinux ADV */ #include #include #include #include int main(void) { uint8_t *p, *ep; size_t s = syslinux_adv_size(); char buf[256]; openconsole(&dev_stdcon_r, &dev_stdcon_w); p = syslinux_adv_ptr(); printf("ADV size: %zd bytes at %p\n", s, p); ep = p+s; /* Need at least opcode+len */ while (p < ep-1 && *p) { int t = *p++; int l = *p++; if (p+l > ep) break; memcpy(buf, p, l); buf[l] = '\0'; printf("ADV %3d: \"%s\"\n", t, buf); p += l; } return 0; } syslinux-legacy-3.63+dfsg/com32/samples/serialinfo.c320000775000175000017500000001001010777447342021237 0ustar evanevanL!1 %)t$$ g;vA( R? PsXZ L$qSQ| PP Ph\^Y[ PhxJf ftRRȻؙPh"PP Ph 1Y[aÃL$$L$T$ ÐVSÍt$QѺ'x=~ى‰ [^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$ЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$0T$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$DiD$DXD$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u1I|$Xt ;L$X~L$X9L$\~ #include int main(int argc, char *argv[]) { syslinux_local_boot(argc > 1 ? atoi(argv[1]) : 0); return 0; } syslinux-legacy-3.63+dfsg/com32/samples/serialinfo.c0000664000175000017500000000214710777447273021106 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * serialinfo.c * * Print serial port info */ #include #include #include #include int main(void) { const struct syslinux_serial_console_info *si; openconsole(&dev_null_r, &dev_stdcon_w); si = syslinux_serial_console_info(); printf("Serial port base: %#06x\n", si->iobase); printf("Serial port divisor: %5d", si->divisor); if (si->divisor) printf(" (%d baud)", 115200/si->divisor); printf("\n" "Flow control bits: %#05x\n", si->flowctl); return 0; } syslinux-legacy-3.63+dfsg/com32/samples/hello.c0000664000175000017500000000163110777447273020053 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * hello.c * * Hello, World! using libcom32 */ #include #include #include int main(int argc, char *argv[]) { int i; openconsole(&dev_stdcon_r, &dev_stdcon_w); printf("Hello, World!\n"); for (i = 1; i < argc; i++) printf("%s%c", argv[i], (i == argc-1) ? '\n' : ' '); return 0; } syslinux-legacy-3.63+dfsg/com32/samples/keytest.c320000775000175000017500000002232010777447343020604 0ustar evanevanL!14<)t$4g;vA4R P@4D4sXZ4L$qQPPjh -.- hM-1ҸtF?t"@=w|PPQh]-뾃 hd-{2uV-1L!tRRPhj-ɐ 21 q- 4{-%UWVSD$ff1H 1T$D$H9 t @u3=7 u*1 f)t fvtmftf9w^a 1 ŊD$D<G.;{uSD$Mu/}SD$5i0t D$[^_]ÐD$aHtD$ÃшD$D$HtD$UWVSƉՉ1҉وJ[^_]LUWVS Ӊ͉1,Eى u7t t t )ÅuЉ [^_]ÐUWVS Ӊ͉1,Eى u7t t t )ÅuЉ [^_]ÐVSΉÉ1)‰uCANu[^Ð 4L$$L$T$ 7Ð x,- < ÐVSÍt$QѺ'x=~ى‰[^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$<1%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$P1L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$1ЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$1T$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$D1D$D1D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u311I|$Xt ;L$X~L$X9L$\~w KfJ mt'wlsu1D$)D$;D$|D$HD$;D$|R\$K)FD$;D$|\$K\$D$)y1D$1RC;D$| D$H=y1SG@H;D$| L$Iy1;T$|\$K\$ЅL1EtR\$t$NPPSVى|$T$ J9PPKD$0RV1|$\$PPCPD$ HP11҉t$_XD$0SJR1rVVD$HPD$ HP1>t"t@;L$SSQD$ HPL$RRQHP1҉\$L$PPQD$ HP1҉t$1ht G$G,D$(|$ WD<1$2BB B BBBB B ~BuBlBcB ZBQBHB?3B3BB#BB3B B AT$(;J8D$G)W(O)L$o(G@\$(1#C0PЃ kG@ G@L$(A;<=>?@ABCDHPKMIQGORS--------- - - - -!-"-#-$-%-&-'-(-)-00000000000000 0 0 0 0!0"0#0$0$1%1% 1&1&1'1'1'!1(%1(*1).1[[AOP[[BOQ[[COR[[DOS[[E[15~[17~[18~[19~[20~[21~[23~[24~[5~[6~[1~[4~OF[2~[@[3~(null)jg(9nw0123456789ABCDEF0123456789abcdefB"($  B B#"($default0%&'++*++++#++,++++++++++++++5+5++>+G++P+++Y+Y+Y+Y+Y+Y+Y+Y+e+u+++++++++++ٿ__ô³؜ %@<##l#t""64422syslinux-legacy-3.63+dfsg/com32/samples/fancyhello.lnx0000775000175000017500000002530510777447343021460 0ustar evanevanELF4L4 (&#444444ԘԘHHHDDPtdDDDQtd/lib/ld-linux.so.2GNU GNU J9; +" )K8gUaj2 ;qq`49Y_)AK؇R.__gmon_start__libc.so.6_IO_stdin_usedputsstdinprintffgetstcsetattrstdoutstderrfwritetcgetattrsetbuf__libc_start_mainGLIBC_2.0ii    ęș̙ U`5%%h%h%h%h%h %h(%ęh0%șh8p%̙h@`1^PTRhh QVhdwUS[t2X[ÐUS=u?̘-ĘX9v&Ę9w[]Ít&'UИtt $ИÐL$qUWVSQ$$D$D$$a޿8t\$$#h밸Y[^_]aÐUD$ $&USTD$$D$$D$$]\$$E EM \$D$$D$ D$ D$$0T[]UD$ D$ D$$:nD$ D$$rÐU]Ít&'UWVS^uE)E}Ut+1ƍED$E D$E$9}u߃[^_]Ë$ÐUSt Ћu[]US[Y[ *** Hello, World! *** > exit: %s;4PzR| AB 8iAB C Ѓ o Hh oHoo*Ԙ.>N^n~GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)d66main#6console_ansi_std2d;0QmLsintG8aoQm-lZ#6### O#^#-### #$8#(  #,}"#0$#4.&Z#8 *Z#<,z#@0>#D^1L#F#2#G6#H?#LH#THI#XJ#\K#`L%#dNZ#hP#l C-  # # Z#t  m  ' BZd w t;0QmLsintG8aoQm-lZ#6### O#^#-### #$8#(  #,}"#0$#4.&Z#8 *Z#<,z#@0>#D^1L#F#2#G6#H?#LH#THI#XJ#\K#`L%#dNZ#hP#l C-  # # Z#t  m  '/70c0{<  # !# "# l## W$# ^%{# N&#4 '#8   =CIotioJ B: 4% : ; I$ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/ .? : ; ' I@4: ; I !I/4: ; I? < % : ; I$ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/ .: ; ' @.? : ; ' @4: ; I 4: ; I 4: ; I? <  /usr/include/usr/include/bits/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includefancyhello.cstdio.hlibio.htypes.hstddef.hdiZ## /usr/include/bits/usr/include/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includeansiline.ctermios.hstdio.hlibio.htypes.hstddef.h<g= .xKKM0Ku%jfg%| (dD  F AB D| @AB @AB D@IAB _IO_buf_end_flags2_old_offset_IO_save_end_IO_write_endsize_tmainlong long unsigned int_IO_write_ptr_flagsshort int_markers_IO_read_end_unused2long long int_lock_cur_column/home/hpa/syslinux/release/syslinux-3.63/com32/samples_pos_sbuf_IO_FILEstdoutunsigned char__pad5_shortbuf_IO_marker_IO_backup_base__pad2_IO_write_base_vtable_offsetshort unsigned intfancyhello.c_next__pad1__pad3__pad4__quad_tbuffer__off64_t_chain__off_tstdin_IO_buf_base_mode_IO_read_base_IO_save_baseGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)_fileno_IO_read_ptr_IO_lock_tc_ispeedc_linec_cctcflag_tc_lflagansiline.ctermiosc_oflagconsole_cleanupc_ospeedspeed_tc_cflagoriginal_termios_settingsc_iflagconsole_initconsole_ansi_std/home/hpa/syslinux/release/syslinux-3.63/com32/libutilcc_tstderrt Q t t uttuttuttu.symtab.strtab.shstrtab.interp.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data.bss.comment.debug_aranges.debug_pubnames.debug_info.debug_abbrev.debug_line.debug_frame.debug_str.debug_loc44#HH 1hh$Do0N V^o**koHH z hh  H Ѓ(ԇpDD``X Ę ИԘ  0Й  |  B @ V B K'5ADN0;Yd<"%: ' 4Hh*Hh  Ѓ   ԇD`ĘИԘЙ !" *Ę8ИESb x@ И  <I &7JԘSЙ ^2p    ԇq؇ Й( 9܇F̘S i c9u_ԙ\ԙ d Ѓ call_gmon_startcrtstuff.c__CTOR_LIST____DTOR_LIST____JCR_LIST__dtor_idx.5662completed.5660__do_global_dtors_auxframe_dummy__CTOR_END____FRAME_END____JCR_END____do_global_ctors_auxfancyhello.cansiline.cconsole_initoriginal_termios_settingsconsole_cleanup_GLOBAL_OFFSET_TABLE___init_array_end__init_array_start_DYNAMICdata_startsetbuf@@GLIBC_2.0__libc_csu_fini_start__gmon_start___Jv_RegisterClasses_fp_hw_finifgets@@GLIBC_2.0__libc_start_main@@GLIBC_2.0tcgetattr@@GLIBC_2.0_IO_stdin_used__data_startstderr@@GLIBC_2.0console_ansi_std__dso_handle__DTOR_END____libc_csu_initprintf@@GLIBC_2.0fwrite@@GLIBC_2.0__bss_startstdin@@GLIBC_2.0_endstdout@@GLIBC_2.0puts@@GLIBC_2.0tcsetattr@@GLIBC_2.0_edata__i686.get_pc_thunk.bxmain_initsyslinux-legacy-3.63+dfsg/com32/samples/resolv.c320000775000175000017500000001021010777447342020420 0ustar evanevanL!1 %)t$ g;vA RO P  sXZo W8¡ D$ D$ 1|$fD$0 ƒfT$$fD$L$ ʸ" D$4t1D$08_ÍL$qVSQÉֺl K^FT…t+QQP%PPPvh PPvh1Y[^aUWVSƉՉ1҉وJ[^_]UWVS Ӊ͉1,Eى u t t t )ÅuЉ [^_]Ð  L$$L$T$ ÐSÉABu[ÐVSÍt$QѺ'x=~ى‰9[^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$TЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$hT$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$DD$DD$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u1I|$Xt ;L$X~L$X9L$\~ #include #include #include #include #include /* Provided by libutil */ #include static void cooked_keys(void) { int key; printf("[cooked]"); for(;;) { key = get_key(stdin, 0); if ( key == 0x03 ) { printf("[done]\n"); exit(0); } else if ( key == '?' ) return; if ( key >= 0x20 && key < 0x100 ) { putchar(key); } else { printf("[%04x]", key); } } } static void raw_keys(void) { int key; printf("[raw]"); for(;;) { key = getc(stdin); if ( key == 0x03 ) { printf("[done]\n"); exit(0); } else if ( key == '!' ) return; printf("<%02x>", key); } } int main(void) { console_ansi_raw(); printf("CLK_TCK = %d\n", (int)CLK_TCK); printf("Press keys, end with Ctrl-C...\n"); for (;;) { cooked_keys(); raw_keys(); } } syslinux-legacy-3.63+dfsg/com32/samples/Makefile0000664000175000017500000000444710777447273020254 0ustar evanevan## ----------------------------------------------------------------------- ## ## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- ## ## samples for syslinux users ## TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \ then echo $(1); else echo $(2); fi; rm -f $$tmpf) M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,) CC = gcc LD = ld -m elf_i386 AR = ar NASM = nasm NASMOPT = -O9999 RANLIB = ranlib CFLAGS = $(M32) -mregparm=3 -DREGPARM=3 -W -Wall -march=i386 -Os \ -fomit-frame-pointer -D__COM32__ \ -nostdinc -iwithprefix include \ -I../libutil/include -I../include \ -Wp,-MT,$@,-MD,$(dir $@).$(notdir $@).d LNXCFLAGS = -W -Wall -O -g -I../libutil/include LNXSFLAGS = -g LNXLDFLAGS = -g SFLAGS = -D__COM32__ -march=i386 LDFLAGS = -T ../lib/com32.ld OBJCOPY = objcopy PPMTOLSS16 = ../ppmtolss16 LIBGCC := $(shell $(CC) --print-libgcc) LIBS = ../libutil/libutil_com.a ../lib/libcom32.a $(LIBGCC) LNXLIBS = ../libutil/libutil_lnx.a .SUFFIXES: .lss .c .o .elf .c32 .lnx all: hello.c32 cat.c32 resolv.c32 vesainfo.c32 serialinfo.c32 \ localboot.c32 \ fancyhello.c32 fancyhello.lnx \ keytest.c32 keytest.lnx \ advdump.c32 .PRECIOUS: %.o %.o: %.S $(CC) $(SFLAGS) -c -o $@ $< .PRECIOUS: %.o %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< .PRECIOUS: %.elf %.elf: %.o $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ .PRECIOUS: %.lo %.lo: %.S $(CC) $(LNXSFLAGS) -c -o $@ $< .PRECIOUS: %.lo %.lo: %.c $(CC) $(LNXCFLAGS) -c -o $@ $< .PRECIOUS: %.lnx %.lnx: %.lo $(LNXLIBS) $(CC) $(LNXLDFLAGS) -o $@ $^ %.c32: %.elf $(OBJCOPY) -O binary $< $@ tidy: rm -f *.o *.lo *.a *.lst *.elf .*.d clean: tidy rm -f *.lss *.c32 *.lnx *.com spotless: clean rm -f *~ \#* install: # Don't install samples -include .*.d syslinux-legacy-3.63+dfsg/com32/samples/fancyhello.c320000775000175000017500000002072010777447343021242 0ustar evanevanL!119)t$1g;vA1Rw P11sXZ1L$qSQe`-k h->\$m-htPPSh-1Y[aÐ .. - X-IUWVS lj։͉ u 9u1C t Nۅt [^_]ÐUWVSƉՉ1҉وJ[^_]UWVS Ӊ͉1,Eى u4t t t )ÅuЉ [^_]ÐL$$L$T$ cÐ _x- l ÐWVSωƉ)‰ut FAOu1[^_ÐVSÍt$QѺ'x=~ى‰[^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$-%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$-L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$(.ЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$<.T$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$Du.D$Dd.D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u-1I|$Xt ;L$X~L$X9L$\~w KfJ mt'wlsu1D$)D$;D$|D$HD$;D$|R\$K)FD$;D$|\$K\$D$)y1D$1RC;D$| D$H=y1SG@H;D$| L$Iy1;T$|\$K\$ЅL1EtR\$t$NPPSVى|$T$ J9PPKD$0RV1|$\$PPCPD$ HP11҉t$_XD$0SJR1rVVD$HPD$ HP1>t"t@;L$SSQD$ HPL$RRQHP1҉\$L$PPQD$ HP1҉t$1ht G$G,D$(|$ WD<1$t/BB B BBBB B ~BuBlBcB ZBQBHB?h0B3BB#BB@0B B AT$(;J8D$G)W(O)L$o(G@\$(1#C0PЃ kG@ G@L$(A exit: %s (null)OJ~tj` .?'1<FP0123456789ABCDEF0123456789abcdefLB"($   B B#"($default0&0''+, +9+E++N+W++`++++++++++++++i+i++r+{+++++++++++++++++++++++++ٿ__ô³؜T%9##l#t""311L/T/syslinux-legacy-3.63+dfsg/com32/samples/hello.c320000775000175000017500000001101410777447342020214 0ustar evanevanL!1 "c')t$$"g;vA("RK P!!sXZ"L$qWVSQ Ɖ׺!  ^&F9t  RP4h. C9|1 Y[^_aÃL$$L$T$ 7Ð  x3  ÐVSÍt$QѺ'x=~ى‰ [^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$< %u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$P L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$ ЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$ T$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$D D$D D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u5 1I|$Xt ;L$X~L$X9L$\~p4ppfh$0123456789ABCDEF0123456789abcdefBP  Bl`'syslinux-legacy-3.63+dfsg/com32/samples/vesainfo.c0000664000175000017500000000356410777447273020571 0ustar evanevan/* * vesainfo.c * * Dump information about what VESA graphics modes are supported. */ #include #include #include #include #include #include "../lib/sys/vesa/vesa.h" /* Wait for a keypress */ static void wait_key(void) { char ch; while (fread(&ch, 1, 1, stdin) == 0) ; } static void print_modes(void) { static com32sys_t rm; struct vesa_general_info *gi; struct vesa_mode_info *mi; uint16_t mode, *mode_ptr; int lines; /* Allocate space in the bounce buffer for these structures */ gi = &((struct vesa_info *)__com32.cs_bounce)->gi; mi = &((struct vesa_info *)__com32.cs_bounce)->mi; gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */ rm.eax.w[0] = 0x4F00; /* Get SVGA general information */ rm.edi.w[0] = OFFS(gi); rm.es = SEG(gi); __intcall(0x10, &rm, &rm); if ( rm.eax.w[0] != 0x004F ) { printf("No VESA BIOS detected\n"); return; } else if ( gi->signature != VESA_MAGIC ) { printf("VESA information structure has bad magic, trying anyway...\n"); } printf("VBE version %d.%d\n" "Mode attrib h_res v_res bpp layout rpos gpos bpos\n", (gi->version >> 8) & 0xff, gi->version & 0xff); lines = 1; mode_ptr = GET_PTR(gi->video_mode_ptr); while ((mode = *mode_ptr++) != 0xFFFF) { if (++lines >= 23) { wait_key(); lines = 0; } rm.eax.w[0] = 0x4F01; /* Get SVGA mode information */ rm.ecx.w[0] = mode; rm.edi.w[0] = OFFS(mi); rm.es = SEG(mi); __intcall(0x10, &rm, &rm); /* Must be a supported mode */ if ( rm.eax.w[0] != 0x004f ) continue; printf("0x%04x 0x%04x %5u %5u %3u %6u %4u %4u %4u\n", mode, mi->mode_attr, mi->h_res, mi->v_res, mi->bpp, mi->memory_layout, mi->rpos, mi->gpos, mi->bpos); } } int main(void) { openconsole(&dev_rawcon_r, &dev_stdcon_w); print_modes(); return 0; } syslinux-legacy-3.63+dfsg/com32/samples/keytest.lnx0000775000175000017500000003703010777447343021022 0ustar evanevanELF 4.4 ('$444444<HHHDDPtdtttQtd/lib/ld-linux.so.2GNU GNU,) ݙ?%ChT@+")K8gUa4U2 I1pzB9_7f.9)u`d|@<D__gmon_start__libc.so.6_IO_stdin_usedexit_IO_putcputsstdinprintfsched_yield__errno_locationtcsetattrreadstdoutstderrfilenofwritetcgetattrtimes_IO_getcsetbuf__libc_start_mainsysconfGLIBC_2.0ii @D`     $ (,04UQ5%%h%h%h%h%h %h(% h0%h8p%h@`%hHP%hP@% hX0%$h` %(hh%,hp%0hx%4h1^PTRhhQVh/US[Ø tX[ÐUS=hu?- Xd9v&d d9wh[]Ít&'Utt $ÐL$qUQ $*D$$l$$zrD$D$ƒu$j$?t/@=w`D$$^몉T$$ $D$u$$4!MD$$뻐UD$$~USTD$D$D$`$D$@$]\$$#E EeEE\$D$$D`D$ D$ D$$T[]U`D$ D$ D$$ʋD$D$$UWVS,} ] $EE$D$UT$$It8 t&ux$+utC$H gfff)ƒ9~+} t;u } ft 9u t&{K$ EEDE@UU܋M؋A9uu܋y9ۉ8u)U؋C9}u܋M؋y9ۉ8}ȎtE 맸 EE,[^_]ÐU]Ít&'UWVS^=/E)E}Ut+1ƍED$E D$E$9}u߃[^_]Ë$ÐUSt Ћu[]US[ä Y[CLK_TCK = %d [cooked][done][%04x][raw]<%02x>Press keys, end with Ctrl-C...;<=>?@ABCDHPKMIQGORS    !" # $%&'()Ԏَݎ   ! ' -!1"5#9$=$B%F%K&O&T'X']'a(e(j)n[[AOP[[BOQ[[COR[[DOS[[E[15~[17~[18~[19~[20~[21~[23~[24~[5~[6~[1~[4~OF[2~[@[3~;4,PzR| AB 8iAB CLj  8o `@ o oo&6FVfvƅօGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)t.main#console_ansi_rawW@get_keyY50 intWs8a\Aom-9Z#?### ##+#T## e#$|#(" #,H"#0($#4&Z#8@*Z#<,z#@/0>#D1L#F2#G6#H?#LH#TI#XJ#\K#`L%#d/NZ#hKP#l L  ;# # Z#t  m  ' QQZ__cPZkeyZ.4key5Z#GZ2Nm,CO"IY 0 intWs8a\Aom-9Z#?### ##+#T## e#$|#(" #,H"#0($#4&Z#8@*Z#<,z#@/0>#D1L#F2#G6#H?#LH#TI#XJ#\K#`L%#d/NZ#hKP#l L  ;# # Z#t  m  'A700{<  # !# "# ## j$# q%{# a&#4 '#8   =vILjtioJ BLj:FS3Y~ 0 intWs8a\Aol1-9Z#?### ##+#T## e#$|#(" #,H"#0($#4&Z#8@*Z#<,z#@/0>#D1L#F2#G6#H?#LH#TI#XJ#\K#`L%#d/NZ#hKP#l L  ;# # Z#    'n=5T - W.Z# /Z# seq05#;7vyZ:fxfdxMzdnc{Zi{Zrv{Zkc| uX\}Zch~7uku`0 7  & 667@% : ; I$ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/ .? : ; ' I : ; I.: ; ' 4: ; I .? : ; ' I@1X Y  U411X Y 1 U414: ; I? < % : ; I$ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/ .: ; ' @.? : ; ' @4: ; I 4: ; I 4: ; I? < % : ; I$ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/ : ; I8 &I.? : ; ' I@: ; I: ; I4: ; I 4: ; I4: ; I4: ; I 4: ; I U4: ; I4: ; I? <  /usr/include/bits/usr/include/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includekeytest.cstdio.hstdio.hlibio.htypes.hstddef.hZUhY['\.  Y /usr/include/bits/usr/include/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includeansiraw.ctermios.hstdio.hlibio.htypes.hstddef.h<g= .xKKM0KKKu%hfg% /usr/include/usr/include/bits/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includeget_key.cstdio.hlibio.htypes.hstddef.htime.h >"-[xuoffK| $D  F AB A| <AB <AB D<LjIAB | tAB F_shortbufshort int_IO_lock_t_IO_buf_end_IO_write_end_flags_flags2_markersputcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)_posstdout_IO_write_baselong long unsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/samplescooked_keys_filenosize_t_vtable_offset_IO_read_base_IO_save_end_modekeytest.c_IO_read_ptr_IO_markerlong long int_IO_save_base__quad_t_IO_backup_base__pad1__pad2__pad3__pad4__pad5unsigned char_IO_read_endstdinraw_keys_lock_old_offset_IO_FILE_sbuf_IO_write_ptr__off_tshort unsigned intmain_chain_cur_column_next__off64_t_unused2_IO_buf_basec_ispeedc_linec_ccconsole_ansi_rawtcflag_tc_lflagtermiosc_oflagconsole_cleanupc_ospeedspeed_tc_cflagansiraw.coriginal_termios_settingsc_iflagconsole_init/home/hpa/syslinux/release/syslinux-3.63/com32/libutilcc_tstderrbufferkeycodeanothertimeout__clock_tget_keyget_key.ckeycodesstartseqlenlatenesst Q t t uafRfrP~PRRP>JPPPttuttuttutttuKKtu%%tu %pSIYPbnPP%V)0VKqV>Jabbh.symtab.strtab.shstrtab.interp.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data.bss.comment.debug_aranges.debug_pubnames.debug_info.debug_abbrev.debug_line.debug_frame.debug_str.debug_loc.debug_ranges44#HH 1hh$Do0N `V^o,ko   z @@  ``    88 ``  ttX    P88@<| <p`  `l. '5#A%N0&Y;* dF,H,r4@&= X:4Hh @ `    8`t 8@ !"#D * 8EdShbp xІ   <LjI @5FYb4t8 2 t     ` 1 8&CW h}zd8@hi 9_ <D&+`=Mbv<}9    call_gmon_startcrtstuff.c__CTOR_LIST____DTOR_LIST____JCR_LIST__dtor_idx.5662completed.5660__do_global_dtors_auxframe_dummy__CTOR_END____FRAME_END____JCR_END____do_global_ctors_auxkeytest.cansiraw.cconsole_initoriginal_termios_settingsconsole_cleanupget_key.ckeycodes_GLOBAL_OFFSET_TABLE___init_array_end__init_array_start_DYNAMICfileno@@GLIBC_2.0data_start__errno_location@@GLIBC_2.0setbuf@@GLIBC_2.0__libc_csu_finisysconf@@GLIBC_2.0get_key_start__gmon_start___Jv_RegisterClasses_fp_hwsched_yield@@GLIBC_2.0_fini__libc_start_main@@GLIBC_2.0_IO_getc@@GLIBC_2.0console_ansi_rawtcgetattr@@GLIBC_2.0read@@GLIBC_2.0_IO_stdin_used__data_startstderr@@GLIBC_2.0__dso_handle__DTOR_END____libc_csu_initprintf@@GLIBC_2.0fwrite@@GLIBC_2.0__bss_startstdin@@GLIBC_2.0_endstdout@@GLIBC_2.0puts@@GLIBC_2.0tcsetattr@@GLIBC_2.0_IO_putc@@GLIBC_2.0_edatatimes@@GLIBC_2.0exit@@GLIBC_2.0__i686.get_pc_thunk.bxmain_initsyslinux-legacy-3.63+dfsg/com32/modules/0000775000175000017500000000000010777447344016606 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/modules/pcitest.c320000775000175000017500000002364410777447341020603 0ustar evanevanL!17=)t$7g;vA7R[ PD7H7sXZ7UWVSňT$ 1D$g$D$ SSD$Ph3f|$ tD17TJ PQBPBPBPPQh3%C D$ 9|Gƈx9mu33QPRh3Ĭ[^_]ÍL$qVSQ쀉85P5 $|ډ ĀY[^aWVS14S CPCPCPPCPRPh 4BF 9|VVPh_4#[^_VW։ljsft_^ÐL$$L$T$ ÐVSÍt$QѺ'x=~ى‰[^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$4%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$4L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$4ЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$4T$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$D%5D$D5D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.uv41I|$Xt ;L$X~L$X9L$\~ C ud54 C z5 C z5 F9|55D$6$'5 $"5 $5 $5 D$<#< 'G ud5RG z5C9|55LŅy$Z5A$J50$*5$:5D$<#< < $j31_1Iv=w7$5$"$Z$J$:$*C$j1…u1ۉk$Z9uT$JW9u@$*yW!9u*$:cW!9u$G  C9|\$!l[^_]ÐUWVS š7t' ttG1 D$f D$fx} ƻ ljff%Ł  [^_]ÐUWVS š7t' ttB1 D$f ɉŋD$ifxz ƻ ljff%Ł [^_] [^_]ÐUWVS<ƍD$D$ 1ljىft$4fD$(T$L$ʸ4D$8tD$0<[^_]WS؉…t 1׉Z[_ÐUWVS lj։͉ u 9u1C t Nۅt [^_]ÐVSƸ15rt +tau#wu BBB uŅtQhPVy1@Z[^ÐUWVS Ӊ͉1,Eىu7t t t )ÅuЉ [^_]ÐS 7)ʋ7t9v 裠77@9sB7+7QA 7A7A7A7 7 7 7 7[ÍvUWVStxX 7eq9r[C 9Ƌyir:Q)މpYH PB AxhQBQBoAxA I9u1[^_]Ð x3 | Ðu1@8uÐSÉABu[ÐUWVSʼnT$1وNJVL$[^_]Ðt77jzÐVS։19s@A1u[^ÐQRP7ÐUWVS ljօu1Pu1Ft Ѕt718;u{tE t(@7\5C5C CtWt҅u*;t3Vt҅t uvus7C [^_]ÐSi(@8Xu7 SZY[ÐVSi(@88t~u7 ;P t҅u,ǃ85FP t҅u(@1҉1Z[^S8L$D1Ҹ5pÅx] 7T$@7fD$07ƒfT$fD$PD$PPj"7D$4uf|$u75i(@8fD$,BD$0BD$fBB B؃8[UWVSlÉΉՍ|$@ 1fD$d7ƒfT$XfD$DD${C ;CCffD$LK@fD$`L$T$@"*D$<t7fD$ fCK+K K@v@KC C76C9vNjS|$){{ ){@D$l[^_]ÐW8fxt8D$ D$ 1|$fD$0BfD$PjD$Pj"718_7Ð7ÐS $$1Z[fUWVS1ɺ ƈ ÈD$ۈ؉t1 1|$Y[^_]Ã= 12 \ && *((int *) (addr)) == MULTIBOOT_MAGIC \ && ! (*((unsigned *) (addr)) + *((unsigned *) (addr + 4)) \ + *((unsigned *) (addr + 8))) \ && (! (MULTIBOOT_AOUT_KLUDGE & *((int *) (addr + 4))) || (len) >= 32) \ && (! (MULTIBOOT_VIDEO_MODE & *((int *) (addr + 4))) || (len) >= 48)) /* Magic value identifying the multiboot_header. */ #define MULTIBOOT_MAGIC 0x1BADB002 /* * Features flags for 'flags'. * If a boot loader sees a flag in MULTIBOOT_MUSTKNOW set * and it doesn't understand it, it must fail. */ #define MULTIBOOT_MUSTKNOW 0x0000FFFF /* currently unsupported flags... this is a kind of version number. */ #define MULTIBOOT_UNSUPPORTED 0x0000FFF8 /* Align all boot modules on i386 page (4KB) boundaries. */ #define MULTIBOOT_PAGE_ALIGN 0x00000001 /* Must pass memory information to OS. */ #define MULTIBOOT_MEMORY_INFO 0x00000002 /* Must pass video information to OS. */ #define MULTIBOOT_VIDEO_MODE 0x00000004 /* This flag indicates the use of the address fields in the header. */ #define MULTIBOOT_AOUT_KLUDGE 0x00010000 syslinux-legacy-3.63+dfsg/com32/modules/mboot.c0000664000175000017500000010351710777447273020102 0ustar evanevan/* * mboot.c * * Loader for Multiboot-compliant kernels and modules. * * Copyright (C) 2005 Tim Deegan * Parts based on GNU GRUB, Copyright 2000 Free Software Foundation, Inc. * Parts based on SYSLINUX, Copyright 1994-2008 H. Peter Anvin. * Thanks to Ram Yalamanchili for the ELF section-header loading. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * */ #include #include #include #include #include #include #include #include "i386-elf.h" #include "mb_info.h" #include "mb_header.h" #include /* For __constructor */ #define MIN(_x, _y) (((_x)<(_y))?(_x):(_y)) #define MAX(_x, _y) (((_x)>(_y))?(_x):(_y)) /* Define this for some more printout */ #undef DEBUG /* Memory magic numbers */ #define STACK_SIZE 0x20000 /* XXX Could be much smaller */ #define MALLOC_SIZE 0x100000 /* XXX Could be much smaller */ #define MIN_RUN_ADDR 0x10000 /* Lowest address we'll consider using */ #define MEM_HOLE_START 0xa0000 /* Memory hole runs from 640k ... */ #define MEM_HOLE_END 0x100000 /* ... to 1MB */ #define X86_PAGE_SIZE 0x1000 size_t __stack_size = STACK_SIZE; /* How much stack we'll use */ extern void *__mem_end; /* Start of malloc() heap */ extern char _end[]; /* End of static data */ /* Pointer to free memory for loading into: load area is between here * and section_addr */ static char *next_load_addr; /* Memory map for run-time */ typedef struct section section_t; struct section { size_t dest; /* Start of run-time allocation */ char *src; /* Current location of data for memmove(), * or NULL for bzero() */ size_t size; /* Length of allocation */ }; static char *section_addr; static int section_count; static size_t max_run_addr; /* Highest address we'll consider using */ static size_t next_mod_run_addr; /* Where the next module will be put */ /* File loads are in units of this much */ #define LOAD_CHUNK 0x20000 /* Layout of the input to the 32-bit lidt instruction */ struct lidt_operand { unsigned int limit:16; unsigned int base:32; } __attribute__((packed)); /* Magic strings */ static const char version_string[] = "COM32 Multiboot loader v0.2"; static const char copyright_string[] = "Copyright (C) 2005-2006 Tim Deegan."; static const char module_separator[] = "---"; /* * Start of day magic, run from __start during library init. */ static void __constructor check_version(void) /* Check the SYSLINUX version. Docs say we should be OK from v2.08, * but in fact we crash on anything below v2.12 (when libc came in). */ { com32sys_t regs_in, regs_out; const char *p, *too_old = "Fatal: SYSLINUX image is too old; " "mboot.c32 needs at least version 2.12.\r\n"; memset(®s_in, 0, sizeof(regs_in)); regs_in.eax.l = 0x0001; /* "Get version" */ __intcall(0x22, ®s_in, ®s_out); if (regs_out.ecx.w[0] >= 0x020c) return; /* Pointless: on older versions this print fails too. :( */ for (p = too_old ; *p ; p++) { memset(®s_in, 0, sizeof(regs_in)); regs_in.eax.b[1] = 0x02; /* "Write character" */ regs_in.edx.b[0] = *p; __intcall(0x21, ®s_in, ®s_out); } __intcall(0x20, ®s_in, ®s_out); /* "Terminate program" */ } static void __constructor grab_memory(void) /* Runs before init_memory_arena() (com32/lib/malloc.c) to let * the malloc() code know how much space it's allowed to use. * We don't use malloc() directly, but some of the library code * does (zlib, for example). */ { /* Find the stack pointer */ register char * sp; asm volatile("movl %%esp, %0" : "=r" (sp)); /* Initialize the allocation of *run-time* memory: don't let ourselves * overwrite the stack during the relocation later. */ max_run_addr = (size_t) sp - (MALLOC_SIZE + STACK_SIZE); /* Move the end-of-memory marker: malloc() will use only memory * above __mem_end and below the stack. We will load files starting * at the old __mem_end and working towards the new one, and allocate * section descriptors at the top of that area, working down. */ next_load_addr = __mem_end; section_addr = sp - (MALLOC_SIZE + STACK_SIZE); section_count = 0; /* But be careful not to move it the wrong direction if memory is * tight. Instead we'll fail more gracefully later, when we try to * load a file and find that next_load_addr > section_addr. */ __mem_end = MAX(section_addr, next_load_addr); } /* * Run-time memory map functions: allocating and recording allocations. */ static int cmp_sections(const void *a, const void *b) /* For sorting section descriptors by destination address */ { const section_t *sa = a; const section_t *sb = b; if (sa->dest < sb->dest) return -1; if (sa->dest > sb->dest) return 1; return 0; } static void add_section(size_t dest, char *src, size_t size) /* Adds something to the list of sections to relocate. */ { section_t *sec; #ifdef DEBUG printf("SECTION: %#8.8x --> %#8.8x (%#x)\n", (size_t) src, dest, size); #endif section_addr -= sizeof (section_t); if (section_addr < next_load_addr) { printf("Fatal: out of memory allocating section descriptor.\n"); exit(1); } sec = (section_t *) section_addr; section_count++; sec->src = src; sec->dest = dest; sec->size = size; /* Keep the list sorted */ qsort(sec, section_count, sizeof (section_t), cmp_sections); } static size_t place_low_section(size_t size, size_t align) /* Find a space in the run-time memory map, below 640K */ { int i; size_t start; section_t *sections = (section_t *) section_addr; start = MIN_RUN_ADDR; start = (start + (align-1)) & ~(align-1); /* Section list is sorted by destination, so can do this in one pass */ for (i = 0; i < section_count; i++) { if (sections[i].dest < start + size) { /* Hit the bottom of this section */ start = sections[i].dest + sections[i].size; start = (start + (align-1)) & ~(align-1); } } if (start + size < MEM_HOLE_START) return start; else return 0; } static size_t place_module_section(size_t size, size_t align) /* Find a space in the run-time memory map for this module. */ { /* Ideally we'd run through the sections looking for a free space * like place_low_section() does, but some OSes (Xen, at least) * assume that the bootloader has loaded all the modules * consecutively, above the kernel. So, what we actually do is * keep a pointer to the highest address allocated so far, and * always allocate modules there. */ size_t start = next_mod_run_addr; start = (start + (align-1)) & ~(align-1); if (start + size > max_run_addr) return 0; next_mod_run_addr = start + size; return start; } static void place_kernel_section(size_t start, size_t size) /* Allocate run-time space for part of the kernel, checking for * sanity. We assume the kernel isn't broken enough to have * overlapping segments. */ { /* We always place modules above the kernel */ next_mod_run_addr = MAX(next_mod_run_addr, start + size); if (start > max_run_addr || start + size > max_run_addr) { /* Overruns the end of memory */ printf("Fatal: kernel loads too high (%#8.8x+%#x > %#8.8x).\n", start, size, max_run_addr); exit(1); } if (start >= MEM_HOLE_END) { /* Above the memory hole: easy */ #ifdef DEBUG printf("Placed kernel section (%#8.8x+%#x)\n", start, size); #endif return; } if (start >= MEM_HOLE_START) { /* In the memory hole. Not so good */ printf("Fatal: kernel load address (%#8.8x) is in the memory hole.\n", start); exit(1); } if (start + size > MEM_HOLE_START) { /* Too big for low memory */ printf("Fatal: kernel (%#8.8x+%#x) runs into the memory hole.\n", start, size); exit(1); } if (start < MIN_RUN_ADDR) { /* Loads too low */ printf("Fatal: kernel load address (%#8.8x) is too low (<%#8.8x).\n", start, MIN_RUN_ADDR); exit(1); } /* Kernel loads below the memory hole: OK */ #ifdef DEBUG printf("Placed kernel section (%#8.8x+%#x)\n", start, size); #endif } static void reorder_sections(void) /* Reorders sections into a safe order, where no relocation * overwrites the source of a later one. */ { section_t *secs = (section_t *) section_addr; section_t tmp; int i, j, tries; #ifdef DEBUG printf("Relocations:\n"); for (i = 0; i < section_count ; i++) { printf(" %#8.8x --> %#8.8x (%#x)\n", (size_t)secs[i].src, secs[i].dest, secs[i].size); } #endif for (i = 0; i < section_count; i++) { tries = 0; scan_again: for (j = i + 1 ; j < section_count; j++) { if (secs[j].src != NULL && secs[i].dest + secs[i].size > (size_t) secs[j].src && secs[i].dest < (size_t) secs[j].src + secs[j].size) { /* Would overwrite the source of the later move */ if (++tries > section_count) { /* Deadlock! */ /* XXX Try to break deadlocks? */ printf("Fatal: circular dependence in relocations.\n"); exit(1); } /* Swap these sections (using struct copies) */ tmp = secs[i]; secs[i] = secs[j]; secs[j] = tmp; /* Start scanning again from the new secs[i]... */ goto scan_again; } } } #ifdef DEBUG printf("Relocations:\n"); for (i = 0; i < section_count ; i++) { printf(" %#8.8x --> %#8.8x (%#x)\n", (size_t)secs[i].src, secs[i].dest, secs[i].size); } #endif } static void init_mmap(struct multiboot_info *mbi) /* Get a full memory map from the BIOS to pass to the kernel. */ { com32sys_t regs_in, regs_out; struct AddrRangeDesc *e820; int e820_slots; size_t mem_lower, mem_upper, run_addr, mmap_size; register size_t sp; /* Default values for mem_lower and mem_upper in case the BIOS won't * tell us: 640K, and all memory up to the stack. */ asm volatile("movl %%esp, %0" : "=r" (sp)); mem_upper = (sp - MEM_HOLE_END) / 1024; mem_lower = (MEM_HOLE_START) / 1024; #ifdef DEBUG printf("Requesting memory map from BIOS:\n"); #endif /* Ask the BIOS for the full memory map of the machine. We'll * build it in Multiboot format (i.e. with size fields) in the * bounce buffer, and then allocate some high memory to keep it in * until boot time. */ e820 = __com32.cs_bounce; e820_slots = 0; regs_out.ebx.l = 0; while(((void *)(e820 + 1)) < __com32.cs_bounce + __com32.cs_bounce_size) { memset(e820, 0, sizeof (*e820)); memset(®s_in, 0, sizeof regs_in); e820->size = sizeof(*e820) - sizeof(e820->size); /* Ask the BIOS to fill in this descriptor */ regs_in.eax.l = 0xe820; /* "Get system memory map" */ regs_in.ebx.l = regs_out.ebx.l; /* Continuation value from last call */ regs_in.ecx.l = 20; /* Size of buffer to write into */ regs_in.edx.l = 0x534d4150; /* "SMAP" */ regs_in.es = SEG(&e820->BaseAddr); regs_in.edi.w[0] = OFFS(&e820->BaseAddr); __intcall(0x15, ®s_in, ®s_out); if ((regs_out.eflags.l & EFLAGS_CF) != 0 && regs_out.ebx.l != 0) break; /* End of map */ if (((regs_out.eflags.l & EFLAGS_CF) != 0 && regs_out.ebx.l == 0) || (regs_out.eax.l != 0x534d4150)) { /* Error */ printf("Error %x reading E820 memory map: %s.\n", (int) regs_out.eax.b[0], (regs_out.eax.b[0] == 0x80) ? "invalid command" : (regs_out.eax.b[0] == 0x86) ? "not supported" : "unknown error"); break; } /* Success */ #ifdef DEBUG printf(" %#16.16Lx -- %#16.16Lx : ", e820->BaseAddr, e820->BaseAddr + e820->Length); switch (e820->Type) { case 1: printf("Available\n"); break; case 2: printf("Reserved\n"); break; case 3: printf("ACPI Reclaim\n"); break; case 4: printf("ACPI NVS\n"); break; default: printf("? (Reserved)\n"); break; } #endif if (e820->Type == 1) { if (e820->BaseAddr == 0) { mem_lower = MIN(MEM_HOLE_START, e820->Length) / 1024; } else if (e820->BaseAddr == MEM_HOLE_END) { mem_upper = MIN(0xfff00000, e820->Length) / 1024; } } /* Move to next slot */ e820++; e820_slots++; /* Done? */ if (regs_out.ebx.l == 0) break; } /* Record the simple information in the MBI */ mbi->flags |= MB_INFO_MEMORY; mbi->mem_lower = mem_lower; mbi->mem_upper = mem_upper; /* Record the full memory map in the MBI */ if (e820_slots != 0) { mmap_size = e820_slots * sizeof(*e820); /* Where will it live at run time? */ run_addr = place_low_section(mmap_size, 1); if (run_addr == 0) { printf("Fatal: can't find space for the e820 mmap.\n"); exit(1); } /* Where will it live now? */ e820 = (struct AddrRangeDesc *) next_load_addr; if (next_load_addr + mmap_size > section_addr) { printf("Fatal: out of memory storing the e820 mmap.\n"); exit(1); } next_load_addr += mmap_size; /* Copy it out of the bounce buffer */ memcpy(e820, __com32.cs_bounce, mmap_size); /* Remember to copy it again at run time */ add_section(run_addr, (char *) e820, mmap_size); /* Record it in the MBI */ mbi->flags |= MB_INFO_MEM_MAP; mbi->mmap_length = mmap_size; mbi->mmap_addr = run_addr; } } /* * Code for loading and parsing files. */ static void load_file(char *filename, char **startp, size_t *sizep) /* Load a file into memory. Returns where it is and how big via * startp and sizep */ { gzFile fp; char *start; int bsize; printf("Loading %s.", filename); start = next_load_addr; startp[0] = start; sizep[0] = 0; /* Open the file */ if ((fp = gzopen(filename, "r")) == NULL) { printf("\nFatal: cannot open %s\n", filename); exit(1); } while (next_load_addr + LOAD_CHUNK <= section_addr) { bsize = gzread(fp, next_load_addr, LOAD_CHUNK); printf("%s","."); if (bsize < 0) { printf("\nFatal: read error in %s\n", filename); gzclose(fp); exit(1); } next_load_addr += bsize; sizep[0] += bsize; if (bsize < LOAD_CHUNK) { printf("%s","\n"); gzclose(fp); return; } } /* Running out of memory. Try and use up the last bit */ if (section_addr > next_load_addr) { bsize = gzread(fp, next_load_addr, section_addr - next_load_addr); printf("%s","."); } else { bsize = 0; } if (bsize < 0) { gzclose(fp); printf("\nFatal: read error in %s\n", filename); exit(1); } next_load_addr += bsize; sizep[0] += bsize; if (!gzeof(fp)) { gzclose(fp); printf("\nFatal: out of memory reading %s\n", filename); exit(1); } printf("%s","\n"); gzclose(fp); return; } static size_t load_kernel(struct multiboot_info *mbi, char *cmdline) /* Load a multiboot/elf32 kernel and allocate run-time memory for it. * Returns the kernel's entry address. */ { unsigned int i; char *load_addr; /* Where the image was loaded */ size_t load_size; /* How big it is */ char *seg_addr; /* Where a segment was loaded */ size_t seg_size, bss_size; /* How big it is */ size_t run_addr, run_size; /* Where it should be put */ size_t shdr_run_addr; char *p; Elf32_Ehdr *ehdr; Elf32_Phdr *phdr; Elf32_Shdr *shdr; struct multiboot_header *mbh; printf("Kernel: %s\n", cmdline); load_addr = 0; load_size = 0; p = strchr(cmdline, ' '); if (p != NULL) *p = 0; load_file(cmdline, &load_addr, &load_size); if (load_size < 12) { printf("Fatal: %s is too short to be a multiboot kernel.", cmdline); exit(1); } if (p != NULL) *p = ' '; /* Look for a multiboot header in the first 8k of the file */ for (i = 0; i <= MIN(load_size - 12, MULTIBOOT_SEARCH - 12); i += 4) { mbh = (struct multiboot_header *)(load_addr + i); if (mbh->magic != MULTIBOOT_MAGIC || ((mbh->magic+mbh->flags+mbh->checksum) & 0xffffffff)) { /* Not a multiboot header */ continue; } if (mbh->flags & (MULTIBOOT_UNSUPPORTED | MULTIBOOT_VIDEO_MODE)) { /* Requires options we don't support */ printf("Fatal: Kernel requires multiboot options " "that I don't support: %#x.\n", mbh->flags & (MULTIBOOT_UNSUPPORTED|MULTIBOOT_VIDEO_MODE)); exit(1); } /* This kernel will do: figure out where all the pieces will live */ if (mbh->flags & MULTIBOOT_AOUT_KLUDGE) { /* Use the offsets in the multiboot header */ #ifdef DEBUG printf("Using multiboot header.\n"); #endif /* Where is the code in the loaded file? */ seg_addr = ((char *)mbh) - (mbh->header_addr - mbh->load_addr); /* How much code is there? */ run_addr = mbh->load_addr; if (mbh->load_end_addr != 0) seg_size = mbh->load_end_addr - mbh->load_addr; else seg_size = load_size - (seg_addr - load_addr); /* How much memory will it take up? */ if (mbh->bss_end_addr != 0) run_size = mbh->bss_end_addr - mbh->load_addr; else run_size = seg_size; if (seg_size > run_size) { printf("Fatal: can't put %i bytes of kernel into %i bytes " "of memory.\n", seg_size, run_size); exit(1); } if (seg_addr + seg_size > load_addr + load_size) { printf("Fatal: multiboot load segment runs off the " "end of the file.\n"); exit(1); } /* Does it fit where it wants to be? */ place_kernel_section(run_addr, run_size); /* Put it on the relocation list */ if (seg_size < run_size) { /* Set up the kernel BSS too */ if (seg_size > 0) add_section(run_addr, seg_addr, seg_size); bss_size = run_size - seg_size; add_section(run_addr + seg_size, NULL, bss_size); } else { /* No BSS */ add_section(run_addr, seg_addr, run_size); } /* Done. */ return mbh->entry_addr; } else { /* Now look for an ELF32 header */ ehdr = (Elf32_Ehdr *)load_addr; if (*(unsigned long *)ehdr != 0x464c457f || ehdr->e_ident[EI_DATA] != ELFDATA2LSB || ehdr->e_ident[EI_CLASS] != ELFCLASS32 || ehdr->e_machine != EM_386) { printf("Fatal: kernel has neither ELF32/x86 nor multiboot load" " headers.\n"); exit(1); } if (ehdr->e_phoff + ehdr->e_phnum*sizeof (*phdr) > load_size) { printf("Fatal: malformed ELF header overruns EOF.\n"); exit(1); } if (ehdr->e_phnum <= 0) { printf("Fatal: ELF kernel has no program headers.\n"); exit(1); } #ifdef DEBUG printf("Using ELF header.\n"); #endif if (ehdr->e_type != ET_EXEC || ehdr->e_version != EV_CURRENT || ehdr->e_phentsize != sizeof (Elf32_Phdr)) { printf("Warning: funny-looking ELF header.\n"); } phdr = (Elf32_Phdr *)(load_addr + ehdr->e_phoff); /* Obey the program headers to load the kernel */ for(i = 0; i < ehdr->e_phnum; i++) { /* How much is in this segment? */ run_size = phdr[i].p_memsz; if (phdr[i].p_type != PT_LOAD) seg_size = 0; else seg_size = (size_t)phdr[i].p_filesz; /* Where is it in the loaded file? */ seg_addr = load_addr + phdr[i].p_offset; if (seg_addr + seg_size > load_addr + load_size) { printf("Fatal: ELF load segment runs off the " "end of the file.\n"); exit(1); } /* Skip segments that don't take up any memory */ if (run_size == 0) continue; /* Place the segment where it wants to be */ run_addr = phdr[i].p_paddr; place_kernel_section(run_addr, run_size); /* Put it on the relocation list */ if (seg_size < run_size) { /* Set up the kernel BSS too */ if (seg_size > 0) add_section(run_addr, seg_addr, seg_size); bss_size = run_size - seg_size; add_section(run_addr + seg_size, NULL, bss_size); } else { /* No BSS */ add_section(run_addr, seg_addr, run_size); } } if (ehdr->e_shoff != 0) { #ifdef DEBUG printf("Loading ELF section table.\n"); #endif /* Section Header */ shdr = (Elf32_Shdr *)(load_addr + ehdr->e_shoff); /* Section Header Table size */ run_size = ehdr->e_shentsize * ehdr->e_shnum; shdr_run_addr = place_module_section(run_size, 0x1000); if (shdr_run_addr == 0) { printf("Warning: Not enough memory to load the " "section table.\n"); return ehdr->e_entry; } add_section(shdr_run_addr, (void*) shdr, run_size); /* Load section tables not loaded thru program segments */ for (i = 0; i < ehdr->e_shnum; i++) { /* This case is when this section is already included in * program header or it's 0 size, so no need to load */ if (shdr[i].sh_addr != 0 || !shdr[i].sh_size) continue; if (shdr[i].sh_addralign == 0) shdr[i].sh_addralign = 1; run_addr = place_module_section(shdr[i].sh_size, shdr[i].sh_addralign); if (run_addr == 0) { printf("Warning: Not enough memory to load " "section %d.\n", i); return ehdr->e_entry; } shdr[i].sh_addr = run_addr; add_section(run_addr, (void*) (shdr[i].sh_offset + load_addr), shdr[i].sh_size); } mbi->flags |= MB_INFO_ELF_SHDR; mbi->syms.e.num = ehdr->e_shnum; mbi->syms.e.size = ehdr->e_shentsize; mbi->syms.e.shndx = ehdr->e_shstrndx; mbi->syms.e.addr = shdr_run_addr; #ifdef DEBUG printf("Section information: shnum: %lu, entSize: %lu, " "shstrndx: %lu, addr: 0x%lx\n", mbi->syms.e.num, mbi->syms.e.size, mbi->syms.e.shndx, mbi->syms.e.addr); #endif } /* Done! */ return ehdr->e_entry; } } /* This is not a multiboot kernel */ printf("Fatal: not a multiboot kernel.\n"); exit(1); } static void load_module(struct mod_list *mod, char *cmdline) /* Load a multiboot module and allocate a memory area for it */ { char *load_addr, *p; size_t load_size, run_addr; printf("Module: %s\n", cmdline); load_addr = 0; load_size = 0; p = strchr(cmdline, ' '); if (p != NULL) *p = 0; load_file(cmdline, &load_addr, &load_size); if (p != NULL) *p = ' '; /* Decide where it's going to live */ run_addr = place_module_section(load_size, X86_PAGE_SIZE); if (run_addr == 0) { printf("Fatal: can't find space for this module.\n"); exit(1); } add_section(run_addr, load_addr, load_size); /* Remember where we put it */ mod->mod_start = run_addr; mod->mod_end = run_addr + load_size; mod->pad = 0; #ifdef DEBUG printf("Placed module (%#8.8x+%#x)\n", run_addr, load_size); #endif } /* * Code for shuffling sections into place and booting the new kernel */ static void trampoline_start(section_t *secs, int sec_count, size_t mbi_run_addr, size_t entry) /* Final shuffle-and-boot code. Running on the stack; no external code * or data can be relied on. */ { int i; struct lidt_operand idt; /* SYSLINUX has set up SS, DS and ES as 32-bit 0--4G data segments, * but doesn't specify FS and GS. Multiboot wants them all to be * the same, so we'd better do that before we overwrite the GDT. */ asm volatile("movl %ds, %ecx; movl %ecx, %fs; movl %ecx, %gs"); /* Turn off interrupts */ asm volatile("cli"); /* SYSLINUX has set up an IDT at 0x100000 that does all the * comboot calls, and we're about to overwrite it. The Multiboot * spec says that the kernel must set up its own IDT before turning * on interrupts, but it's still entitled to use BIOS calls, so we'll * put the IDT back to the BIOS one at the base of memory. */ idt.base = 0; idt.limit = 0x800; asm volatile("lidt %0" : : "m" (idt)); /* Now, shuffle the sections */ for (i = 0; i < sec_count; i++) { if (secs[i].src == NULL) { /* asm bzero() code from com32/lib/memset.c */ char *q = (char *) secs[i].dest; size_t nl = secs[i].size >> 2; asm volatile("cld ; rep ; stosl ; movl %3,%0 ; rep ; stosb" : "+c" (nl), "+D" (q) : "a" (0x0U), "r" (secs[i].size & 3)); } else { /* asm memmove() code from com32/lib/memmove.c */ const char *p = secs[i].src; char *q = (char *) secs[i].dest; size_t n = secs[i].size; if ( q < p ) { asm volatile("cld ; rep ; movsb" : "+c" (n), "+S" (p), "+D" (q)); } else { p += (n-1); q += (n-1); asm volatile("std ; rep ; movsb" : "+c" (n), "+S" (p), "+D" (q)); } } } /* Now set up the last tiny bit of Multiboot environment. * A20 is already enabled. * CR0 already has PG cleared and PE set. * EFLAGS already has VM and IF cleared. * ESP is the kernels' problem. * GDTR is the kernel's problem. * CS is already a 32-bit, 0--4G code segments. * DS, ES, FS and GS are already 32-bit, 0--4G data segments. * * EAX must be 0x2badb002 and EBX must point to the MBI when we jump. */ asm volatile ("jmp %*%2" : : "a" (0x2badb002), "b" (mbi_run_addr), "cdSDm" (entry)); } static void trampoline_end(void) {} static void boot(size_t mbi_run_addr, size_t entry) /* Tidy up SYSLINUX, shuffle memory and boot the kernel */ { com32sys_t regs; section_t *tr_sections; void (*trampoline)(section_t *, int, size_t, size_t); size_t trampoline_size; /* Make sure the relocations are safe. */ reorder_sections(); /* Copy the shuffle-and-boot code and the array of relocations * onto the memory we previously used for malloc() heap. This is * safe because it's not the source or the destination of any * copies, and there'll be no more library calls after the copy. */ tr_sections = ((section_t *) section_addr) + section_count; trampoline = (void *) (tr_sections + section_count); trampoline_size = (void *)&trampoline_end - (void *)&trampoline_start; #ifdef DEBUG printf("tr_sections: %p\n" "trampoline: %p\n" "trampoline_size: %#8.8x\n" "max_run_addr: %#8.8x\n", tr_sections, trampoline, trampoline_size, max_run_addr); #endif printf("Booting: MBI=%#8.8x, entry=%#8.8x\n", mbi_run_addr, entry); memmove(tr_sections, section_addr, section_count * sizeof (section_t)); memmove(trampoline, trampoline_start, trampoline_size); /* Tell SYSLINUX to clean up */ memset(®s, 0, sizeof regs); regs.eax.l = 0x000c; /* "Perform final cleanup" */ regs.edx.l = 0; /* "Normal cleanup" */ __intcall(0x22, ®s, NULL); /* Into the unknown */ trampoline(tr_sections, section_count, mbi_run_addr, entry); } int main(int argc, char **argv) /* Parse the command-line and invoke loaders */ { struct multiboot_info *mbi; struct mod_list *modp; int modules, num_append_args; int mbi_reloc_offset; char *p; size_t mbi_run_addr, mbi_size, entry; int i; /* Say hello */ console_ansi_std(); printf("%s. %s\n", version_string, copyright_string); if (argc < 2 || !strcmp(argv[1], module_separator)) { printf("Fatal: No kernel filename!\n"); exit(1); } #ifdef DEBUG printf("_end: %p\n" "argv[1]: %p\n" "next_load_addr: %p\n" "section_addr %p\n" "__mem_end: %p\n" "argv[0]: %p\n", &_end, argv[1], next_load_addr, section_addr, __mem_end, argv[0]); #endif /* How much space will the MBI need? */ modules = 0; mbi_size = sizeof(struct multiboot_info) + strlen(version_string) + 5; for (i = 1 ; i < argc ; i++) { if (!strcmp(argv[i], module_separator)) { modules++; mbi_size += sizeof(struct mod_list) + 1; } else { mbi_size += strlen(argv[i]) + 1; } } /* Allocate space in the load buffer for the MBI, all the command * lines, and all the module details. */ mbi = (struct multiboot_info *)next_load_addr; next_load_addr += mbi_size; if (next_load_addr > section_addr) { printf("Fatal: out of memory allocating for boot metadata.\n"); exit(1); } memset(mbi, 0, sizeof (struct multiboot_info)); p = (char *)(mbi + 1); mbi->flags = MB_INFO_CMDLINE | MB_INFO_BOOT_LOADER_NAME; /* Figure out the memory map. * N.B. Must happen before place_section() is called */ init_mmap(mbi); mbi_run_addr = place_low_section(mbi_size, 4); if (mbi_run_addr == 0) { printf("Fatal: can't find space for the MBI!\n"); exit(1); } mbi_reloc_offset = (size_t)mbi - mbi_run_addr; add_section(mbi_run_addr, (void *)mbi, mbi_size); /* Module info structs */ modp = (struct mod_list *) (((size_t)p + 3) & ~3); if (modules > 0) mbi->flags |= MB_INFO_MODS; mbi->mods_count = modules; mbi->mods_addr = ((size_t)modp) - mbi_reloc_offset; p = (char *)(modp + modules); /* Append cmdline args show up in the beginning, append these * to kernel cmdline later on */ for (i = 1; i < argc; i++) { if (strchr(argv[i], '=') != NULL) { continue; } break; } /* Command lines: first kernel, then modules */ mbi->cmdline = ((size_t)p) - mbi_reloc_offset; modules = 0; num_append_args = i-1; for (; i < argc ; i++) { if (!strcmp(argv[i], module_separator)) { /* Add append args to kernel cmdline */ if (modules == 0 && num_append_args) { int j; for (j = 1; j < num_append_args+1; j++) { strcpy(p, argv[j]); p += strlen(argv[j]); *p++ = ' '; } } *p++ = '\0'; modp[modules++].cmdline = ((size_t)p) - mbi_reloc_offset; } else { strcpy(p, argv[i]); p += strlen(argv[i]); *p++ = ' '; } } *p++ = '\0'; /* Bootloader ID */ strcpy(p, version_string); mbi->boot_loader_name = ((size_t)p) - mbi_reloc_offset; p += strlen(version_string) + 1; /* Now, do all the loading, and boot it */ entry = load_kernel(mbi, (char *)(mbi->cmdline + mbi_reloc_offset)); for (i=0; i;Dv @dD$,@x,h0%D$@u CT$,+T$@T$<ًT$,D$@;L$,[L$0|$4~|$,T$4D$,PD$0+D$t1n$V‰T$P$9v t:~ ډU9st T$PP)D=1ًT$P7D$T L$XA,9D$TsY $q0A. Ņ1A{ u7{t1{ uC S CthC KS$F(|$XG09rT$, BG.B G2B(j$L$XIL$DM+D$X9%PPVh|$h|$TQD$X@D$D|$01t$<wPPVh֫DŽ$$DŽ$  tÃ$$t  $Ãu $$t_$_GE;$DDT$` HL$d T$tD$p|$t |$lD$\|$t1fwtYD$th@D$h9vEW9s>D$\T$d9T$\~  L$lY D$lD$hF^oA D$d+D$p9uD$pD$t D$pH;D$dXD$4xPkt$d l$`t5Pt$Ht$Hh6k H D^?ٺ?J$ 1DŽ$ DŽ$"" Xt$PL$PHָ(Y[^_]aÐ |  <-D$D$:HtD$ÐUWVSƉՉ1҉وJ[^_]UWVS Ӊ͉1,Eى u t t t )ÅuЉ [^_]ÐVW։ljsft_^ÐVWlj9rt1|9у_^ÐWVS$Ήiً<$$Z[^_à L$$L$T$ +Ð x ÐUWVSD$T$ ͉k 1Í@w ut$ō<D$D$'T$0~wkD$D$D$ )9D$u̓w|$z[^_]Ðu1@8uÐSÉъD$CA)‰u|$uZ[ÐSÉABu[ÐVSÍt$QѺ'x=~ى‰[^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$Ĭ%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$جL$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$ЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$0T$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$DiD$DXD$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u1I|$Xt ;L$X~L$X9L$\~u+C84CPt\CTD$1|$ʉ)щ]CPu"ST%CP`^CPV^CP [^_]ÍvUWVS ÉՅx\w@1@+stK@CH9udCHC C@uGCChC8C)Chu {8uC8{u {8u 떿{8vC8u0C8 [^_]S5u S8tZY[ÍvWVSlj1É [Fu[^_WVSÅu @PtQ[{tC\CDCCdCCh1҉9C8C)CdC)Ch{8uNK )CLcCLs ;CL{8u03111cCL{8u{<uNjCK )CLcCL+C  [^_]ÍvUWVS ʼn׉΅t,~(NtډHuC< u9u~1 [^_]ÐT$HtD$fWVSÉ׉΅tBx\wu5-x t8uxu{ut F~3C $k {*5{SCCDCDCDCDCDCDCDSKC| uH~1CDBCCq111WK(!C|~1҃ƒ1  {dt CqQT$ȿ1)T$T$[{dtV2JV0?111SF0{t~u~u ;,$uC=u~tFl~u{luV=kK| H@wCtu ~LJuUu =. j11҉ uKD{U0EdLfB @fE`MdETy1U0 )1ۃ|$SbEdETEExu|$u ؍D1[^_]UWVSʼnT$D$}lw$El=w |$7}lv6E0udT0MPE@1#ULU@}<WM,!E8fH\$f4W|$tAUd+T$E$-9w. T$uJuT$EXEXMdPf+Mhf ^CIffw ff H9D$Ul+UXUlEX;Exw`v[HEXE0D$ MPL$udFudD$ T0E@L$1#ULU@}<WM,!E8fH\$f4WEXHEXuhEdEX]0UdE@MPT1#ELE@@E0f^SfH9D$MlEd|$MdETy1U0 )jEdETE-ExZMdETy1U0 )1ۃ|$SEdETEExu|$u ؍D1[^_]ÍvUWVS ÉՋx v{lw{lu ClCdClKTCdt9rB)ȉClKdCTy1S0 )jCdCT&xsdKT)ʋC$-9gy1S0 )jtCdCTx.SKdCTy1S0 )V-CdCTxu u D61 [^_]ÐSÉэBT A?…tCtx(uxHu[J[fWSDžxx x$@@@@,XCCCCy؉C{G*C{u 111K 111^HG0C aC$C4KD{t?N4f0f41F0An0n4~4T$ wF`F`BOF`5)Goo~`t_yo_ 1[^_]Åt@t8 t1Ãx4øUWVS D$Ӆrz z$B(׉Džt+~,t,NC(S tC(S${18ڋD$((FD)ȍGDFH)ȍGHFd)‰WdtFV,ى輲o,D$x1 [^_]ÐUWVS ʼn֋X{,u#K@(U C,u{ uKC C(C$+uK 9rC,U )1C(0C()9U wMC,))tC,U )s(C C(C(;C uC(C$;C sC$1C,)ʃ [^_]ÐUWVS ÉՉυpt}> ux111'';Ft]St B^ 9vF,T=)ډAF F$^,))~$F 1 [^_]fUWVS|D$T$ ]pRx H8u x9> u D$@ D$8T$RT$@L$ L$4\$[\$d~0n4\$$D$HVu+ ҃|$<L$|$<L$|$<KL$w-L$D;Ht$T$DD$tD$H|$d\$+{\$DD$+XxX^~t.t*~P Ft )ډw )ډFT$B0~Ѓ@1҃> F4ЋL$A,ut|$ u=|$Hu6D$H,D$H")D$RF8)D$RF8D$H|[^_]UWVSD$ T$1fDDl@u1L$QfDDlB9u$(D$T$f|Tlu JT$W|$Jf||luGu1ɍDLn)‰Au~|$  D$l)HfD$NAT$LfDJfDLjfJu14T$fZft&$fTDLʉL$$fHB $fTLLC9uȋL$9v9s̓|$ t |$ uI$D$4$T$,D$d$D$HD$(T$4T$0D$8$ L$,D$d$D$HD$(D$0@D$4D$8DD$0D$4~$T$,D$ D$HD$(D$8|$$T$@D$D$ D$$t$$D$@\$Ht$$*L$L$?D$@f0;D$8}D$>  1D$>`T$4T$>L$0f4+L$T$|$ډT$D‰+T$D$ L$L$,fpL$>L$?HT$DL$ u̍KT$ uu D$ B#D$ ЉD$ fT\lfJt\$H;\$SL$@AL$AD$HfT\l9l$Ht$ #t$(;t$$|$ul$|$H+|$D$LTl)B~ G;T$rD$|$ u|$L$D$,$ $L$D$,)fD)|$t+D$ #D$(;D$$t$T$,L$?D$D$ L$T$,f@@L$?HKT$ uu\$ B#D$ ЉD$ |$ uD$$$)1 Č[^_]ÐUWVSH$@D$ $K\$AÉ\$ q NA)‰)щL$D$\$[ \$D$@$D$T$R(T$ L$I,L$$\$[0\$u+Q9u!VQVFBFPFAFH [^ÐS )ʋt9v 裀@9sB+QA AAA    [ÍvUWVStxX eq9r[C 9Ƌyir:Q)މpYH PB AxhQBQBoAxA I9u1[^_]ÐVSƉ VCFSIFCu[^ÐD$(D$ PL$4D$0,ÐVSƉ1l衔Z[^ÐlUWVS ljօu1Pu1Ft Ѕt 1 ;u{tE t(@ \C,C CtWt҅u*;t3Vt҅t uvus W [^_]ÐVSi(@  u  SZ[^Hi(@,ÐVSi(@  t~u  ;P t҅u,ǃ FP t҅u(@1҉蚑1Z[^S8L$D1Ҹ\Åx] hT$@dfD$0dƒfT$fD$PD$PPj"`D$4uf|$u 5i(@ fD$,BD$0BD$fBB B؃8[UWVSlÉΉՍ|$@ 1fD$ddƒfT$XfD$DD${C ;CCffD$LK@fD$`L$T$@"D$<t fD$ fCK+K K@v@KC Cd讏C9vNjS藏|$){{ ){@D$l[^_]ÐW8fxt8D$ D$ 1|$fD$0BfD$PjD$Pj"`18_UWVSʼn։L$@@D$1T$T$0Htn T$ tuA tYu5)tONT$KT$u)딋D$H9sT$GFw T$G[^_]Ð Ð Ð1ɺ!GvUWVS f=4׉t8r MB<w£#PЃ vk ‰Hub;}P"[0;k\ CumGN [^_]Ð 1ÍvS‹H xtx uXzt ؃ ˉztz u [Ð fD9f@H=H<1ɺ  svVSƉbQP9u9t-1ɺ[^[^VSˋt$1 bf1ɺ[[^Ɩfx,u fLf1ɺ`铖vVSӉfiD$D$1ɺ^[^AWVSσ=t1։V KFu[^_ÍvS8Ã= fD L$ "ٕ|$%yfD1ɺ "評u@JEb9L$ VD$,fLT$(T$)P @$@ 18[ÐUWVSDՉL$ u ЉT$D$d|$ v D$D$ D$T$T$ED$UT$UT$T$ UT$ T$$UT$$T$(UT$(T$,UT$,T$0UT$0T$4UT$4T$8U T$8T$<U T$w KfJ mt'wlsu1D$)D$;D$|D$HD$;D$|R\$K)FD$;D$|\$K\$D$)y1D$1RC;D$| D$H=y1SG@H;D$| L$Iy1;T$|\$K\$ЅL1EtR\$t$NPPSVى|$T$ J9PPKD$0RV1|$\$PPCPD$ HP11҉t$_XD$0SJR1rVVD$HPD$ HP1>t"t@;L$SSQD$ HPL$RRQHP1҉\$L$PPQD$ HP1҉t$1ht G$G,D$(|$ WD<1$BB B BBBB B ~BuBlBcB ZBQBHB?B3BB#BBB B AT$(;J8D$G)W(O)L$o(G@\$(1#C0PЃ kG@ G@L$(A %#8.8x). Fatal: kernel load address (%#8.8x) is in the memory hole. Fatal: kernel (%#8.8x+%#x) runs into the memory hole. Fatal: kernel load address (%#8.8x) is too low (<%#8.8x). Fatal: SYSLINUX image is too old; mboot.c32 needs at least version 2.12. Fatal: out of memory allocating section descriptor.Loading %s. Fatal: cannot open %s Fatal: read error in %s Fatal: out of memory reading %s %s. %s Fatal: No kernel filename!Fatal: out of memory allocating for boot metadata.invalid commandnot supportedunknown errorError %x reading E820 memory map: %s. Fatal: can't find space for the e820 mmap.Fatal: out of memory storing the e820 mmap.Fatal: can't find space for the MBI!Kernel: %s Fatal: %s is too short to be a multiboot kernel.Fatal: Kernel requires multiboot options that I don't support: %#x. Fatal: can't put %i bytes of kernel into %i bytes of memory. Fatal: multiboot load segment runs off the end of the file.Fatal: kernel has neither ELF32/x86 nor multiboot load headers.Fatal: malformed ELF header overruns EOF.Fatal: ELF kernel has no program headers.Warning: funny-looking ELF header.Fatal: ELF load segment runs off the end of the file.Warning: Not enough memory to load the section table.Warning: Not enough memory to load section %d. Fatal: not a multiboot kernel.Module: %s Fatal: can't find space for this module.Fatal: circular dependence in relocations.Booting: MBI=%#8.8x, entry=%#8.8x COM32 Multiboot loader v0.2Copyright (C) 2005-2006 Tim Deegan.---(null)""6### #(#(##(#(#(##(#(#(#"(#"(#(## %>%C%L%]%%%%%%)))))0123456789ABCDEF0123456789abcdef,,B`-: 1.2.1%c%c%c%c%c%c%c%c%c%c deflate 1.2.1 Copyright 1995-2003 Jean-loup Gailly KHH HE EE E E E   L,l\<|B"bR2r J*jZ:zF&fV6vN.n^>~A!aQ1q I)iY9yE%eU5u M-m]=}   S S  3 3  s s    K K  + +  k k     [ [  ; ;  { {     G G  ' '  g g     W W  7 7  w w     O O  / /  o o     _ _  ? ?     @ `P0pH(hX8xD$dT4tC#c            (08@P`p   0@`  0@`need dictionarystream endfile errorstream errordata errorinsufficient memorybuffer errorincompatible version,<GR_j~incorrect header checkunknown compression methodinvalid window sizeunknown header flags setheader crc mismatchinvalid block typeinvalid stored block lengthstoo many length or distance symbolsinvalid code lengths setinvalid bit length repeatinvalid literal/lengths setinvalid distances setinvalid literal/length codeinvalid distance codeinvalid distance too far backincorrect data checkincorrect length checkopvqqrrr)ss tItttauu=vvAyz{{}}~<~no     A@!  @a`10  @`Psp0  ` @ X ;x8 h( H T+t4  d$ D \ S|< l,  L R#r2  b" B Z Cz: j*  J V@3v6 f& F  ^ c~> n. N `Qq1  a! A Y ;y9 i)  I U+u5  e% E ] S}= m-  M S#s3  c# C [ C{; k+  K W@3w7 g' G  _ c? o/ O `Psp0  ` @ X ;x8 h( H T+t4  d$ D \ S|< l,  L R#r2  b" B Z Cz: j*  J V@3v6 f& F  ^ c~> n. N `Qq1  a! A Y ;y9 i)  I U+u5  e% E ] S}= m-  M S#s3  c# C [ C{; k+  K W@3w7 g' G  _ c? o/ O inflate 1.2.1 Copyright 1995-2003 Mark Adler @@ !1Aa  0@`LB #+3;CScs|  BB default0gOmZ¤ˤԤݤݤݤݤݤݤݤݤ        ٿ__ô³؜dbP8+<@ `h`syslinux-legacy-3.63+dfsg/com32/modules/sdi.c0000664000175000017500000001015410777447273017533 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * sdi.c * * Loader for the Microsoft System Deployment Image (SDI) format */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define DEBUG 0 #if DEBUG # define dprintf printf #else # define dprintf(f, ...) ((void)0) #endif struct SDIHeader { uint32_t Signature; char Version[4]; uint64_t SDIReserved; uint64_t BootCodeOffset; uint64_t BootCodeSize; }; #define SDI_LOAD_ADDR (16 << 20) /* 16 MB */ #define SDI_SIGNATURE ('$' + ('S' << 8) + ('D' << 16) + ('I' << 24)) static inline void error(const char *msg) { fputs(msg, stderr); } static int boot_sdi(void *ptr, size_t len) { const struct SDIHeader *hdr = ptr; struct syslinux_memmap *mmap = NULL, *amap = NULL; struct syslinux_rm_regs regs; struct syslinux_movelist *ml = NULL; char *boot_blob; /* **** Basic sanity checking **** */ if (hdr->Signature != SDI_SIGNATURE) { fputs("No $SDI signature in file\n", stdout); goto bail; } if (memcmp(hdr->Version, "0001", 4)) { int i; fputs("Warning: unknown SDI version: ", stdout); for (i = 0; i < 4; i++) putchar(hdr->Version[i]); putchar('\n'); /* Then try anyway... */ } /* **** Setup **** */ mmap = syslinux_memory_map(); amap = syslinux_dup_memmap(mmap); if (!mmap || !amap) goto bail; /* **** Map the BOOT BLOB to 0x7c00 **** */ if (!hdr->BootCodeOffset) { fputs("No BOOT BLOB in image\n", stdout); goto bail; } if (!hdr->BootCodeSize) { fputs("BOOT BLOB is empty\n", stdout); goto bail; } if (len < hdr->BootCodeOffset + hdr->BootCodeSize) { fputs("BOOT BLOB extends beyond file\n", stdout); goto bail; } if (syslinux_memmap_type(amap, 0x7c00, hdr->BootCodeSize) != SMT_FREE) { fputs("BOOT BLOB too large for memory\n", stdout); goto bail; } if (syslinux_add_memmap(&amap, 0x7c00, hdr->BootCodeSize, SMT_ALLOC)) goto bail; /* The shuffle library doesn't handle duplication well... */ boot_blob = malloc(hdr->BootCodeSize); if (!boot_blob) goto bail; memcpy(boot_blob, (char *)ptr + hdr->BootCodeOffset, hdr->BootCodeSize); if (syslinux_add_movelist(&ml, 0x7c00, (addr_t)boot_blob, hdr->BootCodeSize)) goto bail; /* **** Map the entire image to SDI_LOAD_ADDR **** */ if (syslinux_memmap_type(amap, SDI_LOAD_ADDR, len) != SMT_FREE) { fputs("Image too large for memory\n", stdout); goto bail; } if (syslinux_add_memmap(&amap, SDI_LOAD_ADDR, len, SMT_ALLOC)) goto bail; if (syslinux_add_movelist(&ml, SDI_LOAD_ADDR, (addr_t)ptr, len)) goto bail; /* **** Set up registers **** */ memset(®s, 0, sizeof regs); regs.ip = 0x7c00; regs.esp.l = 0x7c00; regs.edx.l = SDI_LOAD_ADDR | 0x41; fputs("Booting...\n", stdout); syslinux_shuffle_boot_rm(ml, mmap, 0, ®s); bail: syslinux_free_memmap(amap); syslinux_free_memmap(mmap); syslinux_free_movelist(ml); return -1; } int main(int argc, char *argv[]) { void *data; size_t data_len; openconsole(&dev_null_r, &dev_stdcon_w); if (argc != 2) { error("Usage: sdi.c32 sdi_file\n"); return 1; } fputs("Loading ", stdout); fputs(argv[1], stdout); fputs("... ", stdout); if (loadfile(argv[1], &data, &data_len)) { error("failed!\n"); return 1; } fputs("ok\n", stdout); boot_sdi(data, data_len); error("Invalid SDI file or insufficient memory\n"); return 1; } syslinux-legacy-3.63+dfsg/com32/modules/dmitest.c0000664000175000017500000001454210777447273020432 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * dmitest.c * * DMI demo program using libcom32 */ #include #include #include #include "dmi/dmi.h" char display_line; void display_bios(s_dmi *dmi) { moreprintf("BIOS\n"); moreprintf("\tVendor: %s\n",dmi->bios.vendor); moreprintf("\tVersion: %s\n",dmi->bios.version); moreprintf("\tRelease: %s\n",dmi->bios.release_date); moreprintf("\tBios Revision %s\n",dmi->bios.bios_revision); moreprintf("\tFirmware Revision %s\n",dmi->bios.firmware_revision); moreprintf("\tAddress: 0x%04X0\n",dmi->bios.address); moreprintf("\tRuntime address: %u %s\n",dmi->bios.runtime_size,dmi->bios.runtime_size_unit); moreprintf("\tRom size: %u %s\n",dmi->bios.rom_size,dmi->bios.rom_size_unit); display_bios_characteristics(dmi); } void display_system(s_dmi *dmi) { moreprintf("\nSystem\n"); moreprintf("\tManufacturer %s\n",dmi->system.manufacturer); moreprintf("\tProduct Name %s\n",dmi->system.product_name); moreprintf("\tVersion %s\n",dmi->system.version); moreprintf("\tSerial %s\n",dmi->system.serial); moreprintf("\tUUID %s\n",dmi->system.uuid); moreprintf("\tWakeup Type %s\n",dmi->system.wakeup_type); moreprintf("\tSKU Number %s\n",dmi->system.sku_number); moreprintf("\tFamily %s\n",dmi->system.family); } void display_base_board(s_dmi *dmi) { moreprintf("Base board\n"); moreprintf("\tManufacturer %s\n",dmi->base_board.manufacturer); moreprintf("\tProduct Name %s\n",dmi->base_board.product_name); moreprintf("\tVersion %s\n",dmi->base_board.version); moreprintf("\tSerial %s\n",dmi->base_board.serial); moreprintf("\tAsset Tag %s\n",dmi->base_board.asset_tag); moreprintf("\tLocation %s\n",dmi->base_board.location); moreprintf("\tType %s\n",dmi->base_board.type); display_base_board_features(dmi); } void display_chassis(s_dmi *dmi) { moreprintf("\nChassis\n"); moreprintf("\tManufacturer %s\n",dmi->chassis.manufacturer); moreprintf("\tType %s\n",dmi->chassis.type); moreprintf("\tLock %s\n",dmi->chassis.lock); moreprintf("\tVersion %s\n",dmi->chassis.version); moreprintf("\tSerial %s\n",dmi->chassis.serial); moreprintf("\tAsset Tag %s\n",dmi->chassis.asset_tag); moreprintf("\tBoot up state %s\n",dmi->chassis.boot_up_state); moreprintf("\tPower supply state %s\n",dmi->chassis.power_supply_state); moreprintf("\tThermal state %s\n",dmi->chassis.thermal_state); moreprintf("\tSecurity Status %s\n",dmi->chassis.security_status); moreprintf("\tOEM Information %s\n",dmi->chassis.oem_information); moreprintf("\tHeight %u\n",dmi->chassis.height); moreprintf("\tNB Power Cords %u\n",dmi->chassis.nb_power_cords); } void display_cpu(s_dmi *dmi) { moreprintf("\nCPU\n"); moreprintf("\tSocket Designation %s\n",dmi->processor.socket_designation); moreprintf("\tType %s\n",dmi->processor.type); moreprintf("\tFamily %s\n",dmi->processor.family); moreprintf("\tManufacturer %s\n",dmi->processor.manufacturer); moreprintf("\tVersion %s\n",dmi->processor.version); moreprintf("\tExternal Clock %u\n",dmi->processor.external_clock); moreprintf("\tMax Speed %u\n",dmi->processor.max_speed); moreprintf("\tCurrent Speed %u\n",dmi->processor.current_speed); moreprintf("\tCpu Type %u\n",dmi->processor.signature.type); moreprintf("\tCpu Family %u\n",dmi->processor.signature.family); moreprintf("\tCpu Model %u\n",dmi->processor.signature.model); moreprintf("\tCpu Stepping %u\n",dmi->processor.signature.stepping); moreprintf("\tCpu Minor Stepping %u\n",dmi->processor.signature.minor_stepping); moreprintf("\tVoltage %f\n",dmi->processor.voltage); moreprintf("\tStatus %s\n",dmi->processor.status); moreprintf("\tUpgrade %s\n",dmi->processor.upgrade); moreprintf("\tCache L1 Handle %s\n",dmi->processor.cache1); moreprintf("\tCache L2 Handle %s\n",dmi->processor.cache2); moreprintf("\tCache L3 Handle %s\n",dmi->processor.cache3); moreprintf("\tSerial %s\n",dmi->processor.serial); moreprintf("\tPart Number %s\n",dmi->processor.part_number); moreprintf("\tID %s\n",dmi->processor.id); display_processor_flags(dmi); } int main(void) { char buffer[1024]; s_dmi dmi; openconsole(&dev_stdcon_r, &dev_stdcon_w); if ( ! dmi_interate() ) { printf("No DMI Structure found\n"); return -1; } parse_dmitable(&dmi); for (;;) { printf("Available commands are system, chassis, base_board, cpu, bios, all, exit\n"); printf("dmi: "); fgets(buffer, sizeof buffer, stdin); if ( !strncmp(buffer, "exit", 4) ) break; if ( !strncmp(buffer, "system", 6) ) display_system(&dmi); if ( !strncmp(buffer, "chassis", 6) ) display_chassis(&dmi); if ( !strncmp(buffer, "base_board", 10) ) display_base_board(&dmi); if ( !strncmp(buffer, "cpu", 3) ) display_cpu(&dmi); if ( !strncmp(buffer, "bios", 4) ) display_bios(&dmi); if ( !strncmp(buffer, "all", 3) ) { display_bios(&dmi); display_system(&dmi); display_chassis(&dmi); display_base_board(&dmi); display_cpu(&dmi); } } return 0; } syslinux-legacy-3.63+dfsg/com32/modules/cpuid.c0000664000175000017500000002747610777447273020077 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include "cpuid.h" struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; /* * CPUID functions returning a single datum */ static inline unsigned int cpuid_eax(unsigned int op) { unsigned int eax; __asm__("cpuid" : "=a" (eax) : "0" (op) : "bx", "cx", "dx"); return eax; } static inline unsigned int cpuid_ecx(unsigned int op) { unsigned int eax, ecx; __asm__("cpuid" : "=a" (eax), "=c" (ecx) : "0" (op) : "bx", "dx" ); return ecx; } static inline unsigned int cpuid_edx(unsigned int op) { unsigned int eax, edx; __asm__("cpuid" : "=a" (eax), "=d" (edx) : "0" (op) : "bx", "cx"); return edx; } /* Standard macro to see if a specific flag is changeable */ static inline int flag_is_changeable_p(u32 flag) { u32 f1, f2; asm("pushfl\n\t" "pushfl\n\t" "popl %0\n\t" "movl %0,%1\n\t" "xorl %2,%0\n\t" "pushl %0\n\t" "popfl\n\t" "pushfl\n\t" "popl %0\n\t" "popfl\n\t" : "=&r" (f1), "=&r" (f2) : "ir" (flag)); return ((f1^f2) & flag) != 0; } /* Probe for the CPUID instruction */ static int have_cpuid_p(void) { return flag_is_changeable_p(X86_EFLAGS_ID); } static struct cpu_dev amd_cpu_dev = { .c_vendor = "AMD", .c_ident = { "AuthenticAMD" } }; static struct cpu_dev intel_cpu_dev = { .c_vendor = "Intel", .c_ident = { "GenuineIntel" } }; static struct cpu_dev cyrix_cpu_dev = { .c_vendor = "Cyrix", .c_ident = { "CyrixInstead" } }; static struct cpu_dev umc_cpu_dev = { .c_vendor = "UMC", .c_ident = { "UMC UMC UMC" } }; static struct cpu_dev nexgen_cpu_dev = { .c_vendor = "Nexgen", .c_ident = { "NexGenDriven" } }; static struct cpu_dev centaur_cpu_dev = { .c_vendor = "Centaur", .c_ident = { "CentaurHauls" } }; static struct cpu_dev rise_cpu_dev = { .c_vendor = "Rise", .c_ident = { "RiseRiseRise" } }; static struct cpu_dev transmeta_cpu_dev = { .c_vendor = "Transmeta", .c_ident = { "GenuineTMx86", "TransmetaCPU" } }; void init_cpu_devs(void) { cpu_devs[X86_VENDOR_INTEL] = &intel_cpu_dev; cpu_devs[X86_VENDOR_CYRIX] = &cyrix_cpu_dev; cpu_devs[X86_VENDOR_AMD] = &amd_cpu_dev; cpu_devs[X86_VENDOR_UMC] = &umc_cpu_dev; cpu_devs[X86_VENDOR_NEXGEN] = &nexgen_cpu_dev; cpu_devs[X86_VENDOR_CENTAUR] = ¢aur_cpu_dev; cpu_devs[X86_VENDOR_RISE] = &rise_cpu_dev; cpu_devs[X86_VENDOR_TRANSMETA] = &transmeta_cpu_dev; } void get_cpu_vendor(struct cpuinfo_x86 *c) { char *v = c->x86_vendor_id; int i; init_cpu_devs(); for (i = 0; i < X86_VENDOR_NUM; i++) { if (cpu_devs[i]) { if (!strcmp(v,cpu_devs[i]->c_ident[0]) || (cpu_devs[i]->c_ident[1] && !strcmp(v,cpu_devs[i]->c_ident[1]))) { c->x86_vendor = i; return; } } } c->x86_vendor = X86_VENDOR_UNKNOWN; } int get_model_name(struct cpuinfo_x86 *c) { unsigned int *v; char *p, *q; if (cpuid_eax(0x80000000) < 0x80000004) return 0; v = (unsigned int *) c->x86_model_id; cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]); cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]); cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]); c->x86_model_id[48] = 0; /* Intel chips right-justify this string for some dumb reason; undo that brain damage */ p = q = &c->x86_model_id[0]; while ( *p == ' ' ) p++; if ( p != q ) { while ( *p ) *q++ = *p++; while ( q <= &c->x86_model_id[48] ) *q++ = '\0'; /* Zero-pad the rest */ } return 1; } void generic_identify(struct cpuinfo_x86 *c) { u32 tfms, xlvl; int junk; /* Get vendor name */ cpuid(0x00000000, &c->cpuid_level, (int *)&c->x86_vendor_id[0], (int *)&c->x86_vendor_id[8], (int *)&c->x86_vendor_id[4]); get_cpu_vendor(c); /* Intel-defined flags: level 0x00000001 */ if ( c->cpuid_level >= 0x00000001 ) { u32 capability, excap; cpuid(0x00000001, &tfms, &junk, &excap, &capability); c->x86_capability[0] = capability; c->x86_capability[4] = excap; c->x86 = (tfms >> 8) & 15; c->x86_model = (tfms >> 4) & 15; if (c->x86 == 0xf) { c->x86 += (tfms >> 20) & 0xff; c->x86_model += ((tfms >> 16) & 0xF) << 4; } c->x86_mask = tfms & 15; if (capability & (1<<19)) c->x86_cache_alignment = ((junk >> 8) & 0xff) * 8; } else { /* Have CPUID level 0 only - unheard of */ c->x86 = 4; } /* AMD-defined flags: level 0x80000001 */ xlvl = cpuid_eax(0x80000000); if ( (xlvl & 0xffff0000) == 0x80000000 ) { if ( xlvl >= 0x80000001 ) { c->x86_capability[1] = cpuid_edx(0x80000001); c->x86_capability[6] = cpuid_ecx(0x80000001); } if ( xlvl >= 0x80000004 ) get_model_name(c); /* Default name */ } } /* * Checksum an MP configuration block. */ static int mpf_checksum(unsigned char *mp, int len) { int sum = 0; while (len--) sum += *mp++; return sum & 0xFF; } static int smp_scan_config (unsigned long base, unsigned long length) { unsigned long *bp = base; struct intel_mp_floating *mpf; // printf("Scan SMP from %p for %ld bytes.\n", bp,length); if (sizeof(*mpf) != 16) { printf("Error: MPF size\n"); return 0; } while (length > 0) { mpf = (struct intel_mp_floating *)bp; if ((*bp == SMP_MAGIC_IDENT) && (mpf->mpf_length == 1) && !mpf_checksum((unsigned char *)bp, 16) && ((mpf->mpf_specification == 1) || (mpf->mpf_specification == 4)) ) { return 1; } bp += 4; length -= 16; } return 0; } int find_smp_config (void) { // unsigned int address; /* * FIXME: Linux assumes you have 640K of base ram.. * this continues the error... * * 1) Scan the bottom 1K for a signature * 2) Scan the top 1K of base RAM * 3) Scan the 64K of bios */ if (smp_scan_config(0x0,0x400) || smp_scan_config(639*0x400,0x400) || smp_scan_config(0xF0000,0x10000)) return 1; /* * If it is an SMP machine we should know now, unless the * configuration is in an EISA/MCA bus machine with an * extended bios data area. * * there is a real-mode segmented pointer pointing to the * 4K EBDA area at 0x40E, calculate and scan it here. * * NOTE! There are Linux loaders that will corrupt the EBDA * area, and as such this kind of SMP config may be less * trustworthy, simply because the SMP table may have been * stomped on during early boot. These loaders are buggy and * should be fixed. * * MP1.4 SPEC states to only scan first 1K of 4K EBDA. */ // address = get_bios_ebda(); // if (address) // smp_scan_config(address, 0x400); return 0; } void set_cpu_flags(struct cpuinfo_x86 *c, s_cpu *cpu) { cpu->flags.fpu=cpu_has(c, X86_FEATURE_FPU); cpu->flags.vme=cpu_has(c, X86_FEATURE_VME); cpu->flags.de=cpu_has(c, X86_FEATURE_DE); cpu->flags.pse=cpu_has(c, X86_FEATURE_PSE); cpu->flags.tsc=cpu_has(c, X86_FEATURE_TSC); cpu->flags.msr=cpu_has(c, X86_FEATURE_MSR); cpu->flags.pae=cpu_has(c, X86_FEATURE_PAE); cpu->flags.mce=cpu_has(c, X86_FEATURE_MCE); cpu->flags.cx8=cpu_has(c, X86_FEATURE_CX8); cpu->flags.apic=cpu_has(c, X86_FEATURE_APIC); cpu->flags.sep=cpu_has(c, X86_FEATURE_SEP); cpu->flags.mtrr=cpu_has(c, X86_FEATURE_MTRR); cpu->flags.pge=cpu_has(c, X86_FEATURE_PGE); cpu->flags.mca=cpu_has(c, X86_FEATURE_MCA); cpu->flags.cmov=cpu_has(c, X86_FEATURE_CMOV); cpu->flags.pat=cpu_has(c, X86_FEATURE_PAT); cpu->flags.pse_36=cpu_has(c, X86_FEATURE_PSE36); cpu->flags.psn=cpu_has(c, X86_FEATURE_PN); cpu->flags.clflsh=cpu_has(c, X86_FEATURE_CLFLSH); cpu->flags.dts=cpu_has(c, X86_FEATURE_DTES); cpu->flags.acpi=cpu_has(c, X86_FEATURE_ACPI); cpu->flags.mmx=cpu_has(c, X86_FEATURE_MMX); cpu->flags.fxsr=cpu_has(c, X86_FEATURE_FXSR); cpu->flags.sse=cpu_has(c, X86_FEATURE_XMM); cpu->flags.sse2=cpu_has(c, X86_FEATURE_XMM2); cpu->flags.ss=cpu_has(c, X86_FEATURE_SELFSNOOP); cpu->flags.htt=cpu_has(c, X86_FEATURE_HT); cpu->flags.acc=cpu_has(c, X86_FEATURE_ACC); cpu->flags.syscall=cpu_has(c, X86_FEATURE_SYSCALL); cpu->flags.mp=cpu_has(c, X86_FEATURE_MP); cpu->flags.nx=cpu_has(c, X86_FEATURE_NX); cpu->flags.mmxext=cpu_has(c, X86_FEATURE_MMXEXT); cpu->flags.lm=cpu_has(c, X86_FEATURE_LM); cpu->flags.nowext=cpu_has(c, X86_FEATURE_3DNOWEXT); cpu->flags.now=cpu_has(c, X86_FEATURE_3DNOW); cpu->flags.smp = find_smp_config(); } void set_generic_info(struct cpuinfo_x86 *c,s_cpu *cpu) { cpu->family=c->x86; cpu->vendor_id=c->x86_vendor; cpu->model_id=c->x86_model; cpu->stepping=c->x86_mask; strncpy(cpu->vendor,cpu_devs[c->x86_vendor]->c_vendor,CPU_VENDOR_SIZE); strncpy(cpu->model,c->x86_model_id,CPU_MODEL_SIZE); } void detect_cpu(s_cpu *cpu) { struct cpuinfo_x86 c; c.x86_cache_alignment = 32; c.x86_cache_size = -1; c.x86_vendor = X86_VENDOR_UNKNOWN; c.cpuid_level = -1; /* CPUID not detected */ c.x86_model = c.x86_mask = 0; /* So far unknown... */ c.x86_vendor_id[0] = '\0'; /* Unset */ c.x86_model_id[0] = '\0'; /* Unset */ memset(&c.x86_vendor_id,'\0',CPU_VENDOR_SIZE); if (!have_cpuid_p()) return; generic_identify(&c); set_generic_info(&c,cpu); set_cpu_flags(&c,cpu); } syslinux-legacy-3.63+dfsg/com32/modules/elf.c0000664000175000017500000002006710777447273017526 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * elf.c * * Module to load a protected-mode ELF kernel */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* If we don't have this much memory for the stack, signal failure */ #define MIN_STACK 512 #define DEBUG 0 #if DEBUG # define dprintf printf #else # define dprintf(f, ...) ((void)0) #endif static inline void error(const char *msg) { fputs(msg, stderr); } int boot_elf(void *ptr, size_t len, char **argv) { char *cptr = ptr; Elf32_Ehdr *eh = ptr; Elf32_Phdr *ph; unsigned int i; struct syslinux_movelist *ml = NULL; struct syslinux_memmap *mmap = NULL, *amap = NULL; struct syslinux_pm_regs regs; int argc; addr_t argsize; char **argp; addr_t lstart, llen; char *stack_frame = NULL; addr_t stack_frame_size; addr_t stack_pointer; uint32_t *spp; char *sfp; addr_t sfa; memset(®s, 0, sizeof regs); /* * Note: mmap is the memory map (containing free and zeroed regions) * needed by syslinux_shuffle_boot_pm(); amap is a map where we keep * track ourselves which target memory ranges have already been * allocated. */ if ( len < sizeof(Elf32_Ehdr) ) goto bail; /* Must be ELF, 32-bit, littleendian, version 1 */ if ( memcmp(eh->e_ident, "\x7f""ELF\1\1\1", 6) ) goto bail; /* Is this a worthwhile test? In particular x86-64 normally would imply ELF64 support, which we could do as long as the addresses are 32-bit addresses, and entry is 32 bits. 64-bit addresses would take a lot more work. */ if ( eh->e_machine != EM_386 && eh->e_machine != EM_486 && eh->e_machine != EM_X86_64 ) goto bail; if ( eh->e_version != EV_CURRENT ) goto bail; if ( eh->e_ehsize < sizeof(Elf32_Ehdr) || eh->e_ehsize >= len ) goto bail; if ( eh->e_phentsize < sizeof(Elf32_Phdr) ) goto bail; if ( !eh->e_phnum ) goto bail; if ( eh->e_phoff+eh->e_phentsize*eh->e_phnum > len ) goto bail; mmap = syslinux_memory_map(); amap = syslinux_dup_memmap(mmap); if (!mmap || !amap) goto bail; #if DEBUG dprintf("Initial memory map:\n"); syslinux_dump_memmap(stdout, mmap); #endif ph = (Elf32_Phdr *)(cptr+eh->e_phoff); for (i = 0; i < eh->e_phnum; i++) { if (ph->p_type == PT_LOAD || ph->p_type == PT_PHDR) { /* This loads at p_paddr, which is arguably the correct semantics. The SysV spec says that SysV loads at p_vaddr (and thus Linux does, too); that is, however, a major brainfuckage in the spec. */ addr_t addr = ph->p_paddr; addr_t msize = ph->p_memsz; addr_t dsize = min(msize, ph->p_filesz); dprintf("Segment at 0x%08x data 0x%08x len 0x%08x\n", addr, dsize, msize); if (syslinux_memmap_type(amap, addr, msize) != SMT_FREE) { printf("Memory segment at 0x%08x (len 0x%08x) is unavailable\n", addr, msize); goto bail; /* Memory region unavailable */ } /* Mark this region as allocated in the available map */ if (syslinux_add_memmap(&amap, addr, dsize, SMT_ALLOC)) goto bail; if (ph->p_filesz) { /* Data present region. Create a move entry for it. */ if (syslinux_add_movelist(&ml, addr, (addr_t)cptr+ph->p_offset, dsize)) goto bail; } if (msize > dsize) { /* Zero-filled region. Mark as a zero region in the memory map. */ if (syslinux_add_memmap(&mmap, addr+dsize, msize-dsize, SMT_ZERO)) goto bail; } } else { /* Ignore this program header */ } ph = (Elf32_Phdr *)((char *)ph + eh->e_phentsize); } /* Create the invocation record (initial stack frame) */ argsize = argc = 0; for (argp = argv; *argp; argp++) { dprintf("argv[%2d] = \"%s\"\n", argc, *argp); argc++; argsize += strlen(*argp)+1; } /* We need the argument strings, argument pointers, argc, plus four zero-word terminators. */ stack_frame_size = argsize + argc*sizeof(char *) + 5*sizeof(long); stack_frame_size = (stack_frame_size+15) & ~15; stack_frame = calloc(stack_frame_size, 1); if (!stack_frame) goto bail; #if DEBUG dprintf("Right before syslinux_memmap_largest()...\n"); syslinux_dump_memmap(stdout, amap); #endif if (syslinux_memmap_largest(amap, SMT_FREE, &lstart, &llen)) goto bail; /* NO free memory?! */ if (llen < stack_frame_size+MIN_STACK+16) goto bail; /* Insufficient memory */ /* Initial stack pointer address */ stack_pointer = (lstart+llen-stack_frame_size) & ~15; dprintf("Stack frame at 0x%08x len 0x%08x\n", stack_pointer, stack_frame_size); /* Create the stack frame. sfp is the pointer in current memory for the next argument string, sfa is the address in its final resting place. spp is the pointer into the argument array in current memory. */ spp = (uint32_t *)stack_frame; sfp = stack_frame + argc*sizeof(char *) + 5*sizeof(long); sfa = stack_pointer + argc*sizeof(char *) + 5*sizeof(long); *spp++ = argc; for (argp = argv; *argp; argp++) { int bytes = strlen(*argp) + 1; /* Including final null */ *spp++ = sfa; memcpy(sfp, *argp, bytes); sfp += bytes; sfa += bytes; } /* Zero fields are aready taken care of by calloc() */ /* ... and we'll want to move it into the right place... */ #if DEBUG if (syslinux_memmap_type(amap, stack_pointer, stack_frame_size) != SMT_FREE) { dprintf("Stack frame area not free (how did that happen?)!\n"); goto bail; /* Memory region unavailable */ } #endif if (syslinux_add_memmap(&amap, stack_pointer, stack_frame_size, SMT_ALLOC)) goto bail; if (syslinux_add_movelist(&ml, stack_pointer, (addr_t)stack_frame, stack_frame_size)) goto bail; memset(®s, 0, sizeof regs); regs.eip = eh->e_entry; regs.esp = stack_pointer; #if DEBUG dprintf("Final memory map:\n"); syslinux_dump_memmap(stdout, mmap); dprintf("Final available map:\n"); syslinux_dump_memmap(stdout, amap); dprintf("Movelist:\n"); syslinux_dump_movelist(stdout, ml); #endif /* This should not return... */ fputs("Booting...\n", stdout); syslinux_shuffle_boot_pm(ml, mmap, 0, ®s); bail: if (stack_frame) free(stack_frame); syslinux_free_memmap(amap); syslinux_free_memmap(mmap); syslinux_free_movelist(ml); return -1; } int main(int argc, char *argv[]) { void *data; size_t data_len; openconsole(&dev_null_r, &dev_stdcon_w); if (argc < 2) { error("Usage: elf.c32 elf_file arguments...\n"); return 1; } if (loadfile(argv[1], &data, &data_len)) { error("Unable to load file\n"); return 1; } boot_elf(data, data_len, &argv[1]); error("Invalid ELF file or insufficient memory\n"); return 1; } syslinux-legacy-3.63+dfsg/com32/modules/chain.c0000664000175000017500000002541010777447273020037 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * chain.c * * Chainload a hard disk (currently rather braindead.) * * Usage: chain hd [] * chain fd * chain mbr: [] * * ... e.g. "chain hd0 1" will boot the first partition on the first hard * disk. * * The mbr: syntax means search all the hard disks until one with a * specific MBR serial number (bytes 440-443) is found. * * Partitions 1-4 are primary, 5+ logical, 0 = boot MBR (default.) */ #include #include #include #include #include #include #define SECTOR 512 /* bytes/sector */ static inline void error(const char *msg) { fputs(msg, stderr); } /* * Call int 13h, but with retry on failure. Especially floppies need this. */ int int13_retry(const com32sys_t *inreg, com32sys_t *outreg) { int retry = 6; /* Number of retries */ com32sys_t tmpregs; if ( !outreg ) outreg = &tmpregs; while ( retry-- ) { __intcall(0x13, inreg, outreg); if ( !(outreg->eflags.l & EFLAGS_CF) ) return 0; /* CF=0, OK */ } return -1; /* Error */ } /* * Query disk parameters and EBIOS availability for a particular disk. */ struct diskinfo { int disk; int ebios; /* EBIOS supported on this disk */ int cbios; /* CHS geometry is valid */ int head; int sect; } disk_info; int get_disk_params(int disk) { static com32sys_t getparm, parm, getebios, ebios; disk_info.disk = disk; disk_info.ebios = disk_info.cbios = 0; /* Get EBIOS support */ getebios.eax.w[0] = 0x4100; getebios.ebx.w[0] = 0x55aa; getebios.edx.b[0] = disk; getebios.eflags.b[0] = 0x3; /* CF set */ __intcall(0x13, &getebios, &ebios); if ( !(ebios.eflags.l & EFLAGS_CF) && ebios.ebx.w[0] == 0xaa55 && (ebios.ecx.b[0] & 1) ) { disk_info.ebios = 1; } /* Get disk parameters -- really only useful for hard disks, but if we have a partitioned floppy it's actually our best chance... */ getparm.eax.b[1] = 0x08; getparm.edx.b[0] = disk; __intcall(0x13, &getparm, &parm); if ( parm.eflags.l & EFLAGS_CF ) return disk_info.ebios ? 0 : -1; disk_info.head = parm.edx.b[1]+1; disk_info.sect = parm.ecx.b[0] & 0x3f; if ( disk_info.sect == 0 ) { disk_info.sect = 1; } else { disk_info.cbios = 1; /* Valid geometry */ } return 0; } /* * Get a disk block; buf is REQUIRED TO BE IN LOW MEMORY. */ struct ebios_dapa { uint16_t len; uint16_t count; uint16_t off; uint16_t seg; uint64_t lba; } *dapa; int read_sector(void *buf, unsigned int lba) { com32sys_t inreg; memset(&inreg, 0, sizeof inreg); if ( disk_info.ebios ) { dapa->len = sizeof(*dapa); dapa->count = 1; /* 1 sector */ dapa->off = OFFS(buf); dapa->seg = SEG(buf); dapa->lba = lba; inreg.esi.w[0] = OFFS(dapa); inreg.ds = SEG(dapa); inreg.edx.b[0] = disk_info.disk; inreg.eax.b[1] = 0x42; /* Extended read */ } else { unsigned int c, h, s, t; if ( !disk_info.cbios ) { /* We failed to get the geometry */ if ( lba ) return -1; /* Can only read MBR */ s = 1; h = 0; c = 0; } else { s = (lba % disk_info.sect) + 1; t = lba / disk_info.sect; /* Track = head*cyl */ h = t % disk_info.head; c = t / disk_info.head; } if ( s > 63 || h > 256 || c > 1023 ) return -1; inreg.eax.w[0] = 0x0201; /* Read one sector */ inreg.ecx.b[1] = c & 0xff; inreg.ecx.b[0] = s + (c >> 6); inreg.edx.b[1] = h; inreg.edx.b[0] = disk_info.disk; inreg.ebx.w[0] = OFFS(buf); inreg.es = SEG(buf); } return int13_retry(&inreg, NULL); } /* Search for a specific drive, based on the MBR signature; bytes 440-443. */ int find_disk(uint32_t mbr_sig, void *buf) { int drive; for (drive = 0x80; drive <= 0xff; drive++) { if (get_disk_params(drive)) continue; /* Drive doesn't exist */ if (read_sector(buf, 0)) continue; /* Cannot read sector */ if (*(uint32_t *)((char *)buf + 440) == mbr_sig) return drive; } return -1; } /* A DOS partition table entry */ struct part_entry { uint8_t active_flag; /* 0x80 if "active" */ uint8_t start_head; uint8_t start_sect; uint8_t start_cyl; uint8_t ostype; uint8_t end_head; uint8_t end_sect; uint8_t end_cyl; uint32_t start_lba; uint32_t length; } __attribute__((packed)); /* Search for a logical partition. Logical partitions are actually implemented as recursive partition tables; theoretically they're supposed to form a linked list, but other structures have been seen. To make things extra confusing: data partition offsets are relative to where the data partition record is stored, whereas extended partition offsets are relative to the beginning of the extended partition all the way back at the MBR... but still not absolute! */ int nextpart; /* Number of the next logical partition */ struct part_entry * find_logical_partition(int whichpart, char *table, struct part_entry *self, struct part_entry *root) { struct part_entry *ptab = (struct part_entry *)(table + 0x1be); struct part_entry *found; int i; if ( *(uint16_t *)(ptab + 0x1fe) != 0xaa55 ) return NULL; /* Signature missing */ /* We are assumed to already having enumerated all the data partitions in this table if this is the MBR. For MBR, self == NULL. */ if ( self ) { /* Scan the data partitions. */ for ( i = 0 ; i < 4 ; i++ ) { if ( ptab[i].ostype == 0x00 || ptab[i].ostype == 0x05 || ptab[i].ostype == 0x0f || ptab[i].ostype == 0x85 ) continue; /* Skip empty or extended partitions */ if ( !ptab[i].length ) continue; /* Adjust the offset to account for the extended partition itself */ ptab[i].start_lba += self->start_lba; /* Sanity check entry: must not extend outside the extended partition. This is necessary since some OSes put crap in some entries. */ if ( ptab[i].start_lba + ptab[i].length <= self->start_lba || ptab[i].start_lba >= self->start_lba + self->length ) continue; /* OK, it's a data partition. Is it the one we're looking for? */ if ( nextpart++ == whichpart ) return &ptab[i]; } } /* Scan the extended partitions. */ for ( i = 0 ; i < 4 ; i++ ) { if ( ptab[i].ostype != 0x05 && ptab[i].ostype != 0x0f && ptab[i].ostype != 0x85 ) continue; /* Skip empty or data partitions */ if ( !ptab[i].length ) continue; /* Adjust the offset to account for the extended partition itself */ if ( root ) ptab[i].start_lba += root->start_lba; /* Sanity check entry: must not extend outside the extended partition. This is necessary since some OSes put crap in some entries. */ if ( root ) if ( ptab[i].start_lba + ptab[i].length <= root->start_lba || ptab[i].start_lba >= root->start_lba + root->length ) continue; /* Process this partition */ if ( read_sector(table+SECTOR, ptab[i].start_lba) ) continue; /* Read error, must be invalid */ if ( (found = find_logical_partition(whichpart, table+SECTOR, &ptab[i], root ? root : &ptab[i])) ) return found; } /* If we get here, there ain't nothing... */ return NULL; } int main(int argc, char *argv[]) { char *mbr, *boot_sector = NULL; struct part_entry *partinfo; char *drivename, *partition; int hd, drive, whichpart; static com32sys_t inreg; /* In bss, so zeroed automatically */ openconsole(&dev_null_r, &dev_stdcon_w); if ( argc < 2 ) { error("Usage: chain.c32 (hd#|fd#|mbr:#) [partition]\n"); goto bail; } /* Divvy up the bounce buffer. To keep things sector- aligned, give the EBIOS DAPA the first sector, then the MBR next, and the rest is used for the partition- chasing stack. */ dapa = (struct ebios_dapa *)__com32.cs_bounce; mbr = (char *)__com32.cs_bounce + SECTOR; drivename = argv[1]; partition = argv[2]; /* Possibly null */ hd = 0; if ( !memcmp(drivename, "mbr:", 4) ) { drive = find_disk(strtoul(drivename+4, NULL, 0), mbr); if (drive == -1) { error("Unable to find requested MBR signature\n"); goto bail; } } else { if ( (drivename[0] == 'h' || drivename[0] == 'f') && drivename[1] == 'd' ) { hd = drivename[0] == 'h'; drivename += 2; } drive = (hd ? 0x80 : 0) | strtoul(drivename, NULL, 0); } whichpart = 0; /* Default */ if ( partition ) whichpart = strtoul(partition, NULL, 0); if ( !(drive & 0x80) && whichpart ) { error("Warning: Partitions of floppy devices may not work\n"); } /* Get the disk geometry and disk access setup */ if ( get_disk_params(drive) ) { error("Cannot get disk parameters\n"); goto bail; } /* Get MBR */ if ( read_sector(mbr, 0) ) { error("Cannot read Master Boot Record\n"); goto bail; } if ( whichpart == 0 ) { /* Boot the MBR */ partinfo = NULL; boot_sector = mbr; } else if ( whichpart <= 4 ) { /* Boot a primary partition */ partinfo = &((struct part_entry *)(mbr + 0x1be))[whichpart-1]; if ( partinfo->ostype == 0 ) { error("Invalid primary partition\n"); goto bail; } } else { /* Boot a logical partition */ nextpart = 5; partinfo = find_logical_partition(whichpart, mbr, NULL, NULL); if ( !partinfo || partinfo->ostype == 0 ) { error("Requested logical partition not found\n"); goto bail; } } /* Do the actual chainloading */ if ( partinfo ) { /* Actually read the boot sector */ /* Pick the first buffer that isn't already in use */ boot_sector = (char *)(((unsigned long)partinfo + 511) & ~511); if ( read_sector(boot_sector, partinfo->start_lba) ) { error("Cannot read boot sector\n"); goto bail; } /* 0x7BE is the canonical place for the first partition entry. */ inreg.esi.w[0] = 0x7be; memcpy((char *)0x7be, partinfo, sizeof(*partinfo)); } fputs("Booting...\n", stdout); inreg.eax.w[0] = 0x000d; /* Clean up and chain boot */ inreg.edx.w[0] = 0; /* Should be 3 for "keeppxe" */ inreg.edi.l = (uint32_t)boot_sector; inreg.ecx.l = SECTOR; /* One sector */ inreg.ebx.b[0] = drive; /* DL = drive no */ __intcall(0x22, &inreg, NULL); /* If we get here, badness happened */ error("Chainboot failed!\n"); bail: return 255; } syslinux-legacy-3.63+dfsg/com32/modules/cpuidtest.c0000664000175000017500000000646210777447273020767 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * cpuidtest.c * * A CPUID demo program using libcom32 */ #include #include #include #include "cpuid.h" char display_line; int main(void) { s_cpu cpu; openconsole(&dev_stdcon_r, &dev_stdcon_w); for (;;) { detect_cpu(&cpu); printf("Vendor = %s\n",cpu.vendor); printf("Model = %s\n",cpu.model); printf("Vendor ID = %d\n",cpu.vendor_id); printf("Family = %d\n",cpu.family); printf("Model ID = %d\n",cpu.model_id); printf("Stepping = %d\n",cpu.stepping); printf("Flags = "); if (cpu.flags.fpu) printf("fpu "); if (cpu.flags.vme) printf("vme "); if (cpu.flags.de) printf("de "); if (cpu.flags.pse) printf("pse "); if (cpu.flags.tsc) printf("tsc "); if (cpu.flags.msr) printf("msr "); if (cpu.flags.pae) printf("pae "); if (cpu.flags.mce) printf("mce "); if (cpu.flags.cx8) printf("cx8 "); if (cpu.flags.apic) printf("apic "); if (cpu.flags.sep) printf("sep "); if (cpu.flags.mtrr) printf("mtrr "); if (cpu.flags.pge) printf("pge "); if (cpu.flags.mca) printf("mca "); if (cpu.flags.cmov) printf("cmov "); if (cpu.flags.pat) printf("pat "); if (cpu.flags.pse_36) printf("pse_36 "); if (cpu.flags.psn) printf("psn "); if (cpu.flags.clflsh) printf("clflsh "); if (cpu.flags.dts) printf("dts "); if (cpu.flags.acpi) printf("acpi "); if (cpu.flags.mmx) printf("mmx "); if (cpu.flags.sse) printf("sse "); if (cpu.flags.sse2) printf("sse2 "); if (cpu.flags.ss) printf("ss "); if (cpu.flags.htt) printf("ht "); if (cpu.flags.acc) printf("acc "); if (cpu.flags.syscall) printf("syscall "); if (cpu.flags.mp) printf("mp "); if (cpu.flags.nx) printf("nx "); if (cpu.flags.mmxext) printf("mmxext "); if (cpu.flags.lm) printf("lm "); if (cpu.flags.nowext) printf("3dnowext "); if (cpu.flags.now) printf("3dnow! "); printf("\n"); printf("SMP = "); if (cpu.flags.smp) printf("yes\n"); else printf("no\n"); break; } return 0; } syslinux-legacy-3.63+dfsg/com32/modules/ethersel.c320000775000175000017500000001744410777447337020751 0ustar evanevanL!1$/4)t$/g;vA/RP..sXZ/@t ~SCBt t1t:u < 1[UWVS D$Չ|$ËD$8:u[@؉ED$8/u9@ËD$8:t @d ؉D$ [^_]ÍL$qUWVSQ옋Éֺ,,M$D$ K<FDŽ$u-fd/@/ʸ"D/X/к,qŅ$D$Zú,?Cdú,g#CHøxƅ1Fú,tNV,tNV C#뿺,t]C$C$$Ë$8-t @^F$R 88t $8t=FuFD$0t$$$$%t[P/f//ƒf/f/1ɺ/"rDŽ$,ĘY[^_]aÐUWVS lj։͉ (u 9u1C t Nۅt [^_]ÐVSƸ15rt +tau#wu BBB uŅtQhPVy1@Z[^ÐUWVSƉՉ1҉وJ[^_]UWVS Ӊ͉1,Eى{u/t t t )ÅuЉ [^_]ÐS /)ʋ/t9v //@9sB/+/QA /A/A/A/ / / / /[ÍvUWVStxX /eq9r[C 9Ƌyir:Q)މpYH PB AxhQBQBoAxA I9u1[^_]Ð /u1@8uÐSÉABu[ÐWVS1Ӊ*Džt ى[^_ÐjRÐQRP/ÐP..sX%/ÐUWVSŠ,D$5 /<  uA A1ۀ:tBۍQUD$ZI9srZ:uBB9rC /[^_]Si(@/Xu/ SZY[ÐS8L$D1Ҹ,@Åx] /T$@/fD$0/ƒfT$fD$PD$PPj"/D$4uf|$u/5i(@/fD$,BD$0BD$fBB B؃8[UWVSlÉΉՍ|$@ 1fD$d/ƒfT$XfD$DD${C ;CCffD$LK@fD$`L$T$@"D$<t/fD$ fCK+K K@v@KC C/v C9vNjS_ |$){{ ){@D$l[^_]ÐW8fxt8D$ D$ 1|$fD$0BfD$PjD$Pj"/18_VSƉ18ډu8ډuډ u0Z[^ÐWVS0ΉӍ|$ 1D$)1; uD$ T$1ɸ!MD$ CT$1ɸ!6Ouɉ0[^_Ð1Ð@t ~ÐUWVS$M$fk{C 3AAu 3A Au C:Ar:AvF;t$| t$D$1ZY[^_]fUWVSD$T$Ƃ1l$D$ D$ fEƅT$ƂxD$t$ D$ ƋD$ Ɖ/ǃ==t|txF yD$FÍF,L$ʉfJfJf:fBZD$kD$ "ȋL$TD$D$9D$(D$|$ u C u-C - C - F9|,-D$6$'&-$"&-$&-$&-D$<#< 'G u-G -C9|,0- Ņy$Z&-$J&-$*&-$:&-D$<#< < $j1_1Iv=w7$D-$"$Z$J$:$*OC$j1…u1ۉk$Z9uT$JW9u@$*yW!9u*$:cW!9u$G C9|\$P!l[^_]ÐUWVS š4t' ttG18 D$f D$fx} ƻ ljff%Ł  [^_]ÐUWVS š4t' ttB1< D$f ɉŋD$ifxz ƻ ljff%Ł [^_] [^_]ÐUWVS<ƍD$D$ 1ljىft$4fD$(T$L$ʸD$8tD$0<[^_]WS؉…t 1׉Z[_ÐD$HtD$UWVS Ӊ͉1,EىSu/t t t )ÅuЉ [^_]ÐVW։ljsft_^Ð x, ÐUWVS$ʼnT$L$ EL$8|$8t)U-u-uEL$8D$+uED$|$ uc|$8v#}0u$Eu 1$CC@@ZY[ÐHfUWVS$ՉjPxnFu`bT$uND$\$?ljEt.T$6;D$u)11_p[^_]ÐUWVS Ӊ͉1,Eىu.t t t )ÅuЉ [^_]ÐVStyHQ q:uZ9uYZrV !-AA- -AH>u+Q9u!VQVFBFPFAFH [^ÐQRP-ÐUWVS ljօu1Pu1Ft Ѕt.1.;u{tE t(@.\L-C`-C CtWt҅u*;t3Vt҅t uvus.G [^_]ÐVSi(@..u. SZ[^VSi(@..t~u. ;P t҅u,ǃ.L-FP t҅u(@1҉1Z[^S8L$D1Ҹ8-lÅx] -T$@-fD$0-ƒfT$fD$PD$PPj"-D$4uf|$u.5i(@.fD$,BD$0BD$fBB B؃8[UWVSlÉΉՍ|$@ 1fD$d-ƒfT$XfD$DD${C ;CCffD$LK@fD$`L$T$@"&D$<t.fD$ fCK+K K@v@KC C-"C9vNjS |$){{ ){@D$l[^_]ÐW8fxt8D$ D$ 1|$fD$0BfD$PjD$Pj"-18_Ãi(@..u. @t$AB1!B1Ð.Ð.ÐUWVS\D$T$D$T1 uERBuD$XD$D$T_\$@ KSt$`j8 Kj[ u L$\D$`T$XRD$TD$D$T.THЙk . ȋD$L9D$P)ȉD$ D$`jT$0L$TD$XT$IiD$X1G@ u/.J؉љD$ 9{D$TKD$T3k D$\$ )É\$$T$X-.ED$(9~k D$L$11<;|$(u\$$D AD$A F1BABA FGR u\$Fu>;|$(uT$$D AD$A F1AC)ЉA FG[CuT$ T$4L$L$8k D$uEUT$ 9s()‰T$E9s4D$ )щL$(HD$ D$0v+D$ D$;Es t$ t$(ml$D$ D$(D$D$HT$ …t[@|$t L$(L$)+L$(t9;L$vt$|$tT$T$()D$H D$HT$(T$ *E;D$ M;D$ vl$$D$HUVt]}u}L$HL$1s+ 9r t9v؉ʉ{ut\$@t t$$~vq L$LD$HPD$(\$@|$t#+D$> 4) #define ELF32_ST_TYPE(i) ((i) & 0xf) #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) /* symbol binding - page 4-26, figure 4-16 */ #define STB_LOCAL 0 #define STB_GLOBAL 1 #define STB_WEAK 2 #define STB_LOPROC 13 #define STB_HIPROC 15 /* symbol types - page 4-28, figure 4-17 */ #define STT_NOTYPE 0 #define STT_OBJECT 1 #define STT_FUNC 2 #define STT_SECTION 3 #define STT_FILE 4 #define STT_LOPROC 13 #define STT_HIPROC 15 /* Macros to split/combine relocation type and symbol page 4-32 */ #define ELF32_R_SYM(__i) ((__i)>>8) #define ELF32_R_TYPE(__i) ((unsigned char) (__i)) #define ELF32_R_INFO(__s, __t) (((__s)<<8) + (unsigned char) (__t)) /* program header - page 5-2, figure 5-1 */ typedef struct { Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; } Elf32_Phdr; /* segment types - page 5-3, figure 5-2 */ #define PT_NULL 0 #define PT_LOAD 1 #define PT_DYNAMIC 2 #define PT_INTERP 3 #define PT_NOTE 4 #define PT_SHLIB 5 #define PT_PHDR 6 #define PT_LOPROC 0x70000000 #define PT_HIPROC 0x7fffffff /* segment permissions - page 5-6 */ #define PF_X 0x1 #define PF_W 0x2 #define PF_R 0x4 #define PF_MASKPROC 0xf0000000 /* dynamic structure - page 5-15, figure 5-9 */ typedef struct { Elf32_Sword d_tag; union { Elf32_Word d_val; Elf32_Addr d_ptr; } d_un; } Elf32_Dyn; /* Dynamic array tags - page 5-16, figure 5-10. */ #define DT_NULL 0 #define DT_NEEDED 1 #define DT_PLTRELSZ 2 #define DT_PLTGOT 3 #define DT_HASH 4 #define DT_STRTAB 5 #define DT_SYMTAB 6 #define DT_RELA 7 #define DT_RELASZ 8 #define DT_RELAENT 9 #define DT_STRSZ 10 #define DT_SYMENT 11 #define DT_INIT 12 #define DT_FINI 13 #define DT_SONAME 14 #define DT_RPATH 15 #define DT_SYMBOLIC 16 #define DT_REL 17 #define DT_RELSZ 18 #define DT_RELENT 19 #define DT_PLTREL 20 #define DT_DEBUG 21 #define DT_TEXTREL 22 #define DT_JMPREL 23 syslinux-legacy-3.63+dfsg/com32/modules/cpuidtest.c320000775000175000017500000002400410777447340021122 0ustar evanevanL!18=)t$H8g;vAL8RP--sXZ7L$qSQX-D-\$ QQSh* XZD$FPh* Y[D$DPh* XZD$EPh*z Y[D$vPh*h XZD$wPh*V $ +J |$pt h+3 |$qt h + |$rt h%+ |$st h)+ |$tt h.+ |$ut h3+ |$vt h8+ |$wt h=+ |$xt hB+{ |$yt hG+d |$zt hM+M |${t hR+6 |$|t hX+ |$}t h]+ |$~t hb+|$t hh+$t hm+$t hu+$t hz+$t h+r$t h+X$t h+>$t h+$$t h+ $t h+$t h+$t h+$t h+$t h+$t h+n$t h+T$t h+:$t h+ $t h+  h+$t++1ĔY[aÉ 8.$8@/(80,8108348@4885<86UWVSŸ=w1z}81 $E8_OW 1 $G_OW1G _$O(W,Eh@8 t9t B@uBG09vZ[^_]VS։3:_MP_u%zu11Auu B <t<tu1[^ú1u+ uøVS֍X 1eFdڸSFeڸAFfڸ/FgڸFhڸ FiڸFjڸFkڸFlڸ Fmڸ Fnڸ Foڸ Fpڸ{FqڸiFrڸWFsڸEFtڸ3Fuڸ!FvڸFwڸFxڸFyڸFzڸF{ڸF|ڸF}ڸF~ڸFڸ+mڸ3Xڸ4Cڸ6.ڸ=ڸ>ڸ?+[^VSÉ֊B1CB0CBbCBcC 80S8F20[[^UWVS ƍh(1 8t'SqtSt_uF G uF [^_]UWVS,ō@(D$1L$E](D$HPv}~l؉։L$ lj\$(U MEE}uEEEtD$(E|Ef1=u*vUM$v,[^_]WVSD$} D$yD$D$ D$D$D$)D$9\$|$) 1󫜜ZЁ RZ1Щ tOĐ[^_ÐD$D$HtD$ÐUWVS Ӊ͉1,Eى uh8t t t )ÅuЉ [^_]ÐL$$L$T$ Ð C x* l ÐSÉъD$CA)‰u|$uZ[ÐVSƉˉ tABKu[^ÐVSÍt$QѺ'x=~ى‰[^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$,%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$,L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$,ЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$,T$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$D1-D$D -D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u,1I|$Xt ;L$X~L$X9L$\~ #include #include #include #include #include #include const char *progname = "linux.c32"; /* Find the last instance of a particular command line argument (which should include the final =; do not use for boolean arguments) */ static char *find_argument(char **argv, const char *argument) { int la = strlen(argument); char **arg; char *ptr = NULL; for (arg = argv; *arg; arg++) { if (!memcmp(*arg, argument, la)) ptr = *arg + la; } return ptr; } /* Get a value with a potential suffix (k/m/g/t/p/e) */ static unsigned long long suffix_number(const char *str) { char *ep; unsigned long long v; int shift; v = strtoull(str, &ep, 0); switch (*ep|0x20) { case 'k': shift = 10; break; case 'm': shift = 20; break; case 'g': shift = 30; break; case 't': shift = 40; break; case 'p': shift = 50; break; case 'e': shift = 60; break; default: shift = 0; break; } v <<= shift; return v; } /* Truncate to 32 bits, with saturate */ static inline uint32_t saturate32(unsigned long long v) { return (v > 0xffffffff) ? 0xffffffff : (uint32_t)v; } /* Stitch together the command line from a set of argv's */ static char *make_cmdline(char **argv) { char **arg; size_t bytes; char *cmdline, *p; bytes = 1; /* Just in case we have a zero-entry cmdline */ for (arg = argv; *arg; arg++) { bytes += strlen(*arg)+1; } p = cmdline = malloc(bytes); if (!cmdline) return NULL; for (arg = argv; *arg; arg++) { int len = strlen(*arg); memcpy(p, *arg, len); p[len] = ' '; p += len+1; } if (p > cmdline) p--; /* Remove the last space */ *p = '\0'; return cmdline; } int main(int argc, char *argv[]) { uint32_t mem_limit = 0; uint16_t video_mode = 0; const char *kernel_name; struct initramfs *initramfs; char *cmdline; char *boot_image; void *kernel_data; size_t kernel_len; int opt_dhcpinfo = 0; void *dhcpdata; size_t dhcplen; char **argp, *arg, *p; openconsole(&dev_null_r, &dev_stdcon_w); (void)argc; argp = argv+1; while ((arg = *argp) && arg[0] == '-') { if (!strcmp("-dhcpinfo", arg)) { opt_dhcpinfo = 1; } else { fprintf(stderr, "%s: unknown option: %s\n", progname, arg); return 1; } argp++; } if (!arg) { fprintf(stderr, "%s: missing kernel name\n", progname); return 1; } kernel_name = arg; printf("Loading %s... ", kernel_name); if (loadfile(kernel_name, &kernel_data, &kernel_len)) { printf("failed!\n"); goto bail; } printf("ok\n"); boot_image = malloc(strlen(kernel_name)+12); if (!boot_image) goto bail; strcpy(boot_image, "BOOT_IMAGE="); strcpy(boot_image+11, kernel_name); /* argp now points to the kernel name, and the command line follows. Overwrite the kernel name with the BOOT_IMAGE= argument, and thus we have the final argument. */ *argp = boot_image; cmdline = make_cmdline(argp); if (!cmdline) goto bail; /* Initialize the initramfs chain */ initramfs = initramfs_init(); if (!initramfs) goto bail; /* Look for specific command-line arguments we care about */ if ((arg = find_argument(argp, "mem="))) mem_limit = saturate32(suffix_number(arg)); if ((arg = find_argument(argp, "vga="))) { switch (arg[0] | 0x20) { case 'a': /* "ask" */ video_mode = 0xfffd; break; case 'e': /* "ext" */ video_mode = 0xfffe; break; case 'n': /* "normal" */ video_mode = 0xffff; break; default: video_mode = strtoul(arg, NULL, 0); break; } } if ((arg = find_argument(argp, "initrd="))) { do { p = strchr(arg, ','); if (p) *p = '\0'; printf("Loading %s... ", arg); if (initramfs_load_archive(initramfs, arg)) { printf("failed!\n"); goto bail; } printf("ok\n"); if (p) *p++ = ','; } while ((arg = p)); } /* Append the DHCP info */ if (opt_dhcpinfo && !pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) { if (initramfs_add_file(initramfs, dhcpdata, dhcplen, dhcplen, "/dhcpinfo.dat", 0, 0755)) goto bail; } /* This should not return... */ syslinux_boot_linux(kernel_data, kernel_len, initramfs, cmdline, video_mode, mem_limit); bail: fprintf(stderr, "Kernel load failure (insufficient memory?)\n"); return 1; } syslinux-legacy-3.63+dfsg/com32/modules/dmitest.c320000775000175000017500000005241410777447340020575 0ustar evanevanL!1 ecj)t$0eg;vA4eR#0PddsXZzeSàLe@Le<u*Le h`F%D$ $xF%Le@Le<u*Le h`Ft%D$ a$PPPhFK%Le@Le<u*Le h`F%%D$ $PPPhF$Le@Le<u*Le h`F$D$ #QQPhF$Le@Le<u*Le h`F$D$ t#RRPhF^$Le@Le<u*Le h`F8$D$ %#PPPhF$Le@Le<u*Le h`F#D$ "PPPhF#Le@Le<u*Le h`F#D$ "PPPhFq#Le@Le<u*Le h`FK#D$ 8"PP<PhF"#Le@Le<u*Le h`F"D$ !PP\PhG"Le@Le<u*Le h`F"D$ !PP|Ph!G"Le@Le<u*Le h`F^"D$ K!QQPh9G5"Le@Le<u*Le h`F"D$ RRPhQG!Le@Le<u*Le h`F!D$ PPPhcG!([SàLe@Le<u*Le h`Fg!D$ T {Gg!Le@Le<u*Le h`F$!D$  PPPhF Le@Le<u*Le h`F D$ PPPhG Le@Le<u*Le h`F D$ sQQPhF] Le@Le<u*Le h`F7 D$ $RRPhF Le@Le<u*Le h`FD$ PP.PhGLe@Le<u*Le h`FD$ PPVPhGpLe@Le<u*Le h`FJD$ 7PPvPhG!Le@Le<u*Le h`FD$ PPPhG([SàLe@Le<u*Le h`FD$ GLe@Le<u*Le h`FaD$ NRRPhG8Le@Le<u*Le h`FD$ PPPhGLe@Le<u*Le h`FD$ PPPhGLe@Le<u*Le h`FtD$ aPP PhFKLe@Le<u*Le h`F%D$ PP`PhFLe@Le<u*Le h`FD$ PPPh HLe@Le<u*Le h`FD$ sPPPh#H\Le@Le<u*Le h`F6D$ #QQPh:H Le@Le<u*Le h`FD$ RRzPhQHLe@Le<u*Le h`FD$ PP{PhcHlLe@Le<u*Le h`FFD$ 3PP|PhuHLe@Le<u*Le h`FD$ PP}PhHLe@Le<u*Le h`FD$ PP~PhH|Le@Le<u*Le h`FVD$ C ك$hH*Le@Le<u*Le h`FD$ PPPhHLe@Le<u*Le h`FD$ PPPhHLe@Le<u*Le h`FfD$ SQQPhH=Le@Le<u*Le h`FD$ RRPhHLe@Le<u*Le h`FD$ PPPhILe@Le<u*Le h`FyD$ fPPPhFPLe@Le<u*Le h`F*D$ PPPh&ILe@Le<u*Le h`FD$ PP:Ph8I([SàLe@Le<u*Le h`F}D$ jJI}Le@Le<u*Le h`F:D$ 'PPPhFLe@Le<u*Le h`FD$ PPPhGLe@Le<u*Le h`FD$ PPPhFsLe@Le<u*Le h`FMD$ :PPPhF$Le@Le<u*Le h`FD$ PP&PhFLe@Le<u*Le h`FD$ PPFPhUILe@Le<u*Le h`F`D$ MQQfPhG7([SàLe@Le<u*Le h`FD$ [Le@Le<u*Le h`FD$ PPShgILe@Le<u*Le h`FvD$ cPPC PhvIPLe@Le<u*Le h`F*D$ PPC@PhILe@Le<u*Le h`FD$ PPPhILe@Le<u*Le h`FD$ |PPPhIfLe@Le<u*Le h`F@D$ -PPCPPhILe@Le<u*Le h`FD$ QCTPCRPhILe@Le<u*Le h`FD$ RCfPCdPhIyZ([ÍL$qSQ dd4PuJY1D$;J> haJ$\JpWTu D$/gJ6u D$ oJu D$zJu D$~Ju D$J\$5h:1Ą Y[aVS1ۀZtOLe@Le<u*Le h`FD$ PP4ShJC!u[^VS1ۀtOLe@Le<u*Le h`FPD$ =RR4ThJ'Cu[^VS1ۀ|vtOLe@Le<u*Le h`FD$ PP4 ThJCu0ۀtOLe@Le<u*Le h`FD$ qPP4ThJ[Cu0ۀtOLe@Le<u*Le h`F#D$ QQ4ThJCu[^Ð JHfJfHPSˉ¨tAvtD sA u[Sӈ1tƄ Au[Sӈ1tƄ Au[1ɺLBu1éJTt fBRT fBRT<Vw  c4]vWVS׾1 t u111Bt uu(t .Tt.T[^_PPAPAPA PA PA PA PA PAPAPAPAPAPAPAPAPPhT.P P[^_S\$fufv3U[Y[ QRh@U RPhLUSL [VS\$ SU UT$fD$ f e\$ fL$ f"eT$D$ D$ D$  ‰(eff $eT$tPЃPPhYU-  mU> P"eP ePhzU [^5(ehU 6(ef ef$ef"e1[^WSӋPuUW@1эKt:u:u=c&1I1 <^v.G9u׉[_UWVSʼnfT$ x8, $ ]} WW‰m WCF X W.F@C fGfFPW)efG @fFdFfU G W}G}wG}bWt#G|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$DcD$DcD$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.uDc1I|$Xt ;L$X~L$X9L$\~QiQQQQR"R4RLR]RsRRRRR S;SbytesKBNot PresentNot Settable%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02XNot ProvidedNo %s Cache0x%04X_DMI_DMI %d.%d present. DMI present.%d structures occupying %d bytes. DMI table at 0x%08X. Not SpecifiedkB%u.%u0x%08X ID: %02X %02X %02X %02X %02X %02X %02X %02X Pentium III MMXAMD Athlon(TM)AMD Opteron(tm)OtherUnpopulatedL1L2L3Invalid entry length (%u). DMI table is broken! Stop. UnknownLow Profile DesktopPizza BoxMini TowerPortableLaptopHand HeldDocking StationAll In OneSub NotebookSpace-savingLunch BoxMain Server ChassisSub ChassisBus Expansion ChassisPeripheral ChassisRAID ChassisRack Mount ChassisSealed-case PCMulti-systemSafeWarningCriticalNon-recoverableNoneExternal Interface Locked OutExternal Interface EnabledCentral ProcessorMath ProcessorDSP ProcessorVideo Processor80868028680386804868087802878038780487PentiumPentium ProPentium IIPentium MMXCeleronPentium II XeonPentium IIIM1M2DuronK5K6K6-2K6-3AthlonAMD2900K6-2+Power PCPower PC 601Power PC 603Power PC 603+Power PC 604Power PC 620Power PC x704Power PC 750AlphaAlpha 21064Alpha 21066Alpha 21164Alpha 21164PCAlpha 21164aAlpha 21264Alpha 21364MIPSMIPS R4000MIPS R4200MIPS R4400MIPS R4600MIPS R10000SuperSPARCMicroSPARC IIMicroSPARC IIepUltraSPARCUltraSPARC IIUltraSPARC IIiUltraSPARC IIIUltraSPARC IIIi6804068xxx68000680106802068030HobbitCrusoe TM5000Crusoe TM3000Efficeon TM8000WeitekItaniumAthlon 64OpteronSempronPA-RISCPA-RISC 8500PA-RISC 8000PA-RISC 7300LCPA-RISC 7200PA-RISC 7100LCPA-RISC 7100V30Pentium III XeonPentium III SpeedstepPentium 4AS400Xeon MPAthlon XPAthlon MPItanium 2Pentium MIBM390G4G5i860i960Disabled By UserDisabled By BIOSIdleDaughter BoardZIF SocketReplaceable Piggy BackLIF SocketSlot 1Slot 2370-pin SocketSlot ASlot MSocket 423Socket A (Socket 462)Socket 478Socket 754Socket 940Socket 939ReservedAPM TimerModem RingLAN RemotePower SwitchPCI PME#AC Power Restored A-+P,-./V.VVVVVVVVVWVVVWWW&WJW:WFW\WoW|WWWTT.VVWWWW.VVWWW.VVX!X0X>X.VVNXSXYX_XeXjXpXvX|XXXXXXXXXXXXXXXXXXYYY-Y:YGYUYbYhYtYYYYYYYYYYYY*ZYZZ%Z0Z>ZMZ\ZlZrZxZ~ZZZZZZZZZZZZZZ[[[*[9[F[J[[[q[X{[[[[[[[[[[[JJJJJK7KXKvKKKKKL6LdLLLLL M"MAMmMMMMMN@33S@9@VX[[[.V.VV[[ \W \+\2\9\H\O\V\a\w\\\\\\.VV\\\\\\(null)77V888*8H8H848H8H8H8 8H8H8H88H8 8H8H8>8@:^:c:l:}::::::>>>>>0123456789ABCDEF0123456789abcdefABA\B E BED@`jsyslinux-legacy-3.63+dfsg/com32/modules/reboot.c0000664000175000017500000000037510777447273020252 0ustar evanevan#include #include int main(int argc, char *argv[]) { int warm = 0; int i; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-w") || !strcmp(argv[i], "--warm")) warm = 1; } syslinux_reboot(warm); } syslinux-legacy-3.63+dfsg/com32/modules/meminfo.c0000664000175000017500000000503710777447273020412 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * meminfo.c * * Dump the memory map of the system */ #include #include #include #include #include struct e820_data { uint64_t base; uint64_t len; uint32_t type; } __attribute__((packed)); static const char * const e820_types[] = { "usable", "reserved", "ACPI reclaim", "ACPI NVS", }; static void dump_e820(void) { com32sys_t ireg, oreg; struct e820_data ed; uint32_t type; memset(&ireg, 0, sizeof ireg); ireg.eax.w[0] = 0xe820; ireg.edx.l = 0x534d4150; ireg.ecx.l = sizeof(struct e820_data); ireg.edi.w[0] = OFFS(__com32.cs_bounce); ireg.es = SEG(__com32.cs_bounce); do { __intcall(0x15, &ireg, &oreg); if (oreg.eflags.l & EFLAGS_CF || oreg.eax.l != 0x534d4150) break; memcpy(&ed, __com32.cs_bounce, sizeof ed); /* ebx base length end type */ printf("%8x %016llx %016llx %016llx %x", ireg.ebx.l, ed.base, ed.len, ed.base+ed.len, ed.type); type = ed.type - 1; if (type < sizeof(e820_types)/sizeof(e820_types[0])) printf(" %s", e820_types[type]); putchar('\n'); ireg.ebx.l = oreg.ebx.l; } while (ireg.ebx.l); } static void dump_legacy(void) { com32sys_t ireg, oreg; uint16_t dosram = *(uint16_t *)0x413; struct { uint16_t offs, seg; } * const ivt = (void *)0; memset(&ireg, 0, sizeof ireg); __intcall(0x12, &ireg, &oreg); printf("INT 15h = %04x:%04x DOS RAM: %dK (0x%05x) INT 12h: %dK (0x%05x)\n", ivt[0x15].seg, ivt[0x15].offs, dosram, dosram << 10, oreg.eax.w[0], oreg.eax.w[0] << 10); ireg.eax.b[1] = 0x88; __intcall(0x15, &ireg, &oreg); printf("INT 15 88: 0x%04x (%uK) ", oreg.eax.w[0], oreg.eax.w[0]); ireg.eax.w[0] = 0xe801; __intcall(0x15, &ireg, &oreg); printf("INT 15 E801: 0x%04x (%uK) 0x%04x (%uK)\n", oreg.ecx.w[0], oreg.ecx.w[0], oreg.edx.w[0], oreg.edx.w[0] << 6); } int main(void) { openconsole(&dev_null_r, &dev_stdcon_w); dump_legacy(); dump_e820(); return 0; } syslinux-legacy-3.63+dfsg/com32/modules/mb_info.h0000664000175000017500000001166110777447273020376 0ustar evanevan/* * GRUB -- GRand Unified Bootloader * Copyright (C) 2000 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * The structure type "mod_list" is used by the "multiboot_info" structure. */ struct mod_list { /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ unsigned long mod_start; unsigned long mod_end; /* Module command line */ unsigned long cmdline; /* padding to take it to 16 bytes (must be zero) */ unsigned long pad; }; /* * INT-15, AX=E820 style "AddressRangeDescriptor" * ...with a "size" parameter on the front which is the structure size - 4, * pointing to the next one, up until the full buffer length of the memory * map has been reached. */ struct AddrRangeDesc { unsigned long size; unsigned long long BaseAddr; unsigned long long Length; unsigned long Type; /* unspecified optional padding... */ }; /* usable memory "Type", all others are reserved. */ #define MB_ARD_MEMORY 1 /* Drive Info structure. */ struct drive_info { /* The size of this structure. */ unsigned long size; /* The BIOS drive number. */ unsigned char drive_number; /* The access mode (see below). */ unsigned char drive_mode; /* The BIOS geometry. */ unsigned short drive_cylinders; unsigned char drive_heads; unsigned char drive_sectors; /* The array of I/O ports used for the drive. */ unsigned short drive_ports[0]; }; /* Drive Mode. */ #define MB_DI_CHS_MODE 0 #define MB_DI_LBA_MODE 1 /* APM BIOS info. */ struct apm_info { unsigned short version; unsigned short cseg; unsigned long offset; unsigned short cseg_16; unsigned short dseg_16; unsigned short cseg_len; unsigned short cseg_16_len; unsigned short dseg_16_len; }; /* * MultiBoot Info description * * This is the struct passed to the boot image. This is done by placing * its address in the EAX register. */ struct multiboot_info { /* MultiBoot info version number */ unsigned long flags; /* Available memory from BIOS */ unsigned long mem_lower; unsigned long mem_upper; /* "root" partition */ unsigned long boot_device; /* Kernel command line */ unsigned long cmdline; /* Boot-Module list */ unsigned long mods_count; unsigned long mods_addr; union { struct { /* (a.out) Kernel symbol table info */ unsigned long tabsize; unsigned long strsize; unsigned long addr; unsigned long pad; } a; struct { /* (ELF) Kernel section header table */ unsigned long num; unsigned long size; unsigned long addr; unsigned long shndx; } e; } syms; /* Memory Mapping buffer */ unsigned long mmap_length; unsigned long mmap_addr; /* Drive Info buffer */ unsigned long drives_length; unsigned long drives_addr; /* ROM configuration table */ unsigned long config_table; /* Boot Loader Name */ unsigned long boot_loader_name; /* APM table */ unsigned long apm_table; /* Video */ unsigned long vbe_control_info; unsigned long vbe_mode_info; unsigned short vbe_mode; unsigned short vbe_interface_seg; unsigned short vbe_interface_off; unsigned short vbe_interface_len; }; /* * Flags to be set in the 'flags' parameter above */ /* is there basic lower/upper memory information? */ #define MB_INFO_MEMORY 0x00000001 /* is there a boot device set? */ #define MB_INFO_BOOTDEV 0x00000002 /* is the command-line defined? */ #define MB_INFO_CMDLINE 0x00000004 /* are there modules to do something with? */ #define MB_INFO_MODS 0x00000008 /* These next two are mutually exclusive */ /* is there a symbol table loaded? */ #define MB_INFO_AOUT_SYMS 0x00000010 /* is there an ELF section header table? */ #define MB_INFO_ELF_SHDR 0x00000020 /* is there a full memory map? */ #define MB_INFO_MEM_MAP 0x00000040 /* Is there drive info? */ #define MB_INFO_DRIVE_INFO 0x00000080 /* Is there a config table? */ #define MB_INFO_CONFIG_TABLE 0x00000100 /* Is there a boot loader name? */ #define MB_INFO_BOOT_LOADER_NAME 0x00000200 /* Is there a APM table? */ #define MB_INFO_APM_TABLE 0x00000400 /* Is there video information? */ #define MB_INFO_VIDEO_INFO 0x00000800 /* * The following value must be present in the EAX register. */ #define MULTIBOOT_VALID 0x2BADB002 syslinux-legacy-3.63+dfsg/com32/modules/Makefile0000664000175000017500000000544210777447273020254 0ustar evanevan## ----------------------------------------------------------------------- ## ## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- ## ## COM32 standard modules ## TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \ then echo $(1); else echo $(2); fi; rm -f $$tmpf) M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,) CC = gcc LD = ld -m elf_i386 AR = ar NASM = nasm NASMOPT = -O9999 RANLIB = ranlib CFLAGS = $(M32) -mregparm=3 -DREGPARM=3 -W -Wall -march=i386 -Os \ -fomit-frame-pointer -D__COM32__ \ -nostdinc -iwithprefix include \ -I../libutil/include -I../include \ -Wp,-MT,$@,-MD,$(dir $@).$(notdir $@).d LNXCFLAGS = -W -Wall -O -g -I../libutil/include LNXSFLAGS = -g LNXLDFLAGS = -g SFLAGS = -D__COM32__ -march=i386 LDFLAGS = -T ../lib/com32.ld OBJCOPY = objcopy PPMTOLSS16 = ../ppmtolss16 LIBGCC := $(shell $(CC) --print-libgcc) LIBS = ../libutil/libutil_com.a ../lib/libcom32.a $(LIBGCC) LNXLIBS = ../libutil/libutil_lnx.a .SUFFIXES: .lss .c .o .elf .c32 .lnx BINDIR = /usr/bin LIBDIR = /usr/lib AUXDIR = $(LIBDIR)/syslinux INCDIR = /usr/include COM32DIR = $(AUXDIR)/com32 MODULES = chain.c32 ethersel.c32 mboot.c32 dmitest.c32 cpuidtest.c32 \ pcitest.c32 elf.c32 linux.c32 reboot.c32 pmload.c32 meminfo.c32 \ sdi.c32 TESTFILES = all: $(MODULES) $(TESTFILES) .PRECIOUS: %.o %.o: %.S $(CC) $(SFLAGS) -c -o $@ $< .PRECIOUS: %.o %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< .PRECIOUS: %.elf %.elf: %.o $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ .PRECIOUS: %.lo %.lo: %.S $(CC) $(LNXSFLAGS) -c -o $@ $< .PRECIOUS: %.lo %.lo: %.c $(CC) $(LNXCFLAGS) -c -o $@ $< .PRECIOUS: %.lnx %.lnx: %.lo $(LNXLIBS) $(CC) $(LNXLDFLAGS) -o $@ $^ %.c32: %.elf $(OBJCOPY) -O binary $< $@ pcitest.elf : pcitest.o $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ cpuidtest.elf : cpuidtest.o cpuid.o $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ dmitest.elf : dmitest.o dmi_utils.o dmi.o $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ ethersel.elf : ethersel.o $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ tidy: rm -f *.o *.lo *.a *.lst *.elf .*.d clean: tidy rm -f *.lss *.c32 *.lnx *.com spotless: clean rm -f *~ \#* install: all mkdir -m 755 -p $(INSTALLROOT)$(AUXDIR) install -m 644 $(MODULES) $(INSTALLROOT)$(AUXDIR) -include .*.d syslinux-legacy-3.63+dfsg/com32/modules/chain.c320000775000175000017500000000741010777447337020210 0ustar evanevanL!1%)t$P g;vAT RPsXZSp x t fAfUâ`!uf=xUut t E <   t =t 8@|  ? u   x 1ZY[WVS0ljӅuىkC(u1\$Nu׃0[^_WVS0É֍|$ 1=t tLl ff@ڃfPfXp@ ƒfT$fD$ p D$ D$)Bm=x utrk15 r | ?wS1wG=w@fD$(D$%D$$T$!p D$ ؃fD$f\$D$1 11밃0[^_UWVS D$T$ωՁžfUtaFtF<tB<t> #include #include #include #include #include #include #ifdef DEBUG # define dprintf printf #else # define dprintf(...) ((void)0) #endif static const char * get_config(void) { static com32sys_t r; r.eax.w[0] = 0x000E; __intcall(0x22, &r, &r); return MK_PTR(r.es, r.ebx.w[0]); } static char * skipspace(char *p) { while ( *p && *p <= ' ' ) p++; return p; } #define MAX_LINE 512 /* Check to see if we are at a certain keyword (case insensitive) */ static int looking_at(const char *line, const char *kwd) { const char *p = line; const char *q = kwd; while ( *p && *q && ((*p^*q) & ~0x20) == 0 ) { p++; q++; } if ( *q ) return 0; /* Didn't see the keyword */ return *p <= ' '; /* Must be EOL or whitespace */ } static char * get_did(char *p, uint32_t *idptr, uint32_t *maskptr) { unsigned long vid, did, m1, m2; *idptr = -1; *maskptr = 0xffffffff; vid = strtoul(p, &p, 16); if ( *p != ':' ) return p; /* Bogus ID */ did = strtoul(p+1, &p, 16); *idptr = (did << 16) + vid; if ( *p == '/' ) { m1 = strtoul(p+1, &p, 16); if ( *p != ':' ) { *maskptr = (m1 << 16) | 0xffff; } else { m2 = strtoul(p+1, &p, 16); *maskptr = (m1 << 16) | m2; } } return p; } static char * get_rid_range(char *p, uint8_t *rid_min, uint8_t *rid_max) { unsigned long r0, r1; p = skipspace(p+3); r0 = strtoul(p, &p, 16); if ( *p == '-' ) { r1 = strtoul(p+1, &p, 16); } else { r1 = r0; } *rid_min = r0; *rid_max = r1; return p; } static struct match * parse_config(const char *filename) { char line[MAX_LINE], *p; FILE *f; struct match *list = NULL; struct match **ep = &list; struct match *m; if ( !filename ) filename = get_config(); f = fopen(filename, "r"); if ( !f ) return list; while ( fgets(line, sizeof line, f) ) { p = skipspace(line); if ( !looking_at(p, "#") ) continue; p = skipspace(p+1); if ( !looking_at(p, "dev") ) continue; p = skipspace(p+3); m = malloc(sizeof(struct match)); if ( !m ) continue; memset(m, 0, sizeof *m); m->rid_max = 0xff; for(;;) { p = skipspace(p); if ( looking_at(p, "did") ) { p = get_did(p+3, &m->did, &m->did_mask); } else if ( looking_at(p, "sid") ) { p = get_did(p+3, &m->sid, &m->sid_mask); } else if ( looking_at(p, "rid") ) { p = get_rid_range(p+3, &m->rid_min, &m->rid_max); } else { char *e; e = strchr(p, '\n'); if ( *e ) *e = '\0'; e = strchr(p, '\r'); if ( *e ) *e = '\0'; m->filename = strdup(p); if ( !m->filename ) m->did = -1; break; /* Done with this line */ } } dprintf("DEV DID %08x/%08x SID %08x/%08x RID %02x-%02x CMD %s\n", m->did, m->did_mask, m->sid, m->sid_mask, m->rid_min, m->rid_max, m->filename); *ep = m; ep = &m->next; } return list; } static void __attribute__((noreturn)) execute(const char *cmdline) { static com32sys_t ireg; strcpy(__com32.cs_bounce, cmdline); ireg.eax.w[0] = 0x0003; /* Run command */ ireg.ebx.w[0] = OFFS(__com32.cs_bounce); ireg.es = SEG(__com32.cs_bounce); __intcall(0x22, &ireg, NULL); exit(255); /* Shouldn't return */ } int main(int argc, char *argv[]) { struct match *list, *match; struct pci_device_list pci_device_list; struct pci_bus_list pci_bus_list; openconsole(&dev_null_r, &dev_stdcon_w); pci_scan(&pci_bus_list,&pci_device_list); list = parse_config(argc < 2 ? NULL : argv[1]); match = find_pci_device(&pci_device_list,list); if ( match ) execute(match->filename); /* On error, return to the command line */ fputs("Error: no recognized network card found!\n", stderr); return 1; } syslinux-legacy-3.63+dfsg/com32/modules/dmi.c0000664000175000017500000004374610777447273017542 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include "dmi/dmi.h" void to_dmi_header(struct dmi_header *h, u8 *data) { h->type=data[0]; h->length=data[1]; h->handle=WORD(data+2); h->data=data; } void dmi_system_uuid(u8 *p, s_dmi *dmi) { int only0xFF=1, only0x00=1; int i; for(i=0; i<16 && (only0x00 || only0xFF); i++) { if(p[i]!=0x00) only0x00=0; if(p[i]!=0xFF) only0xFF=0; } if(only0xFF) { sprintf(dmi->system.uuid,"Not Present"); return; } if(only0x00) { sprintf(dmi->system.uuid,"Not Settable"); return; } sprintf(dmi->system.uuid,"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); } static void dmi_base_board_features(u8 code, s_dmi *dmi) { if((code&0x1F)!=0) { int i; printf("\n"); for(i=0; i<=4; i++) if(code&(1<base_board.features))[i]=true; } } static void dmi_processor_voltage(u8 code, s_dmi *dmi) { /* 3.3.5.4 */ static const float voltage[]={ 5.0, 3.3, 2.9 }; int i; if(code&0x80) dmi->processor.voltage=((float)(code&0x7f)/10); else { for(i=0; i<=2; i++) if(code&(1<processor.voltage=voltage[i]; } } static void dmi_processor_id(u8 type, u8 *p, const char *version, s_dmi *dmi) { /* * Extra flags are now returned in the ECX register when one calls * the CPUID instruction. Their meaning is explained in table 6, but * DMI doesn't support this yet. */ u32 eax, edx; int sig=0; /* * This might help learn about new processors supporting the * CPUID instruction or another form of identification. */ sprintf(dmi->processor.id,"ID: %02X %02X %02X %02X %02X %02X %02X %02X\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); if(type==0x05) /* 80386 */ { u16 dx=WORD(p); /* * 80386 have a different signature. */ dmi->processor.signature.type=(dx >>12); dmi->processor.signature.family=((dx>>8)&0xF); dmi->processor.signature.stepping=(dx>>4)&0xF; dmi->processor.signature.minor_stepping=(dx&0xF); return; } if(type==0x06) /* 80486 */ { u16 dx=WORD(p); /* * Not all 80486 CPU support the CPUID instruction, we have to find * wether the one we have here does or not. Note that this trick * works only because we know that 80486 must be little-endian. */ if((dx&0x0F00)==0x0400 && ((dx&0x00F0)==0x0040 || (dx&0x00F0)>=0x0070) && ((dx&0x000F)>=0x0003)) sig=1; else { dmi->processor.signature.type=((dx >>12)&0x3); dmi->processor.signature.family=((dx>>8)&0xF); dmi->processor.signature.model=((dx>>4)&0xF); dmi->processor.signature.stepping=(dx&0xF); return; } } else if((type>=0x0B && type<=0x13) /* Intel, Cyrix */ || (type>=0xB0 && type<=0xB3) /* Intel */ || type==0xB5 /* Intel */ || type==0xB9) /* Intel */ sig=1; else if((type>=0x18 && type<=0x1D) /* AMD */ || type==0x1F /* AMD */ || (type>=0xB6 && type<=0xB7) /* AMD */ || (type>=0x83 && type<=0x85)) /* AMD */ sig=2; else if(type==0x01 || type==0x02) { /* * Some X86-class CPU have family "Other" or "Unknown". In this case, * we use the version string to determine if they are known to * support the CPUID instruction. */ if(strncmp(version, "Pentium III MMX", 15)==0) sig=1; else if(strncmp(version, "AMD Athlon(TM)", 14)==0 || strncmp(version, "AMD Opteron(tm)", 15)==0) sig=2; else return; } else /* not X86-class */ return; eax=DWORD(p); edx=DWORD(p+4); switch(sig) { case 1: /* Intel */ dmi->processor.signature.type=((eax >>12)&0x3); dmi->processor.signature.family=(((eax>>16)&0xFF0)+((eax>>8)&0x00F)); dmi->processor.signature.model=(((eax>>12)&0xF0)+((eax>>4)&0x0F)); dmi->processor.signature.stepping=(eax&0xF); break; case 2: /* AMD */ dmi->processor.signature.family=(((eax>>8)&0xF)==0xF?(eax>>20)&0xFF:(eax>>8)&0xF); dmi->processor.signature.model =(((eax>>4)&0xF)==0xF?(eax>>16)&0xF :(eax>>4)&0xF); dmi->processor.signature.stepping=(eax&0xF); break; } edx=DWORD(p+4); if((edx&0x3FF7FDFF)!=0) { int i; for(i=0; i<=31; i++) if(cpu_flags_strings[i]!=NULL && edx&(1<processor.cpu_flags))[i]=true; //printf("%s\t%s\n", prefix, flags[i]); } } void dmi_system_wake_up_type(u8 code, s_dmi *dmi) { /* 3.3.2.1 */ static const char *type[]={ "Reserved", /* 0x00 */ "Other", "Unknown", "APM Timer", "Modem Ring", "LAN Remote", "Power Switch", "PCI PME#", "AC Power Restored" /* 0x08 */ }; if(code<=0x08) { strcpy(dmi->system.wakeup_type,type[code]); } else { strcpy(dmi->system.wakeup_type,out_of_spec); } return; } void dmi_bios_runtime_size(u32 code, s_dmi *dmi) { if(code&0x000003FF) { dmi->bios.runtime_size=code; strcpy(dmi->bios.runtime_size_unit,"bytes"); } else { dmi->bios.runtime_size=code >>10; strcpy(dmi->bios.runtime_size_unit,"KB"); } } void dmi_bios_characteristics(u64 code, s_dmi *dmi) { int i; /* * This isn't very clear what this bit is supposed to mean */ if(code.l&(1<<3)) { ((bool *)(& dmi->bios.characteristics))[0]=true; return; } for(i=4; i<=31; i++) if(code.l&(1<bios.characteristics))[i-3]=true; } void dmi_bios_characteristics_x1(u8 code, s_dmi *dmi) { int i; for(i=0; i<=7; i++) if(code&(1<bios.characteristics_x1))[i]=true; } void dmi_bios_characteristics_x2(u8 code, s_dmi *dmi) { int i; for(i=0; i<=2; i++) if(code&(1<bios.characteristics_x2))[i]=true; } const char *dmi_string(struct dmi_header *dm, u8 s) { char *bp=(char *)dm->data; size_t i, len; if(s==0) return "Not Specified"; bp+=dm->length; while(s>1 && *bp) { bp+=strlen(bp); bp++; s--; } if(!*bp) return bad_index; /* ASCII filtering */ len=strlen(bp); for(i=0; i>4, buf[14]&0x0F); else printf("DMI present.\n"); printf("%d structures occupying %d bytes.\n",dmitable.num, dmitable.len); printf("DMI table at 0x%08X.\n",dmitable.base); return 1; } } dmitable.base=0; dmitable.num=0; dmitable.ver=0; dmitable.len=0; return 0; } void dmi_decode(struct dmi_header *h, u16 ver, s_dmi *dmi) { u8 *data=h->data; /* * Note: DMI types 37, 38 and 39 are untested */ switch(h->type) { case 0: /* 3.3.1 BIOS Information */ // printf("BIOS Information\n"); if(h->length<0x12) break; strcpy(dmi->bios.vendor,dmi_string(h,data[0x04])); strcpy(dmi->bios.version,dmi_string(h,data[0x05])); strcpy(dmi->bios.release_date,dmi_string(h,data[0x08])); dmi->bios.address=WORD(data+0x06); dmi_bios_runtime_size((0x10000-WORD(data+0x06))<<4,dmi); dmi->bios.rom_size=(data[0x09]+1)<<6; strcpy(dmi->bios.rom_size_unit,"kB"); dmi_bios_characteristics(QWORD(data+0x0A),dmi); if(h->length<0x13) break; dmi_bios_characteristics_x1(data[0x12], dmi); if(h->length<0x14) break; dmi_bios_characteristics_x2(data[0x13], dmi); if(h->length<0x18) break; if(data[0x14]!=0xFF && data[0x15]!=0xFF) sprintf(dmi->bios.bios_revision,"%u.%u", data[0x14], data[0x15]); if(data[0x16]!=0xFF && data[0x17]!=0xFF) sprintf(dmi->bios.firmware_revision,"%u.%u", data[0x16], data[0x17]); break; case 1: /* 3.3.2 System Information */ // printf("System Information\n"); if(h->length<0x08) break; strcpy(dmi->system.manufacturer,dmi_string(h,data[0x04])); strcpy(dmi->system.product_name,dmi_string(h,data[0x05])); strcpy(dmi->system.version,dmi_string(h,data[0x06])); strcpy(dmi->system.serial,dmi_string(h,data[0x07])); if(h->length<0x19) break; dmi_system_uuid(data+0x08,dmi); dmi_system_wake_up_type(data[0x18],dmi); if(h->length<0x1B) break; strcpy(dmi->system.sku_number,dmi_string(h,data[0x19])); strcpy(dmi->system.family,dmi_string(h,data[0x1A])); break; case 2: /* 3.3.3 Base Board Information */ // printf("Base Board Information\n"); if(h->length<0x08) break; strcpy(dmi->base_board.manufacturer,dmi_string(h,data[0x04])); strcpy(dmi->base_board.product_name,dmi_string(h,data[0x05])); strcpy(dmi->base_board.version,dmi_string(h,data[0x06])); strcpy(dmi->base_board.serial,dmi_string(h,data[0x07])); if(h->length<0x0F) break; strcpy(dmi->base_board.asset_tag,dmi_string(h,data[0x08])); dmi_base_board_features(data[0x09], dmi); strcpy(dmi->base_board.location,dmi_string(h,data[0x0A])); strcpy(dmi->base_board.type,dmi_string(h,data[0x0D])); if(h->length<0x0F+data[0x0E]*sizeof(u16)) break; break; case 3: /* 3.3.4 Chassis Information */ // printf("Chassis Information\n"); if(h->length<0x09) break; strcpy(dmi->chassis.manufacturer,dmi_string(h,data[0x04])); strcpy(dmi->chassis.type,dmi_chassis_type(data[0x05]&0x7F)); strcpy(dmi->chassis.lock,dmi_chassis_lock(data[0x05]>>7)); strcpy(dmi->chassis.version,dmi_string(h,data[0x06])); strcpy(dmi->chassis.serial,dmi_string(h,data[0x07])); strcpy(dmi->chassis.asset_tag,dmi_string(h,data[0x08])); if(h->length<0x0D) break; strcpy(dmi->chassis.boot_up_state,dmi_chassis_state(data[0x09])); strcpy(dmi->chassis.power_supply_state,dmi_chassis_state(data[0x0A])); strcpy(dmi->chassis.thermal_state,dmi_chassis_state(data[0x0B])); strcpy(dmi->chassis.security_status,dmi_chassis_security_status(data[0x0C])); if(h->length<0x11) break; sprintf(dmi->chassis.oem_information,"0x%08X\n",DWORD(data+0x0D)); if(h->length<0x15) break; dmi->chassis.height=data[0x11]; dmi->chassis.nb_power_cords=data[0x12]; break; case 4: /* 3.3.5 Processor Information */ // printf("Processor Information\n"); if(h->length<0x1A) break; strcpy(dmi->processor.socket_designation,dmi_string(h, data[0x04])); strcpy(dmi->processor.type,dmi_processor_type(data[0x05])); strcpy(dmi->processor.family,dmi_processor_family(data[0x06])); strcpy(dmi->processor.manufacturer,dmi_string(h, data[0x07])); dmi_processor_id(data[0x06], data+8, dmi_string(h, data[0x10]), dmi); strcpy(dmi->processor.version,dmi_string(h, data[0x10])); dmi_processor_voltage(data[0x11],dmi); dmi->processor.external_clock=WORD(data+0x12); dmi->processor.max_speed=WORD(data+0x14); dmi->processor.current_speed=WORD(data+0x16); if(data[0x18]&(1<<6)) strcpy(dmi->processor.status,dmi_processor_status(data[0x18]&0x07)); else sprintf(dmi->processor.status,"Unpopulated"); sprintf(dmi->processor.upgrade,dmi_processor_upgrade(data[0x19])); if(h->length<0x20) break; dmi_processor_cache(WORD(data+0x1A), "L1", ver,dmi->processor.cache1); dmi_processor_cache(WORD(data+0x1C), "L2", ver,dmi->processor.cache2); dmi_processor_cache(WORD(data+0x1E), "L3", ver,dmi->processor.cache3); if(h->length<0x23) break; strcpy(dmi->processor.serial,dmi_string(h, data[0x20])); strcpy(dmi->processor.asset_tag,dmi_string(h, data[0x21])); strcpy(dmi->processor.part_number,dmi_string(h, data[0x22])); break; } } void parse_dmitable(s_dmi *dmi) { int i=0; u8 *data = NULL; u8 buf[dmitable.len]; memcpy(buf,(int *)dmitable.base,sizeof(u8) * dmitable.len); data=buf; while(i\n"); printf("\n"); data=next; i++; } } syslinux-legacy-3.63+dfsg/com32/modules/pmload.c0000664000175000017500000001444710777447273020241 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * pmload.c * * Load a binary file and run it in protected mode. We give it * an ELF-style invocation record, becase, why not? * * Usage: pmload.c32 filename address [arguments...] */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* If we don't have this much memory for the stack, signal failure */ #define MIN_STACK 512 #define DEBUG 0 #if DEBUG # define dprintf printf #else # define dprintf(f, ...) ((void)0) #endif static inline void error(const char *msg) { fputs(msg, stderr); } int boot_raw(void *ptr, size_t len, addr_t where, char **argv) { struct syslinux_movelist *ml = NULL; struct syslinux_memmap *mmap = NULL, *amap = NULL; struct syslinux_pm_regs regs; int argc; addr_t argsize; char **argp; addr_t lstart, llen; char *stack_frame = NULL; addr_t stack_frame_size; addr_t stack_pointer; uint32_t *spp; char *sfp; addr_t sfa; memset(®s, 0, sizeof regs); mmap = syslinux_memory_map(); amap = syslinux_dup_memmap(mmap); if (!mmap || !amap) goto bail; #if DEBUG dprintf("Initial memory map:\n"); syslinux_dump_memmap(stdout, mmap); #endif dprintf("Segment at 0x%08x len 0x%08x\n", where, len); if (syslinux_memmap_type(amap, where, len) != SMT_FREE) { printf("Memory segment at 0x%08x (len 0x%08x) is unavailable\n", where, len); goto bail; /* Memory region unavailable */ } /* Mark this region as allocated in the available map */ if (syslinux_add_memmap(&amap, where, len, SMT_ALLOC)) goto bail; /* Data present region. Create a move entry for it. */ if (syslinux_add_movelist(&ml, where, (addr_t)ptr, len)) goto bail; /* Create the invocation record (initial stack frame) */ argsize = argc = 0; for (argp = argv; *argp; argp++) { dprintf("argv[%2d] = \"%s\"\n", argc, *argp); argc++; argsize += strlen(*argp)+1; } /* We need the argument strings, argument pointers, argc, plus four zero-word terminators. */ stack_frame_size = argsize + argc*sizeof(char *) + 5*sizeof(long); stack_frame_size = (stack_frame_size+15) & ~15; stack_frame = calloc(stack_frame_size, 1); if (!stack_frame) goto bail; #if DEBUG dprintf("Right before syslinux_memmap_largest()...\n"); syslinux_dump_memmap(stdout, amap); #endif if (syslinux_memmap_largest(amap, SMT_FREE, &lstart, &llen)) goto bail; /* NO free memory?! */ if (llen < stack_frame_size+MIN_STACK+16) goto bail; /* Insufficient memory */ /* Initial stack pointer address */ stack_pointer = (lstart+llen-stack_frame_size) & ~15; dprintf("Stack frame at 0x%08x len 0x%08x\n", stack_pointer, stack_frame_size); /* Create the stack frame. sfp is the pointer in current memory for the next argument string, sfa is the address in its final resting place. spp is the pointer into the argument array in current memory. */ spp = (uint32_t *)stack_frame; sfp = stack_frame + argc*sizeof(char *) + 5*sizeof(long); sfa = stack_pointer + argc*sizeof(char *) + 5*sizeof(long); *spp++ = argc; for (argp = argv; *argp; argp++) { int bytes = strlen(*argp) + 1; /* Including final null */ *spp++ = sfa; memcpy(sfp, *argp, bytes); sfp += bytes; sfa += bytes; } /* Zero fields are aready taken care of by calloc() */ /* ... and we'll want to move it into the right place... */ #if DEBUG if (syslinux_memmap_type(amap, stack_pointer, stack_frame_size) != SMT_FREE) { dprintf("Stack frame area not free (how did that happen?)!\n"); goto bail; /* Memory region unavailable */ } #endif if (syslinux_add_memmap(&amap, stack_pointer, stack_frame_size, SMT_ALLOC)) goto bail; if (syslinux_add_movelist(&ml, stack_pointer, (addr_t)stack_frame, stack_frame_size)) goto bail; memset(®s, 0, sizeof regs); regs.eip = where; regs.esp = stack_pointer; #if DEBUG dprintf("Final memory map:\n"); syslinux_dump_memmap(stdout, mmap); dprintf("Final available map:\n"); syslinux_dump_memmap(stdout, amap); dprintf("Movelist:\n"); syslinux_dump_movelist(stdout, ml); #endif /* This should not return... */ fputs("Booting...\n", stdout); syslinux_shuffle_boot_pm(ml, mmap, 0, ®s); bail: if (stack_frame) free(stack_frame); syslinux_free_memmap(amap); syslinux_free_memmap(mmap); syslinux_free_movelist(ml); return -1; } int main(int argc, char *argv[]) { void *data; size_t data_len; addr_t where; openconsole(&dev_null_r, &dev_stdcon_w); if (argc < 3) { error("Usage: pmload.c32 bin_file address arguments...\n"); return 1; } where = strtoul(argv[2], NULL, 0); if (loadfile(argv[1], &data, &data_len)) { error("Unable to load file\n"); return 1; } boot_raw(data, data_len, where, &argv[1]); error("Failed to boot, probably insufficient memory\n"); return 1; } syslinux-legacy-3.63+dfsg/com32/modules/meminfo.c320000775000175000017500000001101010777447341020542 0ustar evanevanL!1"c')t$$"g;vA("R P!!sXZ"L$qUWVSQ!! $D$ lj1t$|$ $W PR PSTPVPh7Ƅ$ $ $QPPh3 fDŽ$$S $$$RQQhM T$pT$,׉1fDŽ$ DŽ$PAMSDŽ$0"ƒfT$xfD$t L$$T$P D$L|$HPAMS$0"$$ $ȉ$$RPSQ$$$hu $H0wRR4 h  #D$|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$D}!D$Dl!D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u 1I|$Xt ;L$X~L$X9L$\~H0123456789ABCDEF0123456789abcdefBT B`'syslinux-legacy-3.63+dfsg/com32/modules/linux.c320000775000175000017500000003265410777447341020270 0ustar evanevanL!1EK)t$Eg;vAERPDELEsXZWEUWVS É1҉эqD$u|$;uD$ [^_]ÍL$qUWVSQ8ӺxCCkD$+A<u D$V5EhAut>-tS5EhAjl$QQVhAL$@T$D8B{1эA Dž=úBG D$8¾1΋Zu3D$#1Kى tUu9t$Ņ!BD$6u D$ zT$$11É֋D$$ e<w$xB<%1!  (2؉ t1v D$ D$ &BD$u1C et ntau$ &! B11[Ǻ+BD$GÅtF,ƅtRRShAډTuBt,F봃|$t9L$(T$,Zu#L$(T$,hjh3BQuPT$4D$8t$Qt$_AB-8Y[^_]aÃL$(L$T$$D$ UWVSƉՉ1҉وJ[^_]UWVS Ӊ͉1,Eى? uFt t t )ÅuЉ [^_]ÐS E)ʋEt9v 補EE@9sBE+EQA EAEAEAE E E E E[ÍvUWVStxX Eeq9r[C 9Ƌyir:Q)މpYH PB AxhQBQBoAxA I9u1[^_]ÐVSΉÉ1)‰uCANu[^ÐVW։ljsft_^ÐL$$L$T$ Ð xkB  Ðu1@8uÐSÉъD$CA)‰u|$uZ[ÐSÉABu[Ðj^ÐjNÐVSÍt$QѺ'x=~ى‰i[^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$B%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$BL$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$CЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$,CT$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$DeCD$DTCD$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.uB1I|$Xt ;L$X~L$X9L$\~Szt؋R J!Ń{t K$W(  C9v# )Ǎ$j:[{u$` 1D$f$jf$hf$ff$df$` f$D$f$| $$Sb$x )D$)p8)D$D$gD$)\$d$$x 븋$< $$Ĝ[^_]ÐUWVS Ɖ׉͋\$$|$ t?t?Cu8w0/…t D$ BzjZ rP1 [^_]f t@ ÐUWVS Ɖ׉D$9tz/t)rD$B/…u;\$|$s9to}/ti)EBEPjCPjjjjjjjjjhARhCt$@|$Dǃ@ى߹)كA1|$/!ŅwD$ [^_]ÍvUWVSD$T$L$D$0fD$1эi|$u111ҋD$Er4Å|$u‹D$<EBEQjEPt$Ht$Hjjt$PjjjjD$>PRhCWǃ@T$)A|$41RRjVڋD$(t [^_]f jjjj1ɺCÐUWVS ƉՉϋ\$ T$$L$(D$,fuf jjSPuD$$\$ [^_] [^_]ÐSÉЍL$T$tL$PPT$jQ[ÐUWVSLD$ՉL$ED$ D$ 1҉ljfD$D fD$8qfT$$ڃfT$(s fD$fCfC fCfCfCL$ ʸ"D$Hu8fft.CzDžtK}CT$1L[^_]ÐWS؉;…t 1׉Z[_ÐUWVS Ӊ͉1,EىKuFt t t )ÅuЉ [^_]ÐVStyHQ q:uZ9uYZrV !EAAE EAH>u+Q9u!VQVFBFPFAFH [^ÐD$(D$ PL$4D$0,ÐUWVS$ʼnT$L$ EL$8|$8t)UADu-uEL$8D$+uED$|$ uc|$8v#}0u$E;|$(uT$$D AD$A F1AC)ЉA FG[CuT$ T$4L$L$8k D$uEUT$ 9s()‰T$E9s4D$ )щL$(HD$ D$0v+D$ D$;Es t$ t$(ml$D$ D$(D$D$HT$ …t[@|$t L$(L$)+L$(t9;L$vt$|$tT$T$()D$H D$HT$(T$ *E;D$ M;D$ vl$$D$HUVt]}u}L$HL$1s+ 9r t9v؉ʉ{ut\$@t t$$~vq L$LD$HPD$(i\$@|$t#+D$; BK\j{cmx0123456789ABCDEF0123456789abcdefB !!070701%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08xTRAILER!!!01X2 Bh20```````````````,,,,,,,,,,```````))))))!!!!!!!!!!!!!!!!!!!!``````******""""""""""""""""""""````0```````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!`!!!!!!!""""""""""""""""""""""""`""""""""x;mBEEEEKsyslinux-legacy-3.63+dfsg/com32/modules/pmload.c320000775000175000017500000002504410777447341020400 0ustar evanevanL!1$:C@)t$D:g;vAH:RP99sXZ:*UWVS|ƉӉL$ D$xD$tT$H 1D$$!D$t|$$ًT$ [HtPSt$(h6 $jًT$0) $ST$011E1ˋ$u<\;#\$8d$8D$8D$4?D$( L$|$T$xR T$lD$89t$p+t$8T$(T:T$,|7|$0|$(/$:1|$ ӋT$0D$4PًT$ D$,\$,\$0D$4}|$ u $jL$Hub $t$DL$8uB\$H D$ D$ht$X6 $S1ɋT$4D$(D$tD$$D$xQ|[^_]ÍL$qWVSQÉֺ88P8 7*F11Ǎ^L$T$FEt 37' T$ D$$SH7Y[^_aÐWS؉…t 1׉Z[_ÐUWVSƉՉ1҉وJ[^_]VStyHQ q:uZ9uYZrV !:AA: :AH>u+Q9u!VQVFBFPFAFH [^ÐUWVS Ӊ͉1,Eى u(;t t t )ÅuЉ [^_]ÐS :)ʋ:t9v ::@9sB:+:QA :A:A:A: : : : :[ÍvUWVStxX :eq9r[C 9Ƌyir:Q)މpYH PB AxhQBQBoAxA I9u1[^_]ÐVW։ljsft_^ÐL$$L$T$ ÐjnÐVSÍt$QѺ'x=~ى‰[^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$7%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$7L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$7ЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$7T$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$D%8D$D8D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.uv71I|$Xt ;L$X~L$X9L$\~;|$(uT$$D AD$A F1AC)ЉA FG[CuT$ T$4L$L$8k D$uEUT$ 9s()‰T$E9s4D$ )щL$(HD$ D$0v+D$ D$;Es t$ t$(ml$D$ D$(D$D$HT$ …t[@|$t L$(L$)+L$(t9;L$vt$|$tT$T$()D$H D$HT$(T$ *E;D$ M;D$ vl$$D$HUVt]}u}L$HL$1s+ 9r t9v؉ʉ{ut\$@t t$$~vq L$LD$HPD$(\$@|$t#+D$)t$8g;vA8R#P8 8sXZ8"UWVS|D$ ӉL$D$xD$tD$pT$D 13(6D$ T$ fBftft f>L$ yA(f39fQ*fA,fA9 D$tD$p|$tumt$ vD$$t n ~^D$pHtPWUh06/9v D$|jىk~t$ L$,N$S9v# )ߍ+$j|$ G*D$$T$ B,9D$$.11E1ˋD$u<\;#\$8d$8D$8D$4<D$( L$xD$|T$tR T$hD$89t$l+t$8T$(T:T$,|7|$0L$()l$:1|$ӋT$0D$4PًT$D$,\$,\$0D$4ML$u D$|jL$Huh $t$DL$8uH\$D T$ BD$dt$Tf6 $$S1D$(D$pD$tD$xI|[^_]ÍL$qVSQÉֺ77 Kr62^L$T$ FNt6T$D$ "6Y[^aÐWS؉…t 1׉Z[_ÐUWVSƉՉ1҉وJ[^_]VStyHQ q:uZ9uYZrV !8AA8 8AH>u+Q9u!VQVFBFPFAFH [^ÐUWVS Ӊ͉1,Eى u9t t t )ÅuЉ [^_]ÐS 8)ʋ8t9v 裘88@9sB8+8QA 8A8A8A8 8 8 8 8[ÍvUWVStxX 8eq9r[C 9Ƌyir:Q)މpYH PB AxhQBQBoAxA I9u1[^_]ÐVSΉÉ1)‰uCANu[^ÐVW։ljsft_^ÐL$$L$T$ ÐVSÍt$QѺ'x=~ى‰ [^UWVSD$T$$L$D$pD$lD$`D$dD$,D$\D$XD$<D$$6%u*D$,D$\D$XD$<MD$9D$ls T$p BT$pD$l/A<wF$6L$<L$< L$<L$<L$< L$<L$A< wkT$\ TЉT$\*uF6t$\y \$\L$<.uOD$XA< wkT$X TЉT$Xc*uF6t$XyD$XBL$4ltEht5jtL ttztqu8,D$,D$,L$,D$,D$,D$,~D$,}D$,nB2cMPtjXydibys5otpG5utx7D$4D$4 L$<L$< 1҉D$`T$dD$XD$4L$<@D$,w$87ЙD$`T$dD$4 D$`ދD$`L$dыVD$`T$dL$<D$4D$,wP$L7T$`>|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$D7D$Dt7D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u61I|$Xt ;L$X~L$X9L$\~;|$(uT$$D AD$A F1AC)ЉA FG[CuT$ T$4L$L$8k D$uEUT$ 9s()‰T$E9s4D$ )щL$(HD$ D$0v+D$ D$;Es t$ t$(ml$D$ D$(D$D$HT$ …t[@|$t L$(L$)+L$(t9;L$vt$|$tT$T$()D$H D$HT$(T$ *E;D$ M;D$ vl$$D$HUVt]}u}L$HL$1s+ 9r t9v؉ʉ{ut\$@t t$$~vq L$LD$HPD$(e\$@|$t#+D$@^cl}0123456789ABCDEF0123456789abcdefB!!*+\, Bl,L/8888D >syslinux-legacy-3.63+dfsg/com32/modules/pcitest.c0000664000175000017500000000753710777447273020442 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * pcitest.c * */ #include #include #include #include #include #include #include #include #ifdef DEBUG # define dprintf printf #else # define dprintf(...) ((void)0) #endif char display_line; #define moreprintf(...) \ do { \ display_line++; \ if (display_line == 24) { \ char tempbuf[10]; \ display_line=0; \ printf("Press Enter to continue\n"); \ fgets(tempbuf, sizeof tempbuf, stdin); \ } \ printf ( __VA_ARGS__); \ } while (0); void display_pci_devices(struct pci_device_list *pci_device_list) { int pci_dev; for (pci_dev=0; pci_dev < pci_device_list->count; pci_dev++) { struct pci_device *pci_device = &pci_device_list->pci_device[pci_dev]; printf("PCI: Vendor=%04x(%s) Product=%04x(%s) " "Sub_vendor=%04x Sub_Product=%04x Release=%02x\n", pci_device->vendor, pci_device->pci_dev_info->vendor_name, pci_device->product, pci_device->pci_dev_info->product_name, pci_device->sub_vendor, pci_device->sub_product, pci_device->revision); } printf("PCI: %d devices found\n",pci_device_list->count); } void display_pci_bus(struct pci_bus_list *pci_bus_list, bool display_pci_devices) { int bus; for (bus=0; buscount;bus++) { struct pci_bus pci_bus = pci_bus_list->pci_bus[bus]; printf("\nPCI BUS No %d:\n", pci_bus.id); if (display_pci_devices) { int pci_dev; for (pci_dev=0; pci_dev < pci_bus.pci_device_count; pci_dev++) { struct pci_device pci_device=*(pci_bus.pci_device[pci_dev]); printf("%s :%04x:%04x[%04x:%04x]) %s:%s\n", pci_device.pci_dev_info->linux_kernel_module, pci_device.vendor, pci_device.product, pci_device.sub_vendor, pci_device.sub_product, pci_device.pci_dev_info->vendor_name, pci_device.pci_dev_info->product_name); } } } printf("PCI: %d bus%s found\n", pci_bus_list->count, pci_bus_list->count == 1 ? "es" : ""); } int main(int argc, char *argv[]) { struct pci_device_list pci_device_list; struct pci_bus_list pci_bus_list; openconsole(&dev_null_r, &dev_stdcon_w); /* Scanning to detect pci buses and devices */ pci_scan(&pci_bus_list,&pci_device_list); /* Assigning product & vendor name for each device*/ get_name_from_pci_ids(&pci_device_list); /* Detecting which kernel module should match each device */ get_module_name_from_pci_ids(&pci_device_list); /* display the pci devices we found */ display_pci_bus(&pci_bus_list,true); return 1; } syslinux-legacy-3.63+dfsg/com32/modules/dmi_utils.c0000664000175000017500000000475610777447273020760 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2006 Erwan Velu - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include "stdio.h" #include "dmi/dmi.h" void display_bios_characteristics(s_dmi *dmi) { int i; for (i=0;ibios.characteristics))[i] == true) { moreprintf("\t\t%s\n", bios_charac_strings[i]); } } for (i=0;ibios.characteristics_x1))[i] == true) { moreprintf("\t\t%s\n", bios_charac_x1_strings[i]); } } for (i=0;ibios.characteristics_x2))[i] == true) { moreprintf("\t\t%s\n", bios_charac_x2_strings[i]); } } } void display_base_board_features(s_dmi *dmi) { int i; for (i=0;i<=BASE_BOARD_NB_ELEMENTS; i++) { if (((bool *)(& dmi->base_board.features))[i] == true) { moreprintf("\t\t%s\n", base_board_features_strings[i]); } } } void display_processor_flags(s_dmi *dmi) { int i; for (i=0;i<=PROCESSOR_FLAGS_ELEMENTS; i++) { if (((bool *)(& dmi->processor.cpu_flags))[i] == true) { moreprintf("\t\t%s\n", cpu_flags_strings[i]); } } } syslinux-legacy-3.63+dfsg/com32/Makefile0000664000175000017500000000020610777447272016574 0ustar evanevanSUBDIRS = lib libutil modules menu samples all tidy clean spotless install: set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done syslinux-legacy-3.63+dfsg/com32/menu/0000775000175000017500000000000010777447345016103 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/menu/readconfig.c0000664000175000017500000005465710777447273020371 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include "menu.h" /* Empty refstring */ const char *empty_string; /* Root menu, starting menu, hidden menu, and list of all menus */ struct menu *root_menu, *start_menu, *hide_menu, *menu_list; /* These are global parameters regardless of which menu we're displaying */ int shiftkey = 0; /* Only display menu if shift key pressed */ int hiddenmenu = 0; long long totaltimeout = 0; /* Linked list of all entires, hidden or not; used by unlabel() */ static struct menu_entry *all_entries; static struct menu_entry **all_entries_end = &all_entries; static const struct messages messages[MSG_COUNT] = { [MSG_AUTOBOOT] = { "autoboot", "Automatic boot in # second{,s}..." }, [MSG_TAB] = { "tabmsg", "Press [Tab] to edit options" }, [MSG_NOTAB] = { "notabmsg", "" }, [MSG_PASSPROMPT] = { "passprompt", "Password required" }, }; #define astrdup(x) ({ char *__x = (x); \ size_t __n = strlen(__x) + 1; \ char *__p = alloca(__n); \ if ( __p ) memcpy(__p, __x, __n); \ __p; }) /* Must match enum kernel_type */ const char * const kernel_types[] = { "none", "localboot", "kernel", "linux", "boot", "bss", "pxe", "fdimage", "comboot", "com32", "config", NULL }; /* * Search the list of all menus for a specific label */ static struct menu * find_menu(const char *label) { struct menu *m; for (m = menu_list; m; m = m->next) { if (!strcmp(label, m->label)) return m; } return NULL; } #define MAX_LINE 4096 static char * skipspace(char *p) { while (*p && my_isspace(*p)) p++; return p; } /* Strip ^ from a string, returning a new reference to the same refstring if none present */ static const char *strip_caret(const char *str) { const char *p, *r; char *q; int carets = 0; p = str; for (;;) { p = strchr(p, '^'); if (!p) break; carets++; p++; } if (!carets) return refstr_get(str); r = q = refstr_alloc(strlen(str)-carets); for (p = str; *p; p++) if (*p != '^') *q++ = *p; *q = '\0'; /* refstr_alloc() already did this... */ return r; } /* Check to see if we are at a certain keyword (case insensitive) */ /* Returns a pointer to the first character past the keyword */ static char * looking_at(char *line, const char *kwd) { char *p = line; const char *q = kwd; while ( *p && *q && ((*p^*q) & ~0x20) == 0 ) { p++; q++; } if ( *q ) return NULL; /* Didn't see the keyword */ return my_isspace(*p) ? p : NULL; /* Must be EOL or whitespace */ } static struct menu * new_menu(struct menu *parent, struct menu_entry *parent_entry, const char *label) { struct menu *m = calloc(1, sizeof(struct menu)); int i; m->label = label; m->title = refstr_get(empty_string); if (parent) { /* Submenu */ m->parent = parent; m->parent_entry = parent_entry; parent_entry->action = MA_SUBMENU; parent_entry->submenu = m; for (i = 0; i < MSG_COUNT; i++) m->messages[i] = refstr_get(parent->messages[i]); memcpy(m->mparm, parent->mparm, sizeof m->mparm); m->allowedit = parent->allowedit; m->timeout = parent->timeout; m->ontimeout = refstr_get(parent->ontimeout); m->onerror = refstr_get(parent->onerror); m->menu_master_passwd = refstr_get(parent->menu_master_passwd); m->menu_background = refstr_get(parent->menu_background); m->color_table = copy_color_table(parent->color_table); for (i = 0; i < 12; i++) { m->fkeyhelp[i].textname = refstr_get(parent->fkeyhelp[i].textname); m->fkeyhelp[i].background = refstr_get(parent->fkeyhelp[i].background); } } else { /* Root menu */ for (i = 0; i < MSG_COUNT; i++) m->messages[i] = refstrdup(messages[i].defmsg); for (i = 0; i < NPARAMS; i++) m->mparm[i] = mparm[i].value; m->allowedit = 1; /* Allow edits of the command line */ m->color_table = default_color_table(); } m->next = menu_list; menu_list = m; return m; } struct labeldata { const char *label; const char *kernel; enum kernel_type type; const char *append; const char *menulabel; const char *passwd; char *helptext; unsigned int ipappend; unsigned int menuhide; unsigned int menudefault; unsigned int menuseparator; unsigned int menudisabled; unsigned int menuindent; enum menu_action action; struct menu *submenu; }; /* Menu currently being parsed */ static struct menu *current_menu; static void clear_label_data(struct labeldata *ld) { refstr_put(ld->label); refstr_put(ld->kernel); refstr_put(ld->append); refstr_put(ld->menulabel); refstr_put(ld->passwd); memset(ld, 0, sizeof *ld); } static struct menu_entry *new_entry(struct menu *m) { struct menu_entry *me; if (m->nentries >= m->nentries_space) { if (!m->nentries_space) m->nentries_space = 1; else m->nentries_space <<= 1; m->menu_entries = realloc(m->menu_entries, m->nentries_space* sizeof(struct menu_entry *)); } me = calloc(1, sizeof(struct menu_entry)); me->entry = m->nentries; m->menu_entries[m->nentries++] = me; *all_entries_end = me; all_entries_end = &me->next; return me; } static void consider_for_hotkey(struct menu *m, struct menu_entry *me) { const char *p = strchr(me->displayname, '^'); if (me->action != MA_DISABLED) { if ( p && p[1] ) { unsigned char hotkey = p[1] & ~0x20; if ( !m->menu_hotkeys[hotkey] ) { me->hotkey = hotkey; m->menu_hotkeys[hotkey] = me; } } } } static void record(struct menu *m, struct labeldata *ld, const char *append) { int i; struct menu_entry *me; const struct syslinux_ipappend_strings *ipappend; if (!ld->label) return; /* Nothing defined */ /* Hidden entries are recorded on a special "hidden menu" */ if (ld->menuhide) m = hide_menu; if ( ld->label ) { char ipoptions[4096], *ipp; const char *a; char *s; me = new_entry(m); me->displayname = ld->menulabel ? refstr_get(ld->menulabel) : refstr_get(ld->label); me->label = refstr_get(ld->label); me->passwd = refstr_get(ld->passwd); me->helptext = ld->helptext; me->hotkey = 0; me->action = ld->action ? ld->action : MA_CMD; if ( ld->menuindent ) { const char *dn; rsprintf(&dn, "%*s%s", ld->menuindent, "", me->displayname); refstr_put(me->displayname); me->displayname = dn; } if ( ld->menuseparator ) { refstr_put(me->displayname); me->displayname = refstr_get(empty_string); } if ( ld->menuseparator || ld->menudisabled ) { me->action = MA_DISABLED; refstr_put(me->label); me->label = NULL; refstr_put(me->passwd); me->passwd = NULL; } if (ld->menulabel) consider_for_hotkey(m, me); switch (me->action) { case MA_CMD: ipp = ipoptions; *ipp = '\0'; if (ld->ipappend) { ipappend = syslinux_ipappend_strings(); for (i = 0; i < ipappend->count; i++) { if ( (ld->ipappend & (1U << i)) && ipappend->ptr[i] ) ipp += sprintf(ipp, " %s", ipappend->ptr[i]); } } a = ld->append; if ( !a ) a = append; if ( !a || (a[0] == '-' && !a[1]) ) a = ""; s = a[0] ? " " : ""; if (ld->type == KT_KERNEL) { rsprintf(&me->cmdline, "%s%s%s%s", ld->kernel, s, a, ipoptions); } else { rsprintf(&me->cmdline, ".%s %s%s%s%s", kernel_types[ld->type], ld->kernel, s, a, ipoptions); } break; case MA_GOTO_UNRES: case MA_EXIT_UNRES: me->cmdline = refstr_get(ld->kernel); break; case MA_GOTO: case MA_EXIT: me->submenu = ld->submenu; break; default: break; } if ( ld->menudefault && me->action == MA_CMD ) m->defentry = m->nentries-1; } clear_label_data(ld); } static struct menu *begin_submenu(const char *tag) { struct menu_entry *me; if (!tag[0]) tag = NULL; me = new_entry(current_menu); me->displayname = refstrdup(tag); return new_menu(current_menu, me, refstr_get(me->displayname)); } static struct menu *end_submenu(void) { return current_menu->parent ? current_menu->parent : current_menu; } static const char *unlabel(const char *str) { /* Convert a CLI-style command line to an executable command line */ const char *p; const char *q; struct menu_entry *me; int pos; p = str; while ( *p && !my_isspace(*p) ) p++; /* p now points to the first byte beyond the kernel name */ pos = p-str; for (me = all_entries; me; me = me->next) { if (!strncmp(str, me->label, pos) && !me->label[pos]) { /* Found matching label */ rsprintf(&q, "%s%s", me->cmdline, p); refstr_put(str); return q; } } return str; } static const char * refdup_word(char **p) { char *sp = *p; char *ep = sp; while (*ep && !my_isspace(*ep)) ep++; *p = ep; return refstrndup(sp, ep-sp); } int my_isxdigit(char c) { unsigned int uc = c; return (uc-'0') < 10 || ((uc|0x20)-'a') < 6; } unsigned int hexval(char c) { unsigned char uc = c | 0x20; unsigned int v; v = uc-'0'; if (v < 10) return v; return uc-'a'+10; } unsigned int hexval2(const char *p) { return (hexval(p[0]) << 4)+hexval(p[1]); } uint32_t parse_argb(char **p) { char *sp = *p; char *ep; uint32_t argb; size_t len, dl; if (*sp == '#') sp++; ep = sp; while (my_isxdigit(*ep)) ep++; *p = ep; len = ep-sp; switch(len) { case 3: /* #rgb */ argb = 0xff000000 + (hexval(sp[0])*0x11 << 16) + (hexval(sp[1])*0x11 << 8) + (hexval(sp[2])*0x11); break; case 4: /* #argb */ argb = (hexval(sp[0])*0x11 << 24) + (hexval(sp[1])*0x11 << 16) + (hexval(sp[2])*0x11 << 8) + (hexval(sp[3])*0x11); break; case 6: /* #rrggbb */ case 9: /* #rrrgggbbb */ case 12: /* #rrrrggggbbbb */ dl = len/3; argb = 0xff000000 + (hexval2(sp+0) << 16) + (hexval2(sp+dl) << 8) + hexval2(sp+dl*2); break; case 8: /* #aarrggbb */ /* #aaarrrgggbbb is indistinguishable from #rrrrggggbbbb, assume the latter is a more common format */ case 16: /* #aaaarrrrggggbbbb */ dl = len/4; argb = (hexval2(sp+0) << 24) + (hexval2(sp+dl) << 16) + (hexval2(sp+dl*2) << 8) + hexval2(sp+dl*3); break; default: argb = 0xffff0000; /* Bright red (error indication) */ break; } return argb; } /* * Parser state. This is global so that including multiple * files work as expected, which is that everything works the * same way as if the files had been concatenated together. */ static const char *append = NULL; static unsigned int ipappend = 0; static struct labeldata ld; static int parse_one_config(const char *filename); static char *is_kernel_type(char *cmdstr, enum kernel_type *type) { const char * const *p; char *q; enum kernel_type t = KT_NONE; for (p = kernel_types; *p; p++, t++) { if ((q = looking_at(cmdstr, *p))) { *type = t; return q; } } return NULL; } static char *is_message_name(char *cmdstr, enum message_number *msgnr) { char *q; enum message_number i; for (i = 0; i < MSG_COUNT; i++) { if ((q = looking_at(cmdstr, messages[i].name))) { *msgnr = i; return q; } } return NULL; } static char *is_fkey(char *cmdstr, int *fkeyno) { char *q; int no; if ((cmdstr[0]|0x20) != 'f') return NULL; no = strtoul(cmdstr+1, &q, 10); if (!my_isspace(*q)) return NULL; if (no < 0 || no > 12) return NULL; *fkeyno = (no == 0) ? 10 : no-1; return q; } static void parse_config_file(FILE *f) { char line[MAX_LINE], *p, *ep, ch; enum kernel_type type; enum message_number msgnr; int fkeyno; struct menu *m = current_menu; while ( fgets(line, sizeof line, f) ) { p = strchr(line, '\r'); if ( p ) *p = '\0'; p = strchr(line, '\n'); if ( p ) *p = '\0'; p = skipspace(line); if ( looking_at(p, "menu") ) { p = skipspace(p+4); if ( looking_at(p, "label") ) { if ( ld.label ) { refstr_put(ld.menulabel); ld.menulabel = refstrdup(skipspace(p+5)); } else if ( m->parent_entry ) { refstr_put(m->parent_entry->displayname); m->parent_entry->displayname = refstrdup(skipspace(p+5)); consider_for_hotkey(m->parent, m->parent_entry); if (!m->title[0]) { /* MENU LABEL -> MENU TITLE on submenu */ refstr_put(m->title); m->title = strip_caret(m->parent_entry->displayname); } } } else if ( looking_at(p, "title") ) { refstr_put(m->title); m->title = refstrdup(skipspace(p+5)); if (m->parent_entry) { /* MENU TITLE -> MENU LABEL on submenu */ if (m->parent_entry->displayname == m->label) { refstr_put(m->parent_entry->displayname); m->parent_entry->displayname = refstr_get(m->title); } } } else if ( looking_at(p, "default") ) { ld.menudefault = 1; } else if ( looking_at(p, "hide") ) { ld.menuhide = 1; } else if ( looking_at(p, "passwd") ) { if ( ld.label ) { refstr_put(ld.passwd); ld.passwd = refstrdup(skipspace(p+6)); } else if ( m->parent_entry ) { refstr_put(m->parent_entry->passwd); m->parent_entry->passwd = refstrdup(skipspace(p+6)); } } else if ( looking_at(p, "shiftkey") ) { shiftkey = 1; } else if ( looking_at(p, "onerror") ) { refstr_put(m->onerror); m->onerror = refstrdup(skipspace(p+7)); } else if ( looking_at(p, "master") ) { p = skipspace(p+6); if ( looking_at(p, "passwd") ) { refstr_put(m->menu_master_passwd); m->menu_master_passwd = refstrdup(skipspace(p+6)); } } else if ( (ep = looking_at(p, "include")) ) { goto do_include; } else if ( (ep = looking_at(p, "background")) ) { p = skipspace(ep); refstr_put(m->menu_background); m->menu_background = refdup_word(&p); } else if ( (ep = looking_at(p, "hidden")) ) { hiddenmenu = 1; } else if ( (ep = is_message_name(p, &msgnr)) ) { refstr_put(m->messages[msgnr]); m->messages[msgnr] = refstrdup(skipspace(ep)); } else if ((ep = looking_at(p, "color")) || (ep = looking_at(p, "colour"))) { int i; struct color_table *cptr; p = skipspace(ep); cptr = m->color_table; for ( i = 0; i < menu_color_table_size; i++ ) { if ( (ep = looking_at(p, cptr->name)) ) { p = skipspace(ep); if (*p) { if (looking_at(p, "*")) { p++; } else { refstr_put(cptr->ansi); cptr->ansi = refdup_word(&p); } p = skipspace(p); if (*p) { if (looking_at(p, "*")) p++; else cptr->argb_fg = parse_argb(&p); p = skipspace(p); if (*p) { if (looking_at(p, "*")) p++; else cptr->argb_bg = parse_argb(&p); /* Parse a shadow mode */ p = skipspace(p); ch = *p | 0x20; if (ch == 'n') /* none */ cptr->shadow = SHADOW_NONE; else if (ch == 's') /* std, standard */ cptr->shadow = SHADOW_NORMAL; else if (ch == 'a') /* all */ cptr->shadow = SHADOW_ALL; else if (ch == 'r') /* rev, reverse */ cptr->shadow = SHADOW_REVERSE; } } } break; } cptr++; } } else if ((ep = looking_at(p, "msgcolor")) || (ep = looking_at(p, "msgcolour"))) { unsigned int fg_mask = MSG_COLORS_DEF_FG; unsigned int bg_mask = MSG_COLORS_DEF_BG; enum color_table_shadow shadow = MSG_COLORS_DEF_SHADOW; p = skipspace(ep); if (*p) { if (!looking_at(p, "*")) fg_mask = parse_argb(&p); p = skipspace(p); if (*p) { if (!looking_at(p, "*")) bg_mask = parse_argb(&p); p = skipspace(p); switch (*p | 0x20) { case 'n': shadow = SHADOW_NONE; break; case 's': shadow = SHADOW_NORMAL; break; case 'a': shadow = SHADOW_ALL; break; case 'r': shadow = SHADOW_REVERSE; break; default: /* go with default */ break; } } } set_msg_colors_global(m->color_table, fg_mask, bg_mask, shadow); } else if ( looking_at(p, "separator") ) { record(m, &ld, append); ld.label = refstr_get(empty_string); ld.menuseparator = 1; record(m, &ld, append); } else if ( looking_at(p, "disable") || looking_at(p, "disabled")) { ld.menudisabled = 1; } else if ( looking_at(p, "indent") ) { ld.menuindent = atoi(skipspace(p+6)); } else if ( looking_at(p, "begin") ) { record(m, &ld, append); m = current_menu = begin_submenu(skipspace(p+5)); } else if ( looking_at(p, "end") ) { record(m, &ld, append); m = current_menu = end_submenu(); } else if ( looking_at(p, "quit") ) { if (ld.label) ld.action = MA_QUIT; } else if ( looking_at(p, "goto") ) { if (ld.label) { ld.action = MA_GOTO_UNRES; refstr_put(ld.kernel); ld.kernel = refstrdup(skipspace(p+4)); } } else if ( looking_at(p, "exit") ) { p = skipspace(p+4); if (ld.label && m->parent) { if (*p) { /* This is really just a goto, except for the marker */ ld.action = MA_EXIT_UNRES; refstr_put(ld.kernel); ld.kernel = refstrdup(p); } else { ld.action = MA_EXIT; ld.submenu = m->parent; } } } else if ( looking_at(p, "start") ) { start_menu = m; } else { /* Unknown, check for layout parameters */ enum parameter_number mp; for (mp = 0; mp < NPARAMS; mp++) { if ( (ep = looking_at(p, mparm[mp].name)) ) { m->mparm[mp] = atoi(skipspace(ep)); break; } } } } else if ( looking_at(p, "text") ) { enum text_cmd { TEXT_UNKNOWN, TEXT_HELP } cmd = TEXT_UNKNOWN; int len = ld.helptext ? strlen(ld.helptext) : 0; int xlen; p = skipspace(p+4); if (looking_at(p, "help")) cmd = TEXT_HELP; while ( fgets(line, sizeof line, f) ) { p = skipspace(line); if (looking_at(p, "endtext")) break; xlen = strlen(line); switch (cmd) { case TEXT_UNKNOWN: break; case TEXT_HELP: ld.helptext = realloc(ld.helptext, len+xlen+1); memcpy(ld.helptext+len, line, xlen+1); len += xlen; break; } } } else if ( (ep = is_fkey(p, &fkeyno)) ) { p = skipspace(ep); if (m->fkeyhelp[fkeyno].textname) { refstr_put(m->fkeyhelp[fkeyno].textname); m->fkeyhelp[fkeyno].textname = NULL; } if (m->fkeyhelp[fkeyno].background) { refstr_put(m->fkeyhelp[fkeyno].background); m->fkeyhelp[fkeyno].background = NULL; } refstr_put(m->fkeyhelp[fkeyno].textname); m->fkeyhelp[fkeyno].textname = refdup_word(&p); if (*p) { p = skipspace(p); m->fkeyhelp[fkeyno].background = refdup_word(&p); } } else if ( (ep = looking_at(p, "include")) ) { do_include: { const char *file; p = skipspace(ep); file = refdup_word(&p); p = skipspace(p); if (*p) { record(m, &ld, append); m = current_menu = begin_submenu(p); parse_one_config(file); record(m, &ld, append); m = current_menu = end_submenu(); } else { parse_one_config(file); } refstr_put(file); } } else if ( looking_at(p, "append") ) { const char *a = refstrdup(skipspace(p+6)); if ( ld.label ) { refstr_put(ld.append); ld.append = a; } else { refstr_put(append); append = a; } } else if ( looking_at(p, "label") ) { p = skipspace(p+5); record(m, &ld, append); ld.label = refstrdup(p); ld.kernel = refstrdup(p); ld.type = KT_KERNEL; ld.passwd = NULL; ld.append = NULL; ld.menulabel = NULL; ld.helptext = NULL; ld.ipappend = ipappend; ld.menudefault = ld.menuhide = ld.menuseparator = ld.menudisabled = ld.menuindent = 0; } else if ( (ep = is_kernel_type(p, &type)) ) { if ( ld.label ) { refstr_put(ld.kernel); ld.kernel = refstrdup(skipspace(ep)); ld.type = type; } } else if ( looking_at(p, "timeout") ) { m->timeout = (atoi(skipspace(p+7))*CLK_TCK+9)/10; } else if ( looking_at(p, "totaltimeout") ) { totaltimeout = (atoll(skipspace(p+13))*CLK_TCK+9)/10; } else if ( looking_at(p, "ontimeout") ) { m->ontimeout = refstrdup(skipspace(p+9)); } else if ( looking_at(p, "allowoptions") ) { m->allowedit = atoi(skipspace(p+12)); } else if ( looking_at(p, "ipappend") ) { if (ld.label) ld.ipappend = atoi(skipspace(p+8)); else ipappend = atoi(skipspace(p+8)); } } } static int parse_one_config(const char *filename) { FILE *f; if (!strcmp(filename, "~")) filename = syslinux_config_file(); f = fopen(filename, "r"); if ( !f ) return -1; parse_config_file(f); fclose(f); return 0; } static void resolve_gotos(void) { struct menu_entry *me; struct menu *m; for (me = all_entries; me; me = me->next) { if (me->action == MA_GOTO_UNRES || me->action == MA_EXIT_UNRES) { m = find_menu(me->cmdline); refstr_put(me->cmdline); me->cmdline = NULL; if (m) { me->submenu = m; me->action--; /* Drop the _UNRES */ } else { me->action = MA_DISABLED; } } } } void parse_configs(char **argv) { const char *filename; struct menu *m; empty_string = refstrdup(""); /* Initialize defaults for the root and hidden menus */ hide_menu = new_menu(NULL, NULL, refstrdup(".hidden")); root_menu = new_menu(NULL, NULL, refstrdup(".top")); start_menu = root_menu; /* Other initialization */ memset(&ld, 0, sizeof(struct labeldata)); /* Actually process the files */ current_menu = root_menu; if ( !*argv ) { parse_one_config("~"); } else { while ( (filename = *argv++) ) parse_one_config(filename); } /* On final EOF process the last label statement */ record(current_menu, &ld, append); /* Common postprocessing */ resolve_gotos(); for (m = menu_list; m; m = m->next) { m->curentry = m->defentry; /* All menus start at their defaults */ if ( m->ontimeout ) m->ontimeout = unlabel(m->ontimeout); if ( m->onerror ) m->onerror = unlabel(m->onerror); } } syslinux-legacy-3.63+dfsg/com32/menu/vesamenu.c320000775000175000017500000042024410777447342020245 0ustar evanevanL!10V-)t$Gg;vAGRP+,sXZ,L$qVSQƉӺtlډY[^aà D$uL8#uD$蜦 úٌʌ鹌@--7UWVS,D$T$1t$C<#uPt$ hVƍl<{$1$1<,uBCCt<}uډ;$u$$ $$$$u$ $($$$|$t 1|$@1+$=wFEB9rFED$$+$=w @T$RTB()Rt$ h=<[^_]à - wu$ 1YRKD=6/(!  ј2뗺 @єu܃ VSƅ@u PPLXPh4肍,PPLXPh?b@LX9  }. uu CPPShK& º蠉Ft @;P~7щCQQShK@;P~Z[^UWVS ƉՉˁ~1H1I9~ωٺ 0^ƃ0)0ɋ0 [^_]UWVSD$ ՋD$0D$D$4D$@D$ +X;`|1Bx 9uVtZ_PT,@Pt$hc݋ @;`,(|")J1Ҹ,胈)z9uD$VD$u&uD$_D$yD$ZD$ZA,uu,E t u D$>D$otY<^^uFފtZE$9uJD$ӇsoD$赇  DOu|$t )D$@`;4~/|$~2D$9D$ |D$9D$ D$0[^_]KD$0} [^_]鷆D$<gUWVSD$ՉL$ 5@`49D$D$6щЙÅA)ōW)ʉљPT$\\$W,T@PX@Ph莉@TqG@,()‹TH9~͍J|h@P,T@PXPh @ ,T@PXPh@TqKC@T(J,)9~кo@XVVt$ t$ T$ C@4X9|Q,T@PSh1@Tq蛄C@T(J,)9~к迄|$ t@ltu @ 1I@RTB()R8XPhoXZ@@h4X,[^_]UWVS ǡ@ @u׸ [^_]1@@|=vft f9slj1ָ^11f)؋@5@19|9w@t)Ή@5@ufdf9vf)W [^_]WVS@uY@p:\ؙ}ރ~@t1()@ptu@h@@[^_UWVSEe@()čD$EP0@PDXPh虅q C@0 (9~PAPXD@PhG 躁C@0 (9~PAPXDPhqfC @(U싱06)‰H9~ϋDX$1PPFPBPSEQRh ~] 1!ǃ t1 uSu>5t=)u0;]v h)K랃 h) K;]w농G=x@+M䋐0⋀()Ѓ9SC*C:;]t3@t U'u}tUE&u1ee[^_UWVS<@tD$0xD$,pfD$:fD$:fD$8=@t#]uhR@D$] @=@t"tD$4 @fD$:@tuD$D$@hD$0D$,xT$,D$04@)9}D$0@+4y1D$,FT$,D$09T$,`)y19~&D$0D$(`)y1ҋD$(9}T$(T$,T$,tD$0@D$uD$0R@D$D$D$D$ D$07D$0 @` D$0@D$0D$09}D$0Qx tߋD$0@`9|&FD$0HD$0D$0~D$0Sx tߋD$0S,D$,xT$,D$04@)9}D$0@+4y1D$,K <=$>"0K.&7' @3@`NfD$:ffT$8fD$6f9w@`zfD$8fT$6f)fD$8fD$:E u1~uD$FU Jw8$Pml$D$jE@tT$0xD$,D$<L$,D$0\$,WW@X)jjoD$D$ /T$0D$,9}D$,+4D$,D$0~ D$0HD$0D$0@tD$0Qx tD$0Q D$0@D$0D$0x tT$0D$,49| D$,ȉD$,D$09} D$0@D$0D$0HtD$0Sx tD$094S D$0HD$0D$0x tD$0@4)ЉD$0D$,)D$0@4D$0D$, @D$0HD$0D$,HD$,D$0D$0Qx ̋ @`KD$0@D$0D$,@D$,D$09lD$0Qx XD$0D$0@`JL$0+4y1D$,!@l} fD$:L$,D$0T$,VVX)jj,@t%1T$,1ɃDu(PP8XPh-@z1D$,D$U8P|@81эqD$~ T$D$umL$9}1Ҹ8@UP<XPh;y1Ҹ8@ P<XPhTdy|$(11à e*K hN y = 8=oM=&7="=#J='=)/7D$8_O)88wON=95)88wOօ81t ؍X8 vÅt @8 wO)88Dw))ljm_98Ft9Ɔ8+j19tQ C=9-9u'8~Ƈ8sD$G)88ov8FD$1|$L$,T$0D$0t$,WW@X)jj(1@St$@tD$0xD$,lfD$:L$,D$0T$,VVX)jj@u D$ 1D$)C=wߡ@Dt fD$:D$01|$ hauD$<[^_]VSL$ T$tD$D$ PCTnt$ \$;(u(1ɋ(y(y1(Au؋u@`uhq\`n@|PP@@htt&1҉4@t11[^Ð@t vSCBt t1t:t1< w[ЍBЃ wà Bà ЍBЃ vBVSFÉ[^UWVSƋ(}#uECu)A w$ EEwElkkkEFE;E0E%kkkkȉ1ÉǍDƍ\]8E$D=ƍD}ÍD$$$Z[^_]UWVS ljՉ˺nƉXC5C,xWZ($([:Z@\$$L$ZCD$HOn1Z$(4%> $(j$(,[^_]UWVSljFt< w)D$@EkL$`u.D$|u#VshD$$PY|$([u[^_]WVSø,k${]Åt)D$(j%k1ID$(O%$T$(%$1߫|$f&ډZcS6D$1|$эqڋD$9],SiMD$1|$эqڋD$ ]u31Ĭ[^_]UWVS ÉЅu1 -@GBVDžuRRPhvZ11tFr tSu|sPw$9WZS~NVB. PPPh Z1ۃ u1ۉUcG}i1Åtˉ؃ [^_]ÐUWVST$ $T$ T$T$ʁT$1\$#ȃt T$T$ څu1$!Àt D$ ؉ptD$(xEu[^_]WVSúhT17%XCt@D7htӉ[^_UWVS T1ۍ;WD;huӍhf1۽@A.PShUYl `؃`t, QRPhFPC t뙉=--j[^_]Sá@Gt bYt g@GXZ[ЅtH@HBuTSÍ@Vu1PDZY[UWVS(ÉՉΉL$$Q11-\u WV \[^_]ÃL$(L$T$$D$ WVSÅu1'1эqLDžt V[^_WVSƅu1XÅt U[^_ÐUWVS.u7u3D$FWu T$D$E`u ufD$411҉ZfD$,9wfD$4fD$ft$؃fD$(f\$ED$,T$1ɸ"c<[^_]ÐUWVSD$ff1d1T$D$Hydt @u3=dn u*1Zdf)t fvtmftf9w^a10dŊD$D<G;{uSD$Tu/}SD$Tit D$[^_]Ð#Eg@@ܺ@ vT2@@@WVS \$ ‰SD$t$DGVF F ‰1ۉ?`ACu`Gu_GDG [^_SÆ[UWVSD$0T$PD$DT$0T$4L$0yL$8\$0[\$HD$0 D$D$9>D$k?1111D x%ƒ~;t$s KEEFGuɉ [^_]SЃ?@CIy[UWVSʼn1эq 56u\$D$ D$|$tT$L$ t<$u\$t&1.  .L$T$.\$U&-L$T$--$k.ك~$D$t-ݍ$1%D$tt$w-uf`G$1bG$L$T$cGZ2D$cGD$T$ƂcG$T$t$-|$k%ـL$t $,؉1tD$L$T$,؉1t D$,|$D$t$,T$$D$-CNf1ۋD$@$$ $ ʹ|$$ $ ʹP$$ $ ʹ$$$ $ ʹ$$ $ ʹ$|$ث`G[^_]UWVSLÉϋD$ AD$(AD$0A D$HAD$AD$8AD$@AD$A A 9sA$\$T$\$1 %  щLLFu΃D$@$]űMMȉ1 111M$D9ul$ T$(T$,D$0D$4T$HT$t$D$8D$+@,h@0kA@4ك@8y!~@<[@H@L@@@D@P@TUWVS $׉΋APQT D$+D$9vōFXD$D$$1FPVTFPVTw=v6ƒ D$NP1ۉNP^TD$TT$D$7,$)vL$u%-FX$,$ǀw〉ڋ$s$tF^PnXD$v ?Àى^PFT [^_]UWVS,ʼnT$@PUTM@]DӉM@]D9wr9sEHULwovp)ÍMXL$Ɖٺ )\$ M@]DΉ1˹ ډ1ۉ˹ ډ1 ډ1 $\$ L$ Ӊ\$ 1ۋD$ ȋT$  ȉD$ ډT$  ΋|$ D$t ؋T$D u@}D1EHUL ׉1˹ ډ1ۉ˹ ډ1 ډ1 1   ΋|$ t=X ؋T$D:D$D$$L$$t|1˹ ډ1ۉ˹ ډ1 ډ1 $\$ L$ Ӊ\$ 1ۋD$ ȋT$  ȉD$ ډT$  ΋|$$D$t ؋T$DG|$$ Ѓ,[^_]UWVS|@uDuNU싅 UU:$u0B=ɚ;vɚ; =sƅDžƅv Dž1эAu Dž/A%)čD$Fu Dž5&)čD$xًًEًًًU @@@Ewr+t E@ AuэUo1 C;uh3)čL$ @@?hw~1CE9Írݍh)čD$ @.@?hwtً Eٺ@1t1tt E@ tUF;2My1ɺ@ Ë}t) hDhy1PS)ǃ y1;v񋕌É)~$CIUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾Ѓ?`CItNUE E ¾!Ѓ?`CIu U 1N'Ѓ?`A~`CAdn"DžCDUh11󪋽fX1҉ X1 t󪃽t󪋅e[^_WVSƉ1эyl9=G}G t&G=G 5G GډW[^_@@#Eg@@ܺ@ vT2UWVS\D$(xD$ D$p D$D$X D$D$@T T$*xj׉!؉! D$ V!! ˋT$$2p $!! ދD$(8ν!ȉ!  T$, |!؉! D$0*ƇG!! ˋT$42F0!! ދD$88F!ȉ!  T$< ؘi!؉! D$@D!! ˋT$D2[!! Ѝ,D$H8\!ȉ! Ѝ D$T$L "k!؋T$! t$D$Pq!T$! ҉T$D$T(Cy#D$! ՋT$XD$!I!!  ًT$ 2b%!!\$ D$΋D$48@@!! T$HQZ^&!ʉ! D$Ƕ!!  ًT$02]/։!! ΋D$D8SD!ډ! T$X؉!ʉ! D$,!!  ًT$@2!!! ΋D$T87É!ډ! T$( !ʉ! D$<ZE!!  ًT$P2㩉!! ,D$$8!ډ! T$8og!ʉ! D$LL*!!  ދD$0(B911D$<8q11ыD$H"am11ˋD$T0 811 ދD$ D꾤11D$,K11ыD$8`K11ˋD$D0p11 ދD$P~(11D$'11ыD$(0ԉ11ˋD$4011 ދD$@9ى11D$L11ыD$X|11ˋD$$0eVĉ11 ދD$D") 1؍0D$8*C 1 D$T# 1ЍD$009 1ȍ 4D$LY[e 1؍0D$( 1 D$D} 1ЍD$ 0] 1ȍ <D$<O~o 1؍8D$X, 1 D$4C 1Ѝ4D$P8N 1ȍ <0\$,~S 18D$H5: 1,D$$0* 1؍ (D$@8ӆ 1‹D$ȋ\$C ЉCD$ T$*1|$\[^_]UWVS ljT$͋@?G9sGG@)9s1;_ T$ډ^?t$@@9rS1ɍD)T$ [^_]sVSƉӋRT$ CD$?7w8x),*T$ ډX1҉[^Ðj 1Ðj 1ÐWS؉…t 1׉Z[_ÐD$EHtD$UWVS lj։͉ u 9u1C t Nۅt [^_]ÐVSƸ15rt +tau#wu BBB uŅtQhPVy1@Z[^ÐшD$D$5HtD$ÉY1bQjr zJÒbjr zbUWVSƉՉ1҉وJ[^_]UWVS Ӊ͉1,Eىudnt t t )ÅuЉ [^_]ÐVStyHQ q:uZ9uYZrV !,AA, ,AH>u+Q9u!VQVFBFPFAFH [^ÐUWVS Ӊ͉1,Eىoudnt t t )ÅuЉ [^_]ÐS -)ʋ,t9v ,,@9sB,+,QA ,A,A,A, , , , ,[ÍvUWVStxX ,eq9r[C 9Ƌyir:Q)މpYH PB AxhQBQBoAxA I9u1[^_]ÐVSΉÉ1)‰uCANu[^ÐVW։ljsft_^ÐVW։ljsft_^ÐVWlj9rt1|9у_^ÐWVS$Ήiً<$$Z[^_ÃL$$L$T$ ÐUWVS ʼnT$uЃ [^_]m|$u p~\$9r 9N>9u39u.AD$9r!AFp QABAPL$N9rlC 9)ىJ^FBVBP r 9v,BB,,BPO,BB,,BP2D$Åu1GL$9v݉ [^_]ÃD$,D$ PL$8T$4D$0,ÃD$(D$ PL$4D$0],Ðu1@8uÐSÉъD$CA)‰u|$uZ[ÐSÉABu[Ð@Jt8u)ÐWVSωƉ)‰ut FAOu1[^_ÐVSƉˉ tABKu[^ÐSˉ tBAKu[ÐUWVS$ʼnT$L$ EL$8|$8t)U!u-uEL$8D$+uED$|$ uc|$8v#}0u$E|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$DMD$D<D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u1I|$Xt ;L$X~L$X9L$\~B t8t4t0t,D$ 1[^Ívtt tÐttB@tt Bt@1VS\$ t$t-t)B t#tttB\B`Bd1[^UWVS\$t$|$ l$$tvtrB tlthtdt`t\tX|$(tQ|$,tJEL$(T$,1[[^_]Ívt1t-B @t'݂D$݂D$@1VS\$ t$t3t/zy)t BhtBlɀt Bpɀ1ɉ[^Åt#tBttBRD$1fttBtt B<1SˋL$t!tz0~tB8tB0B0 t1[fWVSˋ|$t$tXtTBtNzuu1 BDt#BHu1 BHtt B1ɉ[^_Ívtt tÐtÅtÐtÐ%Ð%tÍvtÅtÐtÐtÐUWVS ƉӉϋl$ T$$|$(CECCH<v 0nCT$({v n|$0t CT$0|$4t CT$4|$,t CT$,? %m} 9m;~v Nl1 [^_]ÐHDÍvuHDfw HDƀÍvwHDÍvHD IRMfuÃHDÍvHDffIu H@`@uƀuvƀÐSKD[ÍvHDÁHDÃHD Ívxu@1A9uËHfu@19rfu@1 T9rÐVSӀx up 01KDKKTKA9u[^ÐSH w6Xu -!u .u / B9r[ÍvUWVSƉ͋8@<t<@~ ~ u\x1=ѻADADAC9rDADADAC9uF x1gѻ-ڈADADADA DA DA C9r2DADADADADADAC9uF 0kFF t<@~ u~~ u0x11ZC9u DZC9uF ~Dx1,JDDJA9rDJDDJA9uF ?FF @tf[^_]ÐVSӊP0@ <u?u1 QAAQC9u{uv1DTA9u]<uYu(1QAAQQAAQC9u,u'1ˊDˈTTDDTA9u[^ÉP4H8T$P9f@4É`ÐUWVS,ʼn˅tlt ډ_ffff~f,qf0df4Wft iЀ t PfЀ߉t e8t2+ 1 eC98|e<t2+ 1 eC9<|~e@t2+ 1 UeC9@|Ce6eEH覒x!eeD$d]u} D$1҉軼]u} D$T$ ,[^_]UWVSD$T$L$ u1D$0|$u1D$|$ u D$ D$ D$L$ډrt+ j@ډkXdD$ |$t/ j@T$(7D$("dD$ dD$[^_]UWVSƉ1ҿ\$ډډǰlj^ډ~z豺uj茺uډt^ZuuF<theN<N<u$uF<t  e豾Oùu*螹usyuBTui/u( uquvLu '蛸uvuoQu,uu \qu O÷u H-衷u IF<[^_]Ív@@@uuUWVSƉՉ@@@u\FD<$tyPuK@Ѓt_tO1u*Ѓt>t.u w't pu F<u aFTFX~Ltk1҉9\$ډ ډ.ډt ,atFLFH9vFLNL脺FL)FHu+~Xu~Lu t `N<N@ !tV`u`~X<vt!QQJP@Pʭ @PU]~DuFB@tPtGFDtAwt pŲt6 Tt蝲t苲x`tӃ[^_]ÐUWVS ƉT$D$1D$1ɉbC9uG;|$}1 [^_]fUWVS ʼn׉΅t7u1'1 C;\$ u01ɉ C;\$ ut1 1҉C;\$ u [^_]ÐVSÉ@@@u< 0][[^ UWVSƉT$<woؽ)݉׃  Ɔډt2w!Mډ{t>t+M]wN<\$ډ8 ډ[ljډzEuT$뤹!uT$0뀉ډyuN<T$蛹Ʊu N<+許F<\^uT$7u6F<utuu 4\N<[uT$HŰuT$!螰uT$wuT$nPuT$þ)uT$踼uT$M^ۯuT$7贯uT$药uT$fuT$)?uT$uT$KtuT$tMʮuT$護&T$k[^_]fUWVSƉ׉td?v Yt_t[tt+vt~to t@t*TtL$T$yYt)tIh j@uRWV@D$1#‰VD$D$;G|ԋ.O[^_]fUWVS,Ɖϋ1Ɋ:`tAl$ډwUVÉ1҉JĬǃ@Bǃ@Bǃ UChCl[pCH8ut,u3*Ct fD$D$h[à jjjt$ÐSÉP,tH(@({$t"C$jR Y[[[RXZ[ÍvSX(tXZ[úC Y[[NSfVSƉЉˋN,9t^ [[^$SY[^ÁHDÁH@@ÉD$D$ %x p wuuID ٙ$ٙ(ÍvHDÁHDÁHDÁHDÁHD@ÁHDP0ÐVSƉ@Et/\$dD$D@ 1<T$t$lt$l1RS,$ $BL$) ټ$f$ f$٬$ۜ$٬$$fzGuD$dD$H9D$d:؁Ĝ[^_]ÐUWVSNJD$_GD%=D$_udH<$ ikU kffffw|$_,  Rf ffD ffD fGD  1 PB9|   ?|$_uUfftIه$؏(p s,11PHL$HD$@ټ$f$ f$ ٬$ ߜ$٬$f$$t$tt$tD$XP $T$`$>L$HT$HD$@ټ$f$ f$ ٬$ ߜ$٬$f$$t$lt$l T$@P $$> T$0T$(ټ$f$ f$ ٬$ ߜ$٬$f$$t$lt$lD$@P $$=L$0D$(ټ$f$ f$ ٬$ ߜ$٬$f$$t$lt$lD$@P $T$H$.=L$0T$0D$(ټ$f$ f$ ٬$ ߜ$٬$f$$D$dd9D$dPT$d u#$M$E$UU4fيf)f$fċ0EPT$df U4ffщf)f$fċ0EPT$df U4fff)f$f2ċ0*U,EU,EU,ED$dL$`9L$dH1RP,$\$xt*t-tݔ$ݜ$;ه(ݜ$%ه$هݜ$؏(ݜ$$$݄$P<$\$\$t$VS:L$xټ$f$ f$ ٬$ ۜ$٬$$f$$VS\$ F:L$xD$ټ$f$ f$ ٬$ ۜ$٬$$fff;uf;u f9$$݄$P<$$9L$x ټ$f$ f$ ٬$ ۜ$٬$$f$$݄$P<$T$0$89L$x ټ$f$ f$ ٬$ ۜ$٬$$f$$݄$P<$\$\$t$VS8L$x ټ$f$ f$ ٬$ ۜ$٬$$f$$݄$P<$$C8L$x ټ$f$ f$ ٬$ ۜ$٬$$f$$t$,t$,7L$x ټ$f$ f$ ٬$ ۜ$٬$$f$$VS7L$x ټ$f$ f$ ٬$ ۜ$٬$$fffffff|$_11Q,AQ,AQ,AC9|SK|$_@$$$$1P(u"$$N$FffL$Ff+D$f$fFPf(fFf‰f)щf$fэVPf(fff)f$fڍE;$GD|$_f$D)$E)F)Ãv DŽ$v1v11QՍRЉD$$L$ЉD$@L$ABBEf;$u6  w]  w[^_]ÍvUWVSD$։͋D$$T$Bt<<Nw tj<<Z L$A H<E$ D$N3‰U9u')!ˆ$F ˆuCfOD$t$9t$u$uD$pD$lÉD$ ƒE9u))??!ˆ$C ˆDT$   Ћ$҉)??! ӈuFfD$l\$9\$lY3‰U9u')??!ˆ$F ˆuCfD$pt$9t$pu$uD$xD$tÉD$ ƒE9u))!ˆ$C ˆ6T$  Ћ$҉)! ӈuFfD$t\$9\$tg 3‰U9u')!ˆ$F ˆuCfD$xt$9t$xue $u1T1+1ff;Eu $fG ‹$1A;L$u f2f;Eu$fA2B;T$u $u1D$ n\$ <^\^ff;Eu$fB L$ NfBDN0Ê$Ӌ$fPfL$ NTND$ \$9\$ u` fNfTNf;Eu$fG NfGDNA;L$u' D$x $u 11c ff;Eu0fBf;Eu%fBf;Eu$fAfABfA $BBBBC;\$u ff;Eu1fBf;Eu&fBf;Eu$fGfGBfGBA;L$uH $uDŽ$t$ D$|D$ D$ T$ RT$?L$ qYAD$PyD$ ff;Eu_ff;EuND$Pff;Eu9$fCt$ fCFfCFfCFfCFfCFxD$?$T$ $fPft$ VF$VfPfFVF$VfPfFVD$|D$ \$9\$| qYAD$@yffQf;EuYff;EuHD$@ff;Eu3$fFfFAfFAfFAfFAfFA$|$9$fK l$} $$$1pD^|$ T$( 1 B;T$(|t$([,UT$3DD$ \$ \$T$ fBf;Zs\$ ]T$3TD$LA9||$LuN;t$$| D$L1|$t\$(1Rt$,l$(DŽ$2;D$$|)TKJ;D$$} v[l$,f*f)D*D)F;t$$|$ ;D$$|cTMJ;D$$}DmD$,HX$ffVPN^$$(ꋌ$$\$$9$kDŽ$$t$4;D$$@D$,(l$8PT$<@D$@L$,A)‰хyً\$,t$8)Ɖyыl$,ET$@)…yڍ,L$,D$PCA\$<)ÅyAT$8)…yAT$@)…yڍ9}ʼnt$PF;t$$|L$P\$4 $t$(9$LJl$$l$(kT$(BT$(1 1 B;T$(| D$\T$\D@=ul$(DŽ$D$XD$T`$A$k$D$,D$DƉL$`\$DSF)‰хyًD$DF)‰Ѕy\$DSF)‰Ѕy؍;\$T:D$XD$\L$X$YD$`A D$`9l$`i|$X~$$E9$|$XUDŽ$4$\$\ L$d\m\$D$dH9\$dS9tˉT$hӉL$hMl$@t$L$,ffTT|$uC19:u D$h9u F;t$(| ( ) (;l$$~*L$d L$d$\$T9$t$\TtD$XT$XT$\DCu;l$$~D$T`DŽ$VBE2fD$TO؃fD$8fD$4Lf|$TO5;VESAt Lf{w :ڸs[=SЉD$fD$D$( f%fD$ 1҉=fD$TOD$ fD$PfD$8fD$4T$0ѸKf|$TOV$T$N"L$F D$^VT$#f~fVȃ~fsfh~v ~Xx_fnJ@f~6,f9#Fuf~uFf~ |$# u4|$|$|$t}|$#u!tsuy|$ur|$uk|$tYb|$#u!tOuQ|$ uJ|$uC|$t5:|$#u3t5u)|$ u"|$u|$t1 ;\$(su3;L$ fL$\$(|$f|$f|$(u usT$(hnfD$TT$0Ѹ"ID$Xu"D$Tt6-D$4T$H,8fD$T0fD$HT$0ѸID$4T$@,6-56-6-D$$6-D$$B: )1D$$  |$$V-uы 6-v=uyfL$@fD$TOfL$fL$H\$0ىڸHf|$TOt RfD$TfD$HfD$PfD$L1ɉڸ"H|$(=L0=6-kP8ǣsu ""d$T$ T$ىDM1\[^_]Ð1҃ ƒ)xƀKƀKf1ƀKƀKÍvUWVS| É֡6-D$=sf-usT$ ȉL$4ӍD$ σЍT$TDD$ D$D-DD$HL$IL$@$ PT$XD$(D$,D$2D$3D$<D$vL$HL$@6-KD$9D$HK -L$L$HAL$Du1҃؋L$X!1D$`D$HD$PT$T$ L$DL$LD$8D$\f|$8L$8|$3wT$ T$$|$2}\$,ֽ)D$$ T$$  l$l$ L$ ƊT$`D$3Ѕt ???D$\tp@D$\T$9D$ d$2d$`d$3D$8T$PL$@6-D$9D$P.L$PAL$Du1҃؈D$`0T$`D$PD$8|$3D$  D$$|$2f\$(~vT$LL$<6-D$2D$9L$LAL$B1Ƀ؈D$30L$3BD$(R T$,D$LD$8T$pD$TNfuD$t?N4f0f41F0An0n4~4T$ wF`F`BOF`5)Goo~`t_yo_ 1[^_]Åt@t8 t1Ãx4øUWVS D$Ӆrz z$B(׉Džt+~,t,NC(S tC(S${18ڋD$''((FD)ȍGDFH)ȍGHFd)‰WdtFV,ى'o,D$x1 [^_]ÐUWVS ʼn֋X{,u#K@(U C,u{ uKC C(C$+uK 9rC,U )&C(0C()9U wMC,)&)tC,U )&s(C C(C(;C uC(C$;C sC$1C,)&ʃ [^_]ÐUWVS ÉՉυpt}> ux111XVOV;Ft]St B^ 9vF,T=)ډ &F F$^,)%~$F 1 [^_]fUWVS|D$T$ ]pRx H8u x9> u D$@ D$8T$RT$@L$ L$4\$[\$d~0n4\$$@D$HVu+ ҃|$<L$|$<L$|$<KL$w-L$D;Ht$T$DD$tD$H|$d\$+{\$DD$+XxX^~t.t*~P Ft )ډ )ډDFT$B0~Ѓ@1҃> F4ЋL$A,ut|$ u=|$Hu6D$H,D$H")D$RF8)D$RF8D$H|[^_]UWVSD$ T$1fDDl@u1L$QfDDlB9u$(D$T$f|Tlu JT$W|$Jf||luGu1ɍDLn)‰Au~|$  D$l)HfD$NAT$LfDJfDLjfJu14T$fZft&$fTDLʉL$$fHB $fTLLC9uȋL$9v9s̓|$ t |$ uI$D$4$T$,D$d$D$HD$(T$4T$0D$8$ L$,D$d$D$HD$(D$0D$4D$8DD$0~D$4>$T$,D$ D$HD$(D$8|$$T$@D$D$ D$$t$$D$@\$Ht$$*L$L$?D$@f0;D$8}D$>  1D$>`T$4T$>L$0f4+L$T$|$ډT$D‰+T$D$ L$L$,fpL$>L$?HT$DL$ u̍KT$ uu D$ B#D$ ЉD$ fT\lfJt\$H;\$SL$@AL$AD$HfT\l9l$Ht$ #t$(;t$$|$ul$|$H+|$D$LTl)B~ G;T$rD$|$ u|$L$D$,$ $L$D$,)fD)|$t+D$ #D$(;D$$t$T$,L$?D$D$ L$T$,f@@L$?HKT$ uu\$ B#D$ ЉD$ |$ uD$$$)1 Č[^_]ÐUWVSH$@D$ $K\$AÉ\$ q NA)‰)щL$D$\$[ \$D$@$D$T$R(T$ L$I,L$$\$[0\$tD$)PD$PSUT$ź踟ƃue/ڞPD$nDFD$F jT$#É褞蛞t [^_]UWVS ʼnT$@<u ŠE<tEv=w~-|=wl-=wZ-}=wH-Hq=w6 -x=w$-6=w-=v o#Jo[^_UWVS,ÉT$΋@<u#.t#9t #|$tT$B%u# t$ɖt$(\%D$C D$ |$8w=8w D$=v"$dCD$D$|$8w=8w D$=v;$]D${DŁ|$8w=8wT$=vR$蛕z/ǹƁ8w=8w 8=v k$D$@ D$->v=wkD$ -|=w[D$-=wKD$-}=w;D$-Hq=w+=wP=wx=o#諔\)V $$W $$U $,\$(L$X\$ L$P\$L$T\$L$L\$L$H$T$DQw KfJ mt'wlsu1D$)D$;D$|D$HD$;D$|R\$K)FD$;D$|\$K\$D$)y1D$1RC;D$| D$H=y1SG@H;D$| L$Iy1;T$|\$K\$ЅL1EtR\$t$NPPSVى|$T$ J9PPKD$0RV1|$\$PPCPD$ HP11҉t$_XD$0SJR1rVVD$HPD$ HP1>t"t@;L$SSQD$ HPL$RRQHP1҉\$L$PPQD$ HP1҉t$1ht G$G,D$(|$ WD<1$)BB B BBBB B ~BuBlBcB ZBQBHB?*B3BB#BB`*B B AT$(;J8D$G)W(O)L$o(G@\$(1#C0PЃ kG@ G@L$(AfD$> fD$<̈l$<\$8l$>D$8=~BD$l$<\$8l$>D$8=YBl$T$l$<\$8l$>D$8s=BD$l$<\$8l$>D$8N=ɰBl$l$<\$8l$>D$89=xBD$l$<\$8l$>D$8=3Bl$l$<\$8l$>D$8q=B9 T$CCC +\$\$\$CC CC + + + +l$<\$8l$>D$8=̰1B9v@[^_]Ð11{$81|1u1 v Hv \v v v v v vz@fz@kjPfzPuir`fz`Zp$fzpQ Q@Q`ّّّٙ1v11r`Zp$e%@)0(B#0[?25l#15%d#14[%d;%dH#14 %s #0[%d;1H#16[%d;1H[%d;1H#5#17#3[%d;%dH#1x%s #6#4 #1x #7a[%d;%dH#1lk[%d;%dH#1x#2 %s #1x[%d;%dH#1tu[%d;%dH#1mj#8[%d;%dH%s[%d;%dH#11lk[%d;%dHxx[%d;%dHmj[%d;%dH#12 %s [%d;%dH#13 [%d;1H#0[?25l[%d;1H#9> #10%s#10[%d;3H%s[?25hInitial menu has no LABEL entries! [?25h[%d;1Hpasswordmarginrowstabmsgrowcmdlinerowpasswordrowtimeoutrowhelpmsgrowhelpmsgendrowhshiftvshifthiddenrow#######3   -N-------------12222222 R4P,Yd%*s%s %s.%s %s%s%s%smenulabeltitledefaulthidepasswdshiftkeyonerrormasterincludebackground*msgcolormsgcolourseparatordisabledisabledindentbeginquitgotoexitstarthelpendtexttotaltimeoutontimeoutallowoptionsipappend.hidden.topnonelocalbootkernellinuxbsspxefdimagecombootcom32configautobootAutomatic boot in # second{,s}...Press [Tab] to edit optionsnotabmsgpasspromptPassword requirede%%@)0(B#%03d[?25l#%03dF|F|FF|FdFF|FuF|F|F|F|F|F|F|F|FF|FFmsg%02x1;%s3%d;4%dscreen1;36;44unselhotkey1;37;44hotsel1;7;37;40scrollbar31;40cmdmark1;36;40cmdlinepwdborder30;47pwdheader31;47pwdentrytimeout_msg1;37;401;30;44e@ #!2 )0@ :@RDJRZbl r| l V`;<=>?@ABCDHPKMIQGORS    !"#$%&'()    !"#$$%% &&'''(!(&)*[[AOP[[BOQ[[COR[[DOS[[E[15~[17~[18~[19~[20~[21~[23~[24~[5~[6~[1~[4~OF[2~[@[3~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/$1$./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz%s%zu$$5$rounds=./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/BD7q۵[V9Y?^[1$} Ut]rހܛtiGƝ̡ $o,-tJܩ\ڈvRQ>m1'Y GQcg)) '8!.m,M 8STs e jv.,r迢KfpK£Ql$օ5pjl7LwH'4 9JNOʜ[o.htocxxȄnjlPxqƀ$6$rounds=./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"(ט/Be#D7q/;Mۉ۵8H[V9YO?m^BؾopE[N1$} Uo{t]r;ހ5%ܛ&itJi%O8GՌƝew̡ $u+Yo,-ntJAܩ\SڈvfRQ>2-m1?!'Y= % GoQcpn g))/F '&&\8!.*Zm,M߳ 8ScTs ew< jvG.;5,rdL迢0BKfpK0TQlReU$* qW5ѻ2pjҸSAQl7LwH'Hᵼ4cZų 9ˊAJNscwOʜ[o.h]t`/CocxrxȄ9dnj(c#齂lPyƲ+SrxqƜa&>'!Ǹ}xnO}orgȢ}c ?G5 q}#w($@{2 ˾L*~e)Y:o_XGJDl(null):7ԦԦԦԦԦԦԦԦԦԦԦʦ̨ >GXfw_it~0123456789ABCDEF0123456789abcdefB`la<1.2.8(<Pcw 9To2W}%SM2o/sG*z r y 2 U ^<!%Af,fLD P!""p#*$$%d&&''({)F*++,-a.:/001234i5U6B738%9:; <=>? @AB#C0D?EQFeG|HIJKLN9OaPQRSUPVWXY=[~\] _R`ab>def@hij[lm$opqfstJvw9yz2|}7Fу_P5ܓ2☔Iy9¦V%ʯ{W7Ҿ¥ĜƕȒʑ̔ΙСҭԻ.NqM3t  !!!!"""###$$$$%%%&&&&''''(((()))*****++++,,,,----.....////0000011111222223333344444555556666677777788888999999::::::;;;;;<<<<<<======>>>>>>>??????@@@@@@AAAAAAABBBBBBBCCCCCCDDDDDDDEEEEEEEFFFFFFFGGGGGGGGHHHHHHHIIIIIIIIJJJJJJJKKKKKKKKLLLLLLLLMMMMMMMMNNNNNNNNOOOOOOOOPPPPPPPPQQQQQQQQQRRRRRRRRRSSSSSSSSTTTTTTTTTUUUUUUUUUVVVVVVVVVWWWWWWWWWXXXXXXXXXXYYYYYYYYYZZZZZZZZZZ[[[[[[[[[[\\\\\\\\\\]]]]]]]]]]^^^^^^^^^^__________``````````aaaaaaaaaaabbbbbbbbbbbccccccccccdddddddddddeeeeeeeeeeeefffffffffffggggggggggghhhhhhhhhhhhiiiiiiiiiiijjjjjjjjjjjjkkkkkkkkkkkkllllllllllllmmmmmmmmmmmmnnnnnnnnnnnnoooooooooooooppppppppppppqqqqqqqqqqqqqrrrrrrrrrrrrrssssssssssssstttttttttttttuuuuuuuuuuuuuvvvvvvvvvvvvvvwwwwwwwwwwwwwxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz{{{{{{{{{{{{{{|||||||||||||||}}}}}}}}}}}}}}~~~~~~~~~~~~~~~XT|ĺ libpng version 1.2.8 - December 3, 2004 Copyright (c) 1998-2004 Glenn Randers-Pehrson Copyright (c) 1996-1997 Andreas Dilger Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. libpng version 1.2.8 - December 3, 2004 (header) %d %s %d %02d:%02d:%02d +0000Unknown freer parameter in png_data_freer.Potential overflow in png_zalloc()Too many bytes for PNG signature.1.2.8PNG  IHDRIDATIENDPLTEbKGDcHRMgAMAhISTiCCPiTXtoFFspCALsCALpHYssBITsPLTsRGBtEXttIMEtRNSzTXt"U3UJanFebMarAprMayJunJulAugSepOctNovDecPalette size 0, hIST allocation skipped.Insufficient memory for hIST chunk data.Setting negative gamma to zeroSetting gamma=0Limiting gamma to 21474.83Ignoring attempt to set negative chromaticity valueIgnoring attempt to set chromaticity value exceeding 21474.83Out of memory while processing unknown chunk.Out of memory processing unknown chunk.iTXt chunk not supported.Insufficient memory for pCAL purpose.Insufficient memory for pCAL units.Insufficient memory for pCAL params.Insufficient memory for pCAL parameter.No memory for sPLT palettes.Insufficient memory to process iCCP chunk.Insufficient memory to process iCCP profile.Insufficient memory to store textImage width or height is zero in IHDRimage size exceeds user limits in IHDRInvalid image size in IHDRWidth is too large for libpng to process pixelsInvalid bit depth in IHDRInvalid color type in IHDRInvalid color type/bit depth combination in IHDRUnknown interlace method in IHDRUnknown compression method in IHDRUnknown filter method in IHDRh㈵>Q@APG?Invalid bit depthInvalid color typeInvalid image widthInvalid image heightWidth too large for libpng to process image data.Too many IDAT's foundInvalid attempt to read row dataNot enough image dataExtra compressed dataDecompression errorIgnoring extra png_read_update_info() call; row buffer not reallocatedNot a PNG filePNG file corrupted by ASCII conversionMissing IHDR before IDATMissing PLTE before IDATImage is too high to process with png_read_png()Application uses deprecated png_read_init() and should be recompiled.1.2.1zlib memoryzlib versionUnknown zlib errorApplication was compiled with png.h from libpng-%.20sApplication is running with png.c from libpng-%.20sThe png struct allocated by the application for reading is too small.The info struct allocated by application for reading is too small.1.0.6 or earlierIncompatible libpng version in application and libraryzlib memory errorzlib version error2VIt's an error to set both read_data_fn and write_data_fn in the same structure. Resetting write_data_fn to NULL.Call to NULL read functionRead Error??ư>p?>?C;G (;;;))v9*v9v9v9,v9v9v9v9v9v9v9~,!BHPignoring out of range rgb_to_gray coefficientsApplication must supply a known background gammaCan't discard critical data on CRC error.NULL row buffer for row %ld, pass %dpng_do_rgb_to_gray found nongray pixelpng_do_dither returned rowbytes=0Out of Memory!0123456789ABCDEF * )+ (,5  '-46!&.37<"%/28;=#$019:>??aHP1?oM?lb??;i$? {zQ?]rU? }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz tVYWZ`)\0```````````````,,,,,,,,,,```````))))))!!!!!!!!!!!!!!!!!!!!``````******""""""""""""""""""""````0```````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!`!!!!!!!""""""""""""""""""""""""`"""""""" BP_B`0B``la + incorrect header checkunknown compression methodinvalid window sizeunknown header flags setheader crc mismatchinvalid block typeinvalid stored block lengthstoo many length or distance symbolsinvalid code lengths setinvalid bit length repeatinvalid literal/lengths setinvalid distances setinvalid literal/length codeinvalid distance codeinvalid distance too far backincorrect data checkincorrect length checkz?||>}v}}'~~~e!<ZSo܈lnƊz     A@!  @a`10  @`Psp0  ` @ X ;x8 h( H T+t4  d$ D \ S|< l,  L R#r2  b" B Z Cz: j*  J V@3v6 f& F  ^ c~> n. N `Qq1  a! A Y ;y9 i)  I U+u5  e% E ] S}= m-  M S#s3  c# C [ C{; k+  K W@3w7 g' G  _ c? o/ O `Psp0  ` @ X ;x8 h( H T+t4  d$ D \ S|< l,  L R#r2  b" B Z Cz: j*  J V@3v6 f& F  ^ c~> n. N `Qq1  a! A Y ;y9 i)  I U+u5  e% E ] S}= m-  M S#s3  c# C [ C{; k+  K W@3w7 g' G  _ c? o/ O inflate 1.2.1 Copyright 1995-2003 Mark Adler @@ !1Aa  0@`LB #+3;CScsPNG unsigned integer out of range. Row has too many bytes to allocate in memory.Ignoring bad adaptive filter typeinvalid chunk typeNot enough memory to decompress chunkNot enough memory to decompress chunk.Not enough memory to decompress chunk..Buffer error in compressed datastream in %s chunkData error in compressed datastream in %s chunkIncomplete compressed datastream in %s chunkNot enough memory for text.Unknown zTXt compression type %dCRC errorDecompression ErrorExtra compressed data.Extra compression dataunknown critical chunkMissing IHDR before zTXtOut of memory processing zTXt chunk.Zero length zTXt chunkUnknown compression type in zTXt chunkNot enough memory to process zTXt chunk.Insufficient memory to store zTXt chunk.Missing IHDR before tEXtNo memory to process text chunk.Not enough memory to process text chunk.Insufficient memory to process text chunk.Missing IHDR before sCALInvalid sCAL after IDATDuplicate sCAL chunkOut of memory while processing sCAL chunkmalformed width string in sCAL chunkmalformed height string in sCAL chunkInvalid sCAL dataMissing IHDR before pCALInvalid pCAL after IDATDuplicate pCAL chunkNo memory for pCAL purpose.Invalid pCAL dataInvalid pCAL parameters for equation typeUnrecognized equation type for pCAL chunkNo memory for pCAL params.Missing IHDR before oFFsInvalid oFFs after IDATDuplicate oFFs chunkIncorrect oFFs chunk lengthMissing IHDR before pHYsInvalid pHYs after IDATDuplicate pHYs chunkIncorrect pHYs chunk lengthMissing IHDR before iCCPInvalid iCCP after IDATOut of place iCCP chunkDuplicate iCCP chunkMalformed iCCP chunkIgnoring nonzero compression type in iCCP chunkProfile size field missing from iCCP chunkIgnoring truncated iCCP profile. Missing IHDR before sRGBInvalid sRGB after IDATOut of place sRGB chunkDuplicate sRGB chunkIncorrect sRGB chunk lengthUnknown sRGB intentIgnoring incorrect gAMA value when sRGB is also presentIgnoring incorrect cHRM value when sRGB is also presentMissing IHDR before cHRMInvalid cHRM after IDATMissing PLTE before cHRMDuplicate cHRM chunkIncorrect cHRM chunk lengthInvalid cHRM white pointInvalid cHRM red pointInvalid cHRM green pointInvalid cHRM blue pointMissing IHDR before sBITInvalid sBIT after IDATOut of place sBIT chunkDuplicate sBIT chunkIncorrect sBIT chunk lengthMissing IHDR before gAMAInvalid gAMA after IDATOut of place gAMA chunkDuplicate gAMA chunkIncorrect gAMA chunk lengthIgnoring gAMA chunk with gamma=0No image in fileIncorrect IEND chunk lengthMissing IHDR before PLTEInvalid PLTE after IDATDuplicate PLTE chunkIgnoring PLTE chunk in grayscale PNGInvalid palette chunkTruncating incorrect tRNS chunk lengthTruncating incorrect info tRNS chunk lengthOut of place IHDRInvalid IHDR chunkMissing IHDR before hISTInvalid hIST after IDATMissing PLTE before hISTDuplicate hIST chunkIncorrect hIST chunk lengthMissing IHDR before bKGDInvalid bKGD after IDATMissing PLTE before bKGDDuplicate bKGD chunkIncorrect bKGD chunk lengthIncorrect bKGD chunk index valueMissing IHDR before tRNSInvalid tRNS after IDATDuplicate tRNS chunkIncorrect tRNS chunk lengthMissing PLTE before tRNSZero length tRNS chunktRNS chunk not allowed with alpha channelMissing IHDR before sPLTInvalid sPLT after IDATmalformed sPLT chunksPLT chunk has bad lengthsPLT chunk too longsPLT chunk requires too much memoryf=X'7Pd A %1:CLUU^gpyyyyyyyyٿ__ô³؜B0need dictionarystream endfile errorstream errordata errorinsufficient memorybuffer errorincompatible version8+H+,S+^+k+v+++,?^?u='ԋ?L]]p@,,,,<V- -@ `P0pH(hX8xD$dT4t L,l\<|B"bR2r J*jZ:zF&fV6vN.n^>~A!aQ1q I)iY9yE%eU5u M-m]=}C#cS3s K+k[;{G'gW7wO/o_?@P `0pDT$d4tHX(h8x L\,l<|AQ!a1qEU%e5u IY)i9y M]-m=}BR"b2rFV&f6v JZ*j:zN^.n>~CS#c3sGW'g7w K[+k;{O_/o? 0@P`p!1AQaq"2BRbr#3CScs$4DTdt%5EUeu&6FVfv'7GWgw(8HXhx )9IYiy *:JZjz +;K[k{ ,N^n~/?O_oN K80Da,a aalError decoding compressed text t|m|0syslinux-legacy-3.63+dfsg/com32/menu/background.c0000664000175000017500000000160310777447272020365 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include #include #include "menu.h" const char *current_background = NULL; void set_background(const char *new_background) { if (!current_background || strcmp(current_background, new_background)) { draw_background(new_background); current_background = new_background; } } syslinux-legacy-3.63+dfsg/com32/menu/vesamenu.c0000664000175000017500000000255710777447273020103 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * vesamenu.c * * Simple menu system which displays a list and allows the user to select * a command line and/or edit it. * * VESA graphics version. */ #include #include #include #include "menu.h" void console_prepare(void) { fputs("\033[0m\033[20h\033[25l", stdout); } void console_cleanup(void) { /* For the serial console, be nice and clean up */ fputs("\033[0m\033[20l", stdout); } int draw_background(const char *what) { if (!what) return vesacon_default_background(); else if (what[0] == '#') return vesacon_set_background(parse_argb((char **)&what)); else return vesacon_load_background(what); } int main(int argc, char *argv[]) { openconsole(&dev_rawcon_r, &dev_vesaserial_w); return menu_main(argc, argv); } syslinux-legacy-3.63+dfsg/com32/menu/menu.h0000664000175000017500000001223310777447273017221 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * menu.h * * Header file for the simple menu system */ #ifndef MENU_H #define MENU_H #include #include #include #include #include #include #include #include "refstr.h" #ifndef CLK_TCK # define CLK_TCK sysconf(_SC_CLK_TCK) #endif struct menu; /* Note: the _UNRES variants must always be immediately after their "normal" versions. */ enum menu_action { MA_NONE, /* Undefined value */ MA_CMD, /* Execute a command */ MA_DISABLED, /* Disabled menu entry */ MA_SUBMENU, /* This is a submenu entry */ MA_GOTO, /* Go to another menu */ MA_GOTO_UNRES, /* Unresolved go to */ MA_QUIT, /* Quit to CLI */ MA_EXIT, /* Exit to higher-level menu */ MA_EXIT_UNRES, /* Unresolved exit */ }; struct menu_entry { int entry; /* Entry number inside menu */ const char *displayname; const char *label; const char *passwd; char *helptext; const char *cmdline; struct menu *submenu; struct menu_entry *next; /* Linked list of all labels across menus */ enum menu_action action; unsigned char hotkey; }; static inline bool is_disabled(struct menu_entry *me) { return me->action == MA_DISABLED; } enum kernel_type { /* Meta-types for internal use */ KT_NONE, KT_LOCALBOOT, /* The ones we can pass off to SYSLINUX, in order */ KT_KERNEL, /* Undefined type */ KT_LINUX, /* Linux kernel */ KT_BOOT, /* Bootstrap program */ KT_BSS, /* Boot sector with patch */ KT_PXE, /* PXE NBP */ KT_FDIMAGE, /* Floppy disk image */ KT_COMBOOT, /* COMBOOT image */ KT_COM32, /* COM32 image */ KT_CONFIG, /* Configuration file */ }; extern const char * const kernel_types[]; /* Configurable integer parameters */ enum parameter_number { P_WIDTH, P_MARGIN, P_PASSWD_MARGIN, P_MENU_ROWS, P_TABMSG_ROW, P_CMDLINE_ROW, P_END_ROW, P_PASSWD_ROW, P_TIMEOUT_ROW, P_HELPMSG_ROW, P_HELPMSGEND_ROW, P_HSHIFT, P_VSHIFT, P_HIDDEN_ROW, NPARAMS }; /* Configurable messages */ enum message_number { MSG_TITLE, MSG_AUTOBOOT, MSG_TAB, MSG_NOTAB, MSG_PASSPROMPT, MSG_COUNT }; struct messages { const char *name; /* Message configuration name */ const char *defmsg; /* Default message text */ }; struct menu_parameter { const char *name; int value; }; extern const struct menu_parameter mparm[NPARAMS]; struct fkey_help { const char *textname; const char *background; }; struct menu { struct menu *next; /* Linked list of all menus */ const char *label; /* Goto label for this menu */ struct menu *parent; struct menu_entry *parent_entry; /* Entry for self in parent */ struct menu_entry **menu_entries; struct menu_entry *menu_hotkeys[256]; const char *messages[MSG_COUNT]; int mparm[NPARAMS]; int nentries; int nentries_space; int defentry; int allowedit; int timeout; int curentry; int curtop; const char *title; const char *ontimeout; const char *onerror; const char *menu_master_passwd; const char *menu_background; struct color_table *color_table; struct fkey_help fkeyhelp[12]; }; extern struct menu *root_menu, *start_menu, *hide_menu, *menu_list; /* 2048 is the current definition inside syslinux */ #define MAX_CMDLINE_LEN 2048 /* These are global parameters regardless of which menu we're displaying */ extern int shiftkey; extern int hiddenmenu; extern long long totaltimeout; void parse_configs(char **argv); int draw_background(const char *filename); static inline int my_isspace(char c) { return (unsigned char)c <= ' '; } int my_isxdigit(char c); unsigned int hexval(char c); unsigned int hexval2(const char *p); uint32_t parse_argb(char **p); int menu_main(int argc, char *argv[]); void console_prepare(void); void console_cleanup(void); extern const int message_base_color, menu_color_table_size; int mygetkey(clock_t timeout); int show_message_file(const char *filename, const char *background); /* passwd.c */ int passwd_compare(const char *passwd, const char *entry); /* colors.c */ #define MSG_COLORS_DEF_FG 0x90ffffff #define MSG_COLORS_DEF_BG 0x80ffffff #define MSG_COLORS_DEF_SHADOW SHADOW_NORMAL void set_msg_colors_global(struct color_table *tbl, unsigned int fg, unsigned int bg, enum color_table_shadow shadow); struct color_table *default_color_table(void); struct color_table *copy_color_table(const struct color_table *master); extern const int message_base_color; /* background.c */ extern const char *current_background; void set_background(const char *new_background); /* execute.c */ void execute(const char *cmdline, enum kernel_type type); #endif /* MENU_H */ syslinux-legacy-3.63+dfsg/com32/menu/colors.c0000664000175000017500000001274310777447272017556 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include #include #include #include #include "menu.h" /* * The color/attribute indexes (\1#X, \2#XX, \3#XXX) are as follows * * 00 - screen Rest of the screen * 01 - border Border area * 02 - title Title bar * 03 - unsel Unselected menu item * 04 - hotkey Unselected hotkey * 05 - sel Selection bar * 06 - hotsel Selected hotkey * 07 - scrollbar Scroll bar * 08 - tabmsg Press [Tab] message * 09 - cmdmark Command line marker * 10 - cmdline Command line * 11 - pwdborder Password box border * 12 - pwdheader Password box header * 13 - pwdentry Password box contents * 14 - timeout_msg Timeout message * 15 - timeout Timeout counter * 16 - help Current entry help text * 17 - disabled Disabled menu item */ static const struct color_table default_colors[] = { { "screen", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL }, { "border", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL }, { "title", "1;36;44", 0xc00090f0, 0x00000000, SHADOW_NORMAL }, { "unsel", "37;44", 0x90ffffff, 0x00000000, SHADOW_NORMAL }, { "hotkey", "1;37;44", 0xffffffff, 0x00000000, SHADOW_NORMAL }, { "sel", "7;37;40", 0xe0000000, 0x20ff8000, SHADOW_ALL }, { "hotsel", "1;7;37;40", 0xe0400000, 0x20ff8000, SHADOW_ALL }, { "scrollbar", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL }, { "tabmsg", "31;40", 0x90ffff00, 0x00000000, SHADOW_NORMAL }, { "cmdmark", "1;36;40", 0xc000ffff, 0x00000000, SHADOW_NORMAL }, { "cmdline", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL }, { "pwdborder", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL }, { "pwdheader", "31;47", 0x80ff8080, 0x20ffffff, SHADOW_NORMAL }, { "pwdentry", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL }, { "timeout_msg", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL }, { "timeout", "1;37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL }, { "help", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL }, { "disabled", "1;30;44", 0x60cccccc, 0x00000000, SHADOW_NORMAL }, }; #define NCOLORS (sizeof default_colors/sizeof default_colors[0]) const int message_base_color = NCOLORS; const int menu_color_table_size = NCOLORS+256; /* Algorithmically generate the msgXX colors */ void set_msg_colors_global(struct color_table *tbl, unsigned int fg, unsigned int bg, enum color_table_shadow shadow) { struct color_table *cp = tbl+message_base_color; unsigned int i; unsigned int fga, bga; unsigned int fgh, bgh; unsigned int fg_idx, bg_idx; unsigned int fg_rgb, bg_rgb; static const unsigned int pc2rgb[8] = { 0x000000, 0x0000ff, 0x00ff00, 0x00ffff, 0xff0000, 0xff00ff, 0xffff00, 0xffffff }; /* Converting PC RGBI to sensible RGBA values is an "interesting" proposition. This algorithm may need plenty of tweaking. */ fga = fg & 0xff000000; fgh = ((fg >> 1) & 0xff000000) | 0x80000000; bga = bg & 0xff000000; bgh = ((bg >> 1) & 0xff000000) | 0x80000000; for (i = 0; i < 256; i++) { fg_idx = i & 15; bg_idx = i >> 4; fg_rgb = pc2rgb[fg_idx & 7] & fg; bg_rgb = pc2rgb[bg_idx & 7] & bg; if (fg_idx & 8) { /* High intensity foreground */ fg_rgb |= fgh; } else { fg_rgb |= fga; } if (bg_idx == 0) { /* Default black background, assume transparent */ bg_rgb = 0; } else if (bg_idx & 8) { bg_rgb |= bgh; } else { bg_rgb |= bga; } cp->argb_fg = fg_rgb; cp->argb_bg = bg_rgb; cp->shadow = shadow; cp++; } } struct color_table *default_color_table(void) { unsigned int i; const struct color_table *dp; struct color_table *cp; struct color_table *color_table; static const int pc2ansi[8] = {0, 4, 2, 6, 1, 5, 3, 7}; static char msg_names[6*256]; char *mp; color_table = calloc(NCOLORS+256, sizeof(struct color_table)); dp = default_colors; cp = color_table; for (i = 0; i < NCOLORS; i++) { *cp = *dp; cp->ansi = refstrdup(dp->ansi); cp++; dp++; } mp = msg_names; for (i = 0; i < 256; i++) { cp->name = mp; mp += sprintf(mp, "msg%02x", i)+1; rsprintf(&cp->ansi, "%s3%d;4%d", (i & 8) ? "1;" : "", pc2ansi[i & 7], pc2ansi[(i >> 4) & 7]); cp++; } /*** XXX: This needs to move to run_menu() ***/ console_color_table = color_table; console_color_table_size = NCOLORS+256; set_msg_colors_global(color_table, MSG_COLORS_DEF_FG, MSG_COLORS_DEF_BG, MSG_COLORS_DEF_SHADOW); return color_table; } struct color_table *copy_color_table(const struct color_table *master) { const struct color_table *dp; struct color_table *color_table, *cp; unsigned int i; color_table = calloc(NCOLORS+256, sizeof(struct color_table)); dp = master; cp = color_table; for (i = 0; i < NCOLORS+256; i++) { *cp = *dp; cp->ansi = refstr_get(dp->ansi); cp++; dp++; } return color_table; } syslinux-legacy-3.63+dfsg/com32/menu/menumain.c0000664000175000017500000005624010777447273020067 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * menumain.c * * Simple menu system which displays a list and allows the user to select * a command line and/or edit it. */ #include #include #include #include #include #include #include #include #include #include #include "menu.h" /* The symbol "cm" always refers to the current menu across this file... */ static struct menu *cm; const struct menu_parameter mparm[NPARAMS] = { [P_WIDTH] = { "width", 0 }, [P_MARGIN] = { "margin", 10 }, [P_PASSWD_MARGIN] = { "passwordmargin", 3 }, [P_MENU_ROWS] = { "rows", 12 }, [P_TABMSG_ROW] = { "tabmsgrow", 18 }, [P_CMDLINE_ROW] = { "cmdlinerow", 18 }, [P_END_ROW] = { "endrow", -1 }, [P_PASSWD_ROW] = { "passwordrow", 11 }, [P_TIMEOUT_ROW] = { "timeoutrow", 20 }, [P_HELPMSG_ROW] = { "helpmsgrow", 22 }, [P_HELPMSGEND_ROW] = { "helpmsgendrow", -1 }, [P_HSHIFT] = { "hshift", 0 }, [P_VSHIFT] = { "vshift", 0 }, [P_HIDDEN_ROW] = { "hiddenrow", -2 }, }; /* These macros assume "cm" is a pointer to the current menu */ #define WIDTH (cm->mparm[P_WIDTH]) #define MARGIN (cm->mparm[P_MARGIN]) #define PASSWD_MARGIN (cm->mparm[P_PASSWD_MARGIN]) #define MENU_ROWS (cm->mparm[P_MENU_ROWS]) #define TABMSG_ROW (cm->mparm[P_TABMSG_ROW]+VSHIFT) #define CMDLINE_ROW (cm->mparm[P_CMDLINE_ROW]+VSHIFT) #define END_ROW (cm->mparm[P_END_ROW]) #define PASSWD_ROW (cm->mparm[P_PASSWD_ROW]+VSHIFT) #define TIMEOUT_ROW (cm->mparm[P_TIMEOUT_ROW]+VSHIFT) #define HELPMSG_ROW (cm->mparm[P_HELPMSG_ROW]+VSHIFT) #define HELPMSGEND_ROW (cm->mparm[P_HELPMSGEND_ROW]) #define HSHIFT (cm->mparm[P_HSHIFT]) #define VSHIFT (cm->mparm[P_VSHIFT]) #define HIDDEN_ROW (cm->mparm[P_HIDDEN_ROW]) static char * pad_line(const char *text, int align, int width) { static char buffer[MAX_CMDLINE_LEN]; int n, p; if ( width >= (int) sizeof buffer ) return NULL; /* Can't do it */ n = strlen(text); if ( n >= width ) n = width; memset(buffer, ' ', width); buffer[width] = 0; p = ((width-n)*align)>>1; memcpy(buffer+p, text, n); return buffer; } /* Display an entry, with possible hotkey highlight. Assumes that the current attribute is the non-hotkey one, and will guarantee that as an exit condition as well. */ static void display_entry(const struct menu_entry *entry, const char *attrib, const char *hotattrib, int width) { const char *p = entry->displayname; char marker; if (!p) p = ""; switch (entry->action) { case MA_SUBMENU: marker = '>'; break; case MA_EXIT: marker = '<'; break; default: marker = 0; break; } if (marker) width -= 2; while ( width ) { if ( *p ) { if ( *p == '^' ) { p++; if ( *p && ((unsigned char)*p & ~0x20) == entry->hotkey ) { fputs(hotattrib, stdout); putchar(*p++); fputs(attrib, stdout); width--; } } else { putchar(*p++); width--; } } else { putchar(' '); width--; } } if (marker) { putchar(' '); putchar(marker); } } static void draw_row(int y, int sel, int top, int sbtop, int sbbot) { int i = (y-4-VSHIFT)+top; int dis = (i < cm->nentries) && is_disabled(cm->menu_entries[i]); printf("\033[%d;%dH\1#1\016x\017%s ", y, MARGIN+1+HSHIFT, (i == sel) ? "\1#5" : dis ? "\2#17" : "\1#3"); if ( i >= cm->nentries ) { fputs(pad_line("", 0, WIDTH-2*MARGIN-4), stdout); } else { display_entry(cm->menu_entries[i], (i == sel) ? "\1#5" : dis ? "\2#17" : "\1#3", (i == sel) ? "\1#6" : dis ? "\2#17" : "\1#4", WIDTH-2*MARGIN-4); } if ( cm->nentries <= MENU_ROWS ) { printf(" \1#1\016x\017"); } else if ( sbtop > 0 ) { if ( y >= sbtop && y <= sbbot ) printf(" \1#7\016a\017"); else printf(" \1#1\016x\017"); } else { putchar(' '); /* Don't modify the scrollbar */ } } static jmp_buf timeout_jump; int mygetkey(clock_t timeout) { clock_t t0, t; clock_t tto, to; int key; if ( !totaltimeout ) return get_key(stdin, timeout); for (;;) { tto = min(totaltimeout, INT_MAX); to = timeout ? min(tto, timeout) : tto; t0 = times(NULL); key = get_key(stdin, to); t = times(NULL) - t0; if ( totaltimeout <= t ) longjmp(timeout_jump, 1); totaltimeout -= t; if ( key != KEY_NONE ) return key; if ( timeout ) { if ( timeout <= t ) return KEY_NONE; timeout -= t; } } } static int ask_passwd(const char *menu_entry) { char user_passwd[WIDTH], *p; int done; int key; int x; printf("\033[%d;%dH\2#11\016l", PASSWD_ROW, PASSWD_MARGIN+1); for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ ) putchar('q'); printf("k\033[%d;%dHx", PASSWD_ROW+1, PASSWD_MARGIN+1); for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ ) putchar(' '); printf("x\033[%d;%dHm", PASSWD_ROW+2, PASSWD_MARGIN+1); for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ ) putchar('q'); printf("j\017\033[%d;%dH\2#12 %s \033[%d;%dH\2#13", PASSWD_ROW, (WIDTH-(strlen(cm->messages[MSG_PASSPROMPT])+2))/2, cm->messages[MSG_PASSPROMPT], PASSWD_ROW+1, PASSWD_MARGIN+3); /* Actually allow user to type a password, then compare to the SHA1 */ done = 0; p = user_passwd; while ( !done ) { key = mygetkey(0); switch ( key ) { case KEY_ENTER: case KEY_CTRL('J'): done = 1; break; case KEY_ESC: case KEY_CTRL('C'): p = user_passwd; /* No password entered */ done = 1; break; case KEY_BACKSPACE: case KEY_DEL: case KEY_DELETE: if ( p > user_passwd ) { printf("\b \b"); p--; } break; case KEY_CTRL('U'): while ( p > user_passwd ) { printf("\b \b"); p--; } break; default: if ( key >= ' ' && key <= 0xFF && (p-user_passwd) < WIDTH-2*PASSWD_MARGIN-5 ) { *p++ = key; putchar('*'); } break; } } if ( p == user_passwd ) return 0; /* No password entered */ *p = '\0'; return (cm->menu_master_passwd && passwd_compare(cm->menu_master_passwd, user_passwd)) || (menu_entry && passwd_compare(menu_entry, user_passwd)); } static void draw_menu(int sel, int top, int edit_line) { int x, y; int sbtop = 0, sbbot = 0; const char *tabmsg; int tabmsg_len; if ( cm->nentries > MENU_ROWS ) { int sblen = max(MENU_ROWS*MENU_ROWS/cm->nentries, 1); sbtop = (MENU_ROWS-sblen+1)*top/(cm->nentries-MENU_ROWS+1); sbbot = sbtop+sblen-1; sbtop += 4; sbbot += 4; /* Starting row of scrollbar */ } printf("\033[%d;%dH\1#1\016l", VSHIFT+1, HSHIFT+MARGIN+1); for ( x = 2+HSHIFT ; x <= (WIDTH-2*MARGIN-1)+HSHIFT ; x++ ) putchar('q'); printf("k\033[%d;%dH\1#1x\017\1#2 %s \1#1\016x", VSHIFT+2, HSHIFT+MARGIN+1, pad_line(cm->title, 1, WIDTH-2*MARGIN-4)); printf("\033[%d;%dH\1#1t", VSHIFT+3, HSHIFT+MARGIN+1); for ( x = 2+HSHIFT ; x <= (WIDTH-2*MARGIN-1)+HSHIFT ; x++ ) putchar('q'); fputs("u\017", stdout); for ( y = 4+VSHIFT ; y < 4+VSHIFT+MENU_ROWS ; y++ ) draw_row(y, sel, top, sbtop, sbbot); printf("\033[%d;%dH\1#1\016m", y, HSHIFT+MARGIN+1); for ( x = 2+HSHIFT ; x <= (WIDTH-2*MARGIN-1)+HSHIFT ; x++ ) putchar('q'); fputs("j\017", stdout); if ( edit_line && cm->allowedit && !cm->menu_master_passwd ) tabmsg = cm->messages[MSG_TAB]; else tabmsg = cm->messages[MSG_NOTAB]; tabmsg_len = strlen(tabmsg); printf("\1#8\033[%d;%dH%s", TABMSG_ROW, 1+HSHIFT+((WIDTH-tabmsg_len)>>1), tabmsg); printf("\1#0\033[%d;1H", END_ROW); } static void clear_screen(void) { fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout); } static void display_help(const char *text) { int row; const char *p; if (!text) { text = ""; printf("\1#0\033[%d;1H", HELPMSG_ROW); } else { printf("\2#16\033[%d;1H", HELPMSG_ROW); } for (p = text, row = HELPMSG_ROW; *p && row <= HELPMSGEND_ROW; p++) { switch (*p) { case '\r': case '\f': case '\v': case '\033': break; case '\n': printf("\033[K\033[%d;1H", ++row); break; default: putchar(*p); } } fputs("\033[K", stdout); while (row <= HELPMSGEND_ROW) { printf("\033[K\033[%d;1H", ++row); } } static void show_fkey(int key) { int fkey; while (1) { switch (key) { case KEY_F1: fkey = 0; break; case KEY_F2: fkey = 1; break; case KEY_F3: fkey = 2; break; case KEY_F4: fkey = 3; break; case KEY_F5: fkey = 4; break; case KEY_F6: fkey = 5; break; case KEY_F7: fkey = 6; break; case KEY_F8: fkey = 7; break; case KEY_F9: fkey = 8; break; case KEY_F10: fkey = 9; break; case KEY_F11: fkey = 10; break; case KEY_F12: fkey = 11; break; default: fkey = -1; break; } if (fkey == -1) break; if (cm->fkeyhelp[fkey].textname) key = show_message_file(cm->fkeyhelp[fkey].textname, cm->fkeyhelp[fkey].background); else break; } } static const char * edit_cmdline(const char *input, int top) { static char cmdline[MAX_CMDLINE_LEN]; int key, len, prev_len, cursor; int redraw = 1; /* We enter with the menu already drawn */ strncpy(cmdline, input, MAX_CMDLINE_LEN); cmdline[MAX_CMDLINE_LEN-1] = '\0'; len = cursor = strlen(cmdline); prev_len = 0; for (;;) { if ( redraw > 1 ) { /* Clear and redraw whole screen */ /* Enable ASCII on G0 and DEC VT on G1; do it in this order to avoid confusing the Linux console */ clear_screen(); draw_menu(-1, top, 1); prev_len = 0; } if ( redraw > 0 ) { /* Redraw the command line */ printf("\033[?25l\033[%d;1H\1#9> \2#10%s", CMDLINE_ROW, pad_line(cmdline, 0, max(len, prev_len))); printf("\2#10\033[%d;3H%s\033[?25h", CMDLINE_ROW, pad_line(cmdline, 0, cursor)); prev_len = len; redraw = 0; } key = mygetkey(0); switch( key ) { case KEY_CTRL('L'): redraw = 2; break; case KEY_ENTER: case KEY_CTRL('J'): return cmdline; case KEY_ESC: case KEY_CTRL('C'): return NULL; case KEY_BACKSPACE: case KEY_DEL: if ( cursor ) { memmove(cmdline+cursor-1, cmdline+cursor, len-cursor+1); len--; cursor--; redraw = 1; } break; case KEY_CTRL('D'): case KEY_DELETE: if ( cursor < len ) { memmove(cmdline+cursor, cmdline+cursor+1, len-cursor); len--; redraw = 1; } break; case KEY_CTRL('U'): if ( len ) { len = cursor = 0; cmdline[len] = '\0'; redraw = 1; } break; case KEY_CTRL('W'): if ( cursor ) { int prevcursor = cursor; while ( cursor && my_isspace(cmdline[cursor-1]) ) cursor--; while ( cursor && !my_isspace(cmdline[cursor-1]) ) cursor--; memmove(cmdline+cursor, cmdline+prevcursor, len-prevcursor+1); len -= (cursor-prevcursor); redraw = 1; } break; case KEY_LEFT: case KEY_CTRL('B'): if ( cursor ) { cursor--; redraw = 1; } break; case KEY_RIGHT: case KEY_CTRL('F'): if ( cursor < len ) { putchar(cmdline[cursor++]); } break; case KEY_CTRL('K'): if ( cursor < len ) { cmdline[len = cursor] = '\0'; redraw = 1; } break; case KEY_HOME: case KEY_CTRL('A'): if ( cursor ) { cursor = 0; redraw = 1; } break; case KEY_END: case KEY_CTRL('E'): if ( cursor != len ) { cursor = len; redraw = 1; } break; case KEY_F1: case KEY_F2: case KEY_F3: case KEY_F4: case KEY_F5: case KEY_F6: case KEY_F7: case KEY_F8: case KEY_F9: case KEY_F10: case KEY_F11: case KEY_F12: show_fkey(key); redraw = 1; break; default: if ( key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN-1 ) { if ( cursor == len ) { cmdline[len] = key; cmdline[++len] = '\0'; cursor++; putchar(key); prev_len++; } else { memmove(cmdline+cursor+1, cmdline+cursor, len-cursor+1); cmdline[cursor++] = key; len++; redraw = 1; } } break; } } } static inline int shift_is_held(void) { uint8_t shift_bits = *(uint8_t *)0x417; return !!(shift_bits & 0x5d); /* Caps/Scroll/Alt/Shift */ } static void print_timeout_message(int tol, int row, const char *msg) { char buf[256]; int nc = 0, nnc; const char *tp = msg; char tc; char *tq = buf; while ((size_t)(tq-buf) < (sizeof buf-16) && (tc = *tp)) { tp++; if (tc == '#') { nnc = sprintf(tq, "\2#15%d\2#14", tol); tq += nnc; nc += nnc-8; /* 8 formatting characters */ } else if (tc == '{') { /* Deal with {singular[,dual],plural} constructs */ struct { const char *s, *e; } tx[3]; const char *tpp; int n = 0; memset(tx, 0, sizeof tx); tx[0].s = tp; while (*tp && *tp != '}') { if (*tp == ',' && n < 2) { tx[n].e = tp; n++; tx[n].s = tp+1; } tp++; } tx[n].e = tp; if (*tp) tp++; /* Skip final bracket */ if (!tx[1].s) tx[1] = tx[0]; if (!tx[2].s) tx[2] = tx[1]; /* Now [0] is singular, [1] is dual, and [2] is plural, even if the user only specified some of them. */ switch (tol) { case 1: n = 0; break; case 2: n = 1; break; default: n = 2; break; } for (tpp = tx[n].s; tpp < tx[n].e; tpp++) { if ((size_t)(tq-buf) < (sizeof buf)) { *tq++ = *tpp; nc++; } } } else { *tq++ = tc; nc++; } } *tq = '\0'; /* Let's hope 4 spaces on each side is enough... */ printf("\033[%d;%dH\2#14 %s ", row, HSHIFT+1+((WIDTH-nc-8)>>1), buf); } /* Set the background screen, etc. */ static void prepare_screen_for_menu(void) { console_color_table = cm->color_table; console_color_table_size = menu_color_table_size; set_background(cm->menu_background); } static const char * do_hidden_menu(void) { int key; int timeout_left, this_timeout; clear_screen(); if ( !setjmp(timeout_jump) ) { timeout_left = cm->timeout; while (!cm->timeout || timeout_left) { int tol = timeout_left/CLK_TCK; print_timeout_message(tol, HIDDEN_ROW, cm->messages[MSG_AUTOBOOT]); this_timeout = min(timeout_left, CLK_TCK); key = mygetkey(this_timeout); if (key != KEY_NONE) return NULL; /* Key pressed */ timeout_left -= this_timeout; } } return cm->menu_entries[cm->defentry]->cmdline; /* Default entry */ } static const char * run_menu(void) { int key; int done = 0; volatile int entry = cm->curentry; int prev_entry = -1; volatile int top = cm->curtop; int prev_top = -1; int clear = 1, to_clear; const char *cmdline = NULL; volatile clock_t key_timeout, timeout_left, this_timeout; const struct menu_entry *me; /* Note: for both key_timeout and timeout == 0 means no limit */ timeout_left = key_timeout = cm->timeout; /* If we're in shiftkey mode, exit immediately unless a shift key is pressed */ if ( shiftkey && !shift_is_held() ) { return cm->menu_entries[cm->defentry]->cmdline; } else { shiftkey = 0; } /* Do this before hiddenmenu handling, so we show the background */ prepare_screen_for_menu(); /* Handle hiddenmenu */ if ( hiddenmenu ) { cmdline = do_hidden_menu(); if (cmdline) return cmdline; /* Otherwise display the menu now; the timeout has already been cancelled, since the user pressed a key. */ hiddenmenu = 0; key_timeout = 0; } /* Handle both local and global timeout */ if ( setjmp(timeout_jump) ) { entry = cm->defentry; if ( top < 0 || top < entry-MENU_ROWS+1 ) top = max(0, entry-MENU_ROWS+1); else if ( top > entry || top > max(0, cm->nentries-MENU_ROWS) ) top = min(entry, max(0, cm->nentries-MENU_ROWS)); draw_menu(cm->ontimeout ? -1 : entry, top, 1); cmdline = cm->ontimeout ? cm->ontimeout : cm->menu_entries[entry]->cmdline; done = 1; } while ( !done ) { if ( entry <= 0 ) { entry = 0; while (entry < cm->nentries && is_disabled(cm->menu_entries[entry])) entry++; } if ( entry >= cm->nentries ) { entry = cm->nentries-1; while (entry > 0 && is_disabled(cm->menu_entries[entry])) entry--; } me = cm->menu_entries[entry]; if ( top < 0 || top < entry-MENU_ROWS+1 ) top = max(0, entry-MENU_ROWS+1); else if ( top > entry || top > max(0, cm->nentries-MENU_ROWS) ) top = min(entry, max(0, cm->nentries-MENU_ROWS)); /* Start with a clear screen */ if ( clear ) { /* Clear and redraw whole screen */ /* Enable ASCII on G0 and DEC VT on G1; do it in this order to avoid confusing the Linux console */ if (clear >= 2) prepare_screen_for_menu(); clear_screen(); clear = 0; prev_entry = prev_top = -1; } if ( top != prev_top ) { draw_menu(entry, top, 1); display_help(me->helptext); } else if ( entry != prev_entry ) { draw_row(prev_entry-top+4+VSHIFT, entry, top, 0, 0); draw_row(entry-top+4+VSHIFT, entry, top, 0, 0); display_help(me->helptext); } prev_entry = entry; prev_top = top; cm->curentry = entry; cm->curtop = top; /* Cursor movement cancels timeout */ if ( entry != cm->defentry ) key_timeout = 0; if ( key_timeout ) { int tol = timeout_left/CLK_TCK; print_timeout_message(tol, TIMEOUT_ROW, cm->messages[MSG_AUTOBOOT]); to_clear = 1; } else { to_clear = 0; } this_timeout = min(min(key_timeout, timeout_left), (clock_t)CLK_TCK); key = mygetkey(this_timeout); if ( key != KEY_NONE ) { timeout_left = key_timeout; if ( to_clear ) printf("\033[%d;1H\1#0\033[K", TIMEOUT_ROW); } switch ( key ) { case KEY_NONE: /* Timeout */ /* This is somewhat hacky, but this at least lets the user know what's going on, and still deals with "phantom inputs" e.g. on serial ports. Warning: a timeout will boot the default entry without any password! */ if ( key_timeout ) { if ( timeout_left <= this_timeout ) longjmp(timeout_jump, 1); timeout_left -= this_timeout; } break; case KEY_CTRL('L'): clear = 1; break; case KEY_ENTER: case KEY_CTRL('J'): key_timeout = 0; /* Cancels timeout */ if ( me->passwd ) { clear = 1; done = ask_passwd(me->passwd); } else { done = 1; } cmdline = NULL; if (done) { switch (me->action) { case MA_CMD: cmdline = me->cmdline; break; case MA_SUBMENU: case MA_GOTO: case MA_EXIT: done = 0; clear = 2; cm = me->submenu; entry = cm->curentry; top = cm->curtop; break; case MA_QUIT: /* Quit menu system */ done = 1; clear = 1; draw_row(entry-top+4+VSHIFT, -1, top, 0, 0); break; default: done = 0; break; } } break; case KEY_UP: case KEY_CTRL('P'): while (entry > 0 && entry-- && is_disabled(cm->menu_entries[entry])) { if ( entry < top ) top -= MENU_ROWS; } if ( entry == 0 ) { while (is_disabled(cm->menu_entries[entry])) entry++; } break; case KEY_DOWN: case KEY_CTRL('N'): while (entry < cm->nentries-1 && entry++ && is_disabled(cm->menu_entries[entry])) { if ( entry >= top+MENU_ROWS ) top += MENU_ROWS; } if ( entry >= cm->nentries-1 ) { while (is_disabled(cm->menu_entries[entry])) entry--; } break; case KEY_PGUP: case KEY_LEFT: case KEY_CTRL('B'): case '<': entry -= MENU_ROWS; top -= MENU_ROWS; break; case KEY_PGDN: case KEY_RIGHT: case KEY_CTRL('F'): case '>': case ' ': entry += MENU_ROWS; top += MENU_ROWS; break; case '-': do { entry--; top--; } while (entry > 0 && is_disabled(cm->menu_entries[entry])); break; case '+': do { entry++; top++; } while (entry < cm->nentries-1 && is_disabled(cm->menu_entries[entry])); break; case KEY_CTRL('A'): case KEY_HOME: top = entry = 0; break; case KEY_CTRL('E'): case KEY_END: entry = cm->nentries - 1; top = max(0, cm->nentries-MENU_ROWS); break; case KEY_F1: case KEY_F2: case KEY_F3: case KEY_F4: case KEY_F5: case KEY_F6: case KEY_F7: case KEY_F8: case KEY_F9: case KEY_F10: case KEY_F11: case KEY_F12: show_fkey(key); clear = 1; break; case KEY_TAB: if ( cm->allowedit && me->action == MA_CMD ) { int ok = 1; key_timeout = 0; /* Cancels timeout */ draw_row(entry-top+4+VSHIFT, -1, top, 0, 0); if ( cm->menu_master_passwd ) { ok = ask_passwd(NULL); clear_screen(); draw_menu(-1, top, 0); } else { /* Erase [Tab] message and help text*/ printf("\033[%d;1H\1#0\033[K", TABMSG_ROW); display_help(NULL); } if ( ok ) { cmdline = edit_cmdline(me->cmdline, top); done = !!cmdline; clear = 1; /* In case we hit [Esc] and done is null */ } else { draw_row(entry-top+4+VSHIFT, entry, top, 0, 0); } } break; case KEY_CTRL('C'): /* Ctrl-C */ case KEY_ESC: /* Esc */ if ( cm->parent ) { cm = cm->parent; clear = 2; entry = cm->curentry; top = cm->curtop; } else if ( cm->allowedit ) { done = 1; clear = 1; key_timeout = 0; draw_row(entry-top+4+VSHIFT, -1, top, 0, 0); if ( cm->menu_master_passwd ) done = ask_passwd(NULL); } break; default: if ( key > 0 && key < 0xFF ) { key &= ~0x20; /* Upper case */ if ( cm->menu_hotkeys[key] ) { key_timeout = 0; entry = cm->menu_hotkeys[key]->entry; /* Should we commit at this point? */ } } break; } } printf("\033[?25h"); /* Show cursor */ /* Return the label name so localboot and ipappend work */ return cmdline; } int menu_main(int argc, char *argv[]) { const char *cmdline; struct menu *m; int rows, cols; int i; (void)argc; console_prepare(); if (getscreensize(1, &rows, &cols)) { /* Unknown screen size? */ rows = 24; cols = 80; } parse_configs(argv+1); /* Some postprocessing for all menus */ for (m = menu_list; m; m = m->next) { if (!m->mparm[P_WIDTH]) m->mparm[P_WIDTH] = cols; /* If anyone has specified negative parameters, consider them relative to the bottom row of the screen. */ for (i = 0; i < NPARAMS; i++) if (m->mparm[i] < 0) m->mparm[i] = max(m->mparm[i]+rows, 0); } if ( !cm->nentries ) { fputs("Initial menu has no LABEL entries!\n", stdout); return 1; /* Error! */ } cm = start_menu; for(;;) { cmdline = run_menu(); printf("\033[?25h\033[%d;1H\033[0m", END_ROW); console_cleanup(); if ( cmdline ) { execute(cmdline, KT_NONE); if ( cm->onerror ) execute(cm->onerror, KT_NONE); } else { return 0; /* Exit */ } console_prepare(); /* If we're looping... */ } } syslinux-legacy-3.63+dfsg/com32/menu/refstr.h0000664000175000017500000000212510777447273017561 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * refstr.h * * Simple reference-counted strings */ #ifndef REFSTR_H #define REFSTR_H #include #include static inline __attribute__((always_inline)) const char *refstr_get(const char *r) { if (r) ((unsigned int *)r)[-1]++; return r; } void refstr_put(const char *); char *refstr_alloc(size_t); const char *refstrdup(const char *); const char *refstrndup(const char *, size_t); int rsprintf(const char **, const char *, ...); int vrsprintf(const char **, const char *, va_list); #endif syslinux-legacy-3.63+dfsg/com32/menu/Makefile0000664000175000017500000000523310777447272017545 0ustar evanevan## ----------------------------------------------------------------------- ## ## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, ## Boston MA 02110-1301, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- ## ## Simple menu system ## TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \ then echo $(1); else echo $(2); fi; rm -f $$tmpf) M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,) CC = gcc LD = ld -m elf_i386 AR = ar NASM = nasm NASMOPT = -O9999 RANLIB = ranlib CFLAGS = $(M32) -mregparm=3 -DREGPARM=3 -W -Wall -march=i386 -Os \ -fomit-frame-pointer -D__COM32__ \ -nostdinc -iwithprefix include \ -I../libutil/include -I../include \ -Wp,-MT,$@,-MD,$(dir $@).$(notdir $@).d LNXCFLAGS = -W -Wall -O -g -I../libutil/include -D_GNU_SOURCE LNXSFLAGS = -g LNXLDFLAGS = -g SFLAGS = -D__COM32__ -march=i386 LDFLAGS = -T ../lib/com32.ld OBJCOPY = objcopy PPMTOLSS16 = ../ppmtolss16 LIBGCC := $(shell $(CC) --print-libgcc) LIBS = ../libutil/libutil_com.a ../lib/libcom32.a $(LIBGCC) LNXLIBS = ../libutil/libutil_lnx.a .SUFFIXES: .lss .c .o .elf .c32 .lnx BINDIR = /usr/bin LIBDIR = /usr/lib AUXDIR = $(LIBDIR)/syslinux INCDIR = /usr/include COM32DIR = $(AUXDIR)/com32 MODULES = menu.c32 vesamenu.c32 TESTFILES = COMMONOBJS = menumain.o readconfig.o passwd.o printmsg.o colors.o \ background.o refstr.o execute.o all: $(MODULES) $(TESTFILES) .PRECIOUS: %.o %.o: %.S $(CC) $(SFLAGS) -c -o $@ $< .PRECIOUS: %.o %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< .PRECIOUS: %.elf %.elf: %.o $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ .PRECIOUS: %.lo %.lo: %.S $(CC) $(LNXSFLAGS) -c -o $@ $< .PRECIOUS: %.lo %.lo: %.c $(CC) $(LNXCFLAGS) -c -o $@ $< .PRECIOUS: %.lnx %.lnx: %.lo $(LNXLIBS) $(CC) $(LNXLDFLAGS) -o $@ $^ %.c32: %.elf $(OBJCOPY) -O binary $< $@ menu.elf : menu.o $(COMMONOBJS) $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ vesamenu.elf : vesamenu.o $(COMMONOBJS) $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ tidy: rm -f *.o *.lo *.a *.lst *.elf .*.d clean: tidy rm -f *.lss *.c32 *.lnx *.com spotless: clean rm -f *~ \#* install: all mkdir -m 755 -p $(INSTALLROOT)$(AUXDIR) install -m 644 $(MODULES) $(INSTALLROOT)$(AUXDIR) -include .*.d syslinux-legacy-3.63+dfsg/com32/menu/printmsg.c0000664000175000017500000000475710777447273020127 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __COM32__ #include #endif #include "menu.h" static int draw_message_file(const char *filename) { FILE *f; int ch; enum msgname_state { st_init, /* Base state */ st_si_1, /* digit 1 */ st_si_2, /* digit 2 */ st_skipline, /* Skip until NL */ } state = st_init; int eof = 0; int attr = 0; f = fopen(filename, "r"); if (!f) return -1; /* Clear screen, hide cursor, default attribute */ printf("\033e\033%%@\033)0\033(B\3#%03d\033[?25l\033[2J\033[H", message_base_color+0x07); while (!eof && (ch = getc(f)) != EOF) { switch (state) { case st_init: switch (ch) { case '\f': fputs("\033[2J\033[H", stdout); break; case 15: /* SI */ state = st_si_1; break; case 24: state = st_skipline; break; case 26: eof = 1; break; case '\a': case '\n': case '\r': putchar(ch); break; default: if (ch >= 32) putchar(ch); break; } break; case st_si_1: attr = hexval(ch) << 4; state = st_si_2; break; case st_si_2: attr |= hexval(ch); printf("\3#%03d", attr+message_base_color); state = st_init; break; case st_skipline: if (ch == '\n') state = st_init; break; } } fclose(f); return 0; } int show_message_file(const char *filename, const char *background) { int rv = KEY_NONE; const char *old_background = NULL; if (background) { old_background = current_background; set_background(background); } if ( !(rv = draw_message_file(filename)) ) rv = mygetkey(0); /* Wait for keypress */ if (old_background) set_background(old_background); return rv; } syslinux-legacy-3.63+dfsg/com32/menu/execute.c0000664000175000017500000000354610777447272017720 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include #include #include #include "menu.h" void execute(const char *cmdline, enum kernel_type type) { com32sys_t ireg; const char *p, * const *pp; char *q = __com32.cs_bounce; const char *kernel, *args; memset(&ireg, 0, sizeof ireg); kernel = q; p = cmdline; while ( *p && !my_isspace(*p) ) { *q++ = *p++; } *q++ = '\0'; args = q; while ( *p && my_isspace(*p) ) p++; strcpy(q, p); if (kernel[0] == '.' && type == KT_NONE) { /* It might be a type specifier */ enum kernel_type type = KT_NONE; for (pp = kernel_types; *pp; pp++, type++) { if (!strcmp(kernel+1, *pp)) { execute(p, type); /* Strip the type specifier and retry */ } } } if (type == KT_LOCALBOOT) { ireg.eax.w[0] = 0x0014; /* Local boot */ ireg.edx.w[0] = strtoul(kernel, NULL, 0); } else { if (type < KT_KERNEL) type = KT_KERNEL; ireg.eax.w[0] = 0x0016; /* Run kernel image */ ireg.esi.w[0] = OFFS(kernel); ireg.ds = SEG(kernel); ireg.ebx.w[0] = OFFS(args); ireg.es = SEG(args); ireg.edx.l = type-KT_KERNEL; /* ireg.ecx.l = 0; */ /* We do ipappend "manually" */ } __intcall(0x22, &ireg, NULL); /* If this returns, something went bad; return to menu */ } syslinux-legacy-3.63+dfsg/com32/menu/passwd.c0000664000175000017500000000471010777447273017552 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include #include #include #include #include "menu.h" static int passwd_compare_sha1(const char *passwd, const char *entry) { const char *p; SHA1_CTX ctx; unsigned char sha1[20], pwdsha1[20]; SHA1Init(&ctx); if ( (p = strchr(passwd+3, '$')) ) { SHA1Update(&ctx, (void *)passwd+3, p-(passwd+3)); p++; } else { p = passwd+3; /* Assume no salt */ } SHA1Update(&ctx, (void *)entry, strlen(entry)); SHA1Final(sha1, &ctx); memset(pwdsha1, 0, 20); unbase64(pwdsha1, 20, p); return !memcmp(sha1, pwdsha1, 20); } static int passwd_compare_md5(const char *passwd, const char *entry) { const char *crypted = crypt_md5(entry, passwd+3); int len = strlen(crypted); return !strncmp(crypted, passwd, len) && (passwd[len] == '\0' || passwd[len] == '$'); } static int passwd_compare_sha256(const char *passwd, const char *entry) { const char *crypted = sha256_crypt(entry, passwd+3); int len = strlen(crypted); return !strncmp(crypted, passwd, len) && (passwd[len] == '\0' || passwd[len] == '$'); } static int passwd_compare_sha512(const char *passwd, const char *entry) { const char *crypted = sha512_crypt(entry, passwd+3); int len = strlen(crypted); return !strncmp(crypted, passwd, len) && (passwd[len] == '\0' || passwd[len] == '$'); } int passwd_compare(const char *passwd, const char *entry) { if ( passwd[0] != '$' || !passwd[1] || passwd[2] != '$' ) { /* Plaintext passwd, yuck! */ return !strcmp(entry, passwd); } else { switch (passwd[1]) { case '1': return passwd_compare_md5(passwd, entry); case '4': return passwd_compare_sha1(passwd, entry); case '5': return passwd_compare_sha256(passwd, entry); case '6': return passwd_compare_sha512(passwd, entry); default: return 0; /* Unknown encryption algorithm -> false */ } } } syslinux-legacy-3.63+dfsg/com32/menu/refstr.c0000664000175000017500000000376110777447273017563 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * refstr.c * * Simple reference-counted strings */ #include #include #include #include "refstr.h" /* Allocate space for a refstring of len bytes, plus final null */ /* The final null is inserted in the string; the rest is uninitialized. */ char *refstr_alloc(size_t len) { char *r = malloc(sizeof(unsigned int)+len+1); if (!r) return NULL; *(unsigned int *)r = 1; r += sizeof(unsigned int); r[len] = '\0'; return r; } const char *refstrndup(const char *str, size_t len) { char *r; if (!str) return NULL; len = strnlen(str, len); r = refstr_alloc(len); if (r) memcpy(r, str, len); return r; } const char *refstrdup(const char *str) { char *r; size_t len; if (!str) return NULL; len = strlen(str); r = refstr_alloc(len); if (r) memcpy(r, str, len); return r; } int vrsprintf(const char **bufp, const char *fmt, va_list ap) { va_list ap1; int len; char *p; va_copy(ap1, ap); len = vsnprintf(NULL, 0, fmt, ap1); va_end(ap1); *bufp = p = refstr_alloc(len); if ( !p ) return -1; return vsnprintf(p, len+1, fmt, ap); } int rsprintf(const char **bufp, const char *fmt, ...) { int rv; va_list ap; va_start(ap, fmt); rv = vrsprintf(bufp, fmt, ap); va_end(ap); return rv; } void refstr_put(const char *r) { unsigned int *ref; if (r) { ref = (unsigned int *)r - 1; if (!--*ref) free(ref); } } syslinux-legacy-3.63+dfsg/com32/menu/menu.c0000664000175000017500000000205210777447273017212 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston MA 02110-1301, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * menu.c * * Simple menu system which displays a list and allows the user to select * a command line and/or edit it. */ #include #include "menu.h" void console_prepare(void) { /* Nothing special to do */ } void console_cleanup(void) { /* Nothing special to do */ } int draw_background(const char *arg) { /* Nothing to do... */ (void)arg; return 0; } int main(int argc, char *argv[]) { console_ansi_raw(); return menu_main(argc, argv); } syslinux-legacy-3.63+dfsg/com32/menu/menu.c320000775000175000017500000014511410777447342017366 0ustar evanevanL!1L)t$g;vARPsXZ 1ÍL$qVSQƉy:ډUY[^aÐ`7UWVS,D$T$1t$C<#uPt$ hV3ƍl<{$1$1<,uBCCt<}uډ;$u$$ $$$$u$ $($$$|$t 1|$@1+$=wFEB9rFED$$+$=w `T$RTB()Rt$ h$q<[^_]à - wu$ 1YRKD=6/(!  ј2뗺 `єu܃ VSƅ`u PPLXPh;趍3PPLXPhF薍`LX9  }. uu CPPShRZ ºԉFt `;P~>CQQShR`;P~Z[^UWVS ƉՉˁ~1H1I9~ωٺ `蒌ƃ`)`` [^_]UWVSD$ ՋD$0D$D$4D$`D$ +X;`|1Bx 9u]tafPT,@Pt$hj `;`,(|")J1Ҹ3跈)z9uD$]D$|&uD$fD$D$aD$aA,uu3E t u D$>D$otY<^^uFފtZE$9uJD$s裇D$  xOu|$t ]D$N``;4~/|$~2D$9D$ |D$9D$ D$0[^_]D$0 [^_]D$<gUWVSD$ՉL$ 5``49D$D$6щЙÅA)ōW)ʉљPT$\\$W,T@PX@Ph‰`Tq,G`,()‹TH9~͍J|h`P,T@PXPh@` ,T@PXPh`TqC`T(J,)9~к装`XVVt$ t$ T$ C`4X9|Q,T@PShe`TqτC`T(J,)9~к|$ t`ltu ` 1I`RTB()R8XPh裇XZ`@h;茇,[^_]UWVS ǡ u׸ [^_]1|=vft f9slj1Eָ11-f)؋519|9wd訃)Ή5ufdf9vf)W [^_]WVSdFuY`p:\ؙ}ރ~@t1()`ptu`h@@[^_UWVSEe`()čD$EP0@PDXPhͅq@C`0 (9~PAPXD@Ph{ C`0 (9~PAPXDPh'q蚁C `(U싱06)‰H9~ϋDX$1PPFPBPSEQRh貄] 1!ǃ t1 uSu>5t=)u0;]v h0PK랃 h0=K;]w농G=x`+M䋐0⋀()Ѓ9SC*w:;]t3`t U'u}tUE&u1ee[^_UWVS<`tD$0xD$,pfD$:fD$:fD$8=t#]uhR@D$] =t"tD$4 fD$:duD$D$`hD$0D$,xT$,D$04@)9}D$0@+4y1D$,FT$,D$09T$,`)y19~&D$0D$(`)y1ҋD$(9}T$(T$,T$,tD$0`D$uD$0R@D$D$D$D$ D$07D$0 `` D$0@D$0D$09}D$0Qx tߋD$0``9|&FD$0HD$0D$0~D$0Sx tߋD$0S,D$,xT$,D$04@)9}D$0@+4y1D$,K <=$>"0K.&7' `3``NfD$:ffT$8fD$6f9wdzfD$8fT$6f)fD$8fD$:E u1~uD$FU Jw8$Pml$D$jE`tT$0xD$,D$<L$,D$0\$,WW`X)jjoD$D$ /T$0D$,9}D$,+4D$,D$0~ D$0HD$0D$0@tD$0Qx tD$0Q D$0@D$0D$0x tT$0D$,49| D$,ȉD$,D$09} D$0@D$0D$0HtD$0Sx tD$094S D$0HD$0D$0x tD$0`4)ЉD$0D$,)D$0`4D$0D$, `D$0HD$0D$,HD$,D$0D$0Qx ̋ ``KD$0@D$0D$,@D$,D$09lD$0Qx XD$0D$0``JL$0+4y1D$,!`l} fD$:L$,D$0T$,VVX)jj,`t%1T$,1ɃDu(PP8XPh4tz1D$,D$U`|_`1эqD$~ T$D$umL$9}1Ҹ``UP<XPhBy1Ҹ`` P<XPh[y|$(11à e*K hN y = 8=oM=&7="=#J='=)/7D$`_O)`_xON=95)a`wOօ`1t ؍X` vÅt @` wO)``xw))ljm_9`FC5C,xZ($([nZ\$$L$ZCD$Hn1Z$(4%> $(j$(,[^_]UWVSljFt< w)D$EkL$R`u.D$|u#VshD$$PY|$([u[^_]WVSø3L11h11ƣlp1҉5t Gu "=EG tu5wdS^tuabG_O u=d8htt qt \?uGG [^_ÐUWVSÉր8$u @t{$tډC^<4t_ <1W<5<6ES'D$1|$эqڋD$=^<$D$(rk$]Åt)D$(%k1ID$(%$T$(&$1߫|$&ډZcS7D$1|$эqڋD$m],SMD$1|$эqڋD$?]u31Ĭ[^_]UWVS ÉЅu1 -BWDžuRRPhvZ11tFr tSu|sPw$mWZS~NWB. PPPh?Z1ۃ u1ۉUcGi1Åtˉ؃ [^_]ÐUWVST$ $T$ T$T$ʁT$1\$#ȃt T$T$ څu1$!Àt D$ ؉ptD$(xEu[^_]WVSúT17YXCt@D7htӉ[^_UWVS OT1ۍ;XD;huӍhf1۽.PShUYl `؃`t3 QRPhFPC t뙉=j[^_]Sát Yt XZ[ЅtH@HBuUSÍ@JVu1PDZY[UWVS(ÉՉΉL$$Q11a\u WV>\[^_]ÃL$(L$T$$D$ WVSÅu1'1эqLDžt AV[^_WVSƅu1XÅt V[^_ÐUWVS.u7u3D$FWu T$D$E`u ufD$411҉ZfD$,9wfD$4fD$ft$؃fD$(f\$ED$,T$1ɸ"d<[^_]Ð g pRaRUWVSD$ff1d1T$D$Hydt @u3=t u*1Zdf)t fvtmftf9w^}h10dŊD$D<G ;{uSD$Tu/}SD$Tit D$[^_]Ð#Eg@@ܺ@ vT2@@@WVS \$ ‰SD$t$VF F ‰1ۉ?ACuu [^_SÆ[UWVSD$0T$PD$DT$0T$4L$0yL$8\$0[\$HD$0 D$D$9>D$k?1111D x%ƒ~;t$s KEEFGuɉ [^_]SЃ?`CIy[UWVSʼn1эq@56u\$D$ D$|$tT$L$ t<$u\$t&1.@ .L$T$.\$U&-L$T$--$k.ك~$D$t-ݍ$1%D$tt$w-uf$1$L$T$Z2D$D$T$Ƃ$T$t$-|$k%ـL$t $,؉1tD$L$T$,؉1t D$,|$D$t$,T$$D$-CNf1ۋD$@$$ $ ʹ|$$ $ ʹP$$ $ ʹ$$$ $ ʹ$$ $ ʹ$|$ث[^_]UWVSLÉϋD$ AD$(AD$0A D$HAD$AD$8AD$@AD$A A 9sA$\$T$\$1 %  щLLFu΃D$@$]űMMȉ1 111M$D9ul$ T$(T$,D$0D$4T$HT$t$D$8D$+@,h@0kA@4ك@8y!~@<[@H@L@@@D@P@TUWVS $׉΋APQT D$+D$9vōFXD$D$$1FPVTFPVTw=v6ƒ D$NP1ۉNP^TD$TT$D$7,$)vL$u%-FX$,$ǀw〉ڋ$s$tF^PnXD$v ?Àى^PFT [^_]UWVS,ʼnT$@PUTM@]DӉM@]D9wr9sEHULwovp)ÍMXL$Ɖٺ@)\$ M@]DΉ1˹ ډ1ۉ˹ ډ1 ډ1 $\$ L$ Ӊ\$ 1ۋD$ ȋT$  ȉD$ ډT$  ΋|$ D$t ؋T$D u@}D1EHUL ׉1˹ ډ1ۉ˹ ډ1 ډ1 1   ΋|$ t=X ؋T$D:D$D$$L$$t|1˹ ډ1ۉ˹ ډ1 ډ1 $\$ L$ Ӊ\$ 1ۋD$ ȋT$  ȉD$ ډT$  ΋|$$D$t ؋T$DG|$$ Ѓ,[^_]UWVS|`uduNU싅 UU:$u0B=ɚ;vɚ; =sƅDžƅv Dž1эAu Dž/A%)čD$Fu Dž5&)čD$xًًEًًًU @@@Ewr+t E@ AuэUo1 C;uh3)čL$ @@?hw~1CE9Írݍh)čD$ @.@?hwtً Eٺ@1t1tt E@ tUF;2My1ɺ` Ë}t) hdhy1PS)ǃ y1;v񋕌É)~$CIUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾Ѓ?CItNUE E ¾!Ѓ?CIu U 1N'Ѓ?A~CAt"DžCDUh11󪋽fX1҉ X1 t󪃽t󪋅e[^_WVSƉ1эyl9=} t&= 5 ډW[^_@@#Eg@@ܺ@ vT2UWVS\D$(xD$ D$p D$D$X D$D$@T T$*xj׉!؉! D$ V!! ˋT$$2p $!! ދD$(8ν!ȉ!  T$, |!؉! D$0*ƇG!! ˋT$42F0!! ދD$88F!ȉ!  T$< ؘi!؉! D$@D!! ˋT$D2[!! Ѝ,D$H8\!ȉ! Ѝ D$T$L "k!؋T$! t$D$Pq!T$! ҉T$D$T(Cy#D$! ՋT$XD$!I!!  ًT$ 2b%!!\$ D$΋D$48@@!! T$HQZ^&!ʉ! D$Ƕ!!  ًT$02]/։!! ΋D$D8SD!ډ! T$X؉!ʉ! D$,!!  ًT$@2!!! ΋D$T87É!ډ! T$( !ʉ! D$<ZE!!  ًT$P2㩉!! ,D$$8!ډ! T$8og!ʉ! D$LL*!!  ދD$0(B911D$<8q11ыD$H"am11ˋD$T0 811 ދD$ D꾤11D$,K11ыD$8`K11ˋD$D0p11 ދD$P~(11D$'11ыD$(0ԉ11ˋD$4011 ދD$@9ى11D$L11ыD$X|11ˋD$$0eVĉ11 ދD$D") 1؍0D$8*C 1 D$T# 1ЍD$009 1ȍ 4D$LY[e 1؍0D$( 1 D$D} 1ЍD$ 0] 1ȍ <D$<O~o 1؍8D$X, 1 D$4C 1Ѝ4D$P8N 1ȍ <0\$,~S 18D$H5: 1,D$$0* 1؍ (D$@8ӆ 1‹D$ȋ\$C ЉCD$ T$*1|$\[^_]UWVS ljT$͋@?G9sGG@)9s1;_ T$ډ^?t$@@9rS1ɍD)T$ [^_]sVSƉӋRT$ CD$?7w8x)*T$ ډX1҉[^Ðj 1Ðj 1ÐWS؉…t 1׉Z[_ÐD$EHtD$UWVS lj։͉ u 9u1C t Nۅt [^_]ÐVSƸ15rt +tau#wu BBB uŅtQhPVy1@Z[^ÐшD$D$5HtD$ÉY1bQjr zJÒbjr zbUWVSƉՉ1҉وJ[^_]UWVS Ӊ͉1,Eىutt t t )ÅuЉ [^_]ÐVStyHQ q:uZ9uYZrV !AA AH>u+Q9u!VQVFBFPFAFH [^ÐUWVS Ӊ͉1,Eىoutt t t )ÅuЉ [^_]ÐS )ʋt9v @9sB+QA AAA    [ÍvUWVStxX eq9r[C 9Ƌyir:Q)މpYH PB AxhQBQBoAxA I9u1[^_]ÐVSΉÉ1)‰uCANu[^ÐVW։ljsft_^ÐVW։ljsft_^ÐVWlj9rt1|9у_^ÐWVS$Ήiً<$$Z[^_ÃL$$L$T$ ÐUWVS ʼnT$uЃ [^_]m|$u p~\$9r 9N>9u39u.AD$9r!AFp QABAPL$N9rlC 9)ىJ^FBVBP r 9vBBBPOBBBP2D$Åu1GL$9v݉ [^_]ÃD$,D$ PL$8T$4D$0,ÃD$(D$ PL$4D$0],Ðu1@8uÐSÉъD$CA)‰u|$uZ[ÐSÉABu[Ð@Jt8u)ÐWVSωƉ)‰ut FAOu1[^_ÐVSƉˉ tABKu[^ÐSˉ tBAKu[ÐUWVS$ʼnT$L$ EL$8|$8t)U!u-uEL$8D$+uED$|$ uc|$8v#}0u$E|$`D$d1ɉT$`L$d 1҉D$`T$dNT$`L$dL$9L$lr D$L |$+|$l|$LD$<%D$Hu D$DmD$D\D$<@t%|$dyT$`L$dڃىT$ L$$D$`T$dD$ T$$1L$ \$$1D$4RPȉG uߋ\$< t|$4u G;D$X}D$X9}L$$ L$ uD$<u|$T1|$4D$TG|$TD$@u D$<uD$t |$@G|$tt |$4uD$t|$<u3D$t9D$\~)T$pL$\L$01;L$Ls BAL$0D$t9D$0~T$pL$\L$01Ʌt ;L$Ls(-"D$<t ;L$Ls+D$<t ;L$Ls BAt-|$4u&;L$Ls0BA;D$Ls|$H XBOu%|$@9|$0;L$Ls0BAL$0D$t9D$0T$@T$PL$@L$8׉ˋl$TiMuOK;\$Ls_L$@l$TMOK;\$Ls"D$4QQRPD$0T$4T$DL$@D$4QQRPD$0T$4D$ T$$|$@T$L9T$8s L$P AL$PD$8L$0D$<t |$t9|$0ыD$8D$pD$lU$$.u1I|$Xt ;L$X~L$X9L$\~w KfJ mt'wlsu1D$)D$;D$|D$HD$;D$|R\$K)FD$;D$|\$K\$D$)y1D$1RC;D$| D$H=y1SG@H;D$| L$Iy1;T$|\$K\$ЅL1EtR\$t$NPPSVى|$T$ J9PPKD$0RV1|$\$PPCPD$ HP11҉t$_XD$0SJR1rVVD$HPD$ HP1>t"t@;L$SSQD$ HPL$RRQHP1҉\$L$PPQD$ HP1҉t$1ht G$G,D$(|$ WD<1$tBB B BBBB B ~BuBlBcB ZBQBHB?hB3BB#BB@B B AT$(;J8D$G)W(O)L$o(G@\$(1#C0PЃ kG@ G@L$(A #10%s#10[%d;3H%s[?25hInitial menu has no LABEL entries! [?25h[%d;1HwidthpasswordmarginrowstabmsgrowcmdlinerowpasswordrowtimeoutrowhelpmsgrowhelpmsgendrowhshiftvshifthiddenrowZ^elsz<#m#L#L#m#z#L#    ,,,F-,-F-,,F-,,,-1X2X2R2C2X2R2C2 R4P3Yd%*s%s %s.%s %s%s%s%smenulabeltitledefaulthidepasswdshiftkeyonerrormasterincludebackground*msgcolormsgcolourseparatordisabledisabledindentbeginquitgotoexitstarthelpendtexttotaltimeoutontimeoutallowoptionsipappend.hidden.topnonelocalbootkernellinuxbsspxefdimagecombootcom32configautobootAutomatic boot in # second{,s}...Press [Tab] to edit optionsnotabmsgpasspromptPassword requirede%%@)0(B#%03d[?25l#%03d-F(F(F-F(FF-F(F!F(F(F(F(F(F(F(F(FF(FFmsg%02x1;%s3%d;4%dscreen1;36;44unselhotkey1;37;44hotsel1;7;37;40scrollbar31;40cmdmark1;36;40cmdlinepwdborder30;47pwdheader31;47pwdentrytimeout_msg1;37;401;30;44e@ #!2 )0@ :@RDJRZbl r| l V`;<=>?@ABCDHPKMIQGORS    !"#$%&'()     !"#$$"%&%+&/&'4'9'=(A(F)J[[AOP[[BOQ[[COR[[DOS[[E[15~[17~[18~[19~[20~[21~[23~[24~[5~[6~[1~[4~OF[2~[@[3~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/$1$./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz%s%zu$$5$rounds=./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/BD7q۵[V9Y?^[1$} Ut]rހܛtiGƝ̡ $o,-tJܩ\ڈvRQ>m1'Y GQcg)) '8!.m,M 8STs e jv.,r迢KfpK£Ql$օ5pjl7LwH'4 9JNOʜ[o.htocxxȄnjlPxqƀ$6$rounds=./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"(ט/Be#D7q/;Mۉ۵8H[V9YO?m^BؾopE[N1$} Uo{t]r;ހ5%ܛ&itJi%O8GՌƝew̡ $u+Yo,-ntJAܩ\SڈvfRQ>2-m1?!'Y= % GoQcpn g))/F '&&\8!.*Zm,M߳ 8ScTs ew< jvG.;5,rdL迢0BKfpK0TQlReU$* qW5ѻ2pjҸSAQl7LwH'Hᵼ4cZų 9ˊAJNscwOʜ[o.h]t`/CocxrxȄ9dnj(c#齂lPyƲ+SrxqƜa&>'!Ǹ}xnO}orgȢ}c ?G5 q}#w($@{2 ˾L*~e)Y:o_XGJDl(null)g¦bxʨϨب'8FW?IT^h0123456789ABCDEF0123456789abcdefptBDX0```````````````,,,,,,,,,,```````))))))!!!!!!!!!!!!!!!!!!!!``````******""""""""""""""""""""````0```````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!`!!!!!!!""""""""""""""""""""""""`"""""""" BB DXֿ#,55>GPYYYYYYYYeuٿ__ô³؜ОHPK HиH$syslinux-legacy-3.63+dfsg/com32/libutil/0000775000175000017500000000000010777447344016602 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/libutil/libutil_com.a0000664000175000017500000011066210777447336021255 0ustar evanevan! / 1207848670 0 0 0 246 ` :" :?B?B?BL.Uk:Bconsole_ansi_stdconsole_ansi_rawget_keySHA1Initmybase64SHA1TransformSHA1UpdateSHA1Finalunbase64MD5InitMD5UpdateMD5Finalcrypt_md5sha256_cryptsha512_cryptgenbase64ansiline.o/ 1207848669 1026 1026 100664 1196 ` ELF4(   $GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.1.rel.dtors.comment.note.GNU-stack43 l8 %h+h02hC|?  J.Sc   ] $ $->KWansiline.cconsole_cleanupconsole_ansi_stddev_ansiserial_wdev_stdcon_ropenconsolefputs   * /ansiraw.o/ 1207848669 1026 1026 100664 1192 ` ELF4(   $GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.1.rel.dtors.comment.note.GNU-stack43 h8 %h+h02hC|?  J.Sc   \ $ $,=JVansiraw.cconsole_cleanupconsole_ansi_rawdev_ansiserial_wdev_rawcon_ropenconsolefputs   * /get_key.o/ 1207848669 1026 1026 100664 2716 ` ELFH4( UWVSD$ff11T$D$Ht @u3= u*1f)t fvtmftf9w^1ŊD$D<G`;{uSD$u/}SD$it D$[^_];<=>?@ABCDHPKMIQGORS     ! $!'"*#-$0%3&6'9(<)?  $)/5;A G M S Y!]"a#e$i$n%r%w&{&'''(()[[AOP[[BOQ[[COR[[DOS[[E[15~[17~[18~[19~[20~[21~[23~[24~[5~[6~[1~[4~OF[2~[@[3~GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.rel.rodata.rodata.str1.1.comment.note.GNU-stack4 P % + 4  0  <2K.TdP  PB ` "'-;get_key.ckeycodesget_keytimesreaderrnosyslinux_idlememcmp / < F gp ht(4@LXdp| $0<HT`lxsha1hash.o/ 1207848669 1026 1026 100664 9384 ` ELF 4( #Eg@@ܺ@ vT2@@@WVS \$ ‰D$t$VF F ‰1ۉ? ACuu [^_SÆ[UWVSD$0T$PD$DT$0T$4L$0yL$8\$0[\$HD$0 D$D$9>D$k?1111D x%ƒ~;t$s KEEFGuɉ [^_]ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.rodata.comment.note.GNU-stack4 4 %+0A 8!.AOOQX  ) A"unbase64.c_base64charsunbase64memset 1md5.o/ 1207848669 1026 1026 100664 3248 ` ELF 4( @@#Eg@@ܺ@ vT2UWVS\D$(xD$ D$p D$D$X D$D$@T$*xj׉!؉! D$ V!! ˋT$$2p $!! ދD$(8ν!ȉ!  T$, |!؉! D$0*ƇG!! ˋT$42F0!! ދD$88F!ȉ!  T$< ؘi!؉! D$@D!! ˋT$D2[!! Ѝ,D$H8\!ȉ! Ѝ D$T$L "k!؋T$! t$D$Pq!T$! ҉T$D$T(Cy#D$! ՋT$XD$!I!!  ًT$ 2b%!!\$ D$΋D$48@@!! T$HQZ^&!ʉ! D$Ƕ!!  ًT$02]/։!! ΋D$D8SD!ډ! T$X؉!ʉ! D$,!!  ًT$@2!!! ΋D$T87É!ډ! T$( !ʉ! D$<ZE!!  ًT$P2㩉!! ,D$$8!ډ! T$8og!ʉ! D$LL*!!  ދD$0(B911D$<8q11ыD$H"am11ˋD$T0 811 ދD$ D꾤11D$,K11ыD$8`K11ˋD$D0p11 ދD$P~(11D$'11ыD$(0ԉ11ˋD$4011 ދD$@9ى11D$L11ыD$X|11ˋD$$0eVĉ11 ދD$D") 1؍0D$8*C 1 D$T# 1ЍD$009 1ȍ 4D$LY[e 1؍0D$( 1 D$D} 1ЍD$ 0] 1ȍ <D$<O~o 1؍8D$X, 1 D$4C 1Ѝ4D$P8N 1ȍ <0\$,~S 18D$H5: 1,D$$0* 1؍ (D$@8ӆ 1‹D$ȋ\$C ЉCD$ T$*1|$\[^_]UWVS ljT$͋@?G9sGG@)9s1;_ T$ډ^?t$@@9rS1ɍD)T$ [^_]VSƉӋRT$ CD$?7w8x)T$ ډX1҉[^GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.comment.note.GNU-stack4 p @% @ +@ 0@ .9n n IH  ( E*@*$+5Ip>md5.cMD5TransformPADDINGMD5InitmemcpyMD5UpdateMD5Finalmemsetd  |    E crypt-md5.o/ 1207848669 1026 1026 100664 2224 ` ELF4( SЃ? CIy[UWVSʼn1эqu\$D$ D$|$tT$L$ t<$u\$tL$T$\$L$T$$ك~$D$tݍ$1%D$tt$uf$1$L$T$D$D$T$Ƃ$T$t$|$ـL$t $؉1tD$L$T$؉1t D$|$D$t$T$$D$CNf1ۋD$@$$ $ ʹ|$$ $ ʹP$$ $ ʹ$$$ $ ʹ$$ $ ʹ$|$ث[^_]$1$./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.rodata.comment.note.GNU-stack4d  %+x 0` 8.A..Q8   Xp  @%0x<GFNV`icrypt-md5.c_crypt_to64itoa64.1482magic.1502passwd.1501crypt_md5strncmpMD5InitMD5UpdateMD5Finalmemcpy  @ G  JW_mr{ +?Usha256crypt.o/ 1207848669 1026 1026 100664 5604 ` ELFp4( UWVSLÉϋD$ AD$(AD$0A D$HAD$AD$8AD$@AD$A A 9sA$\$T$\$1 %  щLLFu΃D$@$]űMMȉ1 111M$D9ul$ T$(T$,D$0D$4T$HT$t$D$8D$m1'Y GQcg)) '8!.m,M 8STs e jv.,r迢KfpK£Ql$օ5pjl7LwH'4 9JNOʜ[o.htocxxȄnjlPxqƀGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.1.rodata.comment.note.GNU-stack4  d %, +, 02, ?@  G.P`P  Pf$`&fM6K]`@et @ X sha256crypt.csha256_process_blockKsha256_init_ctxsha256_process_bytessha256_finish_ctxfillbufsha256_crypt_rsha256_salt_prefixsha256_rounds_prefixb64tbuflen.2247buffer.2246memcpystrncmpstrtoulstrcspnmempcpystpncpysnprintferrnomemsetsha256_cryptrealloc0#E n y)  ' ,  ; i    H    ( `    E W        sha512crypt.o/ 1207848670 1026 1026 100664 8652 ` ELF4( UWVSTlj։L$QD$(T$,AQ D$pT$tAQ$$AQ$$A Q$D$8T$+@,h@0kA@4ك@8y!~@<[@H@L@@@D@P@TUWVS $׉΋APQT D$+D$9vōFXD$D$$1FPVTFPVTw=v6ƒ D$NP1ۉNP^TD$TT$D$,$)vL$u%-FX$,$ǀw〉ڋ$s$tF^PnXD$v ?Àى^PFT [^_]UWVS,ʼnT$@PUTM@]DӉM@]D9wr9sEHULwovp)ÍMXL$Ɖٺ\$ M@]DΉ1˹ ډ1ۉ˹ ډ1 ډ1 $\$ L$ Ӊ\$ 1ۋD$ ȋT$  ȉD$ ډT$  ΋|$ D$t ؋T$D u@}D1EHUL ׉1˹ ډ1ۉ˹ ډ1 ډ1 1   ΋|$ t=X ؋T$D:D$D$$L$$t|1˹ ډ1ۉ˹ ډ1 ډ1 $\$ L$ Ӊ\$ 1ۋD$ ȋT$  ȉD$ ډT$  ΋|$$D$t ؋T$DG|$$ Ѓ,[^_]UWVS|uuNU싅 U:$u0B=ɚ;vɚ; =sƅDžƅv Dž1эAu Dž/A%)čD$u Dž5&)čD$xًًEًًًU @@@Ewr+t E@ AuэUo1 C;uh3)čL$ @@?hw1CE9Írݍh)čD$ @@?hwtً Eٺ@1t1tt E@ tUF;2My1ɺË}t) hhy1PS)ǃ y1;v񋕌É)~$CIUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾Ѓ? CItNUE E ¾!Ѓ? CIu U 1N'Ѓ? A~ CA"DžCDUh11󪋽fX1҉X1t󪃽t󪋅e[^_WVSƉ1эyl9=}t&= 5 ډW[^_$%s%zu$$6$rounds=./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"(ט/Be#D7q/;Mۉ۵8H[V9YO?m^BؾopE[N1$} Uo{t]r;ހ5%ܛ&itJi%O8GՌƝew̡ $u+Yo,-ntJAܩ\SڈvfRQ>2-m1?!'Y= % GoQcpn g))/F '&&\8!.*Zm,M߳ 8ScTs ew< jvG.;5,rdL迢0BKfpK0TQlReU$* qW5ѻ2pjҸSAQl7LwH'Hᵼ4cZų 9ˊAJNscwOʜ[o.h]t`/CocxrxȄ9dnj(c#齂lPyƲ+SrxqƜa&>'!Ǹ}xnO}orgȢ}c ?G5 q}#w($@{2 ˾L*~e)Y:o_XGJDlGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.1.rodata.comment.note.GNU-stack4  %+02 ?` G`.P`   $`& 6BK#]e X t @`X sha512crypt.csha512_process_blockKsha512_init_ctxsha512_process_bytessha512_finish_ctxfillbufsha512_crypt_rsha512_salt_prefixsha512_rounds_prefixb64tbuflen.2507buffer.2506memcpystrncmpstrtoulstrcspnmempcpystpncpysnprintferrnomemsetsha512_cryptrealloc079[B G , 1 F Q k   * t ^sT_~ /gG'_?wW~xbase64.o/ 1207848670 1026 1026 100664 1076 ` ELF4( UWVS$ϊD$(>D$(?ы$`D$u1AD$D$L$Q A ƒ1?FEutGu*D$(tC=KD$(t C=C=+$؃[^_]ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.comment.note.GNU-stack4 % A +d0d.9Il   Abase64.ccharz.1361genbase64rsyslinux-legacy-3.63+dfsg/com32/libutil/crypt-md5.c0000664000175000017500000001056010777447272020574 0ustar evanevan/*- * Copyright (c) 2003 Poul-Henning Kamp * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include /* * UNIX password */ static char * _crypt_to64(char *s, uint32_t v, int n) { static const char itoa64[64] = "./0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; while (--n >= 0) { *s++ = itoa64[v&0x3f]; v >>= 6; } return s; } char * crypt_md5(const char *pw, const char *salt) { MD5_CTX ctx,ctx1; unsigned long l; int sl, pl; uint32_t i; uint8_t final[MD5_SIZE]; const char *sp; static char passwd[120]; /* Output buffer */ static const char magic[] = "$1$"; char *p; const int magic_len = sizeof magic - 1; int pwlen = strlen(pw); /* Refine the Salt first */ sp = salt; /* If it starts with the magic string, then skip that */ if (!strncmp(sp, magic, magic_len)) sp += magic_len; /* Compute the salt length: it stops at the first '$', max 8 chars */ for (sl = 0; sl < 8 && sp[sl] && sp[sl] != '$'; sl++) ; MD5Init(&ctx); /* The password first, since that is what is most unknown */ MD5Update(&ctx, pw, pwlen); /* Then our magic string */ MD5Update(&ctx, magic, magic_len); /* Then the raw salt */ MD5Update(&ctx, sp, sl); /* Then just as many characters of the MD5(pw,salt,pw) */ MD5Init(&ctx1); MD5Update(&ctx1, pw, pwlen); MD5Update(&ctx1, sp, sl); MD5Update(&ctx1, pw, pwlen); MD5Final(final, &ctx1); for (pl = pwlen; pl > 0; pl -= MD5_SIZE) MD5Update(&ctx, final, pl > MD5_SIZE ? MD5_SIZE : pl); /* Don't leave anything around in vm they could use. */ memset(final, 0, sizeof final); /* Then something really weird... */ for (i = pwlen; i; i >>= 1) if (i & 1) MD5Update(&ctx, final, 1); else MD5Update(&ctx, pw, 1); /* Now make the output string */ p = passwd; memcpy(p, magic, magic_len); p += magic_len; memcpy(p, sp, sl); p += sl; *p++ = '$'; MD5Final(final, &ctx); /* * and now, just to make sure things don't run too fast * On a 60 Mhz Pentium this takes 34 msec, so you would * need 30 seconds to build a 1000 entry dictionary... */ for (i = 0; i < 1000; i++) { MD5Init(&ctx1); if(i & 1) MD5Update(&ctx1, pw, pwlen); else MD5Update(&ctx1, final, MD5_SIZE); if(i % 3) MD5Update(&ctx1, sp, sl); if(i % 7) MD5Update(&ctx1, pw, pwlen); if(i & 1) MD5Update(&ctx1, final, MD5_SIZE); else MD5Update(&ctx1, pw, pwlen); MD5Final(final, &ctx1); } l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; p = _crypt_to64(p, l, 4); l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; p = _crypt_to64(p, l, 4); l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; p = _crypt_to64(p, l, 4); l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; p = _crypt_to64(p, l, 4); l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; p = _crypt_to64(p, l, 4); l = final[11]; p = _crypt_to64(p, l, 2); *p = '\0'; /* Don't leave anything around in vm they could use. */ memset(final, 0, sizeof final); return passwd; } #ifdef TEST #include int main(int argc, char *argv[]) { int i; for (i = 2; i < argc; i += 2) { puts(crypt_md5(argv[i], argv[i-1])); } return 0; } #endif syslinux-legacy-3.63+dfsg/com32/libutil/unbase64.c0000664000175000017500000000440010777447272020373 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2005-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * unbase64.c * * Convert a string in base64 format to a byte array. */ #include #include static const unsigned char _base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; size_t unbase64(unsigned char *buffer, size_t bufsiz, const char *txt) { unsigned int bits = 0; int nbits = 0; char base64tbl[256]; int i; char v; size_t nbytes = 0; memset(base64tbl, -1, sizeof base64tbl); for ( i = 0 ; _base64chars[i] ; i++ ) { base64tbl[_base64chars[i]] = i; } /* Also support filesystem safe alternate base64 encoding */ base64tbl['.'] = 62; base64tbl['-'] = 62; base64tbl['_'] = 63; while ( *txt ) { if ( (v = base64tbl[(unsigned char) *txt]) >= 0 ) { bits <<= 6; bits += v; nbits += 6; if ( nbits >= 8 ) { if ( nbytes < bufsiz ) *buffer++ = (bits >> (nbits-8)); nbytes++; nbits -= 8; } } txt++; } return nbytes; } syslinux-legacy-3.63+dfsg/com32/libutil/base64.c0000664000175000017500000000305210777447272020032 0ustar evanevan/* * Output a base64 string. * * Options include: * - Character 62 and 63; * - To pad or not to pad. */ #include #include size_t genbase64(char *output, const void *input, size_t size, int flags) { static char charz[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_"; uint8_t buf[3]; int j; const uint8_t *p; char *q; uint32_t bv; int left = size; charz[62] = (char)flags; charz[63] = (char)(flags >> 8); p = input; q = output; while (left > 0) { if (left < 3) { buf[0] = p[0]; buf[1] = (left > 1) ? p[1] : 0; buf[2] = 0; p = buf; } bv = (p[0] << 16) | (p[1] << 8) | p[2]; p += 3; left -= 3; for ( j = 0 ; j < 4 ; j++ ) { *q++ = charz[(bv >> 18) & 0x3f]; bv <<= 6; } } switch (left) { case -1: if (flags & BASE64_PAD) q[-1] = '='; else q--; break; case -2: if (flags & BASE64_PAD) q[-2] = q[-1] = '='; else q -= 2; break; default: break; } *q = '\0'; return q-output; } #ifdef TEST #include #include int main(int argc, char *argv[]) { int i; char buf[4096]; int len, bytes; for (i = 1; i < argc; i++) { printf("Original: \"%s\"\n", argv[i]); len = strlen(argv[i]); bytes = genbase64(buf, argv[i], len, BASE64_MIME|BASE64_PAD); printf(" MIME: \"%s\" (%d)\n", buf, bytes); bytes = genbase64(buf, argv[i], len, BASE64_SAFE); printf(" Safe: \"%s\" (%d)\n", buf, bytes); } return 0; } #endif syslinux-legacy-3.63+dfsg/com32/libutil/ansiraw.c0000664000175000017500000000516110777447272020415 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * ansiraw.c * * Configures the console for ANSI output in raw mode; versions * for COM32 and Linux support. */ #ifdef __COM32__ #include #include #include static void __attribute__((destructor)) console_cleanup(void) { /* For the serial console, be nice and clean up */ fputs("\033[0m\033[20l", stdout); } void console_ansi_raw(void) { openconsole(&dev_rawcon_r, &dev_ansiserial_w); fputs("\033[0m\033[20h", stdout); } #else #include #include static struct termios original_termios_settings; static void __attribute__((constructor)) console_init(void) { tcgetattr(0, &original_termios_settings); } static void __attribute__((destructor)) console_cleanup(void) { fputs("\033[0m\033[20l", stdout); tcsetattr(0, TCSANOW, &original_termios_settings); } void console_ansi_raw(void) { struct termios tio; /* Disable stdio buffering */ setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL); /* Set the termios flag so we behave the same as libcom32 */ tcgetattr(0, &tio); tio.c_iflag &= ~ICRNL; tio.c_iflag |= IGNCR; tio.c_lflag &= ~(ISIG|ICANON|ECHO); tio.c_cc[VMIN] = 0; tio.c_cc[VTIME] = 1; /* Don't 100% busy-wait in Linux */ tcsetattr(0, TCSAFLUSH, &tio); fputs("\033[0m\033[20h", stdout); } #endif syslinux-legacy-3.63+dfsg/com32/libutil/md5.c0000664000175000017500000002101510777447272017432 0ustar evanevan/* * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm * * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All * rights reserved. * * License to copy and use this software is granted provided that it * is identified as the "RSA Data Security, Inc. MD5 Message-Digest * Algorithm" in all material mentioning or referencing this software * or this function. * * License is also granted to make and use derivative works provided * that such works are identified as "derived from the RSA Data * Security, Inc. MD5 Message-Digest Algorithm" in all material * mentioning or referencing the derived work. * * RSA Data Security, Inc. makes no representations concerning either * the merchantability of this software or the suitability of this * software for any particular purpose. It is provided "as is" * without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this * documentation and/or software. * * This code is the same as the code published by RSA Inc. It has been * edited for clarity and style only. */ #include #include #include static void MD5Transform(uint32_t [4], const unsigned char [64]); #define Encode memcpy #define Decode memcpy static unsigned char PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* F, G, H and I are basic MD5 functions. */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. * Rotation is separate from addition to prevent recomputation. */ #define FF(a, b, c, d, x, s, ac) { \ (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } /* MD5 initialization. Begins an MD5 operation, writing a new context. */ void MD5Init (MD5_CTX *context) { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. */ context->state[0] = 0x67452301; context->state[1] = 0xefcdab89; context->state[2] = 0x98badcfe; context->state[3] = 0x10325476; } /* * MD5 block update operation. Continues an MD5 message-digest * operation, processing another message block, and updating the * context. */ void MD5Update (MD5_CTX *context, const void *in, size_t inputLen) { unsigned int i, idx, partLen; const unsigned char *input = in; /* Compute number of bytes mod 64 */ idx = (unsigned int)((context->count[0] >> 3) & 0x3F); /* Update number of bits */ if ((context->count[0] += ((uint32_t)inputLen << 3)) < ((uint32_t)inputLen << 3)) context->count[1]++; context->count[1] += ((uint32_t)inputLen >> 29); partLen = 64 - idx; /* Transform as many times as possible. */ if (inputLen >= partLen) { memcpy((void *)&context->buffer[idx], (const void *)input, partLen); MD5Transform (context->state, context->buffer); for (i = partLen; i + 63 < inputLen; i += 64) MD5Transform (context->state, &input[i]); idx = 0; } else i = 0; /* Buffer remaining input */ memcpy ((void *)&context->buffer[idx], (const void *)&input[i], inputLen-i); } /* * MD5 padding. Adds padding followed by original length. */ static void MD5Pad (MD5_CTX *context) { unsigned char bits[8]; unsigned int idx, padLen; /* Save number of bits */ Encode (bits, context->count, 8); /* Pad out to 56 mod 64. */ idx = (unsigned int)((context->count[0] >> 3) & 0x3f); padLen = (idx < 56) ? (56 - idx) : (120 - idx); MD5Update (context, PADDING, padLen); /* Append length (before padding) */ MD5Update (context, bits, 8); } /* * MD5 finalization. Ends an MD5 message-digest operation, writing the * the message digest and zeroizing the context. */ void MD5Final (unsigned char digest[16], MD5_CTX *context) { /* Do padding. */ MD5Pad (context); /* Store state in digest */ Encode (digest, context->state, 16); /* Zeroize sensitive information. */ memset ((void *)context, 0, sizeof (*context)); } /* MD5 basic transformation. Transforms state based on block. */ static void MD5Transform (state, block) uint32_t state[4]; const unsigned char block[64]; { uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; Decode (x, block, 64); /* Round 1 */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ /* Round 2 */ #define S21 5 #define S22 9 #define S23 14 #define S24 20 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ #define S31 4 #define S32 11 #define S33 16 #define S34 23 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ #define S41 6 #define S42 10 #define S43 15 #define S44 21 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; /* Zeroize sensitive information. */ memset ((void *)x, 0, sizeof (x)); } syslinux-legacy-3.63+dfsg/com32/libutil/ansiline.c0000664000175000017500000000502610777447272020553 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * ansiline.c * * Configures the console for ANSI output in line mode; versions * for COM32 and Linux support. */ #ifdef __COM32__ #include #include #include static void __attribute__((destructor)) console_cleanup(void) { /* For the serial console, be nice and clean up */ fputs("\033[0m\033[20l", stdout); } void console_ansi_std(void) { openconsole(&dev_stdcon_r, &dev_ansiserial_w); fputs("\033[0m\033[20h", stdout); } #else #include #include static struct termios original_termios_settings; static void __attribute__((constructor)) console_init(void) { tcgetattr(0, &original_termios_settings); } static void __attribute__((destructor)) console_cleanup(void) { fputs("\033[0m\033[20l", stdout); tcsetattr(0, TCSANOW, &original_termios_settings); } void console_ansi_std(void) { struct termios tio; /* Disable stdio buffering */ setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL); /* Set the termios flag so we behave the same as libcom32 */ tcgetattr(0, &tio); tio.c_iflag &= ~ICRNL; tio.c_iflag |= IGNCR; tio.c_cflag |= ICANON|ECHO; tcsetattr(0, TCSANOW, &tio); fputs("\033[0m\033[20h", stdout); } #endif syslinux-legacy-3.63+dfsg/com32/libutil/libutil_lnx.a0000664000175000017500000032700210777447337021277 0ustar evanevan! / 1207848671 0 0 0 246 ` :0LfLfLfLfLf:jconsole_ansi_stdconsole_ansi_rawget_keySHA1Initmybase64SHA1TransformSHA1UpdateSHA1Finalunbase64MD5InitMD5UpdateMD5Finalcrypt_md5sha256_cryptsha512_cryptgenbase64ansiline.lo/ 1207848670 1026 1026 100664 5928 ` ELF 4(UD$$USTD$$D$$D$$]\$$E EM \$D$$D$ D$ D$$T[]UD$ D$ D$$ D$D$$% : ; I$ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/ .: ; ' @.? : ; ' @4: ; I 4: ; I 4: ; I? < jP0p=9RintW8a\Kopm%-|Z#### #n#=### #$#(0 #,"#0U$#4&Z#8 *Z#<,z#@0>#D1L#Ff2#G6#H?#LH#TI#XJ#\ K#`KL%#dNZ#hP#l !}  # # Z#t  m  ' 7.00{<  # !# ^"# ## )$# K%{# &#4 '#8   =(I,tioJ BX:d6 /usr/include/bits/usr/include/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includeansiline.ctermios.hstdio.hlibio.htypes.hstddef.h<g= .xKKM0Ku%jfg%| AB AB DIAB ttuttuttu#console_ansi_std_IO_buf_end_flags2_old_offsetc_ispeedc_line_IO_save_end_IO_write_endc_ccsize_tlong long unsigned int_IO_write_ptr_flagsshort int_markers_IO_read_end_unused2tcflag_tc_lflagansiline.ctermioslong long int_lockc_oflaglong int_cur_columnconsole_cleanup_posc_ospeed_sbuf_IO_FILEspeed_tstdoutunsigned char__pad5signed charc_cflag_shortbufunsigned int_IO_marker_IO_backup_base__pad2_IO_write_base_vtable_offsetshort unsigned intcharoriginal_termios_settingsc_iflag_next__pad1__pad3__pad4__quad_tconsole_initconsole_ansi_stdlong unsigned int__off64_t_chain__off_tstdin/home/hpa/syslinux/release/syslinux-3.63/com32/libutil_IO_buf_base_mode_IO_read_base_IO_save_baseGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)_fileno_IO_read_ptrcc_tstderr_offset_IO_lock_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.ctors.rodata.str1.1.rel.dtors.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %D+`< 0`BJ> R_N b@^  i2D|Xx  \` 0@' g  0, .  ,  <  3I CM^dkryansiline.cconsole_initoriginal_termios_settingsconsole_cleanuptcgetattrconsole_ansi_stdstdinsetbufstdoutstderrtcsetattrfwrite ,4AIV^q    !&18?FMTbip{#2AP_n}"1@O^ny '5CQ_m04LPansiraw.lo/ 1207848670 1026 1026 100664 5932 ` ELF 4(UD$$USTD$$D$$D$$]\$$E EeEE\$D$$D$ D$ D$$T[]UD$ D$ D$$ D$D$$% : ; I$ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/ .: ; ' @.? : ; ' @4: ; I 4: ; I 4: ; I? < iP0vC8XintW"8a[Jovm+-|Z#### #n#=### #$#(0 #,"#0T$#4&Z#8 *Z#<,z#@0>#D1L#Fl2#G6#H?#L H#TI#XJ#\K#`QL%#dNZ#hP#l   # %# Z#t  m  ' 7400{<  # !# d"# ## )$# K%{# &#4 '#8   +=I,tioJ BX:c< /usr/include/bits/usr/include/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includeansiraw.ctermios.hstdio.hlibio.htypes.hstddef.h<g= .xKKM0KKKu%hfg%| AB AB DIAB ttuttuttu#console_ansi_raw_IO_buf_end_flags2_old_offsetc_ispeedc_line_IO_save_end_IO_write_endc_ccsize_tlong long unsigned int_IO_write_ptr_flagsconsole_ansi_rawshort int_markers_IO_read_end_unused2tcflag_tc_lflagtermioslong long int_lockc_oflaglong int_cur_columnconsole_cleanup_posc_ospeed_sbuf_IO_FILEspeed_tstdoutunsigned char__pad5signed charc_cflag_shortbufunsigned int_IO_marker_IO_backup_base__pad2_IO_write_base_vtable_offsetansiraw.cshort unsigned intcharoriginal_termios_settingsc_iflag_next__pad1__pad3__pad4__quad_tconsole_initlong unsigned int__off64_t_chain__off_tstdin/home/hpa/syslinux/release/syslinux-3.63/com32/libutil_IO_buf_base_mode_IO_read_base_IO_save_baseGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)_fileno_IO_read_ptrcc_tstderr_offset_IO_lock_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.ctors.rodata.str1.1.rel.dtors.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %L+`< 0`BJ> R_N bD^  i2H|\x  `` 0D' k  0+ .  0  <  2I BL]cjqxansiraw.cconsole_initoriginal_termios_settingsconsole_cleanuptcgetattrconsole_ansi_rawstdinsetbufstdoutstderrtcsetattrfwrite ,4AIV^q   !&18?FMTbip{#2AP_n}"1@O^ny '5CQ_m04LPget_key.lo/ 1207848670 1026 1026 100664 7204 ` ELF04(UWVS,} ] $EE$D$UT$$t8 t&ux$+utC$H gfff)ƒ9~+} t;u } ft 9u t&K$EEDE`UU܋M؋A9uu܋y9ۉ8u)U؋C9}u܋M؋y9ۉ8}tE 맸 EE,[^_]% : ; I$ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/ : ; I8 &I.? : ; ' I@: ; I: ; I4: ; I 4: ; I4: ; I4: ; I 4: ; I U4: ; I4: ; I? < St\$0@T- int8a}o@k1K-MZ###C# v#h#2### #$#(Y #,:"#0$#4&Z#8T*Z#<?,z#@0>#D+1L#F2#G'6#H?#LH#TI#XJ#\K#`L%#dpNZ#hP#l   # b# Z#    '=5 - f.Z# v/Z# seq05#;7yZtfx,xL+zdnc{Zli{Zrv{Zkc| uXQ}Zch~7uk!u` 7  & 667` /usr/include/usr/include/bits/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includeget_key.cstdio.hlibio.htypes.hstddef.htime.h >"-[xuoffK;<=>?@ABCDHPKMIQGORS     ! $!'"*#-$0%3&6'9(<)?  $)/5;A G M S Y!]"a#e$i$n%r%w&{&'''(()[[AOP[[BOQ[[COR[[DOS[[E[15~[17~[18~[19~[20~[21~[23~[24~[5~[6~[1~[4~OF[2~[@[3~| tAB FtttuKKtu%%tu %pSIYPbnPP%V)0VKqVW@get_keytbbh_shortbufshort int_IO_lock_t_IO_buf_endbuffer_IO_write_endunsigned int_flags_flags2GNU C 4.1.2 20070925 (Red Hat 4.1.2-33)keycode_posstdout_unused2stdinlong long unsigned int_IO_backup_base_offsetclock_t_fileno__pad3/home/hpa/syslinux/release/syslinux-3.63/com32/libutilsize_t_vtable_offset_markers_IO_read_baseanother_IO_save_endcodechar_mode_IO_write_base_IO_read_ptrtimeout_IO_markerlong long int_IO_save_base__quad_t__pad1__pad2__pad4__pad5__clock_tget_key_IO_read_endget_key.clong intkeycodesstart_locklong unsigned int_old_offset_IO_FILEunsigned char_sbuf_IO_write_ptrseqlen__off_tsigned charshort unsigned intlateness_chainFILE_cur_column_next__off64_t_IO_buf_baseGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.rodata.rodata.str1.1.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack@t \P%+0LBW> RWN <b@ ^ D j24 } 4y        0/ .??h S `    t").?Gget_key.ckeycodesget_keytimesfilenoread__errno_locationsysconfsched_yield,CUj N  !&18?FMTbip{ *9HWfu )8GVet FQUY f ku z   '3 =Jh t               ( 4 @ L X d p |              $ 0 < H T ` l x            sha1hash.lo/ 1207848670 1026 1026 100664 20520 ` ELFD4(UE#Eg@@ܺ@ vT2@@@]UWVS UEߋBEBEB EBEEuFV V щ? uu [^_]UWVSlE $ >   I : ;  : ;I8 : ; : ; I8 I !I/  : ; .? : ; ' @: ; I .? : ; ' I@: ; I4: ; I 4: ;I4: ;I4: ;I 4: ; I : ;  : ; I 4: ; I 4: ; I &I: ; I4: ; I? < R(6T0TLint8asoTm-jZ##f#b# ##F### #$#(p #,|"#0$#4A&Z#8*Z#<,z#@ 0>#D'1L#F2#G|6#H?#L)H#T0I#X7J#\>K#`EL%#dNZ#hP#l   }# # Z#t  m  '17a40 7  6\ 6# F# ? V# F  V  f7 ?6 8f98,_9X?WiZjZxp9qbvQh [m O wvs&uw?u}awbwcw=dwew@xcyVlz{|ux"3__v0ux__x0J__v0ux__x0r__v0ux__x0{__v0ux__x0__v0ux__x0Rl__v0ux__x0__v0ux__x0:3P__v0ux__x0b__v0ux__x08__v0ux__x0__v0ux__x0 '__v0ux__x0__v0ux__x0*__v0ux__x0Rs__v0ux__x0__v0ux__x07  qs&G'B n } len i j RG'R( _R7 יb i Id7 h @X } x ./include/usr/include/usr/include/bits/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includesha1hash.csha1.hstdint.hstdio.hlibio.htypes.hstddef.hhguuuu. =:ӊv~ h<g%ɹ4use"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_| 8AB 8AB F%AB Is&AB FG' AB Ftt8u89t9;t;u8mmumSmmWmxRRtts&uuxCuyC3uz3uzuzuzuz uz uz J uzJ I uzI uzuz!uz!*uz*buzbquzquzuz{uz{uzuzuzguzgpuzpuz uz !uz!"uz"$uz$%uz%s&uzuxu|u| u|  u| du|dPu|P u| u| u| u| 4u|4?u|?u|u|u|u|fu|fyu|yu| u} u}u}u}u}Vu}VY u}Y !u}!d"u}d"#u}#$u}$%u}%s&u}luxlRuyRuyuyuyuy uy  uy T uyT Y uyY uy uy$uy$0uy0uyquyquyuysuysuyuyuymuymvuyvuyuy#!uy#!"uy"3#uy3#$$uy$$b%uyb%s&uyuxu{$u{$u{uu{usu{su{ u{ u{ u{ : u{: Cu{Cu{u{u{u{bu{buu{uu{u{u|u|u|u|au|aeu|e u| !u|!"u|"#u|#$u|$%u|%s&u|~{u}{u}u}u~u~Au~A' u~' q u~q c u~c u~ u~ 0u~03u~3u~u~u~u~ju~ju~u~u~u~|u~|u~u~J u~J 2!u~2!U"u~U"B#u~B#$u~$q%u~q%s&u~s&t&tt&v&tv&G'us&&&G'us&&&'u 'G's&&&G'u&D'V&&Q'-'QG'H'tH'J'tJ'R(uG'^'^'O(VO(R(uG'^'^'N(SN(R(u [''R'R(RWqSHA1Initmybase64OSHA1TransformSHA1UpdateSHA1FinalR(_shortbuf_IO_lock_tinput_IO_buf_end_vtable_offsetSHA1_CTXbuffer_IO_write_endunsigned intuint32_t_flagsSHA1Update_markersshort intGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)_posstdoutCHAR64LONG16countlong long unsigned intSHA1Final_offset/home/hpa/syslinux/release/syslinux-3.63/com32/libutilsha1hash.c_filenofinalcountsize_toutput_IO_read_base_IO_save_end_next_IO_write_ptrchar_modeuint8_t_IO_write_base_IO_read_ptrdata_IO_markerlong long int_IO_save_basecontextmybase64charz_IO_buf_base__quad_t_IO_backup_base__pad1__pad2__pad3__pad4__pad5short unsigned intdigest_IO_read_endlong int_locklong unsigned int_old_offsetstdin_IO_FILESHA1Initunsigned char_sbufSHA1Transformstateblock__off_tsigned char_chain_flags2_cur_column__off64_t_unused2GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4R( Jp%(+(0(B.*> KR2|N O^2B4m`4a y4u OP p5 @[ Pv@  P0@(C.CCH @J_  A    #8,85%Cs&NUG' sha1hash.coutput.3859charz.3857SHA1Initmybase64SHA1TransformSHA1UpdatememcpySHA1Finali &&';'' '' '' !&18?FMTbip{#2AP_n}"1@O^ny (gw~     # (4U\`d iw     '+OSw{?Cgk /3SW        # (2 ? D~ 0 4P Tp t unbase64.lo/ 1207848670 1026 1026 100664 3724 ` ELF4(UWVS}]D$D$$Auƅ">ƅ!>ƅS?Džt`Džx2~!9E v NCu[^_]% : ; I$ > $ >  I&I.? : ; ' I@: ; I : ; I 4: ; I 4: ; I 4: ; I I!I/ i0mmintRWzFT/0)%(0,#(%W txt(L **0 +E ,6} i-E v.W f/%u}^ FW7 V^7@ %gF\ /usr/lib/gcc/x86_64-redhat-linux/4.1.2/includeunbase64.cstddef.h(  ʟuuv%=g=Yuw<ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/| AB Ittu::Wuu ::SuSu}RRV:}RRPPmunbase64size_tunbase64short unsigned intbufsizbitslong long unsigned intunsigned charlong unsigned intnbytesunsigned intcharbuffer_base64charslong long intnbitsGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intunbase64.cbase64tbllong intsigned char/home/hpa/syslinux/release/syslinux-3.63/com32/libutilGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4  % + 0 Bm> , 0RJN \^A j$4f d wX2 t  |0:.11 0  ) A    "unbase64.c_base64charsunbase64memset,J  !&18?X_fmt{        !Wc i md5.lo/ 1207848670 1026 1026 100664 10048 ` ELF4(UE@@#Eg@@ܺ@ vT2]UWVSxp M$xJtZpJ lZhJdZ`J\Z XJ$TZ(PJ,LZ0HJ4DZ8@R< $ >  : ;  : ; I8 I!I/ .? : ; ' @ : ; I  I .: ; ' @ : ; I4: ; I4: ; I &I: ; I4: ; I4: ; I &.: ; ' : ; I4: ; I4: ; I1X Y 1 41 41 `.0intx8AX40X" ##T$#)%#77S7?p& %R1 aQ%  1v , X Zka~bcdx  S7 CJdv P  ac%incC Oc% ie0@ idxe0S 0e0| fup Iia%4idx00S7 P ' a% J^ W^ bupm x$ S9&x ./include/usr/include/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includemd5.cmd5.hstdint.hstddef.hgguuu.h#3&$$3%*$&**/""2""2"%()%&)"*h/=?/~i0KY .nֽK?f[u| 1AB 1E AB Iv AB FP AB Ett1u12t24t4v u1c P1RSSSSS!S.1S14S4SWWW]`W`bWbWWWxWWW%W%(R.7uQQ*Q25Q57Q7QQQQQQmpRpsRsyQRRQpsRsvRv|QRRQhkRkmRs u~ RRuRRu=@V@BVBVVVWVfiVikVkVRRuWWWWWxWWWWWWHWPSWUWRRRuRURUXRX^VRRVA s V@,W;>W>@W@WWWbWruRuwRzuSSSSS5SDGSGJSJSSSvSvyVy|V|VVV^VfiVikVkVVV.V69V;VRRV(+R+.R.4WRRW$ ' R' * R* 0 WC VVVVVVAVPSVSUVRRuRRu#R#%R(uRRNuNQRQWRW]uSSDSLOSOQSQSSSSS!SRRS  R RSRRS R R  Sv w tw y ty P uv  P uv  P u v  P u M V Q  Q' 6 Q N WP Q tQ S tS uP w w V uP w w S u o R~ P P5MD5InitMD5UpdateMD5Final MD5Finalstatesize_tpadLenshort intdigestmd5.cbitsPADDINGlong long intinputLenlong intcontextMD5PadMD5_CTXunsigned charsigned charlong long unsigned intuint32_tunsigned intMD5TransforminputMD5Initshort unsigned intchar/home/hpa/syslinux/release/syslinux-3.63/com32/libutilbufferpartLenlong unsigned intMD5UpdatecountblockGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4  X$0% @ +` 0` xB > $XR|N &bt^ &@ oB ~B9z (' {  0'0#.QQ"` $E1E @   1$v .5P >md5.cMD5TransformPADDINGMD5InitMD5UpdatememcpyMD5Finalmemset D      !&18?MT[bipw~  07;? DN S] j w        ! &0 5OXcy      0 4P Tp tcrypt-md5.lo/ 1207848670 1026 1026 100664 6012 ` ELF4(UWVSljӉΉȃx%؃? 9u<9[^_]UWVS] }у0޿(8u (t(t<$u]$0$D$UT$$D$D$$ t$(D$$D$$T$ED$$ T$(D$$$T$ED$$\$4$$~8$4u؃~D$|$4$Dž4Dž8Dž<Dž@tGtD$4D$E$D$UT$E$uf$1$ D$(T$$ , Ƃ$ED$4$D4$؃t$T$ED$4$D$4T$4$R9t T$(D$4$%I$))9t$T$ED$4$tD$4D$4$$T$ED$4$t$4$t8Dž4Dž8Dž<Dž@$,4: @ ʹ5; A ʹ6< B ʹ7= C ʹk8> 9 ʹB?1[^_]% $ > $ > : ; I : ;  : ; I8 I!I/ &I  I .: ; ' I@ : ; I 4: ; I .? : ; ' I@: ; I4: ; I 4: ; I4: ; I4: ; I."kKint4,1L]4ewX"##$#%#ZZL?U&s 3  B  h% ? s$ , v$ZU n$3~ c&y Y2 ? pw11ctx3 '3~l4sl53pl53Gi6Ze 7Y~sp8u~p; < =3u~ \9~ V:iAy? iw N /usr/include./includecrypt-md5.cstdint.hmd5.h$dyx w!u(Y J샑!go e3)))))B$1$./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz| ?AB C?AB Itt?uPW=RR;S;?RQ<V<?Q?@t@BtBu?u?Su VVVSSu~SSS}u~u~PPhcrypt_md5salt_crypt_to64pwlenstatecrypt_md5ctx1uint8_tlong long intlong intshort intMD5_CTXunsigned charsigned charlong long unsigned intuint32_tunsigned int/home/hpa/syslinux/release/syslinux-3.63/com32/libutilfinalcharbuffershort unsigned intlong unsigned intmagic_lencountcrypt-md5.cGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)magicpasswditoa64GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack4 %+ x 0  B*> RN <^ ` j Tf D  wt G  dg  l0 j . <h ? @ % 0x   <?FNXacrypt-md5.c_crypt_to64itoa64.1924magic.1944passwd.1943crypt_md5MD5InitMD5UpdateMD5Finalmemcpy" r  8Tm4?GchsTt !&-;BMT[fm|#'+8ERWc ny}(7CHT [ 8 <sha256crypt.lo/ 1207848671 1026 1026 100664 20404 ` ELFh=4(UWVSTÉ @I@ I@I@ЋA A 9vA$0 %  щuɃ@,E쉅w̋OOȉ1 111O;uDž` 1Љ1É#!1Ëى3!#1Љ 1ʉ1؃@t+ljuXQAQ AQAQT[^_]ËhUg j@g@rn<@ :O@RQ@h@ك@[@$@ @(]UWVSƉ׉MY()؉U9vEE,E؋UT$t$$EUB(B(@v:ƒMEEP(?P(E؃ET$D$U$u+}?@],UB,FCFCF C FCFCFCFCF C F$C$F(C(F,C,F0C0F4C4F8C8F $ >   I : ;  : ;I8 : ; : ; I8 I !I/ &I& : ; I8 .: ; ' @: ; I: ; I4: ; I4: ; I4: ; I  4: ; I 4: ; I4: ; I: ; I  4: ;I.: ; ' I@.? : ;' I : ;I : ;I!4: ;I".: ;' I@#: ;I$: ;I%4: ;I &4: ;I '4: ;I(4: ;I)1UX Y*1+1, U-41.1UX Y/.? : ;' I@0: ;I 14: ; I? < ?=|0@int@mQb408L8z@x-w7#*#{## ###2### #$#(| #,"#0R$#4(&7#8Y*7#<,#@h0Z#D1>#F2#G6#H?#L0H#TI#XJ#\ K#`'L%#dN7#hP#l d  t# # 7#  x  ' =FH=# LM# 7a#( +]#, Ma  ]a  m GV+F,lenF%`ctxFtH07IXJ%u}aKabLaKcMadNaeOafPagQaXhRaW_}`aaazbacadaea>faaga.T1aT2a a a ? VctxP]+len%=ctx|B%add%ulU%]rctx!i0a"pad%5?o%__s 7!=%%__s 7 7!=%%__s 7 7 7!=%"p =rS#key<$_<$+<$7<7%>p L%@p &ctxB~%tC|%dD%u|%E%u|'cntF%'cpGA%~Hu|%kIu|JKM%N  f<(numY%Zu|%[sP<(xx_7(yy_s] <'xxd0# (yyd7<.d 3d 8d )d*& +,-2)# ?0d*j= *^[ +R,P-v.pd* * * +,-w  (tmpi ! a (tmpr ( [ 'n7+  [ t (xx0(yy% 'w0> (n7 q'w0g (n7C q'w 0 (n 7i B'w 0 (n 7 B'w 0 (n 7 'w 0 (n 7 y'w 04 (n 7 y'w0] (n7' E'w0{ (n7M E'w0 (n7'w0 (n7 S / 2? 0key1$_1" 197M  !?%+7%787 # S ?*4 `  K.H `  ] %E(o  M %M+  t ?%&7  11 /usr/include/bits/usr/lib/gcc/x86_64-redhat-linux/4.1.2/include/usr/includesha256crypt.cstring2.hstddef.hstdint.hstdio.hlibio.htypes.h?KpJf ,97fEu3igggGב=guuuuuuvu*.ɼZ=@ s8|/ALhu=Z=h@KL57$1\v#8.{<;{{<{<:{#z<zt<zJX:z40K+0K+33112u@!YLbQ-21=-22wwL!11g1f'hL/11Lg<gijgjfgffg\vjBɟuɑ~% ϡa >/giu $%s%zu$$5$rounds=./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/BD7q۵[V9Y?^[1$} Ut]rހܛtiGƝ̡ $o,-tJܩ\ڈvRQ>m1'Y GQcg)) '8!.m,M 8STs e jv.,r迢KfpK£Ql$օ5pjl7LwH'4 9JNOʜ[o.htocxxȄnjlPxqƀ| VAB IVQAB AB F]AB FrX AB IuAB IttVuPSBSFQSRRFVR!Q!Vu}S u}QVSu}VLVV'u}WPWP.PFVW6u}u}RcREu}au}aQQTu}Vu}cu}zu}zCVFLVru}u}SOBSFQSu}u}Vu}u}Vu}OSVWtWYtYutt]uPZVZ]PRWR[W[]RQ]udSYS]^t^`t`ru]qPqpW]zRzrulnSVoVrstsutuurPu| u|rR! u|a u|rQu|r  ( W( u QWMWPPP&6QQuWW  S> S Q ; QT T S{ S Q Q  S] . S[ d S1S|Q ; R R V V S S SSCNVN_Sk}SVSSBBSBNV}VSWSVMMWXiWsyWyySyVSWWS V"ESEEWEQVVSRS&)R)/S~RSVSVSWSWWVSWV u|vu| u|u|"+u|5u|)+u|<u|Z_RRRGiRRR U Ra n RCPP.PiwPPfsRR;RiRRPWiW~QQQQS? Sa g S>iQQ5iS? Sa g S+iVI Va V V( Z V{ " V  V+VY ] P R RquR2IRIuRRRBFRRRFRRRlRRRRy}R<SRS}RRREIRRRoRRRRSRRtt?u8S8?u ;W sha256_crypt?j{~j{~(>i59+2(>i59+2_shortbuf_IO_lock_tchar_IO_buf_endb64tbuffer_IO_write_endunsigned intsha256_rounds_prefixuint32_tcopied_salt_flagscopied_key_markersshort intalt_resultendpGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)e_save_posnew_bufferstdoutlong long unsigned intsha256_init_ctxfillbufresbuf_fileno__pad1words/home/hpa/syslinux/release/syslinux-3.63/com32/libutilalt_ctxsize_t_vtable_offsetsha256_crypt_IO_read_base_Boolbytesb_savesha256_process_bytessha256crypt.ctemp_resultleft_overrounds_modesha256_process_block_IO_write_base_IO_read_ptrbufleng_savesha256_salt_prefixnwordssalt_IO_marker__strcspn_c1_IO_save_endlong long int__strcspn_c2__strcspn_c3_IO_save_bases_bytes__rejectsha256_crypt_rkey_len__quad_t_IO_backup_basesha256_finish_ctx__pad2__pad3__pad4__pad5__r0__r1__r2__resultsha256_ctxshort unsigned intsalt_lenunsigned char_IO_read_endrounds_customlong int__reject1__reject2__reject3srounds_offsetd_save_locklong unsigned int_old_offsetstdin_IO_FILEf_savea_savep_bytes_sbuf_IO_write_ptrneeded__off_tsigned chartotal_chain_flags2h_save_cur_column_nextc_save_unused2_IO_buf_base__off64_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack@? E%+0B > G0R#N 4O^2& m& y(u S # "  :V &tD`*w$l%%%%%%'' !&1?FMT[bmt{.=L[jy-<KZiy!/ry} '4AFJ\gr} #*.27AP_hlq '3E_kw !,1@`p (8FJko~   ( 4 = F P b f |             " & 4 H L Z n r              , 0 > N R `                 $ 0 D ^ k       8<PTptsha512crypt.lo/ 1207848671 1026 1026 100664 25720 ` ELFtP4(UWVSlv $K[ K[K[hlK [$04K([,`dK0[4PTK8[<@DֿщJ@ZDJ@ZD9r 9vBHRL/`1y1 Ӊ%¸ Ӊ% Ӊ% Ӊ% Ӊ% Ӊ p t0^FVF؋VFVȉΉ111111ڋ11AQE9 $ hl04`dX\PTHL@DDž`dpt11ڋ11ڋ׋Ћ#H#L#X#\11׉8<#### 11Ӌ# #1Ɖ1։1111(,HLX\ Pt}(, 8+@,h@0kA@4ك@8y!~@<[@H@L@@@D@P@T]U8]u}E։ϋAPQT E+E9vÍGXEE\$UT$$غGPWTGPWTw=vAƒ EyGPGPWTMىMMD$L$E$])ރv〉ڋE,]t]_PWXU؉t$ML$$v+EÀ\$D$E$_PGT]u}]UWVSLEU܋HPXTƋ@@VDډF@VD9rw9v E@HPLwov ) p)΋UXUˉȉt$D$$މuMA@QDÉ]uĉ1¸ ӋE%¸ ӋE% ӋE% ӋEU% ӋEU% Ɖuȉ ։űEȋ}ĉ UMD E D ]{D1CHSL ׉1 Ӊ%¸ Ӊ% Ӊ%EU ȉE ډỦ%M Mȋ] Ӊ]̉%M Mȋ] Ӊ]̋Eȉ UM E D ʃMEcE]Et|1 Ӊ%¸ Ӊ% Ӊ%EU ȉE ډỦ%M Mȋ] Ӊ]̉%M Mȋ] Ӊ]̋Eȉ UM܉DE DU ȃL[^_]UWVS׹8u8u^D$ D$$:$u0=ɚ;vɚ;=sƅDžƅuэQ%uF99=uQ 9929t|9txހ=uN t[9tQ9tJ9tA:t09t)9t%9t!D$$v DžуDžt@&)čD$#T$L$$Džt@&)čD$#\$t$$ًbًOً/ًً UC@v+u@@@ 䍍E tE@tuˍU񋕔>9w⍕pj)čD$#ƒ?ptBxB|B EBEBEBEBEB EB$EB(EB,EB0EB4EB8EB<@@?wpL$D$$Et,񋕐0E9wߍpU)čD$#ƒ?ptBxB|B EBEBEBEBEB EB$EB(EB,EB0EB4EB8EB<@@?wpL$D$$؃t񋕔@ER9t񋕐%I$))9t񋕔t@E񋕔~U;0E#ED$D$ $Ƌ}t3\$D$ D$!D$4$)ljЉ!;v\$D$4$Ɖ)م?$xUE]څ  ‰Ѓ? F~Ѓ? _9t ߅uiUEu   Ѓ? sЃ? ~9t ufUE]Dž[   ‰Ѓ? _Ѓ? s9t ugUE]݅  ‰Ѓ? ^Ѓ? 9t uUEu  Ѓ? sЃ? 9t uFUE]ʅ<  ‰Ѓ? ^Ѓ? 9t uiUEu  Ѓ? {sЃ? _9t ߅ugUEu  Ѓ? {Ѓ? 9t ufUE]ͅ  ‰Ѓ? _wЃ? {9t ugUE]  ‰Ѓ? _wЃ? 9t uoUEu  Ѓ? {Ѓ? 9t u UE]Ѕ  ‰Ѓ? _wЃ? 9t uUEu  Ѓ? {Ѓ? 9t uKUE]  ‰Ѓ? _wЃ? 9t uUEuӅ  Ѓ? sЃ? ~9t ufUE]  ‰Ѓ? _Ѓ? s9t ufUE]!  ‰Ѓ? ~Ѓ? _9t ߅ujUEuօ  Ѓ? {Ѓ? 9t unUE]  ‰Ѓ? _wЃ? 9t uUEuÅ  Ѓ? {Ѓ? 9t uUE]م  ‰Ѓ? _wЃ? 9t u9E~1ЉЃ? A~s CA"DžF9Up󫋕T$D$ $t$D$<$D$XD$$D$XD$$t D$D$$&L$D$$E)Up)čD$#Wvvf3ffRfuf1ffSe[^_]U]}] эyl;=~(|$$¸t$=$ ڋE]}]% : ; I$ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/ &I& : ;  : ; I8 .: ; ' @: ; I: ; I4: ; I4: ; I4: ; I  4: ; I 4: ; I4: ; I: ; I .: ;' @: ;I: ;I  4: ;I !4: ;I"4: ;I#.: ; ' I@$.? : ;' I %: ;I&: ;I'4: ;I(.: ;' I@)4: ;I *4: ;I+1UX Y,1-1. U/4101UX Y1.? : ;' I@2: ;I 34: ; I? <  G0@int.c0;l8L&Yz@x-Y7##>## ##2### #$#(V #,"#0@$#49&7#8G*7#<,#@h0Z#D1>#F2#G6#H?#LH#TI#XJ#\K#`L%#dN7#hP#l >  t# # 7#  x  ' >XH># :N#@ a#P +^#X Na  ^a  n $ff+e,lene%Uctxehtg0Ahi%uyajabkacla*dmalenafoagpahqa.!tW~zaazaaaaaaaT1auyT2a a a Of PctxP` H |+len%ctx* %ul!add% ; "9%G#OH ectx2i0apad%$JI%%__s&7' %$q%%__s&o7&y7' %$~%%__s&o7&y7&7' %( _ * key^19^^+^^7 `  b ~)ctxd| ~ey 'f%uy g%uy!cnth%Q!cpi ujuy Mkuy"l "m "o% "Kp. r a*num{ |uy }sP)a*xx7*yysi a!xx0 *yy7a" " " +,1 -%./=+/ J0,u9 ,iW -].P/0p, , , -./ /*tmp B*tmp !n7'  !*xx0*yy% N!w)0: *n)7) !w*0X *n*7O !w+0 *n+7u !w,0 *n,7 U!w-0 *n-7 U!w.0 *n.7 "!w/0% *n/7 "!w00N *n073 !w10l *n17Y V!w20 *n27 V!w30 *n37 '!w40 *n47 '!w50*n57 !w60O*n67 a!w70x*n77= a!w80*n87c -!w90*n97 -!w:0*n:7 !w;0*n;7 h!w<0:*n<7 h!w=0y*n=7!w>0*n>7 . S ?1 b`* 2key_9_"g7 U } 'm +e f7 S *1  K5 `    J 2  MD " Y ? &Yk I33 /usr/include/bits/usr/lib/gcc/x86_64-redhat-linux/4.1.2/include/usr/includesha512crypt.cstring2.hstddef.hstdint.hstdio.hlibio.htypes.h#guuuuuuypf q%uuuuuuuuGtguuuuuuu=*.[=0=2X=AL>=Z=j!#jv#8.{<;{{<{<:{{<{t<{JX:{40K+0K+33112u@!YLbQ-n[=-n\wwL!11g1f'hL/11Lg<gifgjdigfgjgjgiffjgjd2vjPɟ/uɑ~%  >/giu $%s%zu$$6$rounds=./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"(ט/Be#D7q/;Mۉ۵8H[V9YO?m^BؾopE[N1$} Uo{t]r;ހ5%ܛ&itJi%O8GՌƝew̡ $u+Yo,-ntJAܩ\SڈvfRQ>2-m1?!'Y= % GoQcpn g))/F '&&\8!.*Zm,M߳ 8ScTs ew< jvG.;5,rdL迢0BKfpK0TQlReU$* qW5ѻ2pjҸSAQl7LwH'Hᵼ4cZų 9ˊAJNscwOʜ[o.h]t`/CocxrxȄ9dnj(c#齂lPyƲ+SrxqƜa&>'!Ǹ}xnO}orgȢ}c ?G5 q}#w($@{2 ˾L*~e)Y:o_XGJDl| fAB IfAB  DAB LH OAB F AB I* uAB Ittfu:PPKfPRQfuy!!uy!fuy!uy!fuy4!uz!!uz!fuyL!uz!!uz!fuyd!uz!uzQSQS|!uz!fuy!uz!!uz!fuy!uz!!uz+VWVW!uz!!uz!fuy!uz!fuyfgtgiti u  t  t H u  P H ud R A V " Q" D W7 ` S` f PRf S S; > S  S > SH I tI K tK uH Z PZ u`H e Re u\] QS V V t t * u P uy/* uy R Buy* uy Q * uy W;u;KQW"]WP P-QuQWW9S_SQQSSQ%QS SS1SQRR9V9KVKWSV*SV_SWSSV&/VUaSSSSVWS"S""W".V]]WhyWWSSWWS'SSWbSSW3S3<V[aWamSSSWW -S--W--V-9WSVS9WhhShtVSWV &VRWSVSVSSSWSWWSWSWSWWVSW  S  Suyy* uyuy* uyGPuyZ* uyNPuya* uyRR3RhRR R/vRRhPP3OPPPRR3\RRRqWWQQ3QQ3S`SS_QQVS`SSLVjVV9VVVV+V PuR"RR"RRE\RRRUYRR,R,YRRR|RR"&RR&RRLcRRRVZR-R-ZRRRRR'+RRRRRQhRhRRRRaeRR"9R9eRRR-1RRRWnRnRR RRhlR  R(?R?lRR R  RRR R R-R* + t+ - t- u* U U S u M W5 sha512_crypt 33<I_VZLS<I_VZLS_shortbuf_IO_lock_tchar_IO_buf_endb64tbuffer_IO_write_endunsigned intcopied_salt_flagssha512_process_bytescopied_key_markersshort intalt_resultendpsha512_init_ctxGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)e_savesha512_crypt_r_posnew_bufferstdoutsha512_ctxlong long unsigned intfillbufresbuf_filenowords/home/hpa/syslinux/release/syslinux-3.63/com32/libutilalt_ctxsize_t_vtable_offsetsha512_salt_prefix_IO_read_base_Boolbytesb_savetemp_resultleft_overrounds_mode_IO_write_base_IO_read_ptrbufleng_savenwordssha512_process_blocksalt_IO_marker__strcspn_c1_IO_save_endlong long int__strcspn_c2__strcspn_c3_IO_save_basesha512crypt.cs_bytes__rejectkey_len__quad_t_IO_backup_base__pad1__pad2__pad3__pad4__pad5__r0__r1__r2__resultshort unsigned intsalt_lenunsigned char_IO_read_endrounds_customlong intsha512_crypt__reject1__reject2__reject3uint64_tsrounds_offsetd_save_locklong unsigned int_old_offsetstdin_IO_FILEf_savesha512_rounds_prefixa_savep_bytes_sbuf_IO_write_ptrneeded__off_tsigned chartotal_chain_flags2sha512_finish_ctxh_save_cur_column_nextc_save_unused2_IO_buf_base__off64_tGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rodata.str1.1.rodata.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_ranges.debug_str.comment.note.GNU-stack@  X% + 0 B#> Z8 R+2N c^2C5 m`5` y8u d` 9*I# `dI  hdI0JZO.OOT Wf$` &f6 DKH O]  e t  @    * u sha512crypt.csha512_process_blockKsha512_init_ctxsha512_process_bytessha512_finish_ctxfillbufsha512_crypt_rsha512_salt_prefixsha512_rounds_prefixb64tbuflen.3882buffer.3881.LC0memcpystrtoulstrcspnstpncpysnprintf__errno_locationmemsetsha512_cryptreallocU   -      d5!r"#3"}Mi9Tp: Yu*F_{0L$f%%%%%%O Z b 's y ~   !&1?FMT[bmt{.=L[jy-<KZiy"0sz~(5BGK]hs~  $,049DTdmqv 2>Pjv ',7<Ll| #4DRVw{   $ 4 @ I R \ n r              . 2 @ T X f z ~             $ 8 < J ^ b p               . B F T h l z             / ; G K O c n s ~            3@Zgq~8<PTptbase64.lo/ 1207848671 1026 1026 100664 3676 ` ELF4(UWVS}E>E?EE~tu EuFEEuF V уU?uE~돃tu4Et E@=!mEt E@=@=mEE+E[^_]ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_% $ > $ > : ; I.? : ; ' I@: ; I4: ; I 4: ; I 4: ; I 4: ; I  I & I!I/ &IIx int1LVd4ewe9 s 9, FL sx 3bufMij3pdq9bvZQ 3 o ? L ]A]w jA?]@s /usr/lib/gcc/x86_64-redhat-linux/4.1.2/include/usr/includebase64.cstddef.hstdint.h > wfH?Ygxh=:t J XxQ| AB Fttu**u--u **u* *u-S-V&-u`-WRmR W|~genbase64size_tbase64.cleftgenbase64/home/hpa/syslinux/release/syslinux-3.63/com32/libutilunsigned charshort unsigned intunsigned intflagslong long unsigned intuint8_tlong long intcharGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)short intoutputcharzuint32_tinputsigned charsizeGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33).symtab.strtab.shstrtab.rel.text.data.bss.debug_abbrev.rel.debug_info.rel.debug_line.rel.debug_frame.debug_loc.rel.debug_pubnames.rel.debug_aranges.debug_str.comment.note.GNU-stack@ %@A +0BM|> 0RN ,b|4^ 4 o~ z D   L0 &.TT    A   base64.ccharz.1414genbase64}   ! & - ; B M T [ f m t               # ( 4@ ^  syslinux-legacy-3.63+dfsg/com32/libutil/include/0000775000175000017500000000000010777447272020225 5ustar evanevansyslinux-legacy-3.63+dfsg/com32/libutil/include/getkey.h0000664000175000017500000000446710777447272021701 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * getkey.h * * Function to get a key symbol and parse it */ #ifndef LIBUTIL_GETKEY_H #define LIBUTIL_GETKEY_H #include #include #include #ifndef CLK_TCK # define CLK_TCK sysconf(_SC_CLK_TCK) #endif #define KEY_NONE (-1) #define KEY_CTRL(x) ((x) & 0x001f) #define KEY_BACKSPACE 0x0008 #define KEY_TAB 0x0009 #define KEY_ENTER 0x000d #define KEY_ESC 0x001b #define KEY_DEL 0x007f #define KEY_F1 0x0100 #define KEY_F2 0x0101 #define KEY_F3 0x0102 #define KEY_F4 0x0103 #define KEY_F5 0x0104 #define KEY_F6 0x0105 #define KEY_F7 0x0106 #define KEY_F8 0x0107 #define KEY_F9 0x0108 #define KEY_F10 0x0109 #define KEY_F11 0x010A #define KEY_F12 0x010B #define KEY_UP 0x0120 #define KEY_DOWN 0x0121 #define KEY_LEFT 0x0122 #define KEY_RIGHT 0x0123 #define KEY_PGUP 0x0124 #define KEY_PGDN 0x0125 #define KEY_HOME 0x0126 #define KEY_END 0x0127 #define KEY_INSERT 0x0128 #define KEY_DELETE 0x0129 int get_key(FILE *, clock_t); #endif /* LIBUTIL_GETKEY_H */ syslinux-legacy-3.63+dfsg/com32/libutil/include/libutil.h0000664000175000017500000000312310777447272022041 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2005-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * libutil.h * * Misc libutil functions */ #ifndef LIBUTIL_LIBUTIL_H #define LIBUTIL_LIBUTIL_H #ifdef __COM32__ # include # define do_idle syslinux_idle #else /* not __COM32__ */ # include # define do_idle sched_yield #endif #endif syslinux-legacy-3.63+dfsg/com32/libutil/include/md5.h0000664000175000017500000000265610777447272021074 0ustar evanevan/* MD5.H - header file for MD5C.C */ /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. */ #ifndef _LIBUTIL_MD5_H #define _LIBUTIL_MD5_H #include #include #define MD5_SIZE 16 /* 128 bits */ /* MD5 context. */ typedef struct { uint32_t state[4]; /* state (ABCD) */ uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ unsigned char buffer[64]; /* input buffer */ } MD5_CTX; void MD5Init(MD5_CTX *); void MD5Update(MD5_CTX *, const void *, size_t); void MD5Final(unsigned char [MD5_SIZE], MD5_CTX *); char *crypt_md5(const char *, const char *); #endif syslinux-legacy-3.63+dfsg/com32/libutil/include/sha1.h0000664000175000017500000000071110777447272021231 0ustar evanevan#ifndef LIBUTIL_SHA1_H #define LIBUTIL_SHA1_H #include typedef struct { uint32_t state[5]; uint32_t count[2]; unsigned char buffer[64]; } SHA1_CTX; void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); void SHA1Init(SHA1_CTX* context); void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); /* JHB */ void SHA1Final(unsigned char digest[20], SHA1_CTX* context); #endif /* LIBUTIL_SHA1_H */ syslinux-legacy-3.63+dfsg/com32/libutil/include/consoles.h0000664000175000017500000000304210777447272022222 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * consoles.h * * Utility functions for common console configurations */ #ifndef LIBUTIL_CONSOLES_H #define LIBUTIL_CONSOLES_H void console_ansi_std(void); void console_ansi_raw(void); #endif /* LIBUTIL_CONSOLES_H */ syslinux-legacy-3.63+dfsg/com32/libutil/include/minmax.h0000664000175000017500000000327310777447272021674 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #ifndef _MINMAX_H #define _MINMAX_H /* * minmax.h: Type-independent safe min/max macros */ #define min(x,y) ({ __typeof(x) xx = (x); \ __typeof(y) yy = (y); \ xx < yy ? xx : yy; }) #define max(x,y) ({ __typeof(x) xx = (x); \ __typeof(y) yy = (y); \ xx > yy ? xx : yy; }) #endif /* _MINMAX_H */ syslinux-legacy-3.63+dfsg/com32/libutil/include/base64.h0000664000175000017500000000365010777447272021466 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2005-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * base64.h * * Simple routines for handing base64 text */ #ifndef LIBUTIL_BASE64_H #define LIBUTIL_BASE64_H #include #define BASE64_PAD 0x10000 /* There is plenty of disagreement w.r.t. the last few characters... */ #define BASE64_MIME ('+' + ('/' << 8)) #define BASE64_SAFE ('-' + ('_' << 8)) #define BASE64_CRYPT ('.' + ('/' << 8)) #define BASE64_URL ('*' + ('-' << 8)) /* Haven't seen myself */ #define BASE64_REGEX ('|' + ('-' << 8)) /* Ditto... */ size_t genbase64(char *output, const void *digest, size_t size, int flags); size_t unbase64(unsigned char *, size_t, const char *); #endif syslinux-legacy-3.63+dfsg/com32/libutil/include/xcrypt.h0000664000175000017500000000036410777447272021732 0ustar evanevan#ifndef _LIBUTIL_XCRYPT_H #define _LIBUTIL_XCRYPT_H /* Extended crypt() implementations */ char *crypt_md5(const char *, const char *); char *sha256_crypt (const char *, const char *); char *sha512_crypt (const char *, const char *); #endif syslinux-legacy-3.63+dfsg/com32/libutil/Makefile0000664000175000017500000000646510777447272020255 0ustar evanevan## ----------------------------------------------------------------------- ## ## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved ## ## Permission is hereby granted, free of charge, to any person ## obtaining a copy of this software and associated documentation ## files (the "Software"), to deal in the Software without ## restriction, including without limitation the rights to use, ## copy, modify, merge, publish, distribute, sublicense, and/or ## sell copies of the Software, and to permit persons to whom ## the Software is furnished to do so, subject to the following ## conditions: ## ## The above copyright notice and this permission notice shall ## be included in all copies or substantial portions of the Software. ## ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ## OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ## HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ## WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ## FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ## OTHER DEALINGS IN THE SOFTWARE. ## ## ----------------------------------------------------------------------- ## ## Utility companion library for the COM32 library ## TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \ then echo $(1); else echo $(2); fi; rm -f $$tmpf) M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,) CC = gcc LD = ld -m elf_i386 AR = ar NASM = nasm NASMOPT = -O9999 RANLIB = ranlib CFLAGS = $(M32) -mregparm=3 -DREGPARM=3 -W -Wall -march=i386 -Os \ -fomit-frame-pointer -D__COM32__ \ -nostdinc -iwithprefix include \ -I./include -I../include \ -Wp,-MT,$@,-MD,$(dir $@).$(notdir $@).d SFLAGS = $(M32) -D__COM32__ -march=i386 LDFLAGS = -T ../lib/com32.ld LNXCFLAGS = -I./include -W -Wall -O -g -D_GNU_SOURCE LNXSFLAGS = -g LNXLDFLAGS = -g OBJCOPY = objcopy LIBOBJS = ansiline.o ansiraw.o get_key.o sha1hash.o unbase64.o \ md5.o crypt-md5.o sha256crypt.o sha512crypt.o base64.o LNXLIBOBJS = $(patsubst %.o,%.lo,$(LIBOBJS)) .SUFFIXES: .lss .c .lo .o .elf .c32 .lnx BINDIR = /usr/bin LIBDIR = /usr/lib AUXDIR = $(LIBDIR)/syslinux INCDIR = /usr/include COM32DIR = $(AUXDIR)/com32 all: libutil_com.a libutil_lnx.a libutil_com.a: $(LIBOBJS) rm -f $@ $(AR) cq $@ $(LIBOBJS) $(RANLIB) $@ libutil_lnx.a: $(LNXLIBOBJS) rm -f $@ $(AR) cq $@ $(LNXLIBOBJS) $(RANLIB) $@ .PRECIOUS: %.o %.o: %.S $(CC) $(SFLAGS) -c -o $@ $< .PRECIOUS: %.o %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< .PRECIOUS: %.elf %.elf: %.o $(LIB) $(LD) $(LDFLAGS) -o $@ $^ $(LIBGCC) .PRECIOUS: %.lo %.lo: %.S $(CC) $(LNXSFLAGS) -c -o $@ $< .PRECIOUS: %.lo %.lo: %.c $(CC) $(LNXCFLAGS) -c -o $@ $< .PRECIOUS: %.lnx %.lnx: %.lo $(CC) $(LNXCFLAGS) -o $@ $^ %.c32: %.elf $(OBJCOPY) -O binary $< $@ tidy: rm -f *.o *.lo *.lst *.elf .*.d clean: tidy rm -f *.lss *.a *.c32 *.lnx *.com spotless: clean rm -f *~ \#* install: all mkdir -m 755 -p $(INSTALLROOT)$(COM32DIR) install -m 644 libutil_com.a libutil_lnx.a $(INSTALLROOT)$(COM32DIR) -include .*.d syslinux-legacy-3.63+dfsg/com32/libutil/sha512crypt.c0000664000175000017500000006432110777447272021041 0ustar evanevan/* SHA512-based Unix crypt implementation. Released into the Public Domain by Ulrich Drepper . */ #include #include #include #include #include #include #include #include #include #include #include #include "xcrypt.h" #define MIN(x,y) min(x,y) #define MAX(x,y) max(x,y) /* Structure to save state of computation between the single steps. */ struct sha512_ctx { uint64_t H[8]; uint64_t total[2]; uint64_t buflen; char buffer[256]; /* NB: always correctly aligned for uint64_t. */ }; #if __BYTE_ORDER == __LITTLE_ENDIAN # define SWAP(n) \ (((n) << 56) \ | (((n) & 0xff00) << 40) \ | (((n) & 0xff0000) << 24) \ | (((n) & 0xff000000) << 8) \ | (((n) >> 8) & 0xff000000) \ | (((n) >> 24) & 0xff0000) \ | (((n) >> 40) & 0xff00) \ | ((n) >> 56)) #else # define SWAP(n) (n) #endif /* This array contains the bytes used to pad the buffer to the next 64-byte boundary. (FIPS 180-2:5.1.2) */ static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ... */ }; /* Constants for SHA512 from FIPS 180-2:4.2.3. */ static const uint64_t K[80] = { UINT64_C (0x428a2f98d728ae22), UINT64_C (0x7137449123ef65cd), UINT64_C (0xb5c0fbcfec4d3b2f), UINT64_C (0xe9b5dba58189dbbc), UINT64_C (0x3956c25bf348b538), UINT64_C (0x59f111f1b605d019), UINT64_C (0x923f82a4af194f9b), UINT64_C (0xab1c5ed5da6d8118), UINT64_C (0xd807aa98a3030242), UINT64_C (0x12835b0145706fbe), UINT64_C (0x243185be4ee4b28c), UINT64_C (0x550c7dc3d5ffb4e2), UINT64_C (0x72be5d74f27b896f), UINT64_C (0x80deb1fe3b1696b1), UINT64_C (0x9bdc06a725c71235), UINT64_C (0xc19bf174cf692694), UINT64_C (0xe49b69c19ef14ad2), UINT64_C (0xefbe4786384f25e3), UINT64_C (0x0fc19dc68b8cd5b5), UINT64_C (0x240ca1cc77ac9c65), UINT64_C (0x2de92c6f592b0275), UINT64_C (0x4a7484aa6ea6e483), UINT64_C (0x5cb0a9dcbd41fbd4), UINT64_C (0x76f988da831153b5), UINT64_C (0x983e5152ee66dfab), UINT64_C (0xa831c66d2db43210), UINT64_C (0xb00327c898fb213f), UINT64_C (0xbf597fc7beef0ee4), UINT64_C (0xc6e00bf33da88fc2), UINT64_C (0xd5a79147930aa725), UINT64_C (0x06ca6351e003826f), UINT64_C (0x142929670a0e6e70), UINT64_C (0x27b70a8546d22ffc), UINT64_C (0x2e1b21385c26c926), UINT64_C (0x4d2c6dfc5ac42aed), UINT64_C (0x53380d139d95b3df), UINT64_C (0x650a73548baf63de), UINT64_C (0x766a0abb3c77b2a8), UINT64_C (0x81c2c92e47edaee6), UINT64_C (0x92722c851482353b), UINT64_C (0xa2bfe8a14cf10364), UINT64_C (0xa81a664bbc423001), UINT64_C (0xc24b8b70d0f89791), UINT64_C (0xc76c51a30654be30), UINT64_C (0xd192e819d6ef5218), UINT64_C (0xd69906245565a910), UINT64_C (0xf40e35855771202a), UINT64_C (0x106aa07032bbd1b8), UINT64_C (0x19a4c116b8d2d0c8), UINT64_C (0x1e376c085141ab53), UINT64_C (0x2748774cdf8eeb99), UINT64_C (0x34b0bcb5e19b48a8), UINT64_C (0x391c0cb3c5c95a63), UINT64_C (0x4ed8aa4ae3418acb), UINT64_C (0x5b9cca4f7763e373), UINT64_C (0x682e6ff3d6b2b8a3), UINT64_C (0x748f82ee5defb2fc), UINT64_C (0x78a5636f43172f60), UINT64_C (0x84c87814a1f0ab72), UINT64_C (0x8cc702081a6439ec), UINT64_C (0x90befffa23631e28), UINT64_C (0xa4506cebde82bde9), UINT64_C (0xbef9a3f7b2c67915), UINT64_C (0xc67178f2e372532b), UINT64_C (0xca273eceea26619c), UINT64_C (0xd186b8c721c0c207), UINT64_C (0xeada7dd6cde0eb1e), UINT64_C (0xf57d4f7fee6ed178), UINT64_C (0x06f067aa72176fba), UINT64_C (0x0a637dc5a2c898a6), UINT64_C (0x113f9804bef90dae), UINT64_C (0x1b710b35131c471b), UINT64_C (0x28db77f523047d84), UINT64_C (0x32caab7b40c72493), UINT64_C (0x3c9ebe0a15c9bebc), UINT64_C (0x431d67c49c100d4c), UINT64_C (0x4cc5d4becb3e42b6), UINT64_C (0x597f299cfc657e2a), UINT64_C (0x5fcb6fab3ad6faec), UINT64_C (0x6c44198c4a475817) }; /* Process LEN bytes of BUFFER, accumulating context into CTX. It is assumed that LEN % 128 == 0. */ static void sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx) { unsigned int t; const uint64_t *words = buffer; size_t nwords = len / sizeof (uint64_t); uint64_t a = ctx->H[0]; uint64_t b = ctx->H[1]; uint64_t c = ctx->H[2]; uint64_t d = ctx->H[3]; uint64_t e = ctx->H[4]; uint64_t f = ctx->H[5]; uint64_t g = ctx->H[6]; uint64_t h = ctx->H[7]; /* First increment the byte count. FIPS 180-2 specifies the possible length of the file up to 2^128 bits. Here we only compute the number of bytes. Do a double word increment. */ ctx->total[0] += len; if (ctx->total[0] < len) ++ctx->total[1]; /* Process all bytes in the buffer with 128 bytes in each round of the loop. */ while (nwords > 0) { uint64_t W[80]; uint64_t a_save = a; uint64_t b_save = b; uint64_t c_save = c; uint64_t d_save = d; uint64_t e_save = e; uint64_t f_save = f; uint64_t g_save = g; uint64_t h_save = h; /* Operators defined in FIPS 180-2:4.1.2. */ #define Ch(x, y, z) ((x & y) ^ (~x & z)) #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) #define S0(x) (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39)) #define S1(x) (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41)) #define R0(x) (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7)) #define R1(x) (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6)) /* It is unfortunate that C does not provide an operator for cyclic rotation. Hope the C compiler is smart enough. */ #define CYCLIC(w, s) ((w >> s) | (w << (64 - s))) /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */ for (t = 0; t < 16; ++t) { W[t] = SWAP (*words); ++words; } for (t = 16; t < 80; ++t) W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16]; /* The actual computation according to FIPS 180-2:6.3.2 step 3. */ for (t = 0; t < 80; ++t) { uint64_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t]; uint64_t T2 = S0 (a) + Maj (a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; } /* Add the starting values of the context according to FIPS 180-2:6.3.2 step 4. */ a += a_save; b += b_save; c += c_save; d += d_save; e += e_save; f += f_save; g += g_save; h += h_save; /* Prepare for the next round. */ nwords -= 16; } /* Put checksum in context given as argument. */ ctx->H[0] = a; ctx->H[1] = b; ctx->H[2] = c; ctx->H[3] = d; ctx->H[4] = e; ctx->H[5] = f; ctx->H[6] = g; ctx->H[7] = h; } /* Initialize structure containing state of computation. (FIPS 180-2:5.3.3) */ static void sha512_init_ctx (struct sha512_ctx *ctx) { ctx->H[0] = UINT64_C (0x6a09e667f3bcc908); ctx->H[1] = UINT64_C (0xbb67ae8584caa73b); ctx->H[2] = UINT64_C (0x3c6ef372fe94f82b); ctx->H[3] = UINT64_C (0xa54ff53a5f1d36f1); ctx->H[4] = UINT64_C (0x510e527fade682d1); ctx->H[5] = UINT64_C (0x9b05688c2b3e6c1f); ctx->H[6] = UINT64_C (0x1f83d9abfb41bd6b); ctx->H[7] = UINT64_C (0x5be0cd19137e2179); ctx->total[0] = ctx->total[1] = 0; ctx->buflen = 0; } /* Process the remaining bytes in the internal buffer and the usual prolog according to the standard and write the result to RESBUF. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ static void * sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf) { unsigned int i; /* Take yet unprocessed bytes into account. */ uint64_t bytes = ctx->buflen; size_t pad; /* Now count remaining bytes. */ ctx->total[0] += bytes; if (ctx->total[0] < bytes) ++ctx->total[1]; pad = bytes >= 112 ? 128 + 112 - bytes : 112 - bytes; memcpy (&ctx->buffer[bytes], fillbuf, pad); /* Put the 128-bit file length in *bits* at the end of the buffer. */ *(uint64_t *) &ctx->buffer[bytes + pad + 8] = SWAP (ctx->total[0] << 3); *(uint64_t *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 61)); /* Process last bytes. */ sha512_process_block (ctx->buffer, bytes + pad + 16, ctx); /* Put result from CTX in first 64 bytes following RESBUF. */ for (i = 0; i < 8; ++i) ((uint64_t *) resbuf)[i] = SWAP (ctx->H[i]); return resbuf; } static void sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx) { /* When we already have some bits in our internal buffer concatenate both inputs first. */ if (ctx->buflen != 0) { size_t left_over = ctx->buflen; size_t add = 256 - left_over > len ? len : 256 - left_over; memcpy (&ctx->buffer[left_over], buffer, add); ctx->buflen += add; if (ctx->buflen > 128) { sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx); ctx->buflen &= 127; /* The regions in the following copy operation cannot overlap. */ memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~127], ctx->buflen); } buffer = (const char *) buffer + add; len -= add; } /* Process available complete blocks. */ if (len >= 128) { #if !_STRING_ARCH_unaligned /* To check alignment gcc has an appropriate operator. Other compilers don't. */ # if __GNUC__ >= 2 # define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint64_t) != 0) # else # define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint64_t) != 0) # endif if (UNALIGNED_P (buffer)) while (len > 128) { sha512_process_block (memcpy (ctx->buffer, buffer, 128), 128, ctx); buffer = (const char *) buffer + 128; len -= 128; } else #endif { sha512_process_block (buffer, len & ~127, ctx); buffer = (const char *) buffer + (len & ~127); len &= 127; } } /* Move remaining bytes into internal buffer. */ if (len > 0) { size_t left_over = ctx->buflen; memcpy (&ctx->buffer[left_over], buffer, len); left_over += len; if (left_over >= 128) { sha512_process_block (ctx->buffer, 128, ctx); left_over -= 128; memcpy (ctx->buffer, &ctx->buffer[128], left_over); } ctx->buflen = left_over; } } /* Define our magic string to mark salt for SHA512 "encryption" replacement. */ static const char sha512_salt_prefix[] = "$6$"; /* Prefix for optional rounds specification. */ static const char sha512_rounds_prefix[] = "rounds="; /* Maximum salt string length. */ #define SALT_LEN_MAX 16 /* Default number of rounds if not explicitly specified. */ #define ROUNDS_DEFAULT 5000 /* Minimum number of rounds. */ #define ROUNDS_MIN 1000 /* Maximum number of rounds. */ #define ROUNDS_MAX 999999999 /* Table with characters for base64 transformation. */ static const char b64t[64] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static char * sha512_crypt_r (const char *key, const char *salt, char *buffer, int buflen) { unsigned char alt_result[64] __attribute__ ((__aligned__ (__alignof__ (uint64_t)))); unsigned char temp_result[64] __attribute__ ((__aligned__ (__alignof__ (uint64_t)))); struct sha512_ctx ctx; struct sha512_ctx alt_ctx; size_t salt_len; size_t key_len; size_t cnt; char *cp; char *copied_key = NULL; char *copied_salt = NULL; char *p_bytes; char *s_bytes; /* Default number of rounds. */ size_t rounds = ROUNDS_DEFAULT; bool rounds_custom = false; /* Find beginning of salt string. The prefix should normally always be present. Just in case it is not. */ if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0) /* Skip salt prefix. */ salt += sizeof (sha512_salt_prefix) - 1; if (strncmp (salt, sha512_rounds_prefix, sizeof (sha512_rounds_prefix) - 1) == 0) { const char *num = salt + sizeof (sha512_rounds_prefix) - 1; char *endp; unsigned long int srounds = strtoul (num, &endp, 10); if (*endp == '$') { salt = endp + 1; rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX)); rounds_custom = true; } } salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX); key_len = strlen (key); if ((key - (char *) 0) % __alignof__ (uint64_t) != 0) { char *tmp = (char *) alloca (key_len + __alignof__ (uint64_t)); key = copied_key = memcpy (tmp + __alignof__ (uint64_t) - (tmp - (char *) 0) % __alignof__ (uint64_t), key, key_len); } if ((salt - (char *) 0) % __alignof__ (uint64_t) != 0) { char *tmp = (char *) alloca (salt_len + __alignof__ (uint64_t)); salt = copied_salt = memcpy (tmp + __alignof__ (uint64_t) - (tmp - (char *) 0) % __alignof__ (uint64_t), salt, salt_len); } /* Prepare for the real work. */ sha512_init_ctx (&ctx); /* Add the key string. */ sha512_process_bytes (key, key_len, &ctx); /* The last part is the salt string. This must be at most 8 characters and it ends at the first `$' character (for compatibility with existing implementations). */ sha512_process_bytes (salt, salt_len, &ctx); /* Compute alternate SHA512 sum with input KEY, SALT, and KEY. The final result will be added to the first context. */ sha512_init_ctx (&alt_ctx); /* Add key. */ sha512_process_bytes (key, key_len, &alt_ctx); /* Add salt. */ sha512_process_bytes (salt, salt_len, &alt_ctx); /* Add key again. */ sha512_process_bytes (key, key_len, &alt_ctx); /* Now get result of this (64 bytes) and add it to the other context. */ sha512_finish_ctx (&alt_ctx, alt_result); /* Add for any character in the key one byte of the alternate sum. */ for (cnt = key_len; cnt > 64; cnt -= 64) sha512_process_bytes (alt_result, 64, &ctx); sha512_process_bytes (alt_result, cnt, &ctx); /* Take the binary representation of the length of the key and for every 1 add the alternate sum, for every 0 the key. */ for (cnt = key_len; cnt > 0; cnt >>= 1) if ((cnt & 1) != 0) sha512_process_bytes (alt_result, 64, &ctx); else sha512_process_bytes (key, key_len, &ctx); /* Create intermediate result. */ sha512_finish_ctx (&ctx, alt_result); /* Start computation of P byte sequence. */ sha512_init_ctx (&alt_ctx); /* For every character in the password add the entire password. */ for (cnt = 0; cnt < key_len; ++cnt) sha512_process_bytes (key, key_len, &alt_ctx); /* Finish the digest. */ sha512_finish_ctx (&alt_ctx, temp_result); /* Create byte sequence P. */ cp = p_bytes = alloca (key_len); for (cnt = key_len; cnt >= 64; cnt -= 64) cp = mempcpy (cp, temp_result, 64); memcpy (cp, temp_result, cnt); /* Start computation of S byte sequence. */ sha512_init_ctx (&alt_ctx); /* For every character in the password add the entire password. */ for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt) sha512_process_bytes (salt, salt_len, &alt_ctx); /* Finish the digest. */ sha512_finish_ctx (&alt_ctx, temp_result); /* Create byte sequence S. */ cp = s_bytes = alloca (salt_len); for (cnt = salt_len; cnt >= 64; cnt -= 64) cp = mempcpy (cp, temp_result, 64); memcpy (cp, temp_result, cnt); /* Repeatedly run the collected hash value through SHA512 to burn CPU cycles. */ for (cnt = 0; cnt < rounds; ++cnt) { /* New context. */ sha512_init_ctx (&ctx); /* Add key or last result. */ if ((cnt & 1) != 0) sha512_process_bytes (p_bytes, key_len, &ctx); else sha512_process_bytes (alt_result, 64, &ctx); /* Add salt for numbers not divisible by 3. */ if (cnt % 3 != 0) sha512_process_bytes (s_bytes, salt_len, &ctx); /* Add key for numbers not divisible by 7. */ if (cnt % 7 != 0) sha512_process_bytes (p_bytes, key_len, &ctx); /* Add key or last result. */ if ((cnt & 1) != 0) sha512_process_bytes (alt_result, 64, &ctx); else sha512_process_bytes (p_bytes, key_len, &ctx); /* Create intermediate result. */ sha512_finish_ctx (&ctx, alt_result); } /* Now we can construct the result string. It consists of three parts. */ cp = stpncpy (buffer, sha512_salt_prefix, MAX (0, buflen)); buflen -= sizeof (sha512_salt_prefix) - 1; if (rounds_custom) { int n = snprintf (cp, MAX (0, buflen), "%s%zu$", sha512_rounds_prefix, rounds); cp += n; buflen -= n; } cp = stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len)); buflen -= MIN ((size_t) MAX (0, buflen), salt_len); if (buflen > 0) { *cp++ = '$'; --buflen; } #define b64_from_24bit(B2, B1, B0, N) \ do { \ unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \ int n = (N); \ while (n-- > 0 && buflen > 0) \ { \ *cp++ = b64t[w & 0x3f]; \ --buflen; \ w >>= 6; \ } \ } while (0) b64_from_24bit (alt_result[0], alt_result[21], alt_result[42], 4); b64_from_24bit (alt_result[22], alt_result[43], alt_result[1], 4); b64_from_24bit (alt_result[44], alt_result[2], alt_result[23], 4); b64_from_24bit (alt_result[3], alt_result[24], alt_result[45], 4); b64_from_24bit (alt_result[25], alt_result[46], alt_result[4], 4); b64_from_24bit (alt_result[47], alt_result[5], alt_result[26], 4); b64_from_24bit (alt_result[6], alt_result[27], alt_result[48], 4); b64_from_24bit (alt_result[28], alt_result[49], alt_result[7], 4); b64_from_24bit (alt_result[50], alt_result[8], alt_result[29], 4); b64_from_24bit (alt_result[9], alt_result[30], alt_result[51], 4); b64_from_24bit (alt_result[31], alt_result[52], alt_result[10], 4); b64_from_24bit (alt_result[53], alt_result[11], alt_result[32], 4); b64_from_24bit (alt_result[12], alt_result[33], alt_result[54], 4); b64_from_24bit (alt_result[34], alt_result[55], alt_result[13], 4); b64_from_24bit (alt_result[56], alt_result[14], alt_result[35], 4); b64_from_24bit (alt_result[15], alt_result[36], alt_result[57], 4); b64_from_24bit (alt_result[37], alt_result[58], alt_result[16], 4); b64_from_24bit (alt_result[59], alt_result[17], alt_result[38], 4); b64_from_24bit (alt_result[18], alt_result[39], alt_result[60], 4); b64_from_24bit (alt_result[40], alt_result[61], alt_result[19], 4); b64_from_24bit (alt_result[62], alt_result[20], alt_result[41], 4); b64_from_24bit (0, 0, alt_result[63], 2); if (buflen <= 0) { errno = ERANGE; buffer = NULL; } else *cp = '\0'; /* Terminate the string. */ /* Clear the buffer for the intermediate result so that people attaching to processes or reading core dumps cannot get any information. We do it in this way to clear correct_words[] inside the SHA512 implementation as well. */ sha512_init_ctx (&ctx); sha512_finish_ctx (&ctx, alt_result); memset (temp_result, '\0', sizeof (temp_result)); memset (p_bytes, '\0', key_len); memset (s_bytes, '\0', salt_len); memset (&ctx, '\0', sizeof (ctx)); memset (&alt_ctx, '\0', sizeof (alt_ctx)); if (copied_key != NULL) memset (copied_key, '\0', key_len); if (copied_salt != NULL) memset (copied_salt, '\0', salt_len); return buffer; } /* This entry point is equivalent to the `crypt' function in Unix libcs. */ char * sha512_crypt (const char *key, const char *salt) { /* We don't want to have an arbitrary limit in the size of the password. We can compute an upper bound for the size of the result in advance and so we can prepare the buffer we pass to `sha512_crypt_r'. */ static char *buffer; static int buflen; int needed = (sizeof (sha512_salt_prefix) - 1 + sizeof (sha512_rounds_prefix) + 9 + 1 + strlen (salt) + 1 + 86 + 1); if (buflen < needed) { char *new_buffer = (char *) realloc (buffer, needed); if (new_buffer == NULL) return NULL; buffer = new_buffer; buflen = needed; } return sha512_crypt_r (key, salt, buffer, buflen); } #ifdef TEST static const struct { const char *input; const char result[64]; } tests[] = { /* Test vectors from FIPS 180-2: appendix C.1. */ { "abc", "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31" "\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a" "\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd" "\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f" }, /* Test vectors from FIPS 180-2: appendix C.2. */ { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f" "\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18" "\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a" "\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09" }, /* Test vectors from the NESSIE project. */ { "", "\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07" "\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce" "\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f" "\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e" }, { "a", "\x1f\x40\xfc\x92\xda\x24\x16\x94\x75\x09\x79\xee\x6c\xf5\x82\xf2" "\xd5\xd7\xd2\x8e\x18\x33\x5d\xe0\x5a\xbc\x54\xd0\x56\x0e\x0f\x53" "\x02\x86\x0c\x65\x2b\xf0\x8d\x56\x02\x52\xaa\x5e\x74\x21\x05\x46" "\xf3\x69\xfb\xbb\xce\x8c\x12\xcf\xc7\x95\x7b\x26\x52\xfe\x9a\x75" }, { "message digest", "\x10\x7d\xbf\x38\x9d\x9e\x9f\x71\xa3\xa9\x5f\x6c\x05\x5b\x92\x51" "\xbc\x52\x68\xc2\xbe\x16\xd6\xc1\x34\x92\xea\x45\xb0\x19\x9f\x33" "\x09\xe1\x64\x55\xab\x1e\x96\x11\x8e\x8a\x90\x5d\x55\x97\xb7\x20" "\x38\xdd\xb3\x72\xa8\x98\x26\x04\x6d\xe6\x66\x87\xbb\x42\x0e\x7c" }, { "abcdefghijklmnopqrstuvwxyz", "\x4d\xbf\xf8\x6c\xc2\xca\x1b\xae\x1e\x16\x46\x8a\x05\xcb\x98\x81" "\xc9\x7f\x17\x53\xbc\xe3\x61\x90\x34\x89\x8f\xaa\x1a\xab\xe4\x29" "\x95\x5a\x1b\xf8\xec\x48\x3d\x74\x21\xfe\x3c\x16\x46\x61\x3a\x59" "\xed\x54\x41\xfb\x0f\x32\x13\x89\xf7\x7f\x48\xa8\x79\xc7\xb1\xf1" }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x20\x4a\x8f\xc6\xdd\xa8\x2f\x0a\x0c\xed\x7b\xeb\x8e\x08\xa4\x16" "\x57\xc1\x6e\xf4\x68\xb2\x28\xa8\x27\x9b\xe3\x31\xa7\x03\xc3\x35" "\x96\xfd\x15\xc1\x3b\x1b\x07\xf9\xaa\x1d\x3b\xea\x57\x78\x9c\xa0" "\x31\xad\x85\xc7\xa7\x1d\xd7\x03\x54\xec\x63\x12\x38\xca\x34\x45" }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\x1e\x07\xbe\x23\xc2\x6a\x86\xea\x37\xea\x81\x0c\x8e\xc7\x80\x93" "\x52\x51\x5a\x97\x0e\x92\x53\xc2\x6f\x53\x6c\xfc\x7a\x99\x96\xc4" "\x5c\x83\x70\x58\x3e\x0a\x78\xfa\x4a\x90\x04\x1d\x71\xa4\xce\xab" "\x74\x23\xf1\x9c\x71\xb9\xd5\xa3\xe0\x12\x49\xf0\xbe\xbd\x58\x94" }, { "123456789012345678901234567890123456789012345678901234567890" "12345678901234567890", "\x72\xec\x1e\xf1\x12\x4a\x45\xb0\x47\xe8\xb7\xc7\x5a\x93\x21\x95" "\x13\x5b\xb6\x1d\xe2\x4e\xc0\xd1\x91\x40\x42\x24\x6e\x0a\xec\x3a" "\x23\x54\xe0\x93\xd7\x6f\x30\x48\xb4\x56\x76\x43\x46\x90\x0c\xb1" "\x30\xd2\xa4\xfd\x5d\xd1\x6a\xbb\x5e\x30\xbc\xb8\x50\xde\xe8\x43" } }; #define ntests (sizeof (tests) / sizeof (tests[0])) static const struct { const char *salt; const char *input; const char *expected; } tests2[] = { { "$6$saltstring", "Hello world!", "$6$saltstring$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu" "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1" }, { "$6$rounds=10000$saltstringsaltstring", "Hello world!", "$6$rounds=10000$saltstringsaltst$OW1/O6BYHV6BcXZu8QVeXbDWra3Oeqh0sb" "HbbMCVNSnCM/UrjmM0Dp8vOuZeHBy/YTBmSK6H9qs/y3RnOaw5v." }, { "$6$rounds=5000$toolongsaltstring", "This is just a test", "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQ" "zQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0" }, { "$6$rounds=1400$anotherlongsaltstring", "a very much longer text to encrypt. This one even stretches over more" "than one line.", "$6$rounds=1400$anotherlongsalts$POfYwTEok97VWcjxIiSOjiykti.o/pQs.wP" "vMxQ6Fm7I6IoYN3CmLs66x9t0oSwbtEW7o7UmJEiDwGqd8p4ur1" }, { "$6$rounds=77777$short", "we have a short salt string but not a short password", "$6$rounds=77777$short$WuQyW2YR.hBNpjjRhpYD/ifIw05xdfeEyQoMxIXbkvr0g" "ge1a1x3yRULJ5CCaUeOxFmtlcGZelFl5CxtgfiAc0" }, { "$6$rounds=123456$asaltof16chars..", "a short string", "$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwc" "elCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1" }, { "$6$rounds=10$roundstoolow", "the minimum number is still observed", "$6$rounds=1000$roundstoolow$kUMsbe306n21p9R.FRkW3IGn.S9NPN0x50YhH1x" "hLsPuWGsUSklZt58jaTfF4ZEQpyUNGc0dqbpBYYBaHHrsX." }, }; #define ntests2 (sizeof (tests2) / sizeof (tests2[0])) int main (void) { struct sha512_ctx ctx; char sum[64]; int result = 0; int cnt; for (cnt = 0; cnt < (int) ntests; ++cnt) { sha512_init_ctx (&ctx); sha512_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx); sha512_finish_ctx (&ctx, sum); if (memcmp (tests[cnt].result, sum, 64) != 0) { printf ("test %d run %d failed\n", cnt, 1); result = 1; } sha512_init_ctx (&ctx); for (int i = 0; tests[cnt].input[i] != '\0'; ++i) sha512_process_bytes (&tests[cnt].input[i], 1, &ctx); sha512_finish_ctx (&ctx, sum); if (memcmp (tests[cnt].result, sum, 64) != 0) { printf ("test %d run %d failed\n", cnt, 2); result = 1; } } /* Test vector from FIPS 180-2: appendix C.3. */ char buf[1000]; memset (buf, 'a', sizeof (buf)); sha512_init_ctx (&ctx); for (int i = 0; i < 1000; ++i) sha512_process_bytes (buf, sizeof (buf), &ctx); sha512_finish_ctx (&ctx, sum); static const char expected[64] = "\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63" "\x8e\x1f\x98\xb1\x3b\x20\x44\x28\x56\x32\xa8\x03\xaf\xa9\x73\xeb" "\xde\x0f\xf2\x44\x87\x7e\xa6\x0a\x4c\xb0\x43\x2c\xe5\x77\xc3\x1b" "\xeb\x00\x9c\x5c\x2c\x49\xaa\x2e\x4e\xad\xb2\x17\xad\x8c\xc0\x9b"; if (memcmp (expected, sum, 64) != 0) { printf ("test %d failed\n", cnt); result = 1; } for (cnt = 0; cnt < ntests2; ++cnt) { char *cp = sha512_crypt (tests2[cnt].input, tests2[cnt].salt); if (strcmp (cp, tests2[cnt].expected) != 0) { printf ("test %d: expected \"%s\", got \"%s\"\n", cnt, tests2[cnt].expected, cp); result = 1; } } if (result == 0) puts ("all tests OK"); return result; } #endif syslinux-legacy-3.63+dfsg/com32/libutil/sha256crypt.c0000664000175000017500000005303310777447272021044 0ustar evanevan/* SHA256-based Unix crypt implementation. Released into the Public Domain by Ulrich Drepper . */ #include #include #include #include #include #include #include #include #include #include #include #include "xcrypt.h" #define MIN(x,y) min(x,y) #define MAX(x,y) max(x,y) /* Structure to save state of computation between the single steps. */ struct sha256_ctx { uint32_t H[8]; uint32_t total[2]; uint32_t buflen; char buffer[128]; /* NB: always correctly aligned for uint32_t. */ }; #if __BYTE_ORDER == __LITTLE_ENDIAN # define SWAP(n) \ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) #else # define SWAP(n) (n) #endif /* This array contains the bytes used to pad the buffer to the next 64-byte boundary. (FIPS 180-2:5.1.1) */ static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; /* Constants for SHA256 from FIPS 180-2:4.2.2. */ static const uint32_t K[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; /* Process LEN bytes of BUFFER, accumulating context into CTX. It is assumed that LEN % 64 == 0. */ static void sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx) { unsigned int t; const uint32_t *words = buffer; size_t nwords = len / sizeof (uint32_t); uint32_t a = ctx->H[0]; uint32_t b = ctx->H[1]; uint32_t c = ctx->H[2]; uint32_t d = ctx->H[3]; uint32_t e = ctx->H[4]; uint32_t f = ctx->H[5]; uint32_t g = ctx->H[6]; uint32_t h = ctx->H[7]; /* First increment the byte count. FIPS 180-2 specifies the possible length of the file up to 2^64 bits. Here we only compute the number of bytes. Do a double word increment. */ ctx->total[0] += len; if (ctx->total[0] < len) ++ctx->total[1]; /* Process all bytes in the buffer with 64 bytes in each round of the loop. */ while (nwords > 0) { uint32_t W[64]; uint32_t a_save = a; uint32_t b_save = b; uint32_t c_save = c; uint32_t d_save = d; uint32_t e_save = e; uint32_t f_save = f; uint32_t g_save = g; uint32_t h_save = h; /* Operators defined in FIPS 180-2:4.1.2. */ #define Ch(x, y, z) ((x & y) ^ (~x & z)) #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) #define S0(x) (CYCLIC (x, 2) ^ CYCLIC (x, 13) ^ CYCLIC (x, 22)) #define S1(x) (CYCLIC (x, 6) ^ CYCLIC (x, 11) ^ CYCLIC (x, 25)) #define R0(x) (CYCLIC (x, 7) ^ CYCLIC (x, 18) ^ (x >> 3)) #define R1(x) (CYCLIC (x, 17) ^ CYCLIC (x, 19) ^ (x >> 10)) /* It is unfortunate that C does not provide an operator for cyclic rotation. Hope the C compiler is smart enough. */ #define CYCLIC(w, s) ((w >> s) | (w << (32 - s))) /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */ for (t = 0; t < 16; ++t) { W[t] = SWAP (*words); ++words; } for (t = 16; t < 64; ++t) W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16]; /* The actual computation according to FIPS 180-2:6.2.2 step 3. */ for (t = 0; t < 64; ++t) { uint32_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t]; uint32_t T2 = S0 (a) + Maj (a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; } /* Add the starting values of the context according to FIPS 180-2:6.2.2 step 4. */ a += a_save; b += b_save; c += c_save; d += d_save; e += e_save; f += f_save; g += g_save; h += h_save; /* Prepare for the next round. */ nwords -= 16; } /* Put checksum in context given as argument. */ ctx->H[0] = a; ctx->H[1] = b; ctx->H[2] = c; ctx->H[3] = d; ctx->H[4] = e; ctx->H[5] = f; ctx->H[6] = g; ctx->H[7] = h; } /* Initialize structure containing state of computation. (FIPS 180-2:5.3.2) */ static void sha256_init_ctx (struct sha256_ctx *ctx) { ctx->H[0] = 0x6a09e667; ctx->H[1] = 0xbb67ae85; ctx->H[2] = 0x3c6ef372; ctx->H[3] = 0xa54ff53a; ctx->H[4] = 0x510e527f; ctx->H[5] = 0x9b05688c; ctx->H[6] = 0x1f83d9ab; ctx->H[7] = 0x5be0cd19; ctx->total[0] = ctx->total[1] = 0; ctx->buflen = 0; } /* Process the remaining bytes in the internal buffer and the usual prolog according to the standard and write the result to RESBUF. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ static void * sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf) { unsigned int i; /* Take yet unprocessed bytes into account. */ uint32_t bytes = ctx->buflen; size_t pad; /* Now count remaining bytes. */ ctx->total[0] += bytes; if (ctx->total[0] < bytes) ++ctx->total[1]; pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; memcpy (&ctx->buffer[bytes], fillbuf, pad); /* Put the 64-bit file length in *bits* at the end of the buffer. */ *(uint32_t *) &ctx->buffer[bytes + pad + 4] = SWAP (ctx->total[0] << 3); *(uint32_t *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); /* Process last bytes. */ sha256_process_block (ctx->buffer, bytes + pad + 8, ctx); /* Put result from CTX in first 32 bytes following RESBUF. */ for (i = 0; i < 8; ++i) ((uint32_t *) resbuf)[i] = SWAP (ctx->H[i]); return resbuf; } static void sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx) { /* When we already have some bits in our internal buffer concatenate both inputs first. */ if (ctx->buflen != 0) { size_t left_over = ctx->buflen; size_t add = 128 - left_over > len ? len : 128 - left_over; memcpy (&ctx->buffer[left_over], buffer, add); ctx->buflen += add; if (ctx->buflen > 64) { sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx); ctx->buflen &= 63; /* The regions in the following copy operation cannot overlap. */ memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], ctx->buflen); } buffer = (const char *) buffer + add; len -= add; } /* Process available complete blocks. */ if (len >= 64) { /* To check alignment gcc has an appropriate operator. Other compilers don't. */ #if __GNUC__ >= 2 # define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint32_t) != 0) #else # define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint32_t) != 0) #endif if (UNALIGNED_P (buffer)) while (len > 64) { sha256_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); buffer = (const char *) buffer + 64; len -= 64; } else { sha256_process_block (buffer, len & ~63, ctx); buffer = (const char *) buffer + (len & ~63); len &= 63; } } /* Move remaining bytes into internal buffer. */ if (len > 0) { size_t left_over = ctx->buflen; memcpy (&ctx->buffer[left_over], buffer, len); left_over += len; if (left_over >= 64) { sha256_process_block (ctx->buffer, 64, ctx); left_over -= 64; memcpy (ctx->buffer, &ctx->buffer[64], left_over); } ctx->buflen = left_over; } } /* Define our magic string to mark salt for SHA256 "encryption" replacement. */ static const char sha256_salt_prefix[] = "$5$"; /* Prefix for optional rounds specification. */ static const char sha256_rounds_prefix[] = "rounds="; /* Maximum salt string length. */ #define SALT_LEN_MAX 16 /* Default number of rounds if not explicitly specified. */ #define ROUNDS_DEFAULT 5000 /* Minimum number of rounds. */ #define ROUNDS_MIN 1000 /* Maximum number of rounds. */ #define ROUNDS_MAX 999999999 /* Table with characters for base64 transformation. */ static const char b64t[64] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static char * sha256_crypt_r (const char *key, const char *salt, char *buffer, int buflen) { unsigned char alt_result[32] __attribute__ ((__aligned__ (__alignof__ (uint32_t)))); unsigned char temp_result[32] __attribute__ ((__aligned__ (__alignof__ (uint32_t)))); struct sha256_ctx ctx; struct sha256_ctx alt_ctx; size_t salt_len; size_t key_len; size_t cnt; char *cp; char *copied_key = NULL; char *copied_salt = NULL; char *p_bytes; char *s_bytes; /* Default number of rounds. */ size_t rounds = ROUNDS_DEFAULT; bool rounds_custom = false; /* Find beginning of salt string. The prefix should normally always be present. Just in case it is not. */ if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0) /* Skip salt prefix. */ salt += sizeof (sha256_salt_prefix) - 1; if (strncmp (salt, sha256_rounds_prefix, sizeof (sha256_rounds_prefix) - 1) == 0) { const char *num = salt + sizeof (sha256_rounds_prefix) - 1; char *endp; unsigned long int srounds = strtoul (num, &endp, 10); if (*endp == '$') { salt = endp + 1; rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX)); rounds_custom = true; } } salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX); key_len = strlen (key); if ((key - (char *) 0) % __alignof__ (uint32_t) != 0) { char *tmp = (char *) alloca (key_len + __alignof__ (uint32_t)); key = copied_key = memcpy (tmp + __alignof__ (uint32_t) - (tmp - (char *) 0) % __alignof__ (uint32_t), key, key_len); } if ((salt - (char *) 0) % __alignof__ (uint32_t) != 0) { char *tmp = (char *) alloca (salt_len + __alignof__ (uint32_t)); salt = copied_salt = memcpy (tmp + __alignof__ (uint32_t) - (tmp - (char *) 0) % __alignof__ (uint32_t), salt, salt_len); } /* Prepare for the real work. */ sha256_init_ctx (&ctx); /* Add the key string. */ sha256_process_bytes (key, key_len, &ctx); /* The last part is the salt string. This must be at most 8 characters and it ends at the first `$' character (for compatibility with existing implementations). */ sha256_process_bytes (salt, salt_len, &ctx); /* Compute alternate SHA256 sum with input KEY, SALT, and KEY. The final result will be added to the first context. */ sha256_init_ctx (&alt_ctx); /* Add key. */ sha256_process_bytes (key, key_len, &alt_ctx); /* Add salt. */ sha256_process_bytes (salt, salt_len, &alt_ctx); /* Add key again. */ sha256_process_bytes (key, key_len, &alt_ctx); /* Now get result of this (32 bytes) and add it to the other context. */ sha256_finish_ctx (&alt_ctx, alt_result); /* Add for any character in the key one byte of the alternate sum. */ for (cnt = key_len; cnt > 32; cnt -= 32) sha256_process_bytes (alt_result, 32, &ctx); sha256_process_bytes (alt_result, cnt, &ctx); /* Take the binary representation of the length of the key and for every 1 add the alternate sum, for every 0 the key. */ for (cnt = key_len; cnt > 0; cnt >>= 1) if ((cnt & 1) != 0) sha256_process_bytes (alt_result, 32, &ctx); else sha256_process_bytes (key, key_len, &ctx); /* Create intermediate result. */ sha256_finish_ctx (&ctx, alt_result); /* Start computation of P byte sequence. */ sha256_init_ctx (&alt_ctx); /* For every character in the password add the entire password. */ for (cnt = 0; cnt < key_len; ++cnt) sha256_process_bytes (key, key_len, &alt_ctx); /* Finish the digest. */ sha256_finish_ctx (&alt_ctx, temp_result); /* Create byte sequence P. */ cp = p_bytes = alloca (key_len); for (cnt = key_len; cnt >= 32; cnt -= 32) cp = mempcpy (cp, temp_result, 32); memcpy (cp, temp_result, cnt); /* Start computation of S byte sequence. */ sha256_init_ctx (&alt_ctx); /* For every character in the password add the entire password. */ for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt) sha256_process_bytes (salt, salt_len, &alt_ctx); /* Finish the digest. */ sha256_finish_ctx (&alt_ctx, temp_result); /* Create byte sequence S. */ cp = s_bytes = alloca (salt_len); for (cnt = salt_len; cnt >= 32; cnt -= 32) cp = mempcpy (cp, temp_result, 32); memcpy (cp, temp_result, cnt); /* Repeatedly run the collected hash value through SHA256 to burn CPU cycles. */ for (cnt = 0; cnt < rounds; ++cnt) { /* New context. */ sha256_init_ctx (&ctx); /* Add key or last result. */ if ((cnt & 1) != 0) sha256_process_bytes (p_bytes, key_len, &ctx); else sha256_process_bytes (alt_result, 32, &ctx); /* Add salt for numbers not divisible by 3. */ if (cnt % 3 != 0) sha256_process_bytes (s_bytes, salt_len, &ctx); /* Add key for numbers not divisible by 7. */ if (cnt % 7 != 0) sha256_process_bytes (p_bytes, key_len, &ctx); /* Add key or last result. */ if ((cnt & 1) != 0) sha256_process_bytes (alt_result, 32, &ctx); else sha256_process_bytes (p_bytes, key_len, &ctx); /* Create intermediate result. */ sha256_finish_ctx (&ctx, alt_result); } /* Now we can construct the result string. It consists of three parts. */ cp = stpncpy (buffer, sha256_salt_prefix, MAX (0, buflen)); buflen -= sizeof (sha256_salt_prefix) - 1; if (rounds_custom) { int n = snprintf (cp, MAX (0, buflen), "%s%zu$", sha256_rounds_prefix, rounds); cp += n; buflen -= n; } cp = stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len)); buflen -= MIN ((size_t) MAX (0, buflen), salt_len); if (buflen > 0) { *cp++ = '$'; --buflen; } #define b64_from_24bit(B2, B1, B0, N) \ do { \ unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \ int n = (N); \ while (n-- > 0 && buflen > 0) \ { \ *cp++ = b64t[w & 0x3f]; \ --buflen; \ w >>= 6; \ } \ } while (0) b64_from_24bit (alt_result[0], alt_result[10], alt_result[20], 4); b64_from_24bit (alt_result[21], alt_result[1], alt_result[11], 4); b64_from_24bit (alt_result[12], alt_result[22], alt_result[2], 4); b64_from_24bit (alt_result[3], alt_result[13], alt_result[23], 4); b64_from_24bit (alt_result[24], alt_result[4], alt_result[14], 4); b64_from_24bit (alt_result[15], alt_result[25], alt_result[5], 4); b64_from_24bit (alt_result[6], alt_result[16], alt_result[26], 4); b64_from_24bit (alt_result[27], alt_result[7], alt_result[17], 4); b64_from_24bit (alt_result[18], alt_result[28], alt_result[8], 4); b64_from_24bit (alt_result[9], alt_result[19], alt_result[29], 4); b64_from_24bit (0, alt_result[31], alt_result[30], 3); if (buflen <= 0) { errno = ERANGE; buffer = NULL; } else *cp = '\0'; /* Terminate the string. */ /* Clear the buffer for the intermediate result so that people attaching to processes or reading core dumps cannot get any information. We do it in this way to clear correct_words[] inside the SHA256 implementation as well. */ sha256_init_ctx (&ctx); sha256_finish_ctx (&ctx, alt_result); memset (temp_result, '\0', sizeof (temp_result)); memset (p_bytes, '\0', key_len); memset (s_bytes, '\0', salt_len); memset (&ctx, '\0', sizeof (ctx)); memset (&alt_ctx, '\0', sizeof (alt_ctx)); if (copied_key != NULL) memset (copied_key, '\0', key_len); if (copied_salt != NULL) memset (copied_salt, '\0', salt_len); return buffer; } /* This entry point is equivalent to the `crypt' function in Unix libcs. */ char * sha256_crypt (const char *key, const char *salt) { /* We don't want to have an arbitrary limit in the size of the password. We can compute an upper bound for the size of the result in advance and so we can prepare the buffer we pass to `sha256_crypt_r'. */ static char *buffer; static int buflen; int needed = (sizeof (sha256_salt_prefix) - 1 + sizeof (sha256_rounds_prefix) + 9 + 1 + strlen (salt) + 1 + 43 + 1); if (buflen < needed) { char *new_buffer = (char *) realloc (buffer, needed); if (new_buffer == NULL) return NULL; buffer = new_buffer; buflen = needed; } return sha256_crypt_r (key, salt, buffer, buflen); } #ifdef TEST static const struct { const char *input; const char result[32]; } tests[] = { /* Test vectors from FIPS 180-2: appendix B.1. */ { "abc", "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23" "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" }, /* Test vectors from FIPS 180-2: appendix B.2. */ { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39" "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" }, /* Test vectors from the NESSIE project. */ { "", "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24" "\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55" }, { "a", "\xca\x97\x81\x12\xca\x1b\xbd\xca\xfa\xc2\x31\xb3\x9a\x23\xdc\x4d" "\xa7\x86\xef\xf8\x14\x7c\x4e\x72\xb9\x80\x77\x85\xaf\xee\x48\xbb" }, { "message digest", "\xf7\x84\x6f\x55\xcf\x23\xe1\x4e\xeb\xea\xb5\xb4\xe1\x55\x0c\xad" "\x5b\x50\x9e\x33\x48\xfb\xc4\xef\xa3\xa1\x41\x3d\x39\x3c\xb6\x50" }, { "abcdefghijklmnopqrstuvwxyz", "\x71\xc4\x80\xdf\x93\xd6\xae\x2f\x1e\xfa\xd1\x44\x7c\x66\xc9\x52" "\x5e\x31\x62\x18\xcf\x51\xfc\x8d\x9e\xd8\x32\xf2\xda\xf1\x8b\x73" }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39" "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xdb\x4b\xfc\xbd\x4d\xa0\xcd\x85\xa6\x0c\x3c\x37\xd3\xfb\xd8\x80" "\x5c\x77\xf1\x5f\xc6\xb1\xfd\xfe\x61\x4e\xe0\xa7\xc8\xfd\xb4\xc0" }, { "123456789012345678901234567890123456789012345678901234567890" "12345678901234567890", "\xf3\x71\xbc\x4a\x31\x1f\x2b\x00\x9e\xef\x95\x2d\xd8\x3c\xa8\x0e" "\x2b\x60\x02\x6c\x8e\x93\x55\x92\xd0\xf9\xc3\x08\x45\x3c\x81\x3e" } }; #define ntests (sizeof (tests) / sizeof (tests[0])) static const struct { const char *salt; const char *input; const char *expected; } tests2[] = { { "$5$saltstring", "Hello world!", "$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5" }, { "$5$rounds=10000$saltstringsaltstring", "Hello world!", "$5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2." "opqey6IcA" }, { "$5$rounds=5000$toolongsaltstring", "This is just a test", "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8" "mGRcvxa5" }, { "$5$rounds=1400$anotherlongsaltstring", "a very much longer text to encrypt. This one even stretches over more" "than one line.", "$5$rounds=1400$anotherlongsalts$Rx.j8H.h8HjEDGomFU8bDkXm3XIUnzyxf12" "oP84Bnq1" }, { "$5$rounds=77777$short", "we have a short salt string but not a short password", "$5$rounds=77777$short$JiO1O3ZpDAxGJeaDIuqCoEFysAe1mZNJRs3pw0KQRd/" }, { "$5$rounds=123456$asaltof16chars..", "a short string", "$5$rounds=123456$asaltof16chars..$gP3VQ/6X7UUEW3HkBn2w1/Ptq2jxPyzV/" "cZKmF/wJvD" }, { "$5$rounds=10$roundstoolow", "the minimum number is still observed", "$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL97" "2bIC" }, }; #define ntests2 (sizeof (tests2) / sizeof (tests2[0])) int main (void) { struct sha256_ctx ctx; char sum[32]; int result = 0; int cnt; for (cnt = 0; cnt < (int) ntests; ++cnt) { sha256_init_ctx (&ctx); sha256_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx); sha256_finish_ctx (&ctx, sum); if (memcmp (tests[cnt].result, sum, 32) != 0) { printf ("test %d run %d failed\n", cnt, 1); result = 1; } sha256_init_ctx (&ctx); for (int i = 0; tests[cnt].input[i] != '\0'; ++i) sha256_process_bytes (&tests[cnt].input[i], 1, &ctx); sha256_finish_ctx (&ctx, sum); if (memcmp (tests[cnt].result, sum, 32) != 0) { printf ("test %d run %d failed\n", cnt, 2); result = 1; } } /* Test vector from FIPS 180-2: appendix B.3. */ char buf[1000]; memset (buf, 'a', sizeof (buf)); sha256_init_ctx (&ctx); for (int i = 0; i < 1000; ++i) sha256_process_bytes (buf, sizeof (buf), &ctx); sha256_finish_ctx (&ctx, sum); static const char expected[32] = "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67" "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0"; if (memcmp (expected, sum, 32) != 0) { printf ("test %d failed\n", cnt); result = 1; } for (cnt = 0; cnt < ntests2; ++cnt) { char *cp = sha256_crypt (tests2[cnt].input, tests2[cnt].salt); if (strcmp (cp, tests2[cnt].expected) != 0) { printf ("test %d: expected \"%s\", got \"%s\"\n", cnt, tests2[cnt].expected, cp); result = 1; } } if (result == 0) puts ("all tests OK"); return result; } #endif syslinux-legacy-3.63+dfsg/com32/libutil/sha1hash.c0000664000175000017500000002252510777447272020454 0ustar evanevan/* SHA-1 in C By Steve Reid 100% Public Domain ----------------- Modified 7/98 By James H. Brown Still 100% Public Domain Corrected a problem which generated improper hash values on 16 bit machines Routine SHA1Update changed from void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len) to void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned long len) The 'len' parameter was declared an int which works fine on 32 bit machines. However, on 16 bit machines an int is too small for the shifts being done against it. This caused the hash function to generate incorrect values if len was greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). Since the file IO in main() reads 16K at a time, any file 8K or larger would be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million "a"s). I also changed the declaration of variables i & j in SHA1Update to unsigned long from unsigned int for the same reason. These changes should make no difference to any 32 bit implementations since an int and a long are the same size in those environments. -- I also corrected a few compiler warnings generated by Borland C. 1. Added #include for exit() prototype 2. Removed unused variable 'j' in SHA1Final 3. Changed exit(0) to return(0) at end of main. ALL changes I made can be located by searching for comments containing 'JHB' ----------------- Modified 8/98 By Steve Reid Still 100% public domain 1- Removed #include and used return() instead of exit() 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) 3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net ----------------- Modified 4/01 By Saul Kravitz Still 100% PD Modified to run on Compaq Alpha hardware. ----------------- Modified 2/03 By H. Peter Anvin Still 100% PD Modified to run on any hardware with and Changed the driver program */ /* Test Vectors (from FIPS PUB 180-1) "abc" A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 A million repetitions of "a" 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F */ /* #define SHA1HANDSOFF */ #include #include #include #include /* For htonl/ntohl/htons/ntohs */ #include "sha1.h" #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) /* blk0() and blk() perform the initial expand. */ /* I got the idea of expanding during the round function from SSLeay */ #define blk0(i) (block->l[i] = ntohl(block->l[i])) #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ ^block->l[(i+2)&15]^block->l[i&15],1)) /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); #ifdef VERBOSE /* SAK */ void SHAPrintContext(SHA1_CTX *context, char *msg){ printf("%s (%d,%d) %x %x %x %x %x\n", msg, context->count[0], context->count[1], context->state[0], context->state[1], context->state[2], context->state[3], context->state[4]); } #endif /* Hash a single 512-bit block. This is the core of the algorithm. */ void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) { uint32_t a, b, c, d, e; typedef union { unsigned char c[64]; uint32_t l[16]; } CHAR64LONG16; CHAR64LONG16* block; #ifdef SHA1HANDSOFF static unsigned char workspace[64]; block = (CHAR64LONG16*)workspace; memcpy(block, buffer, 64); #else block = (CHAR64LONG16*)buffer; #endif /* Copy context->state[] to working vars */ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; /* 4 rounds of 20 operations each. Loop unrolled. */ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); /* Add the working vars back into context.state[] */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; /* Wipe variables */ a = b = c = d = e = 0; } /* SHA1Init - Initialize new context */ void SHA1Init(SHA1_CTX* context) { /* SHA1 initialization constants */ context->state[0] = 0x67452301; context->state[1] = 0xEFCDAB89; context->state[2] = 0x98BADCFE; context->state[3] = 0x10325476; context->state[4] = 0xC3D2E1F0; context->count[0] = context->count[1] = 0; } /* Run your data through this. */ void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len) /* JHB */ { uint32_t i, j; /* JHB */ #ifdef VERBOSE SHAPrintContext(context, "before"); #endif j = (context->count[0] >> 3) & 63; if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; context->count[1] += (len >> 29); if ((j + len) > 63) { memcpy(&context->buffer[j], data, (i = 64-j)); SHA1Transform(context->state, context->buffer); for ( ; i + 63 < len; i += 64) { SHA1Transform(context->state, &data[i]); } j = 0; } else i = 0; memcpy(&context->buffer[j], &data[i], len - i); #ifdef VERBOSE SHAPrintContext(context, "after "); #endif } /* Add padding and return the message digest. */ void SHA1Final(unsigned char digest[20], SHA1_CTX* context) { uint32_t i; /* JHB */ unsigned char finalcount[8]; for (i = 0; i < 8; i++) { finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ } SHA1Update(context, (unsigned char *)"\200", 1); while ((context->count[0] & 504) != 448) { SHA1Update(context, (unsigned char *)"\0", 1); } SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ for (i = 0; i < 20; i++) { digest[i] = (unsigned char) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } /* Wipe variables */ i = 0; /* JHB */ memset(context->buffer, 0, 64); memset(context->state, 0, 20); memset(context->count, 0, 8); memset(finalcount, 0, 8); /* SWR */ #ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ SHA1Transform(context->state, context->buffer); #endif } /*************************************************************/ /* This is not quite the MIME base64 algorithm: it uses _ instead of /, and instead of padding the output with = characters we just make the output shorter. */ char *mybase64(uint8_t digest[20]) { static const char charz[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_"; uint8_t input[21]; static char output[28]; int i, j; uint8_t *p; char *q; uint32_t bv; memcpy(input, digest, 20); input[20] = 0; /* Pad to multiple of 3 bytes */ p = input; q = output; for ( i = 0 ; i < 7 ; i++ ) { bv = (p[0] << 16) | (p[1] << 8) | p[2]; p += 3; for ( j = 0 ; j < 4 ; j++ ) { *q++ = charz[(bv >> 18) & 0x3f]; bv <<= 6; } } *--q = '\0'; /* The last character is not significant */ return output; } #ifdef FOR_TESTING_ONLY int main(int argc, char** argv) { int i; SHA1_CTX context; uint8_t digest[20], buffer[16384]; FILE* file; if (argc < 2) { file = stdin; } else { if (!(file = fopen(argv[1], "rb"))) { fputs("Unable to open file.", stderr); return(-1); } } SHA1Init(&context); while (!feof(file)) { /* note: what if ferror(file) */ i = fread(buffer, 1, 16384, file); SHA1Update(&context, buffer, i); } SHA1Final(digest, &context); fclose(file); puts(mybase64(digest)); return 0; } #endif syslinux-legacy-3.63+dfsg/com32/libutil/get_key.c0000664000175000017500000001144410777447272020401 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * get_key.c * * Get a single key, and try to pick apart function key codes. * This doesn't decode anywhere close to all possiblities, but * hopefully is enough to be useful. */ #include #include #include #include #include #include #include #include struct keycode { int code; int seqlen; const unsigned char *seq; }; #define MAXLEN 8 #define CODE(x,y) { x, (sizeof y)-1, y } static const struct keycode keycodes[] = { /* First, the BIOS combined codes */ CODE(KEY_F1, "\0\x3B"), CODE(KEY_F2, "\0\x3C"), CODE(KEY_F3, "\0\x3D"), CODE(KEY_F4, "\0\x3E"), CODE(KEY_F5, "\0\x3F"), CODE(KEY_F6, "\0\x40"), CODE(KEY_F7, "\0\x41"), CODE(KEY_F8, "\0\x42"), CODE(KEY_F9, "\0\x43"), CODE(KEY_F10, "\0\x44"), CODE(KEY_F11, "\0\x85"), CODE(KEY_F12, "\0\x86"), CODE(KEY_UP, "\0\x48"), CODE(KEY_DOWN, "\0\x50"), CODE(KEY_LEFT, "\0\x4B"), CODE(KEY_RIGHT,"\0\x4D"), CODE(KEY_PGUP, "\0\x49"), CODE(KEY_PGDN, "\0\x51"), CODE(KEY_HOME, "\0\x47"), CODE(KEY_END, "\0\x4F"), CODE(KEY_INSERT, "\0\x52"), CODE(KEY_DELETE, "\0\x53"), /* Now, VT/xterm/Linux codes */ CODE(KEY_F1, "\033[[A"), CODE(KEY_F1, "\033OP"), CODE(KEY_F2, "\033[[B"), CODE(KEY_F2, "\033OQ"), CODE(KEY_F3, "\033[[C"), CODE(KEY_F3, "\033OR"), CODE(KEY_F4, "\033[[D"), CODE(KEY_F4, "\033OS"), CODE(KEY_F5, "\033[[E"), CODE(KEY_F5, "\033[15~"), CODE(KEY_F6, "\033[17~"), CODE(KEY_F7, "\033[18~"), CODE(KEY_F8, "\033[19~"), CODE(KEY_F9, "\033[20~"), CODE(KEY_F10, "\033[21~"), CODE(KEY_F11, "\033[23~"), CODE(KEY_F12, "\033[24~"), CODE(KEY_UP, "\033[A"), CODE(KEY_DOWN, "\033[B"), CODE(KEY_LEFT, "\033[D"), CODE(KEY_RIGHT,"\033[C"), CODE(KEY_PGUP, "\033[5~"), CODE(KEY_PGUP, "\033[V"), CODE(KEY_PGDN, "\033[6~"), CODE(KEY_PGDN, "\033[U"), CODE(KEY_HOME, "\033[1~"), CODE(KEY_HOME, "\033[H"), CODE(KEY_END, "\033[4~"), CODE(KEY_END, "\033[F"), CODE(KEY_END, "\033OF"), CODE(KEY_INSERT, "\033[2~"), CODE(KEY_INSERT, "\033[@"), CODE(KEY_DELETE, "\033[3~"), }; #define NCODES ((int)(sizeof keycodes/sizeof(struct keycode))) #define KEY_TIMEOUT ((CLK_TCK+9)/10) int get_key(FILE *f, clock_t timeout) { unsigned char buffer[MAXLEN]; int nc, i, rv; const struct keycode *kc; int another; unsigned char ch; clock_t start; /* We typically start in the middle of a clock tick */ if ( timeout ) timeout++; nc = 0; start = times(NULL); do { rv = read(fileno(f), &ch, 1); if ( rv == 0 || (rv == -1 && errno == EAGAIN) ) { clock_t lateness = times(NULL)-start; if ( nc && lateness > 1+KEY_TIMEOUT ) { if ( nc == 1 ) return buffer[0]; /* timeout in sequence */ else if ( timeout && lateness > timeout ) return KEY_NONE; } else if ( !nc && timeout && lateness > timeout ) return KEY_NONE; /* timeout before sequence */ do_idle(); another = 1; continue; } start = times(NULL); buffer[nc++] = ch; another = 0; for ( i = 0, kc = keycodes ; i < NCODES ; i++, kc++ ) { if ( nc == kc->seqlen && !memcmp(buffer, kc->seq, nc) ) return kc->code; else if ( nc < kc->seqlen && !memcmp(buffer, kc->seq, nc) ) { another = 1; break; } } } while ( another ); /* We got an unrecognized sequence; return the first character */ /* We really should remember this and return subsequent characters later */ return buffer[0]; } syslinux-legacy-3.63+dfsg/libfat/0000775000175000017500000000000010777447273015455 5ustar evanevansyslinux-legacy-3.63+dfsg/libfat/fat.h0000664000175000017500000000711010777447273016377 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * fat.h * * Basic data structures for a FAT filesystem */ #ifndef FAT_H #define FAT_H #include "ulint.h" /* The poor excuse FAT has for a superblock -- in the boot sector */ struct fat_bootsect { le8_t bsJump[3]; /* Jump to code */ char bsOemName[8]; /* Formatting program */ le16_t bsBytesPerSec; /* Bytes/sector */ le8_t bsSecPerClust; /* Sectors/cluster */ le16_t bsResSectors; /* Reserved sectors */ le8_t bsFATs; /* Number of FATs */ le16_t bsRootDirEnts; /* Number of entries/root directory */ le16_t bsSectors; /* Number of sectors [1] */ le8_t bsMedia; /* Magic media type byte */ le16_t bsFATsecs; /* Sectors/FAT */ le16_t bsSecPerTrack; /* Sectors/track */ le16_t bsHeads; /* Number of heads */ le32_t bsHiddenSecs; /* Number of hidden sectors */ le32_t bsHugeSectors; /* Number of sectors [2] */ union { /* FAT12/16 */ struct { le8_t bsDriveNumber; /* Drive number */ le8_t bsReserved1; /* Reserved */ le8_t bsBootSignature; /* 0x29 */ le32_t bsVolumeID; /* Volume serial number */ char bsVolumeLabel[11]; /* Volume name */ char bsFileSysType[8]; /* File system type */ le8_t bsCode[448]; /* Boot sector code */ } fat16; /* FAT32 */ struct { le32_t bpb_fatsz32; /* Sectors/FAT */ le16_t bpb_extflags; /* Extended flags */ le16_t bpb_fsver; /* Filesystem version */ le32_t bpb_rootclus; /* Root directory cluster */ le16_t bpb_fsinfo; /* FSINFO sector number */ le16_t bpb_bkbootsec; /* Backup boot sector (superblock) */ char bpb_reserved[12]; /* Same shit, different offset! */ le8_t bsDriveNumber; /* Drive number */ le8_t bsReserved1; /* Reserved */ le8_t bsBootSignature; /* 0x29 */ le32_t bsVolumeID; /* Volume serial number */ char bsVolumeLabel[11]; /* Volume name */ char bsFileSysType[8]; /* File system type */ le8_t bsCode[420]; /* Boot sector code */ } fat32; } u; le16_t bsSignature; /* 0xAA55 */ }; #define BS_BOOTSIGNATURE 0x29 #define BS_SIGNATURE 0xAA55 /* A FAT filesystem directory entry */ struct fat_dirent { le8_t name[11]; /* Mangled filename */ le8_t attribute; /* File type/attribute */ le8_t caseflags; /* VFAT: case for basis and extension */ le8_t ctime_ms; /* ms of creation time */ le32_t ctime; /* Creation time */ le16_t atime; /* Date portion (high 16 bits) of atime */ le16_t clusthi; /* FAT32: high 16 bits of cluster */ le32_t mtime; /* Modification time */ le16_t clustlo; /* First cluster pointer */ le32_t size; /* File size (bytes) */ }; /* A VFAT filesystem continuation entry */ struct fat_vfat_slot { le8_t id; /* Sequence number for slot */ le16_t name0[5]; /* 5 characters */ le8_t attribute; /* Attribute byte */ le8_t reserved; /* Reserved, MBZ */ le8_t alias_csum; /* Short name checksum */ le16_t name5[6]; /* 6 characters */ le16_t firstclust; /* MBZ */ le16_t name11[2]; /* 2 characters */ }; #endif /* FAT_H */ syslinux-legacy-3.63+dfsg/libfat/fatchain.c0000664000175000017500000000645110777447273017404 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * fatchain.c * * Follow a FAT chain */ #include "libfatint.h" #include "ulint.h" /* * Convert a cluster number (or 0 for the root directory) to a * sector number. Return -1 on failure. */ libfat_sector_t libfat_clustertosector(const struct libfat_filesystem *fs, int32_t cluster) { if ( cluster == 0 ) cluster = fs->rootcluster; if ( cluster == 0 ) return fs->rootdir; else if ( cluster < 2 || cluster >= fs->endcluster ) return -1; else return fs->data + ((libfat_sector_t)(cluster-2) << fs->clustshift); } /* * Get the next sector of either the root directory or a FAT chain. * Returns 0 on end of file and -1 on error. */ libfat_sector_t libfat_nextsector(struct libfat_filesystem *fs, libfat_sector_t s) { int32_t cluster, nextcluster; uint32_t fatoffset; libfat_sector_t fatsect; uint8_t *fsdata; uint32_t clustmask = fs->clustsize - 1; libfat_sector_t rs; if ( s < fs->data ) { if ( s < fs->rootdir ) return -1; /* Root directory */ s++; return ( s < fs->data ) ? s : 0; } rs = s - fs->data; if ( ~rs & clustmask ) return s+1; /* Next sector in cluster */ cluster = 2 + (rs >> fs->clustshift); if ( cluster >= fs->endcluster ) return -1; switch ( fs->fat_type ) { case FAT12: /* Get first byte */ fatoffset = cluster + (cluster >> 1); fatsect = fs->fat + (fatoffset >> LIBFAT_SECTOR_SHIFT); fsdata = libfat_get_sector(fs, fatsect); if ( !fsdata ) return -1; nextcluster = fsdata[fatoffset & LIBFAT_SECTOR_MASK]; /* Get second byte */ fatoffset++; fatsect = fs->fat + (fatoffset >> LIBFAT_SECTOR_SHIFT); fsdata = libfat_get_sector(fs, fatsect); if ( !fsdata ) return -1; nextcluster |= fsdata[fatoffset & LIBFAT_SECTOR_MASK] << 8; /* Extract the FAT entry */ if ( cluster & 1 ) nextcluster >>= 4; else nextcluster &= 0x0FFF; if ( nextcluster >= 0x0FF8 ) return 0; break; case FAT16: fatoffset = cluster << 1; fatsect = fs->fat + (fatoffset >> LIBFAT_SECTOR_SHIFT); fsdata = libfat_get_sector(fs, fatsect); if ( !fsdata ) return -1; nextcluster = read16((le16_t *)&fsdata[fatoffset & LIBFAT_SECTOR_MASK]); if ( nextcluster >= 0x0FFF8 ) return 0; break; case FAT28: fatoffset = cluster << 2; fatsect = fs->fat + (fatoffset >> LIBFAT_SECTOR_SHIFT); fsdata = libfat_get_sector(fs, fatsect); if ( !fsdata ) return -1; nextcluster = read32((le32_t *)&fsdata[fatoffset & LIBFAT_SECTOR_MASK]); nextcluster &= 0x0FFFFFFF; if ( nextcluster >= 0x0FFFFFF8 ) return 0; break; default: return -1; /* WTF? */ } return libfat_clustertosector(fs, nextcluster); } syslinux-legacy-3.63+dfsg/libfat/open.c0000664000175000017500000000571110777447273016566 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * open.c * * Open a FAT filesystem and compute some initial values; return NULL * on failure. */ #include #include "libfatint.h" #include "ulint.h" struct libfat_filesystem * libfat_open(int (*readfunc)(intptr_t, void *, size_t, libfat_sector_t), intptr_t readptr) { struct libfat_filesystem *fs = NULL; struct fat_bootsect *bs; int i; uint32_t sectors, fatsize, minfatsize, rootdirsize; uint32_t nclusters; fs = malloc(sizeof(struct libfat_filesystem)); if ( !fs ) goto barf; fs->sectors = NULL; fs->read = readfunc; fs->readptr = readptr; bs = libfat_get_sector(fs, 0); if ( !bs ) goto barf; if ( read16(&bs->bsBytesPerSec) != LIBFAT_SECTOR_SIZE ) goto barf; for ( i = 0 ; i <= 8 ; i++ ) { if ( (uint8_t)(1 << i) == read8(&bs->bsSecPerClust) ) break; } if ( i > 8 ) goto barf; fs->clustsize = 1 << i; /* Treat 0 as 2^8 = 64K */ fs->clustshift = i; sectors = read16(&bs->bsSectors); if ( !sectors ) sectors = read32(&bs->bsHugeSectors); fs->end = sectors; fs->fat = read16(&bs->bsResSectors); fatsize = read16(&bs->bsFATsecs); if ( !fatsize ) fatsize = read32(&bs->u.fat32.bpb_fatsz32); fs->rootdir = fs->fat + fatsize * read8(&bs->bsFATs); rootdirsize = ((read16(&bs->bsRootDirEnts) << 5) + LIBFAT_SECTOR_MASK) >> LIBFAT_SECTOR_SHIFT; fs->data = fs->rootdir + rootdirsize; /* Sanity checking */ if ( fs->data >= fs->end ) goto barf; /* Figure out how many clusters */ nclusters = (fs->end - fs->data) >> fs->clustshift; fs->endcluster = nclusters + 2; if ( nclusters <= 0xff4 ) { fs->fat_type = FAT12; minfatsize = fs->endcluster + (fs->endcluster >> 1); } else if ( nclusters <= 0xfff4 ) { fs->fat_type = FAT16; minfatsize = fs->endcluster << 1; } else if ( nclusters <= 0xffffff4 ) { fs->fat_type = FAT28; minfatsize = fs->endcluster << 2; } else goto barf; /* Impossibly many clusters */ minfatsize = (minfatsize + LIBFAT_SECTOR_SIZE-1) >> LIBFAT_SECTOR_SHIFT; if ( minfatsize > fatsize ) goto barf; /* The FATs don't fit */ if ( fs->fat_type == FAT28 ) fs->rootcluster = read32(&bs->u.fat32.bpb_rootclus); else fs->rootcluster = 0; return fs; /* All good */ barf: if ( fs ) free(fs); return NULL; } void libfat_close(struct libfat_filesystem *fs) { libfat_flush(fs); free(fs); } syslinux-legacy-3.63+dfsg/libfat/cache.c0000664000175000017500000000305010777447273016662 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * cache.c * * Simple sector cache */ #include #include "libfatint.h" void * libfat_get_sector(struct libfat_filesystem *fs, libfat_sector_t n) { struct libfat_sector *ls; for ( ls = fs->sectors ; ls ; ls = ls->next ) { if ( ls->n == n ) return ls->data; /* Found in cache */ } /* Not found in cache */ ls = malloc(sizeof(struct libfat_sector)); if ( !ls ) { libfat_flush(fs); ls = malloc(sizeof(struct libfat_sector)); if ( !ls ) return NULL; /* Can't allocate memory */ } if ( fs->read(fs->readptr, ls->data, LIBFAT_SECTOR_SIZE, n) != LIBFAT_SECTOR_SIZE ) { free(ls); return NULL; /* I/O error */ } ls->n = n; ls->next = fs->sectors; fs->sectors = ls; return ls->data; } void libfat_flush(struct libfat_filesystem *fs) { struct libfat_sector *ls, *lsnext; lsnext = fs->sectors; fs->sectors = NULL; for ( ls = lsnext ; ls ; ls = lsnext ) { lsnext = ls->next; free(ls); } } syslinux-legacy-3.63+dfsg/libfat/searchdir.c0000664000175000017500000000352010777447273017565 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * searchdir.c * * Search a FAT directory for a particular pre-mangled filename. * Copies the directory entry into direntry and returns the starting cluster * if found; returns -2 on not found, -1 on error, 0 on empty file. */ #include #include "libfatint.h" int32_t libfat_searchdir(struct libfat_filesystem *fs, int32_t dirclust, const void *name, struct libfat_direntry *direntry) { struct fat_dirent *dep; int nent; libfat_sector_t s = libfat_clustertosector(fs, dirclust); while ( 1 ) { if ( s == 0 ) return -2; /* Not found */ else if ( s == (libfat_sector_t)-1 ) return -1; /* Error */ dep = libfat_get_sector(fs, s); if ( !dep ) return -1; /* Read error */ for ( nent = 0 ; nent < LIBFAT_SECTOR_SIZE ; nent += sizeof(struct fat_dirent) ) { if ( !memcmp(dep->name, name, 11) ) { if ( direntry ) { memcpy(direntry->entry, dep, sizeof (*dep)); direntry->sector = s; direntry->offset = nent; } if ( read32(&dep->size) == 0 ) return 0; /* An empty file has no clusters */ else return read16(&dep->clustlo) + (read16(&dep->clusthi) << 16); } if ( dep->name[0] == 0 ) return -2; /* Hit high water mark */ dep++; } s = libfat_nextsector(fs, s); } } syslinux-legacy-3.63+dfsg/libfat/libfatint.h0000664000175000017500000000270610777447273017607 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * libfatint.h * * Internals for the libfat filesystem */ #ifndef LIBFATINT_H #define LIBFATINT_H #include "libfat.h" #include "fat.h" struct libfat_sector { libfat_sector_t n; /* Sector number */ struct libfat_sector *next; /* Next in list */ char data[LIBFAT_SECTOR_SIZE]; }; enum fat_type { FAT12, FAT16, FAT28 }; struct libfat_filesystem { int (*read)(intptr_t, void *, size_t, libfat_sector_t); intptr_t readptr; enum fat_type fat_type; unsigned int clustsize; int clustshift; int32_t endcluster; /* Highest legal cluster number + 1 */ int32_t rootcluster; /* Root directory cluster */ libfat_sector_t fat; /* Start of FAT */ libfat_sector_t rootdir; /* Start of root directory */ libfat_sector_t data; /* Start of data area */ libfat_sector_t end; /* End of filesystem */ struct libfat_sector *sectors; }; #endif /* LIBFATINT_H */ syslinux-legacy-3.63+dfsg/libfat/libfat.h0000664000175000017500000000456010777447273017074 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * libfat.h * * Headers for the libfat library */ #ifndef LIBFAT_H #define LIBFAT_H #include #include #define LIBFAT_SECTOR_SHIFT 9 #define LIBFAT_SECTOR_SIZE 512 #define LIBFAT_SECTOR_MASK 511 typedef uint32_t libfat_sector_t; struct libfat_filesystem; struct libfat_direntry { libfat_sector_t sector; int offset; unsigned char entry[32]; }; /* * Open the filesystem. The readfunc is the function to read * sectors, in the format: * int readfunc(intptr_t readptr, void *buf, size_t secsize, * libfat_sector_t secno) * * ... where readptr is a private argument. * * A return value of != secsize is treated as error. */ struct libfat_filesystem * libfat_open(int (*readfunc)(intptr_t, void *, size_t, libfat_sector_t), intptr_t readptr); void libfat_close(struct libfat_filesystem *); /* * Convert a cluster number (or 0 for the root directory) to a * sector number. Return -1 on failure. */ libfat_sector_t libfat_clustertosector(const struct libfat_filesystem *fs, int32_t cluster); /* * Get the next sector of either the root directory or a FAT chain. * Returns 0 on end of file and -1 on error. */ libfat_sector_t libfat_nextsector(struct libfat_filesystem *fs, libfat_sector_t s); /* * Flush all cached sectors for this filesystem. */ void libfat_flush(struct libfat_filesystem *fs); /* * Get a pointer to a specific sector. */ void * libfat_get_sector(struct libfat_filesystem *fs, libfat_sector_t n); /* * Search a FAT directory for a particular pre-mangled filename. * Copies the directory entry into direntry and returns 0 if found. */ int32_t libfat_searchdir(struct libfat_filesystem *fs, int32_t dirclust, const void *name, struct libfat_direntry *direntry); #endif /* LIBFAT_H */ syslinux-legacy-3.63+dfsg/libfat/ulint.h0000664000175000017500000000427610777447273016772 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, * USA; either version 2 of the License, or (at your option) any later * version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * ulint.h * * Basic operations on unaligned, littleendian integers */ #ifndef ULINT_H #define ULINT_H #include /* These are unaligned, littleendian integer types */ typedef uint8_t le8_t; /* 8-bit byte */ typedef uint8_t le16_t[2]; /* 16-bit word */ typedef uint8_t le32_t[4]; /* 32-bit dword */ /* Read/write these quantities */ static inline unsigned char read8(le8_t *_p) { return *_p; } static inline void write8(le8_t *_p, uint8_t _v) { *_p = _v; } #if defined(__i386__) || defined(__x86_64__) /* Littleendian architectures which support unaligned memory accesses */ static inline unsigned short read16(le16_t *_p) { return *((const uint16_t *)_p); } static inline void write16(le16_t *_p, unsigned short _v) { *((uint16_t *)_p) = _v; } static inline unsigned int read32(le32_t *_p) { return *((const uint32_t *)_p); } static inline void write32(le32_t *_p, uint32_t _v) { *((uint32_t *)_p) = _v; } #else /* Generic, mostly portable versions */ static inline unsigned short read16(le16_t *_pp) { uint8_t *_p = *_pp; uint16_t _v; _v = _p[0]; _v |= _p[1] << 8; return _v; } static inline void write16(le16_t *_pp, uint16_t _v) { uint8_t *_p = *_pp; _p[0] = _v & 0xFF; _p[1] = (_v >> 8) & 0xFF; } static inline unsigned int read32(le32_t *_pp) { uint8_t *_p = *_pp; uint32_t _v; _v = _p[0]; _v |= _p[1] << 8; _v |= _p[2] << 16; _v |= _p[3] << 24; return _v; } static inline void write32(le32_t *_pp, uint32_t _v) { uint8_t *_p = *_pp; _p[0] = _v & 0xFF; _p[1] = (_v >> 8) & 0xFF; _p[2] = (_v >> 16) & 0xFF; _p[3] = (_v >> 24) & 0xFF; } #endif #endif /* ULINT_H */ syslinux-legacy-3.63+dfsg/parseconfig.inc0000664000175000017500000002267710777447273017225 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; parseconfig.inc ;; ;; Configuration file operations ;; section .text ; ; "default" command ; pc_default: mov di,default_cmd call getline mov byte [di-1],0 ; null-terminate ret ; ; "ontimeout" command ; pc_ontimeout: mov di,Ontimeout call getline sub di,Ontimeout+1 ; Don't need final space mov [OntimeoutLen],di ret ; ; "onerror" command ; pc_onerror: mov di,Onerror call getline sub di,Onerror mov [OnerrorLen],di ret ; ; "append" command ; pc_append: cmp byte [VKernel],0 ja .vk mov di,AppendBuf call getline sub di,AppendBuf .app1: mov [AppendLen],di ret .vk: mov di,VKernelBuf+vk_append ; "append" command (vkernel) call getline sub di,VKernelBuf+vk_append cmp di,byte 2 jne .app2 cmp byte [VKernelBuf+vk_append],'-' jne .app2 xor di,di ; If "append -" -> null string .app2: mov [VKernelBuf+vk_appendlen],di ret ; ; "ipappend" command (PXELINUX only) ; %if IS_PXELINUX pc_ipappend: call getint jc .err cmp byte [VKernel],0 jne .vk mov [IPAppend],bl .err: ret .vk: mov [VKernelBuf+vk_ipappend],bl ret %endif ; ; "localboot" command (PXELINUX, ISOLINUX) ; %if IS_PXELINUX || IS_ISOLINUX pc_localboot: call getint cmp byte [VKernel],0 ; ("label" section only) je .err mov di,VKernelBuf+vk_rname xor ax,ax mov cx,FILENAME_MAX rep stosb ; Null kernel name %if IS_PXELINUX ; PXELINUX uses the first 4 bytes of vk_rname for the ; mangled IP address mov [VKernelBuf+vk_rname+5], bx ; Return type %else mov [VKernelBuf+vk_rname+1], bx ; Return type %endif .err: ret %endif ; ; "kernel", "config", ... command ; pc_kernel: cmp byte [VKernel],0 je .err ; ("label" section only) mov [VKernelBuf+vk_type],al call pc_getline mov di,VKernelBuf+vk_rname call mangle_name .err: ret ; ; "timeout", "totaltimeout" command ; ; N.B. 1/10 s ~ 1.D2162AABh clock ticks ; pc_timeout: push ax call getint pop si jc .err mov eax,0D2162AABh mul ebx ; clock ticks per 1/10 s add ebx,edx mov [si],ebx .err: ret ; ; "totaltimeout" command ; pc_totaltimeout: ; ; Generic integer variable setting commands: ; "prompt", "implicit" ; pc_setint16: push ax call getint pop si jc .err mov [si],bx .err: ret ; ; Generic file-processing commands: ; "font", "kbdmap", ; pc_filecmd: push ax ; Function to tailcall call pc_getline mov di,MNameBuf call mangle_name call searchdir jnz .ok pop ax ; Drop the successor function .ok: ret ; Tailcall if OK, error return ; ; Commands that expect the file to be opened on top of the getc stack. ; "display", "include" ; pc_opencmd: push ax ; Function to tailcall call pc_getline mov di,MNameBuf call mangle_name call open jnz .ok pop ax ; Drop the successor function .ok: ret ; Tailcall if OK, error return ; ; "include" command (invoked from pc_opencmd) ; pc_include: inc word [IncludeLevel] .err: ret ; ; "serial" command ; pc_serial: call getint jc .err push bx ; Serial port # call skipspace jnc .ok pop bx .err: ret .ok: call ungetc call getint mov [FlowControl], word 0 ; Default to no flow control jc .nobaud .valid_baud: push ebx call skipspace jc .no_flow call ungetc call getint ; Hardware flow control? jnc .valid_flow .no_flow: xor bx,bx ; Default -> no flow control .valid_flow: and bh,0Fh ; FlowIgnore shl bh,4 mov [FlowIgnore],bh mov bh,bl and bx,0F003h ; Valid bits mov [FlowControl],bx pop ebx ; Baud rate jmp short .parse_baud .nobaud: mov ebx,DEFAULT_BAUD ; No baud rate given .parse_baud: pop di ; Serial port # cmp ebx,byte 75 jb .err ; < 75 baud == bogus mov eax,BAUD_DIVISOR cdq div ebx mov [BaudDivisor],ax push ax ; Baud rate divisor cmp di,3 ja .port_is_io ; If port > 3 then port is I/O addr shl di,1 mov di,[di+serial_base] ; Get the I/O port from the BIOS .port_is_io: mov [SerialPort],di ; ; Begin code to actually set up the serial port ; lea dx,[di+3] ; DX -> LCR mov al,83h ; Enable DLAB call slow_out pop ax ; Divisor mov dx,di ; DX -> LS call slow_out inc dx ; DX -> MS mov al,ah call slow_out mov al,03h ; Disable DLAB inc dx ; DX -> LCR inc dx call slow_out in al,dx ; Read back LCR (detect missing hw) cmp al,03h ; If nothing here we'll read 00 or FF jne .serial_port_bad ; Assume serial port busted dec dx dec dx ; DX -> IER xor al,al ; IRQ disable call slow_out inc dx ; DX -> FCR/IIR mov al,01h call slow_out ; Enable FIFOs if present in al,dx cmp al,0C0h ; FIFOs enabled and usable? jae .fifo_ok xor ax,ax ; Disable FIFO if unusable call slow_out .fifo_ok: inc dx inc dx ; DX -> MCR in al,dx or al,[FlowOutput] ; Assert bits call slow_out ; Show some life cmp byte [SerialNotice],0 je .notfirst mov byte [SerialNotice],0 mov si,syslinux_banner call write_serial_str mov si,copyright_str call write_serial_str .notfirst: ret .serial_port_bad: mov [SerialPort], word 0 ret ; ; "F"-key command ; pc_fkey: push ax call pc_getline pop di call mangle_name ; Mangle file name ret ; ; "label" command ; pc_label: call commit_vk ; Commit any current vkernel mov di,VKernelBuf ; Erase the vkernelbuf for better compression mov cx,(vk_size >> 1) xor ax,ax rep stosw call pc_getline mov di,VKernelBuf+vk_vname call mangle_name ; Mangle virtual name mov byte [VKernel],1 ; We've seen a "label" statement mov si,VKernelBuf+vk_vname ; By default, rname == vname ; mov di,VKernelBuf+vk_rname ; -- already set mov cx,FILENAME_MAX rep movsb mov si,AppendBuf ; Default append==global append mov di,VKernelBuf+vk_append mov cx,[AppendLen] mov [VKernelBuf+vk_appendlen],cx rep movsb %if IS_PXELINUX ; PXELINUX only mov al,[IPAppend] ; Default ipappend==global ipappend mov [VKernelBuf+vk_ipappend],al %endif ret ; ; "say" command ; pc_say: call pc_getline ; "say" command call writestr jmp crlf ; tailcall ; ; "text" command; ignore everything until we get an "endtext" line ; pc_text: call pc_getline ; Ignore rest of line .loop: call pc_getline jc .eof ; Leading spaces are already removed... lodsd and eax,0xdfdfdfdf ; Upper case cmp eax,'ENDT' jne .loop lodsd and eax,0x00dfdfdf ; Upper case and mask cmp eax,'EXT' jne .loop ; If we get here we hit ENDTEXT .eof: ret ; ; Comment line ; pc_comment: ; Fall into pc_getline ; ; Common subroutine: load line into trackbuf; returns with SI -> trackbuf ; CF is set on EOF. ; pc_getline: mov di,trackbuf push di call getline mov byte [di],0 ; Null-terminate pop si ret ; ; Main loop for configuration file parsing ; parse_config: mov di,VKernelBuf ; Clear VKernelBuf at start xor ax,ax mov cx,vk_size rep stosb .again: call getcommand ; Parse one command jnc .again ; If not EOF... call close dec word [IncludeLevel] ; Still parsing? jnz .again ; ; The fall through to commit_vk to commit any final ; VKernel being read ; ; ; commit_vk: Store the current VKernelBuf into buffer segment ; commit_vk: ; For better compression, clean up the append field mov ax,[VKernelBuf+vk_appendlen] mov di,VKernelBuf+vk_append add di,ax mov cx,max_cmd_len+1 sub cx,ax xor ax,ax rep stosb ; Pack into high memory mov si,VKernelBuf mov edi,[VKernelEnd] mov cx,vk_size call rllpack mov [VKernelEnd],edi ret .overflow: mov si,vk_overflow_msg call writestr ret section .data vk_overflow_msg db 'Out of memory parsing config file', CR, LF, 0 SerialNotice db 1 ; Only print this once section .bss alignb 4 VKernelEnd resd 1 ; Lowest high memory address used ; This symbol should be used by loaders to indicate ; the highest address *they* are allowed to use. HighMemRsvd equ VKernelEnd ; by vkernels section .config align 4, db 0 KbdTimeout dd 0 ; Keyboard timeout (if any) TotalTimeout dd 0 ; Total timeout (if any) AppendLen dw 0 ; Bytes in append= command OntimeoutLen dw 0 ; Bytes in ontimeout command OnerrorLen dw 0 ; Bytes in onerror command CmdLinePtr dw cmd_line_here ; Command line advancing pointer ForcePrompt dw 0 ; Force prompt NoEscape dw 0 ; No escape AllowImplicit dw 1 ; Allow implicit kernels AllowOptions dw 1 ; User-specified options allowed IncludeLevel dw 1 ; Nesting level SerialPort dw 0 ; Serial port base (or 0 for no serial port) VKernel db 0 ; Have we seen any "label" statements? %if IS_PXELINUX IPAppend db 0 ; Default IPAPPEND option %endif section .uibss alignb 4 ; For the good of REP MOVSD command_line resb max_cmd_len+2 ; Command line buffer alignb 4 default_cmd resb max_cmd_len+1 ; "default" command line %include "rllpack.inc" syslinux-legacy-3.63+dfsg/parsecmd.inc0000664000175000017500000000645010777447273016512 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; parsecmd.inc ;; ;; Command line parser code ;; section .text ; ------------------------------------------------------------------------- ; getcommand: Get a keyword from the current "getc" file and match it ; against a list of keywords (keywd_table). Each entry in ; that table should have the following form: ; <32 bit hash value> <16 bit handler offset> ; ; The handler is called, and upon return this function ; returns with CF = 0. On EOF, this function returns ; with CF = 1. ; ------------------------------------------------------------------------- getcommand: .find: call skipspace ; Skip leading whitespace jz .eof ; End of file jc .find ; End of line: try again ; Do this explicitly so #foo is treated as a comment cmp al,'#' ; Leading hash mark -> comment je .skipline or al,20h ; Convert to lower case movzx ebx,al ; Hash for a one-char keyword .read_loop: push ebx call getc pop ebx jc .eof cmp al,' ' ; Whitespace jbe .done or al,20h rol ebx,5 xor bl,al jmp short .read_loop .done: call ungetc call skipspace jz .eof jc .noparm call ungetc ; Return nonwhitespace char to buf mov si,keywd_table mov cx,keywd_count .table_search: lodsd cmp ebx,eax je .found_keywd lodsd ; Skip entrypoint/argument loop .table_search ; Otherwise unrecognized keyword mov si,err_badcfg jmp short .error ; No parameter .noparm: mov si,err_noparm mov al,10 ; Already at EOL .error: call cwritestr jmp short .skipline .found_keywd: lodsw ; Load argument into ax call [si] clc ret .eof: stc ret .skipline: cmp al,10 ; Search for LF je .find call getc jc .eof jmp short .skipline section .data err_badcfg db 'Unknown keyword in configuration file.', CR, LF, 0 err_noparm db 'Missing parameter in configuration file.', CR, LF, 0 section .uibss alignb 4 vk_size equ (vk_end + 3) & ~3 VKernelBuf: resb vk_size ; "Current" vkernel AppendBuf resb max_cmd_len+1 ; append= Ontimeout resb max_cmd_len+1 ; ontimeout Onerror resb max_cmd_len+1 ; onerror KbdMap resb 256 ; Keyboard map FKeyName resb MAX_FKEYS*FILENAME_MAX ; File names for F-key help KernelCNameLen resw 1 ; Length of unmangled kernel name InitRDCNameLen resw 1 ; Length of unmangled initrd name %if IS_SYSLINUX KernelName resb FILENAME_MAX+1 ; Mangled name for kernel KernelCName resb FILENAME_MAX+2 ; Unmangled kernel name InitRDCName resb FILENAME_MAX+2 ; Unmangled initrd name %else KernelName resb FILENAME_MAX ; Mangled name for kernel KernelCName resb FILENAME_MAX ; Unmangled kernel name InitRDCName resb FILENAME_MAX ; Unmangled initrd name %endif MNameBuf resb FILENAME_MAX InitRD resb FILENAME_MAX syslinux-legacy-3.63+dfsg/.gitignore0000664000175000017500000000046110777447271016203 0ustar evanevan*.0 *.a *.bin *.bss *.c32 *.com *.d *.elf *.exe *.gen *.lnx *.lo *.lsr *.lst *.map *.o *.orig *.rej *.s *.sys *_bin.c *~ .depend com32/lib/sys/vesa/alphatbl.c extlinux/extlinux gethostip memdisk/memdisk mkdiskimage mtools/syslinux release sample/syslogo.lss unix/syslinux unix/syslinux-nomtools version.h syslinux-legacy-3.63+dfsg/kernel.inc0000664000175000017500000000657610777447273016205 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; kernel.inc ;; ;; Header file for the kernel interface definitions ;; %ifndef _KERNEL_INC %define _KERNEL_INC ;; ;; Structure of the real_mode_seg ;; struc real_mode_seg_t resb 20h-($-$$) ; org 20h kern_cmd_magic resw 1 ; 0020 Magic # for command line kern_cmd_offset resw 1 ; 0022 Offset for kernel command line resb 497-($-$$) ; org 497d bs_setupsecs resb 1 ; 01F1 Sectors for setup code (0 -> 4) bs_rootflags resw 1 ; 01F2 Root readonly flag bs_syssize resw 1 ; 01F4 bs_swapdev resw 1 ; 01F6 Swap device (obsolete) bs_ramsize resw 1 ; 01F8 Ramdisk flags, formerly ramdisk size bs_vidmode resw 1 ; 01FA Video mode bs_rootdev resw 1 ; 01FC Root device bs_bootsign resw 1 ; 01FE Boot sector signature (0AA55h) su_jump resb 1 ; 0200 0EBh su_jump2 resb 1 ; 0201 Size of following header su_header resd 1 ; 0202 New setup code: header su_version resw 1 ; 0206 See linux/arch/i386/boot/setup.S su_switch resw 1 ; 0208 su_setupseg resw 1 ; 020A su_startsys resw 1 ; 020C su_kver resw 1 ; 020E Kernel version pointer su_loader resb 1 ; 0210 Loader ID su_loadflags resb 1 ; 0211 Load high flag su_movesize resw 1 ; 0212 su_code32start resd 1 ; 0214 Start of code loaded high su_ramdiskat resd 1 ; 0218 Start of initial ramdisk su_ramdisklen resd 1 ; 021C Length of initial ramdisk su_bsklugeoffs resw 1 ; 0220 su_bsklugeseg resw 1 ; 0222 su_heapend resw 1 ; 0224 su_pad1 resw 1 ; 0226 su_cmd_line_ptr resd 1 ; 0228 su_ramdisk_max resd 1 ; 022C resb (0e000h-12)-($-$$) ; Were bootsect.S puts it... linux_stack equ $ ; DFF4 linux_fdctab resb 12 cmd_line_here equ $ ; E000 Should be out of the way endstruc ; ; Old kernel command line signature ; CMD_MAGIC equ 0A33Fh ; Command line magic ; ; If we're loading the command line old-style, we need a smaller ; heap. ; old_cmd_line_here equ 9800h old_linux_fdctab equ old_cmd_line_here-12 old_linux_stack equ old_linux_fdctab ; ; Magic number of su_header field ; HEADER_ID equ 'HdrS' ; HdrS (in littleendian hex) ; ; Flags for the su_loadflags field ; LOAD_HIGH equ 01h ; Large kernel, load high CAN_USE_HEAP equ 80h ; Boot loader reports heap size ; ; ID codes for various modules ; syslinux_id equ 031h ; 3 = SYSLINUX family; 1 = SYSLINUX pxelinux_id equ 032h ; 3 = SYSLINUX family; 2 = PXELINUX isolinux_id equ 033h ; 3 = SYSLINUX family; 3 = ISOLINUX extlinux_id equ 034h ; 3 = SYSLINUX family; 4 = EXTLINUX ; ; Types of vkernels ; VK_KERNEL equ 0 ; Choose by filename VK_LINUX equ 1 ; Linux kernel image VK_BOOT equ 2 ; Boot sector VK_BSS equ 3 ; BSS boot sector VK_PXE equ 4 ; PXE NBP VK_FDIMAGE equ 5 ; Floppy disk image VK_COMBOOT equ 6 ; COMBOOT image VK_COM32 equ 7 ; COM32 image VK_CONFIG equ 8 ; Configuration file VK_TYPES equ 9 ; Number of VK types %endif ; _KERNEL_INC syslinux-legacy-3.63+dfsg/extlinux.bss0000664000175000017500000000100010777447307016572 0ustar evanevanXEXTLINUX1м{W{ػx7V$0 x?Gd|M'EufEf|r uB|?|UA$0rUu t}f}~f>$~JLLy>f|f1OUffRfPSWjf`$0Bfadr]f) !uf`1$0fa}O]fRfPUSf6|f>|f1ɇfk)9vAň֊$0f`farf []fXfZf)uMuޕ.}u1ּ{fx} t ;.}v.}Boot error ᆳsyslinux-legacy-3.63+dfsg/TODO0000664000175000017500000000146310777447271014706 0ustar evanevan*** To do in the short term: - PXELINUX: Figure out localboot/idle problems. - PXELINUX: Support changing the default server and boot file prefix? - Support loading a new configuration file. - Library support for "shuffle and boot" extension. - Library support for all the comboot system calls. - Deal with non-512-byte sectors (if I can get media which does...) - Add support for getting the hardware address on Infinibad. *** Future projects: - Clean up the command-line parsing. - Cleaned up documentation, with a real man page. - Support files that span multiple input media (SYSLINUX) -> Seems to be getting less important; floppies are dying? - Clean up the handling of sections. - API call to get directory listing. - COM32-based CLI. - Rewrite the filesystems to run in protected mode C code. syslinux-legacy-3.63+dfsg/NEWS0000664000175000017500000012675010777447271014724 0ustar evanevanStarting with 1.47, changes marked with SYSLINUX/PXELINUX/ISOLINUX apply to that specific program only; other changes apply to all of them. Changes in 3.63: * Fix errors in the PCI and DMI detection modules (Erwan Velu, Sebastian Herbszt). * Fix host dependencies and other issues in the build system. * PXELINUX: Allow class E addresses as unicast. * sdi.c32: module to load Microsoft System Deployment Images. For additional information, please see: http://msdn2.microsoft.com/en-us/library/ms838543.aspx * EXTLINUX: Correct reading directories with deleted entries. * Shuffle library: correct the handling of certain geometries (an upward move with source material blocking the move); as required by sdi.c32 but theoretically possible for other formats as well. * Add "make netinstall" to install /tftpboot. * Fix some documentation files that didn't get moved/renamed. Changes in 3.62: * Clean up garbage after "aborted." message. * Clean up memdump.com filenames. * Support SHA256 and SHA512 encrypted passwords. * The shuffle library now can generate chained descriptors, thus allowing pretty much arbitrarily complex memory maps. * Handle command lines up to 2047 characters, the current Linux kernel limit. * vesamenu: support systems without linear framebuffer support (sigh, what is this, 1993?) and 15-bit RGB modes. * Move the label storage (for the command-line interface) to high memory, removing the size limit and freeing up 64K of low memory. * Get rid of 4096-entry limit in the simple menu system. * New hierarchial submenu support: see MENU BEGIN, MENU END, MENU GOTO in doc/menu.txt. * MENU QUIT allows creating a menu entry for returning to the command line. * ISOLINUX: Work around bug in certain Adaptec BIOSes, patch by Bruce Robson. * pngtopnm dependency removed from samples/ directory. * Text documentation files (in doc/) renamed *.doc -> *.txt. Changes in 3.61: * EXTLINUX: fix crash when accessing an empty file. * elf.c32: If a PHDR segment is present, load it. * Fix SHA-1 and MD5 passwords. * ISOLINUX: fix booting when mastered without mkisofs -boot-info-table (broken since 3.50, sigh...) * Handle BIOSes which emit multiple contiguous valid memory regions in the e820 map. Changes in 3.60: * Support for "auxilliary data vector", a small amount of writable storage. Currently only supported for EXTLINUX, but the infrastructure is there for the other derivatives, assuming a suitable storage location can be found. * EXTLINUX: boot-once support (--once, --clear-once, and --reset-adv). * A command is now required to the EXTLINUX installer, i.e. at least one of --install, --update, --once, --clear-once, or --reset-adv. Changes in 3.55: * PXELINUX: as per RFC 5071, PXELINUX no longer requires the use of the magic cookie option (208) for unencapsulated options. Currently it does not require it for vendor-encapsulated options (vendor-option-space) either, but that MAY be reverted in the future if it causes problems. * Documentation text files moved to a common "doc" directory; man pages from the Debian project added to the "man" directory. * Correct bug with self-overlapping memory areas when using the shuffle interface. Changes in 3.54: * Add "menu separator", "menu indent", "menu disabled" (see README.menu). * vesamenu: fix handing of VESA modes with noncontiguous memory buffers. In particular, Qemu/KVM sets up such a mode when Cirrus Logic emulation is enabled (which is the default.) * Support for calling real mode functions using far calls, with argument on the stack. This was implemented to support the BIOS BBS specification, but subsequent experiments show that the at least one of the most common BIOS cores, Award, passes the presence check but doesn't actually implement the functionality. Changes in 3.53: * Fix bugs related to the $PnP BIOS functionality on some platforms. * PXELINUX: Fix the "naked" version of :: (suppress prefix.) * elf.c32: better error messages. * Faster operation under Intel VT virtualization. * PXELINUX: Fix DHCP bootfile option. * mkdiskimage: Support more than 1024 cylinders. * (Hopefully) fix installer on non-x86 platforms. * Fix shuffle_and_boot_rm, used by linux.c32. * Fix shuffle_and_boot_pm on 386/486. * ISOLINUX (at least): fix bss memory overwrite hang. * MBR: Fix booting from logical partitions. * Code cleanups. Changes in 3.52: * Handle capitalized F-key commands in the menu system. * Fix padding error when loading multiple ramdisks. * Workaround for VMware crashing when trying to print a message during early kernel boot (does not seem to work, consider deleting.) * chain.c32: add the ability to search for a specific MBR signature at runtime. * Fall back to the server identity option if the siaddr field in the DHCP header isn't set. This seems to match the behaviour of most PXE stacks. * mkdiskimage: give the generated disk image an MBR signature. * MEMDISK: Fix failures on some BIOSes. * Simple menu system: new "MENU HIDDEN" option to not display the menu unless the user presses a key. * Simple menu system: support MD5-encrypted passwords (modern Unix standard style, with "$1$" prefixes.) * pcitest.c32: now functions as a full "lspci". Thanks to Erwan Velu for this work. * MEMDISK: Make EDD actually work. * ISOLINUX: Fix for certain broken CD-ROM BIOSes which randomly corrupted register FS. * Simple menu system: fix memory overwrite bug that caused some systems to lock up or behave weirdly. * Fix building on 64-bit systems without a 32-bit libc installed. Changes in 3.51: * EXTLINUX: Fix failure to find the configuration file. Changes in 3.50: * New keywords allow the type of file to be specified in the configuration file. * It is now supported to load a different configuration file with the CONFIG keyword. * Fix API call 0x0019 (Read Disk.) * MENU AUTOBOOT, MENU TABMSG, MENU PASSPROMPT allows internationalization of menu messages. * A new feature, TEXT HELP, allows the administrator to set a multi-line help message for individual selections. * Fix API call 0x0012 (Cleanup, shuffle and boot.) * New API call "Cleanup, shuffle and boot to flat protected mode" * New API call "Cleanup, shuffle and boot to real mode", similar to API call 0x0012 but allows arbitrary register setting. * Introduce a library interface for loading arbitrary binary formats with relatively easily understood code. See the elf.c32 module for an example on how to use it. * New module "elf.c32", to load a protected-mode ELF kernel. * MBR (old and new): Fix bug in CHS mode when LBA > 65535*sectors. * vesamenu: fix decoding of palettized PNG images. * Update the Linux kernel boot protocol. * PXELINUX: Press Ctrl-N at the boot prompt to read out the network info. * Instead of the (non-existent) MAC, use the client identifier for networks like Infiniband and Firewire/1394. * Add a new INCLUDE command to the core syslinux parser. * Allow binding help text to F11 and F12. * F-key help now available in the simple menu system. * Disabled the polling for ARP during idle. It is simply too slow on some (broken!) PXE stacks. * PXELINUX: also try to fetch the config file based on UUID. * SYSLINUX/EXTLINUX: New RAID mode (-r) which calls the BIOS to load the next device (typically the next drive) on boot failure. Changes in 3.36: * MEMDISK: Disable EDD by default on floppy disks. EDD can be enabled with the "edd" option and disabled with "noedd". This (hopefully) should make Ghost work again. * SYSLINUX: "unix" installer now uses Linux ioctls instead of using libfat. * New MBR which can boot from logical partitions. * SYSLINUX: Fix bug in detecting special extensions which was introduced in 3.35 :( * PXELINUX: Unbreak chainbooting FreeBSD (and possibly others.) Changes in 3.35: * MEMDISK: New "safeint" mode. * MEMDISK: Be more compliant with the PnP BIOS spec. * MEMDISK: Turn on EDD support by default. * MEMDISK: Try to work on some machines on which it would not work when there was no floppy drive in the system. * Simple menu system: fix serial console support (broken in 3.30). * SYSLINUX: Support subdirectories. Like ISOLINUX, the "current directory" is the directory in which syslinux.cfg is found; this is searched for in the sequence /boot/syslinux, /syslinux, /. As a side benefit, label names like "linux-2.6.18" and "linux-2.6.19" are now supported. To install ldlinux.sys in a subdirectory, pass the -d directory option to the SYSLINUX installer. This work was sponsored by slax.org (thanks, Tomas!) * New API call: read disk. * Invoke ONERROR on initrd load failure. Changes in 3.31: * The simple menu system (menu.c32 and vesamenu.c32) now support loading more than one configuration file at a time, using MENU INCLUDE or by specifying multiple filenames. * The MENU COLOR statement can now control the shadowing mode. Changes in 3.30: * libcom32 extended to support graphics mode and graphical console. * vesamenu.c32, new graphical version of the Simple Menu System, see README.menu. * New com32 modules by Erwan Velu do selection based on CPUID or PCI devices present. * RPM spec: add syslinux-tftpboot module; move syslinux by default to the /usr/share/syslinux directory. * RPM spec: extlinux is now a separate package. Changes in 3.20: * EXTLINUX: New options --install (-i) and --update (-U), to make it clear if a boot loader should be installed or updated. For now, defaults to --install for compatibility; a future version will require one of these options. * New library functions to load and place files in memory. * mboot.c32 bug fixes. * Remove 8 MB kernel size restriction. * Add "klibc" target for building unix/syslinux and extlinux/extlinux with klcc (klibc-1.4.27 or later.) * PXELINUX: Fail (and eventually reboot) if no configuration file was found. * COM32 module by Erwan Velu to make decisions based on DMI info. * Fix issue where going back and forth between menus a lot would cause a hang. * ISOLINUX: Fix bug which made "cd boot sectors" not work. Changes in 3.11: * MEMDISK: Fix bug by which accessing the real floppy disk as B: in MS-DOS was broken. * Simple menu system: allow tweaking of the screen layout. * Simple menu system: better command-line editing, correctly handle command lines above 256 characters. * PXELINUX: revert memory allocation change that caused problems on some network cards. * MEMDISK: Try work around a bug on some BIOSes when no physical floppy disk is present in the system. * Enable the 16550A FIFOs, if present, when doing serial console. * New "totaltimeout" command establishes a timeout without regard for any user input. * Simple menu system: timeout behaviour now more in line with user expectations. * Simple menu system: "ontimeout" should now work correctly. Changes in 3.10: * gcc 4.0.1 compilation fixes. * Add support for querying the PCI BIOS in libcom32 (used by ethersel et al.) * Fix PCI handing (ethersel etc) on several old chipsets (and VMWare.) * Try to deal with systems with broken EBIOS. * New API call to do "localboot". * New API call to query features. * New API call to run kernel image, a lower-level call than "run command". See comboot.doc. * Fix for bug in EBIOS code discovered by Arwin Vosselman. * NOESCAPE security fix. * Comments are now recognized even without a space following #. * Fix incorrect handling of mixes of entries with and without MENU PASSWD. * The idle API call now harmlessly returns failure if it is a no-op. That way the caller can decide whether or not to bother invoking it again. * Temporarily disable the idle API call on PXELINUX, due to some platforms on which the idle API call seems to hang; this problem has not yet been debugged. * MEMDISK: the handling of DOSEMU-headered images was broken; fix it. * EXTLINUX: symlinks are now supported. * Simple menu system: N and P now work correctly as hotkeys. * MEMDISK: more BIOS bug workarounds. Changes in 3.09: * gcc4 compilation fix. * (Ctrl-G) in message files now causes a beep. * Reduce the command line to 511 characters; 1023 caused memory overflows. Changes in 3.08: * SYSLINUX: Fix performance regression (-s mode always enabled.) * Add API function for idle loop. * libutil: Add do_idle() function for idle loop, make get_key() use it. * libutil: Add SHA-1 and base64 functions. * Simple menu system: add password support. * EXTLINUX: Sparse files now handled correctly. * EXTLINUX: Large directories now handled correctly. * ALL: At the prompt, Ctrl-X now forces text mode. * Fix configuration file parsing error, that could cause hangs. * Rewritten advanced menuing system from Murali Ganapathy. * MEMDISK: New "bigraw" mode to work around certain broken BIOS flash programs. * COM32 module to boot Multiboot systems, including Xen. See com32/modules/mboot.doc. * Max command line changed to 1023 characters. Note that the kernel proper still can only handle 255 characters without patching, and COM16 binaries can only handle 125 characters. Changes in 3.07: * Fix chainloading (chain.c32). * Fix zlib build problem. * Use a private copy of . Changes in 3.06: * Fix typo that caused the ramdisk to load in the wrong place. Changes in 3.05: * New API function "shuffle and boot"; allows COM32 modules to load or construct (almost) arbitrarily complex objects, e.g. a kernel and its initrd/initramfs in pieces, and have the API core reorganize memory for booting. (A library API for this function will be introduced in a later version.) * The initrd= option now supports multiple filenames separated by commas. This is mostly useful for initramfs, which can be composed of multiple separate cpio or cpio.gz archives. (Note: all files except the last one are zero-padded to a 4K page boundary. This should not affect initramfs.) * EXTLINUX: Fix API function 000Ah (get derivative-specific info). * libcom32/ethersel: Support PCI Config Mechanism #2 on machines still infested with that hideous old hack. * SYSLINUX: Fix directory-parsing bug. Changes in 3.02: * SYSLINUX: The "unix" installer now sets the MS-DOS attributes (hidden, system, readonly.) * COM32 library: build the .lnx (test modules for running under Linux) as architecture native modules, in case i386 devel libraries aren't installed. * EXTLINUX: Hack for systems which don't have BLKGETSIZE64 defined in the standard header files. * Simple menu system: minor aestetic improvements, and try to work better over a serial console (speed, and readability on monochrome terminal emulators.) * New CONSOLE directive to control output on the video console (useful for dealing with some broken serial-forwarding BIOSes.) * New com32 module "ethersel" for searching for an Ethernet card and selecting the proper version of Etherboot. * EXTLINUX: Allow the user to override the detected geometry. Add help. Changes in 3.01: * EXTLINUX, SYSLINUX: Fix compile errors on some systems. * EXTLINUX: Default to zipdrive geometry (64 heads, 32 sectors) if no other geometry can be detected. Changes in 3.00: * SYSLINUX: Support FAT32 and EDD. As an unfortunate consequence, LDLINUX.SYS is no longer an ordinary file; it is block-mapped at install time, which means it can only be written using the syslinux installers. * SYSLINUX: Reorganize the source code for the installers; each one of the installers (dos, win32, unix, mtools) is now built in its own subdirectory. In particular, "mtools" is the unprivileged installer which uses mtools; "unix" is the privileged installer which uses system calls. * SYSLINUX: Completely rewritten DOS installer in C. * ALL: "label" statement information is now stored in a compressed format, which means that a lot more labels are permitted (500-1000 in a typical configuration, but depends on the complexity.) * EXTLINUX: New derivative, which boots from an ext2/ext3 filesystem. * SYSLINUX: The DOS and Win32 installers can now optionally write the boot sector to a file instead of the real boot sector. This is not supported in the Linux installers, however. * ALL: New NOESCAPE command, disables the "hold down the Shift key to display the prompt" behaviour. * New simple menu system, as an alternative to the advanced menu system already present. See README.menu for details. * PXELINUX: Filenames can now be prefixed with an IP address or DNS name plus :: (e.g. 192.0.2.1::filename or server.domain.com::filename), which downloads a file from an alternate TFTP server, or just a :: (e.g. ::filename), which suppresses the common pathname prefix. See pxelinux.doc. * SYSLINUX: Add an -m option to the DOS and Win32 installers to write an MBR and -a to mark the partition SYSLINUX is being installed on active. * MEMDISK: Give a way to query the boot loader type while running MEMDISK; see memdisk/memdisk.doc and sample/mdiskchk.c. * mkdiskimage: substantially improved mkdiskimage which, among other things, can now be used to initialize USB keys as zipdrives; see README.usbkey for more information. Changes in 2.13: * MEMDISK: Fix command-line parsing "brown paper bag" class bug. * MEMDISK: Add "raw" mode to support the DOS boot disk from WinME/XP, which seems to deliberately crash the system when someone uses the "INT 15h mover" highmem API. * Make "make install" do something sane for the com32 development environment. * In the spec file, create a separate -devel RPM for the com32 development environment. Changes in 2.12: * Simple C library, based on klibc, for writing COM32 programs. * Fix the handling of file length in loading of COM32 programs. * MEMDISK: Work around a linker bug by rearranging the code to not use the linker for the 16-bit code. * SYSLINUX: If we're building on a machine without a Win32 (mingw) compiler, just skip building syslinux.exe. * ISOLINUX: Support non-mkisofs mastering programs, at least as long as the image is single-session. For best results, ISOLINUX should be the only boot loader installed. * MEMDISK: Allow the user to specify that the simulated disk should be write-protected. Changes in 2.11: * ALL: Add an API call to get the configuration file name. * SYSLINUX: Fix bug in 2.10 that prevented it from working correctly for a lot of people. * SYSLINUX: In the installer, make mtools a bit less fussy. * Make the menu system compile with newer gcc's. Changes in 2.10: * MEMDISK: Handle images compressed with zip as well as with gzip. Some Windows-based image tools apparently generate these kinds of images by default. Patch by Patrick LoPresti. * Major menu improvement from Murali Ganapathy. * ISOLINUX: Wonderfully sick and brilliant workaround for severe bugs in certain Award BIOSes; from Knut Petersen. * SYSLINUX: Fix for the nomtools installed, from Frederic Pasteleurs. * PXELINUX: Fix handling of IP numbers in the ranges 100-109 and 200-209. * ALL: New option "allowoptions" (defaults to 1), which controls if options are allowed on the command line or not. * SYSLINUX: Support building under klibc (see the klibc distribution for details.) Changes in 2.09: * SYSLINUX: Remove residual setuid crap from syslinux-nomtools. * Handle video pages correctly when using the API functions. * Handle compiling on an x86-64 platform correctly. * Menu system from Murali Krishnan Ganapathy; see the menu directory for information. * COMBOOT: Allow COMBOOT programs to change screen text mode. * COMBOOT: Correct the documentation of how to detect SYSLINUX from COMBOOT!!!! * COMBOOT: Fix "get key without echo" API function. * SYSLINUX: Fix bug that affected the API open function. * ALL: Improve the E820 memory parser, to work around some buggy BIOSes. Changes in 2.08: * Add new configuration command "ontimeout" to allow timeout to have a different action than just pressing Enter. * Add new configuration command "onerror" to allow a custom command to be executed in case the kernel image is not found. * Fix bugs in the COMBOOT/COM32 command-line parsing. APPEND now works with COMBOOT/COM32 images. * PXELINUX: Poll for ARP requests while sitting at the prompt. This makes some boot servers a lot less unhappy. * PXELINUX: Actually free sockets when we get a failure (including file not found.) This bug would cause us to run out of sockets and thus "go deaf" after a while. * MEMDISK: Add an API to query for the existence of MEMDISK. * SYSLINUX: Fix loading boot sectors (.bs/.bss) from floppy disk. * .c32 is now one of the extensions searched for automatically. * PXELINUX: RFBG.exe seems to randomly overwrite memory location 0x5700. Thus, don't use it! * PXELINUX: Change pathname length max from 63 to 127; change max vkernels from 128 to 64. * Support Ctrl-U -> kill entire command line input. * The "samples" directory contains a (barely at all tested) chain loading example, chain.c32, which may be used to chainload local floppy disks and hard disks. Use with "chain fdN" or "chain hdN [partition]"; N = 0 for the first drive of each type. Changes in 2.07: * MEMDISK: Workaround for BIOSes which go into a snit when they get a RESET command for the floppy system when there is no floppy in the system. * PXELINUX: Add "ipappend 2", which passes the hardware address of the boot interface to the kernel as a command-line option. * mkdiskimage: fix the generation of the end limit. * PXELINUX: Fix multiple bugs in chainloading of other NBPs. * MEMDISK: Fix bug that would occationally cause "ran out of input data" when using compressed disk images. * SYSLINUX: Updates for the win32 installer (from Lars Munch.) * PXELINUX: PXELINUX-specific options are now recognized both in a vendor-option-space (a.k.a. type 43 encapsulated) as well as in a site-option-space (unencapsulated.) * COM32: Don't crash when DS != 0. * COMBOOT/COM32: Make file reading work correctly. Thanks to Phung Chi Kien for submitting a test program. Changes in 2.06: * ALL: Fix problem that would occationally cause a boot failure, depending on the length of the kernel. * ISOLINUX: Fix problem that would occationally cause a boot failure, depending on the length of directories. * SYSLINUX: Win32 installer now flushes buffers. * ppmtolss16: Be fully compliant with the PNM spec; actually process comments in the header and odd alignments of the various parameters, as well as "plain" (not raw) files and PBM and PGM files. * PXELINUX: Lower the default MTU to 1472 in order to deal with systems with slightly nonstandard MTUs, and PXE stacks which don't defragment correctly. Unfortunately this is very hard to test dynamically. Changes in 2.05: * PXELINUX: Add a default query based on the hardware address of the boot device. This is in lower case hexadecimal form separated by dashes and including the hardware type, for example, the Ethernet (type 1) address 88:99:AA:BB:CC:DD would query the file pxelinux.cfg/01-88-99-aa-bb-cc-dd. * PXELINUX: Fix bug involving non-IP-based config file names. * SYSLINUX: New installer for WinNT-based systems, from Lars Munch. * MEMDISK: Fix handling of memory region overlap when decompressing. Thanks to Mikhail Kupchik for identifying the problem. Changes in 2.04: * ALL: Reclaim even more low memory by observing that comboot_seg == real_mode_seg is perfectly fine, and by the fact that the 1000h segment managed to get unused in all derivatives... * PXELINUX: Attempt to negotiate full Ethernet-sized blocks (1468 bytes) using the blksize option. * SYSLINUX: Resurrect the old no-mtools version of the installer, although as a root-only tool. Some distributors have indicated that they need a small standalone installer. * MEMDISK: Fix a memory offset computation error when installing compressed disks which generally would cause 1 MB of memory to be wasted. * MEMDISK: Fix installing the E820 memory map. Calling INT 15h AX=0E820h with MEMDISK 2.03 loaded would give a completely corrupt memory map. * SYSLINUX: Make libsyslinux a dynamic library, so that it can be updated separately from client programs. The whole idea, after all, is to enable alternate programs to become syslinux installers. * Include an rpm spec file in the distribution, so rpmbuild -ta works. Changes in 2.03: * Actually support comment lines in the configuration file. * PXELINUX: Try to resolve some problems with stack switches. * PXELINUX: Handle PXE stacks with broken routing. With these workarounds, the remote install PXE boot floppy (rbfg.exe) from Argon Technologies should work correctly. * Fix problems with Perl scripts in UTF-8 locales. * You probably need NASM 0.98.34 or later to compile this version. 0.98.36 is recommended. * MEMDISK: Now supports gzip compressed images. Changes in 2.02: * SYSLINUX: Security flaws have been found in the SYSLINUX installer when running setuid root. Rewrite the SYSLINUX installer so it uses mtools instead. It therefore now requires mtools (specifically mcopy and mattrib) to exist on your system, but it will not require root privileges and SHOULD NOT be setuid. Changes in 2.01: * MEMDISK: Fix memory sizing bug when the ramdisk crosses the 16 MB boundary. * MEMDISK: Add a "pause" option to stop immediately before booting, to read off the messages. * MEMDISK: Support disk images with DOSEMU headers. * Update the mkdiskimage script to handle newer mtools versions, and be able to generate disk images with DOSEMU headers (controlled by the -d option). * Fix the COM32 sample program. * PXELINUX, ISOLINUX: Fix some COMBOOT API calls. * PXELINUX: Doc fix. * Build SYSLINUX into a small library for encapsulation into other programs (however, please keep in mind this is a GPL'd library.) * SYSLINUX: Make installer work with "owner" in /etc/fstab. * SYSLINUX: Fix issue with working on nonpartitioned hard disk devices. THIS CONFIGURATION IS NOT RECOMMENDED. Changes in 2.00: * ALL: Add support for "COM32" (32-bit COMBOOT) images. * ALL: Add an API for COMBOOT/COM32 images. See comboot.doc for details. There is a C development environment for COM32 being created; it should be ready at some point in the future. * Fix mbr.asm so that it actually works. * SYSLINUX: The syslinux installer *SHOULD* now be safe to run setuid root. * PXELINUX: Fix bug where PXELINUX would override random chunks of the UNDI code segment! Thanks to Kevin Tran for finding this bug. * ISOLINUX: Fix a bug related to slashes in pathnames. * ISOLINUX: Fix a bug in handling initrds over 128 MB. * ALL: Make the key print out the version; this is to help debugging. * Add a small script, mkdiskimage, to create a DOS-formatted hard disk image using mtools. This may be useful in conjunction with MEMDISK. * ISOLINUX: Search for a /boot/isolinux directory as well as /isolinux. * ALL: Fix a bug related to very long configuration files. * PXELINUX: Work around a NASM bug which would result in no delay before reset if an error occurs. Changes in 1.76: * ISOLINUX: Remove code no longer used which caused hangs on some Toshiba laptops. Changes in 1.75: * ALL: NASM 0.98.32 or later is now required to build SYSLINUX from sources. * SYSLINUX: put back in the workaround for the BIOS floppy table. This seems to be a requirement for "extended" floppy formats to work correctly. * SYSLINUX: No longer warn if one is trying to boot on a 286 or older. The above BIOS workaround no longer fits if the requirement to use only 8086-compatible code in the early boot is maintained. It made sense in 1994, but in 2002 a 286 or older is a museum object. * SYSLINUX: Use a downright bizarre, stateful algorithm to try to guess the maximum transfer size. I am *hoping* this will cut down on the number of systems for which -s is required to work at any acceptable speed. * ISOLINUX: Add a few more workarounds for various broken El Torito BIOSes. * Make sure .depend files aren't accidentally packed... * ALL: Fix bugs in the extension-detect code; this caused files like COMBOOT images and CD boot sectors to be mis-identified as Linux kernels and rejected. * ALL: Fix the return from COMBOOT. * ALL: Do some of the early groundwork for supporting DOS system calls in COMBOOT. * Get rid of unnecessary "near" directives, making the code bigger. * PXELINUX: Put the PXE stack back in the init state before invoking a chain-loaded NBP. * PXELINUX: Actually found the combination of calls that allows some (most?) PXE 2+ stacks to be unloaded from memory properly. * PXELINUX: Add "keeppxe" command-line option to disable the standard unloading of the PXE stack. Changes in 1.74: * SYSLINUX: fix bug that would cause valid kernel images to be labelled "invalid". Changes in 1.73: * Work on removing gratuitous differences between modules. * Break up the source in common and module-specific files. * PXELINUX: Allow chaining of other PXE NBPs. * ISOLINUX: Allow loading "CD-ROM boot sectors". * ALL: generalize the definition of a boot sector/NBP. Changes in 1.72: * PXELINUX, ISOLINUX: Fix bugs in the new core code. Changes in 1.71: * Fix a "brown paper bag" class bug in the new core code. Changes in 1.70: * Major code restructuring. * Relax the conventional memory limits somewhat. * MEMDISK: Set up the "version number string" pointer in the header correctly. * SYSLINUX: Fix, again, "the bug that won't die": the use of the offset parameter with the SYSLINUX installer. * SYSLINUX: Fix possible superblock corruption problem in the SYSLINUX installer. Changes in 1.67: * Handle bug in the location of initrd. Changes in 1.66: * MEMDISK: Make compile with newer versions of gcc. Changes in 1.65: * ISOLINUX: Support booting disk image files (to boot DOS or other non-Linux operating systems), *IF* the BIOS works correctly; unfortunately many BIOSes apparently don't. * Support Linux boot protocol version 2.03 (explicitly specify the initrd address limit.) * Handle small "pseudo-kernels"; images that use the Linux kernel boot protocols but are less than 64K in size. * MEMDISK: New subsystem; this is a driver which allows legacy OSes to boot using an in-memory simulated disk. See memdisk/memdisk.doc for more info. * PXELINUX, ISOLINUX: Correctly handle files larger than 65535 blocks (32 MB for PXELINUX, 128 MB for ISOLINUX.) * PXELINUX: Make a best-effort attempt at freeing all memory claimed. From the looks of it, it will fail on most PXE stacks. Changes in 1.64: * Limited support for hardware flow control when using a serial port console. * Support specifying the serial port I/O address explicitly. * Make DOS installer hopefully behave more nicely when used on recent Windows versions. * Fix returning to text mode when a font has been specified. * Attempt to detect missing serial port hardware and disable the serial port if there is nothing there. Changes in 1.63: * Make the ppmtolss16 program handle color conversion more correctly. * Clean up "make install" target, honour INSTALLROOT if it exists. * SYSLINUX: Fix stack-smash bug identified by Steffen Winterfeldt. * Hopefully fix return-to-text-mode on some graphics cards. * ISOLINUX: Bug workaround for Award BIOS 4.51, and perhaps other buggy BIOSes as well. Changes in 1.62: * PXELINUX: Allow the DHCP server to override the configuration file name and pathname prefix, using "site-specific" DHCP options. * PXELINUX: Documentation fixes. * PXELINUX: Fix the "ipappend" option; the last two values were reversed vs. what the kernel expected. * Introduce a way to return to text mode once we are already in graphics mode. This may be useful for F-key help screens. * Fix several bugs in the way return to text mode was handled. Changes in 1.61: * ISOLINUX: Support full pathname searches. Max length for a pathname is 255 characters. As a result, only 64 "label" statements are supported in ISOLINUX. * PXELINUX: Max filename length extended to 63 characters. Changes in 1.60: * Add support for graphical splash screens. * Add mode control characters, which allows you to control message display output depending on output mode (text, graphics, or serial port.) * ISOLINUX: New program, which boots Linux from a CD-ROM without using floppy emulation mode. See isolinux.doc for more details. * PXELINUX: Don't search for boot sector file types, since they don't work anyway. * SYSLINUX: Document the LOCK command for Win9x, and the error dialog box for WinNT/2K. Changes in 1.54: * PXELINUX: Fix code for finding !PXE from PXENV+. This was due to a spec bug; match the most recent spec since that seems to be what implementations actually do. * SYSLINUX: Add some smarts to the boot sector, which hopefully should reduce the number of systems which require stupid mode ("syslinux -s"). * PXELINUX: Document further some of the pathologies with old PXE stacks. * When specifying a "default" command line, no longer automatically appent "auto". See the "DEFAULT" command in syslinux.doc for more information. * PXELINUX: Clean up the allocation of local socket numbers. Changes in 1.53: * PXELINUX: Rename pxelinux.bin to pxelinux.0, to match what most PXE servers seem to expect. * PXELINUX: Update the DHCP/boot server setup documentation. * PXELINUX: Support new "localboot" option for "label" sections. * PXELINUX: More robust parsing of DHCP/boot server packets. * PXELINUX: Include a small utility program "gethostip" to compute hexadecimal IP addresses. Changes in 1.52: * PXELINUX: Fix bugs introduced by new A20 code. (SYSLINUX has also been changed for code consistency reasons, but I'm pretty sure the changes are don't care on SYSLINUX.) * Documentation updates. * PXELINUX: Add "ipappend" option to generate an ip= option to the kernel. Changes in 1.51: * PXELINUX: Not all PXE stacks fill in the IP address for a type 3 cached info query. Use a type 2 cached info query for this information (only.) * Yet another attempt at A20 coding. Now support BIOS call 15:2401 as well, and handle machines which always have A20 on separately. * Support memory detection using INT 15h, AX=0E820h. BIOS manufacturers have apparently gotten sloppy about keeping INT 15h, AX=0E801h working properly. * Don't issue onto the serial port when we're doing screen wraparound. Changes in 1.50: * Yet another A20-code update. It seems some "legacy-free" machines and embedded gear simply don't have a KBC to talk to, and that waiting for one will wait forever. Sigh. Changes in 1.49: * SYSLINUX: Implement a hack for BIOS drivers which hog significant chunks of low memory during boot. (Note: PXELINUX already had this modification. SYSLINUX does still require that the low 512K is available; PXELINUX requires 384K. Machines with a physical memory hole in the low 640K cannot boot Linux no matter what.) Depending what the reason is for the memory hole, a new kernel (2.4.0-test3-pre3 or later) may be required. * SYSLINUX: Default installer binary now compiled against glibc 2.1. If this is inappropriate for your system and you still want to use the offical version of SYSLINUX, please follow the instructions in "distrib.doc" to rebuild the installer. * SYSLINUX: Linux installer program now supports -o option which does a loopback mount with the -o loop,offset=<> option. Useful to run SYSLINUX on an individual partition of a whole-harddisk image. * Include the source code to a Master Boot Record (MBR) functionally equivalent to the one installed DOS except it includes EBIOS support, and should be resistant to geometry changes. The MBR code is public domain. * PXELINUX: Fix "double p" bug: if the tftp prefix was null, all filenames would get a "p" preprended, e.g. "ppxelinux.cfg" and "pvmlinux". Changes in 1.48: * PXELINUX: Workaround for PXE ROMs based on the Intel PXE PDK 3.0 build 071 and earlier: missing !PXE structure pointer. * PXELINUX: Handle larger BOOTP/DHCP packages. * PXELINUX: The command line passing was broken; fix. * PXELINUX: Make COMBOOT images work. * PXELINUX: Documentation on how to make booting work using the PDK 3.0-derived clients, which aren't so generous as to allow booting with only "PXEClient" specified. Changes in 1.47: * PXELINUX: RFC 1123 states that a TFTP implementation MUST use adaptive timeout, "at least an exponential backoff of retransmission timeout is necessary." Implement a very simple exponential backoff for retransmits. * PXELINUX: Updated documentation, including pointer to new TFTP server. * PXELINUX: When sending ERROR due to bad OACK, use the proper destination port number (why are TFTP port numbers so odd?) * PXELINUX: If the boot dies in the middle somewhere, eventually give up and reset the machine (unattended operation.) Changes in 1.46: * New program PXELINUX to do network booting using a PXE-compliant (Pre-Execution Environment) network booting PROM. See pxelinux.doc for details. Changes in 1.45: * Serial console support. See syslinux.doc for details. Changes in 1.44: * Change HIGHMEM_MAX to 38000000h to (hopefully) avoid the kernel stepping on it; 3f000000h was apparently a higher limit than the kernel used! Changes in 1.43: * Add sys2ansi.pl script to display the contents of a colorized SYSLINUX file. * Changed the io_delay once again, after a report that the old delay port causes hangs on some systems. Changes in 1.42: * Frob the "fast A20 gate" port as well as the keyboard controller; will this help systems with problems? * Be even more paranoid about A20, unfortunately even this seems to be not paranoid enough... what I don't understand is that if there is hardware out there *this broken*, how can it run Linux at all? Report an error message rather than hang forever if A20 is stuck. * Include some intermediate files in the distribution, plus provide a "make installer" target for distributors to relink the install programs only. I would prefer the syslinux boot loader proper to be "binary clean" for debuggablity -- use "make clean ; make installer" to rebuild the installers only. Changes in 1.41: * Don't get confused by directories, volume labels, or VFAT long names. * Use INT 15h, AX=0E801h to query memory size before trying INT 15h, AH=88h. This not only provides more headroom between the kernel and the initrd on large-memory machines, but it appears some recent BIOSes actually have started returning garbage for the AH=88h (older) call. * Trust high memory beyond the 15 MB mark if the user has specified it, or if obtained with INT 15h, AH=0E801h (with no memory holes above 1 MB.) Changes in 1.40: * Increase A20M delay and put in a test to avoid problems on certain IBM Thinkpads (thanks to Donnie Barnes of RedHat for vital info on this one.) * Support COMBOOT style boot command images. * Support chain loading (foreign operating systems, e.g. DOS). * Include a new "copybs" DOS utility to copy a boot sector to a file (under Linux, use "dd".) * Fix the DOS installer to work for disks over 32 MB. * SYSLINUX should now handle disks with more than 65536 tracks. Changes in 1.37: * Fix a bug that caused "label" statements in syslinux.cfg to not be handled properly. * Updated the documentation. Among other things, we now allow up to 128 "label" statements. Changes in 1.36: * Fix for booting old (pre-initrd) kernels. * It seems at least some versions of OS/2 doesn't set up all the fields in the superblock correctly. Account for that. * Fix bug that caused boot failure when using the mem= option. Changes in 1.35: * Loading from partitions now should work properly. (Actually tested, this time. You should even be able to dd a floppy to a partition and boot from it.) * Removed large workaround code for an alleged ancient BIOS bug I have never actually seen. The -s option should work on those machines, anyway. * Support for simple keyboard remappings, same as used by LILO (once again to support localization.) The program keytab-lilo.pl from the LILO distribution included to generate such maps. * Added a "safe, slow and stupid" (-s) option to the installers. This option will lobotomize the boot sector to hopefully work on even very buggy BIOSes. Changes in 1.34: * Ability to load a VGA font on bootup (for localized Linux distributions.) Changes in 1.33: * Bug fix in the Linux installer. * Added a workaround for a bug in certain AMI/Intel BIOSes when booting from CD-ROM. * Documentation changes. Changes in 1.32: * FAT16 filesystems are now supported. Changes in 1.31: * Now compiles under Linux, using NASM, rather than using Turbo Assembler under DOS. See http://www.cryogen.com/Nasm for information about NASM. * Linux-hosted SYSLINUX installer, as well as a rewritten DOS installer (now is written in assembler, so we don't need Turbo C.) Changes in 1.30: * Added support for loading bzImage and initrd loading, and made SYSLINUX new-setup-code aware (SYSLINUX 1.30 id=0x31). * Added LILO-style kernel labels; see the LABEL and IMPLICIT keywords in README file. * Added support for colorization of intro and help screens. * The vga= option is now handled correctly. * Massive rewrite of large chunks of the code in order to support the first two new features. Changes in 1.20: * Added simple online help at the "boot:" prompt. * Removed 2880K image as I no longer have access to such a floppy drive. (Donations accepted!!) * Decided to distribute the source in a subdirectory rather than in a nested zipfile. Changes in 1.11: * Removed a sanity check which would cause booting to fail on Phoenix BIOS version 4.03. Apparently this BIOS is buggy. Changes in 1.10: * Added configuration file SYSLINUX.CFG. This file contains all configurable options, and can be edited from any OS which can access an MS-DOS filesystem; there is no longer a need to run SYSLINUX.EXE except to write the boot sector. * Default command line now given by "default" line in config file. * LINUXMSG.TXT and BOOTMSG.TXT hard-coded file names replaced by "display" and "prompt" lines in config file. * LILO-style option appending now supported ("append" line in config file). * Prompt timeout is now supported ("timeout" line in config file). The timeout is cancelled when anything is typed on the command line. * Pressing or at the Loading... stage now aborts the kernel loading in progress and returns the user to the boot: prompt. * The installer now automatically sets the READONLY flag on LDLINUX.SYS. * Added 2880K disk image. Changes in 1.03: * Fixed bug that would prevent booting from double-density floppies and other DOS filesystems with multiple sectors per cluster. * Added 720K disk image. * Changed default kernel name on disk images to LINUX. Changes in 1.02: * Fixed bug that would garble the command line on recent kernels with more than 4 sectors of setup code (this wasn't really a *bug*; rather, a kernel change broke the code. Unfortunately the Linux boot interface is still sorely undocumented). * Added BOOTMSG.TXT file support (message file which does not force display of the boot prompt). Changes in 1.01: * Fixed bug on some (most?) 386 BIOSes would require two boot attempts. syslinux-legacy-3.63+dfsg/macros.inc0000664000175000017500000000446110777447273016200 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; macros.inc ;; ;; Convenient macros ;; %ifndef _MACROS_INC %define _MACROS_INC ; ; Identify the module we're compiling; the "correct" should be defined ; in the module itself to 1 ; %ifndef IS_SYSLINUX %define IS_SYSLINUX 0 %endif %ifndef IS_MDSLINUX %define IS_MDSLINUX 0 %endif %ifndef IS_PXELINUX %define IS_PXELINUX 0 %endif %ifndef IS_ISOLINUX %define IS_ISOLINUX 0 %endif %ifndef IS_EXTLINUX %define IS_EXTLINUX 0 %endif ; ; Macros similar to res[bwd], but which works in the code segment (after ; section .text) or the data segment (section .data) ; %macro zb 1.nolist times %1 db 0 %endmacro %macro zw 1.nolist times %1 dw 0 %endmacro %macro zd 1.nolist times %1 dd 0 %endmacro ; ; Macro to emit an unsigned decimal number as a string ; %macro asciidec 1.nolist %ifndef DEPEND ; Not safe for "depend" %if %1 >= 1000000000 db ((%1/1000000000) % 10) + '0' %endif %if %1 >= 100000000 db ((%1/100000000) % 10) + '0' %endif %if %1 >= 10000000 db ((%1/10000000) % 10) + '0' %endif %if %1 >= 1000000 db ((%1/1000000) % 10) + '0' %endif %if %1 >= 100000 db ((%1/100000) % 10) + '0' %endif %if %1 >= 10000 db ((%1/10000) % 10) + '0' %endif %if %1 >= 1000 db ((%1/1000) % 10) + '0' %endif %if %1 >= 100 db ((%1/100) % 10) + '0' %endif %if %1 >= 10 db ((%1/10) % 10) + '0' %endif db (%1 % 10) + '0' %endif %endmacro ; ; Macros for network byte order of constants ; %define htons(x) ( ( ((x) & 0FFh) << 8 ) + ( ((x) & 0FF00h) >> 8 ) ) %define ntohs(x) htons(x) %define htonl(x) ( ( ((x) & 0FFh) << 24) + ( ((x) & 0FF00h) << 8 ) + ( ((x) & 0FF0000h) >> 8 ) + ( ((x) & 0FF000000h) >> 24) ) %define ntohl(x) htonl(x) ; ; ASCII ; CR equ 13 ; Carriage Return LF equ 10 ; Line Feed FF equ 12 ; Form Feed BS equ 8 ; Backspace %endif ; _MACROS_INC syslinux-legacy-3.63+dfsg/head.inc0000664000175000017500000000151110777447273015606 0ustar evanevan; -*- fundamental -*- (asm-mode sucks) ; ----------------------------------------------------------------------- ; ; Copyright 2006-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Boston MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; ----------------------------------------------------------------------- ; ; head.inc ; ; Common header includes ; %ifndef _HEAD_INC %include "macros.inc" %include "config.inc" %include "kernel.inc" %include "bios.inc" %include "tracers.inc" %include "layout.inc" %include "stack.inc" %endif ; _HEAD_INC syslinux-legacy-3.63+dfsg/configinit.inc0000664000175000017500000000257310777447273017047 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; configinit.inc ;; ;; Initialize the configuration section ;; section .text reset_config: call highmemsize ; Initialize the .config section xor eax,eax mov si,section..config.start mov di,section..config.vstart mov cx,section..config.end.start sub cx,di shr cx,2 rep movsd %ifndef DEPEND %if NULLFILE != 0 mov al,NULLFILE mov di,FKeyName mov cx,MAX_FKEYS*(1 << FILENAME_MAX_LG2) rep stosb %endif %endif mov si,linuxauto_cmd ; Default command: "linux auto" mov di,default_cmd mov cx,linuxauto_len rep movsb mov di,KbdMap ; Default keymap 1:1 xor al,al inc ch ; CX <- 256 mkkeymap: stosb inc al loop mkkeymap mov eax,[HighMemSize] mov [VKernelEnd],eax ret section .data linuxauto_cmd db 'linux auto',0 linuxauto_len equ $-linuxauto_cmd syslinux-legacy-3.63+dfsg/mkdiskimage0000775000175000017500000002020510777447307016424 0ustar evanevan#!/usr/bin/perl ## ----------------------------------------------------------------------- ## ## Copyright 2002-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- # # Creates a blank MS-DOS formatted hard disk image # use bytes; use integer; use Fcntl; use Errno; use Cwd; use IO::Handle; # For flush() sub absolute_path($) { my($f) = @_; my($c); return $f if ( $f =~ /^\// ); $c = cwd(); $c = '' if ( $c eq '/' ); return $c.'/'.$f; } sub is_linux() { return !!eval '{ '. 'use POSIX; '. '($sysname, $nodename, $release, $version, $machine) = POSIX::uname(); '. "return \$sysname eq \'Linux\'; }"; } sub get_random() { # Get a 32-bit random number my $rfd, $rnd; my $rid; if (sysopen($rfd, '/dev/urandom', O_RDONLY) && sysread($rfd, $rnd, 4) == 4) { $rid = unpack("V", $rnd); } close($rfd) if (defined($rfd)); return $rid if (defined($rid)); # This sucks but is better than nothing... return ($$+time()) & 0xffffffff; } $is_linux = is_linux(); if ( $is_linux ) { # IOCTL numbers $BLKRRPART = 0x125f; $BLKGETSIZE = 0x1260; } %opt = (); @args = (); while (defined($a = shift(@ARGV))) { if ( $a =~ /^\-/ ) { foreach $o ( split(//, substr($a,1)) ) { $opt{$o} = 1; if ($o eq 'i') { $id = shift(@ARGV); } } } else { push(@args, $a); } } ($file,$c,$h,$s) = @args; $c += 0; $h += 0; $s += 0; $pentry = 1; $pentry = 2 if ( $opt{'2'} ); $pentry = 3 if ( $opt{'3'} ); $pentry = 4 if ( $opt{'4'} ); if ( $opt{'z'} ) { $h = $h || 64; $s = $s || 32; } if ( $opt{'M'} && $h && $s ) { # Specify size in megabytes, not in cylinders $c = ($c*1024*2)/($h*$s); } $is_open = 0; if ( $c == 0 && $file ne '' ) { $len = 0; if ( sysopen(OUTPUT, $file, O_RDWR, 0666) ) { $is_open = 1; if ( (@filestat = stat(OUTPUT)) && S_ISREG($filestat[2]) ) { $len = $filestat[7] >> 9; } elsif ( $is_linux && S_ISBLK($filestat[2]) ) { $blksize = pack("L!", 0); if ( ioctl(OUTPUT, $BLKGETSIZE, $blksize) == 0 ) { $len = unpack("L!", $blksize); # In 512-byte sectors! } } } if ( !$len ) { print STDERR "$0: $file: don't know how to determine the size of this device\n"; exit 1; } $c = $len/($h*$s); } if ( $file eq '' || $c < 1 || $h < 1 || $h > 256 || $s < 1 || $s > 63 ) { print STDERR "Usage: $0 [-doFMz4][-i id] file c h s (max: 1024 256 63)\n"; print STDERR " -d add DOSEMU header\n"; print STDERR " -o print filesystem offset to stdout\n"; print STDERR " -F format partition as FAT32\n"; print STDERR " -M \"c\" argument is megabytes, calculate cylinders\n"; print STDERR " -z use zipdisk geometry (h=64 s=32)\n"; print STDERR " -4 use partition entry 4 (standard for zipdisks)\n"; print STDERR " -i specify the MBR ID\n"; exit 1; } if ($c > 1024) { print STDERR "Warning: more than 1024 cylinders ($c).\n"; print STDERR "Not all BIOSes will be able to boot this device.\n"; $cc = 1024; } else { $cc = $c; } $cylsize = $h*$s*512; if ( !$is_open ) { sysopen(OUTPUT, $file, O_CREAT|O_RDWR|O_TRUNC, 0666) or die "$0: Cannot open: $file\n"; } binmode OUTPUT; # Print out DOSEMU header, if requested if ( $opt{'d'} ) { $emuhdr = "DOSEMU\0" . pack("VVVV", $h, $s, $c, 128); $emuhdr .= "\0" x (128 - length($emuhdr)); print OUTPUT $emuhdr; } # Print the MBR and partition table $mbr = ''; while ( $line = ) { chomp $line; foreach $byte ( split(/\s+/, $line) ) { $mbr .= chr(hex($byte)); } } if ( length($mbr) > 440 ) { die "$0: Bad MBR code\n"; } $mbr .= "\0" x (440 - length($mbr)); if (defined($id)) { $id = to_int($id); } else { $id = get_random(); } $mbr .= pack("V", $id); # Offset 440: MBR ID $mbr .= "\0\0"; # Offset 446: actual partition table print OUTPUT $mbr; # Print partition table $psize = $c*$h*$s-$s; $bhead = ($h > 1) ? 1 : 0; $bsect = 1; $bcyl = ($h > 1) ? 0 : 1; $ehead = $h-1; $esect = $s + ((($cc-1) & 0x300) >> 2); $ecyl = ($cc-1) & 0xff; if ( $c > 1024 ) { $fstype = 0x0e; } elsif ( $psize > 65536 ) { $fstype = 0x06; } else { $fstype = 0x04; } for ( $i = 1 ; $i <= 4 ; $i++ ) { if ( $i == $pentry ) { print OUTPUT pack("CCCCCCCCVV", 0x80, $bhead, $bsect, $bcyl, $fstype, $ehead, $esect, $ecyl, $s, $psize); } else { print OUTPUT "\0" x 16; } } print OUTPUT "\x55\xaa"; # Output blank file $totalsize = $c*$h*$s; $tracks = $c*$h; $track = "\0" x (512*$s); # Print fractional track print OUTPUT "\0" x (512 * ($s-1)); for ( $i = 1 ; $i < $tracks ; $i++ ) { print OUTPUT $track; } # Print mtools temp file $n = 0; while ( !defined($tmpdir) ) { $tmpdir = "/tmp/mkdiskimage.$$.".($n++); if ( !mkdir($tmpdir, 0700) ) { die "$0: Failed to make temp directory: $tmpdir\n" if ( $! != EEXIST ); undef $tmpdir; } } $cfgfile = $tmpdir.'/mtools.conf'; $imglink = $tmpdir.'/disk.img'; die "$0: Failed to create symlink $imglink\n" if ( !symlink(absolute_path($file), $imglink) ); $header_size = ($opt{'d'} ? 128 : 0); # Start of filesystem $offset = $s*512 + $header_size; # Start of partition table entry $pstart = $header_size + 446 + 16*($pentry-1); open(MCONFIG, "> ${cfgfile}") or die "$0: Cannot make mtools config\n"; print MCONFIG "drive z:\n"; print MCONFIG "file=\"${imglink}\"\n"; print MCONFIG "cylinders=${c}\n"; print MCONFIG "heads=${h}\n"; print MCONFIG "sectors=${s}\n"; print MCONFIG "offset=${offset}\n"; print MCONFIG "mformat_only\n"; close(MCONFIG); # Output the filesystem offset to stdout if appropriate if ( $opt{'o'} ) { print $offset, "\n"; } $ENV{'MTOOLSRC'} = $cfgfile; if ( $opt{'F'} ) { system('mformat', '-F', 'z:'); } else { system('mformat', 'z:'); } # Clean up in /tmp unlink($cfgfile); unlink($imglink); rmdir($tmpdir); # MTOOLS doesn't write the bsHiddenSecs field correctly seek(OUTPUT, $offset + 0x1c, 0); print OUTPUT pack("V", ($offset-$header_size)>>9); # Set the partition type if ( $opt{'F'} ) { if ( $c > 1024 ) { $fstype = 0x0c; # FAT32 LBA } else { $fstype = 0x0b; } } else { if ( $c > 1024 ) { $fstype = 0x0e; # FAT16 LBA } elsif ( $psize > 65536 ) { $fstype = 0x06; # FAT16 > 32MB } else { $fstype = 0x04; # FAT16 <= 32MB } seek(OUTPUT, $offset + 0x36, 0); read(OUTPUT, $fsname, 8); # FAT12: adjust partition type if ( $fsname eq 'FAT12 ' ) { $fstype = 0x01; # FAT12 } } seek(OUTPUT, $pstart+4, 0); print OUTPUT pack("C", $fstype); flush OUTPUT; # Just in case this is a block device, try to flush the partition table if ( $is_linux ) { ioctl(OUTPUT, $BLKRRPART, 0); }; exit 0; __END__ fa 31 c0 8e d8 8e d0 bc 0 7c 89 e6 6 57 52 8e c0 fb fc bf 0 6 b9 0 1 f3 a5 ea 20 6 0 0 52 b4 41 bb aa 55 31 c9 30 f6 f9 cd 13 72 13 81 fb 55 aa 75 d d1 e9 73 9 66 c7 6 8d 6 b4 42 eb 15 5a b4 8 cd 13 83 e1 3f 51 f b6 c6 40 f7 e1 52 50 66 31 c0 66 99 e8 66 0 e8 21 1 4d 69 73 73 69 6e 67 20 6f 70 65 72 61 74 69 6e 67 20 73 79 73 74 65 6d 2e d a 66 60 66 31 d2 bb 0 7c 66 52 66 50 6 53 6a 1 6a 10 89 e6 66 f7 36 f4 7b c0 e4 6 88 e1 88 c5 92 f6 36 f8 7b 88 c6 8 e1 41 b8 1 2 8a 16 fa 7b cd 13 83 c4 10 66 61 c3 e8 c4 ff be be 7d bf be 7 b9 20 0 f3 a5 c3 66 60 89 e5 bb be 7 b9 4 0 31 c0 53 51 f6 7 80 74 3 40 89 de 83 c3 10 e2 f3 48 74 5b 79 39 59 5b 8a 47 4 3c f 74 6 24 7f 3c 5 75 22 66 8b 47 8 66 8b 56 14 66 1 d0 66 21 d2 75 3 66 89 c2 e8 ac ff 72 3 e8 b6 ff 66 8b 46 1c e8 a0 ff 83 c3 10 e2 cc 66 61 c3 e8 62 0 4d 75 6c 74 69 70 6c 65 20 61 63 74 69 76 65 20 70 61 72 74 69 74 69 6f 6e 73 2e d a 66 8b 44 8 66 3 46 1c 66 89 44 8 e8 30 ff 72 13 81 3e fe 7d 55 aa f 85 6 ff bc fa 7b 5a 5f 7 fa ff e4 e8 1e 0 4f 70 65 72 61 74 69 6e 67 20 73 79 73 74 65 6d 20 6c 6f 61 64 20 65 72 72 6f 72 2e d a 5e ac b4 e 8a 3e 62 4 b3 7 cd 10 3c a 75 f1 cd 18 f4 eb fd syslinux-legacy-3.63+dfsg/copybs.asm0000664000175000017500000001230110777447273016212 0ustar evanevan; -*- fundamental -*- (asm-mode sucks) ; ----------------------------------------------------------------------- ; ; Copyright 1998-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Boston MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; ----------------------------------------------------------------------- ; ; copybs.asm ; ; Small DOS program to copy the boot sector from a drive ; to a file ; ; Usage: copybs : ; absolute 0 pspInt20: resw 1 pspNextParagraph: resw 1 resb 1 ; reserved pspDispatcher: resb 5 pspTerminateVector: resd 1 pspControlCVector: resd 1 pspCritErrorVector: resd 1 resw 11 ; reserved pspEnvironment: resw 1 resw 23 ; reserved pspFCB_1: resb 16 pspFCB_2: resb 16 resd 1 ; reserved pspCommandLen: resb 1 pspCommandArg: resb 127 section .text org 100h ; .COM format _start: mov ax,3000h ; Get DOS version int 21h xchg al,ah mov [DOSVersion],ax cmp ax,0200h ; DOS 2.00 minimum jae dosver_ok mov dx,msg_ancient_err jmp die section .bss alignb 2 DOSVersion: resw 1 section .text ; ; Scan command line for a drive letter followed by a colon ; dosver_ok: xor cx,cx mov si,pspCommandArg mov cl,[pspCommandLen] cmdscan1: jcxz bad_usage ; End of command line? lodsb ; Load character dec cx cmp al,' ' ; White space jbe cmdscan1 or al,020h ; -> lower case cmp al,'a' ; Check for letter jb bad_usage cmp al,'z' ja bad_usage sub al,'a' ; Convert to zero-based index mov [DriveNo],al ; Save away drive index section .bss DriveNo: resb 1 section .text ; ; Got the leading letter, now the next character must be a colon ; got_letter: jcxz bad_usage lodsb dec cx cmp al,':' jne bad_usage ; ; Got the colon; now we should have at least one whitespace ; followed by a filename ; got_colon: jcxz bad_usage lodsb dec cx cmp al,' ' ja bad_usage skipspace: jcxz bad_usage lodsb dec cx cmp al,' ' jbe skipspace mov di,FileName copyfile: stosb jcxz got_cmdline lodsb dec cx cmp al,' ' ja copyfile jmp short got_cmdline ; ; We end up here if the command line doesn't parse ; bad_usage: mov dx,msg_unfair jmp die section .data msg_unfair: db 'Usage: copybs : ', 0Dh, 0Ah, '$' section .bss alignb 4 FileName resb 256 ; ; Parsed the command line OK. Get device parameter block to get the ; sector size. ; struc DPB dpbDrive: resb 1 dpbUnit: resb 1 dpbSectorSize: resw 1 dpbClusterMask: resb 1 dpbClusterShift: resb 1 dpbFirstFAT: resw 1 dpbFATCount: resb 1 dpbRootEntries: resw 1 dpbFirstSector: resw 1 dpbMaxCluster: resw 1 dpbFATSize: resw 1 dpbDirSector: resw 1 dpbDriverAddr: resd 1 dpbMedia: resb 1 dpbFirstAccess: resb 1 dpbNextDPB: resd 1 dpbNextFree: resw 1 dpbFreeCnt: resw 1 endstruc section .bss alignb 2 SectorSize resw 1 section .text got_cmdline: xor al,al ; Zero-terminate filename stosb mov dl,[DriveNo] inc dl ; 1-based mov ah,32h int 21h ; Get Drive Parameter Block and al,al jnz filesystem_error mov dx,[bx+dpbSectorSize] ; Save sector size ; ; Read the boot sector. ; section .data align 4, db 0 DISKIO equ $ diStartSector: dd 0 ; Absolute sector 0 diSectors: dw 1 ; One sector diBuffer: dw SectorBuffer ; Buffer offset dw 0 ; Buffer segment section .text read_bootsect: mov ax,cs ; Set DS <- CS mov ds,ax mov [SectorSize],dx ; Saved sector size from above cmp word [DOSVersion],0400h ; DOS 4.00 has a new interface jae .new .old: mov bx,SectorBuffer mov cx,1 ; One sector jmp short .common .new: mov [diBuffer+2],ax ; == DS mov bx,DISKIO mov cx,-1 .common: xor dx,dx ; Absolute sector 0 mov al,[DriveNo] int 25h ; DOS absolute disk read pop ax ; Remove flags from stack jc disk_read_error ; ; Open the file and write the boot sector to the file. ; mov dx,FileName mov cx,0020h ; Attribute = ARCHIVE mov ah,3Ch ; Create file int 21h jc file_write_error mov bx,ax push ax ; Handle mov cx,[SectorSize] mov dx,SectorBuffer mov ah,40h ; Write file int 21h jc file_write_error cmp ax,[SectorSize] jne file_write_error pop bx ; Handle mov ah,3Eh ; Close file int 21h jc file_write_error ; ; We're done! ; mov ax,4C00h ; exit(0) int 21h ; ; Error routine jump ; filesystem_error: mov dx,msg_filesystem_err jmp short die disk_read_error: mov dx,msg_read_err jmp short die file_write_error: mov dx,msg_write_err die: push cs pop ds push dx mov dx,msg_error mov ah,09h int 21h pop dx mov ah,09h ; Write string int 21h mov ax,4C01h ; Exit error status int 21h section .data msg_error: db 'ERROR: $' msg_ancient_err: db 'DOS version 2.00 or later required', 0Dh, 0Ah, '$' msg_filesystem_err: db 'Filesystem not found on disk', 0Dh, 0Ah, '$' msg_read_err: db 'Boot sector read failed', 0Dh, 0Ah, '$' msg_write_err: db 'File write failed', 0Dh, 0Ah, '$' section .bss alignb 4 SectorBuffer: resb 4096 syslinux-legacy-3.63+dfsg/gethostip.c0000664000175000017500000000572710777447273016401 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * gethostip.c * * Small program to use gethostbyname() to print out a hostname in * hex and/or dotted-quad notation */ #include #include #include #include #include #include #define _GNU_SOURCE /* For getopt_long */ #include const struct option options[] = { { "hexadecimal", 0, NULL, 'x' }, { "decimal", 0, NULL, 'd' }, { "dotted-quad", 0, NULL, 'd' }, { "full-output", 0, NULL, 'f' }, { "name", 0, NULL, 'n' }, { "help", 0, NULL, 'h' }, { NULL, 0, NULL, 0 } }; const char *program; void usage(int exit_code) { fprintf(stderr, "Usage: %s [-dxnf] hostname/ip...\n", program); exit(exit_code); } int main(int argc, char *argv[]) { int opt; int output = 0; int i; char *sep; int err = 0; struct hostent *host; program = argv[0]; while ( (opt = getopt_long(argc, argv, "dxfnh", options, NULL)) != -1 ) { switch ( opt ) { case 'd': output |= 2; /* Decimal output */ break; case 'x': output |= 4; /* Hexadecimal output */ break; case 'n': output |= 1; /* Canonical name output */ break; case 'f': output = 7; /* Full output */ break; case 'h': usage(0); break; default: usage(EX_USAGE); break; } } if ( optind == argc ) usage(EX_USAGE); if ( output == 0 ) output = 7; /* Default output */ for ( i = optind ; i < argc ; i++ ) { sep = ""; host = gethostbyname(argv[i]); if ( !host ) { herror(argv[i]); err = 1; continue; } if ( host->h_addrtype != AF_INET || host->h_length != 4 ) { fprintf(stderr, "%s: No IPv4 address associated with name\n", argv[i]); err = 1; continue; } if ( output & 1 ) { printf("%s%s", sep, host->h_name); sep = " "; } if ( output & 2 ) { printf("%s%u.%u.%u.%u", sep, ((unsigned char *)host->h_addr)[0], ((unsigned char *)host->h_addr)[1], ((unsigned char *)host->h_addr)[2], ((unsigned char *)host->h_addr)[3]); sep = " "; } if ( output & 4 ) { printf("%s%02X%02X%02X%02X", sep, ((unsigned char *)host->h_addr)[0], ((unsigned char *)host->h_addr)[1], ((unsigned char *)host->h_addr)[2], ((unsigned char *)host->h_addr)[3]); sep = " "; } putchar('\n'); } return err; } syslinux-legacy-3.63+dfsg/mkdiskimage.in0000775000175000017500000001600110777447273017032 0ustar evanevan#!/usr/bin/perl ## ----------------------------------------------------------------------- ## ## Copyright 2002-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- # # Creates a blank MS-DOS formatted hard disk image # use bytes; use integer; use Fcntl; use Errno; use Cwd; use IO::Handle; # For flush() sub absolute_path($) { my($f) = @_; my($c); return $f if ( $f =~ /^\// ); $c = cwd(); $c = '' if ( $c eq '/' ); return $c.'/'.$f; } sub is_linux() { return !!eval '{ '. 'use POSIX; '. '($sysname, $nodename, $release, $version, $machine) = POSIX::uname(); '. "return \$sysname eq \'Linux\'; }"; } sub get_random() { # Get a 32-bit random number my $rfd, $rnd; my $rid; if (sysopen($rfd, '/dev/urandom', O_RDONLY) && sysread($rfd, $rnd, 4) == 4) { $rid = unpack("V", $rnd); } close($rfd) if (defined($rfd)); return $rid if (defined($rid)); # This sucks but is better than nothing... return ($$+time()) & 0xffffffff; } $is_linux = is_linux(); if ( $is_linux ) { # IOCTL numbers $BLKRRPART = 0x125f; $BLKGETSIZE = 0x1260; } %opt = (); @args = (); while (defined($a = shift(@ARGV))) { if ( $a =~ /^\-/ ) { foreach $o ( split(//, substr($a,1)) ) { $opt{$o} = 1; if ($o eq 'i') { $id = shift(@ARGV); } } } else { push(@args, $a); } } ($file,$c,$h,$s) = @args; $c += 0; $h += 0; $s += 0; $pentry = 1; $pentry = 2 if ( $opt{'2'} ); $pentry = 3 if ( $opt{'3'} ); $pentry = 4 if ( $opt{'4'} ); if ( $opt{'z'} ) { $h = $h || 64; $s = $s || 32; } if ( $opt{'M'} && $h && $s ) { # Specify size in megabytes, not in cylinders $c = ($c*1024*2)/($h*$s); } $is_open = 0; if ( $c == 0 && $file ne '' ) { $len = 0; if ( sysopen(OUTPUT, $file, O_RDWR, 0666) ) { $is_open = 1; if ( (@filestat = stat(OUTPUT)) && S_ISREG($filestat[2]) ) { $len = $filestat[7] >> 9; } elsif ( $is_linux && S_ISBLK($filestat[2]) ) { $blksize = pack("L!", 0); if ( ioctl(OUTPUT, $BLKGETSIZE, $blksize) == 0 ) { $len = unpack("L!", $blksize); # In 512-byte sectors! } } } if ( !$len ) { print STDERR "$0: $file: don't know how to determine the size of this device\n"; exit 1; } $c = $len/($h*$s); } if ( $file eq '' || $c < 1 || $h < 1 || $h > 256 || $s < 1 || $s > 63 ) { print STDERR "Usage: $0 [-doFMz4][-i id] file c h s (max: 1024 256 63)\n"; print STDERR " -d add DOSEMU header\n"; print STDERR " -o print filesystem offset to stdout\n"; print STDERR " -F format partition as FAT32\n"; print STDERR " -M \"c\" argument is megabytes, calculate cylinders\n"; print STDERR " -z use zipdisk geometry (h=64 s=32)\n"; print STDERR " -4 use partition entry 4 (standard for zipdisks)\n"; print STDERR " -i specify the MBR ID\n"; exit 1; } if ($c > 1024) { print STDERR "Warning: more than 1024 cylinders ($c).\n"; print STDERR "Not all BIOSes will be able to boot this device.\n"; $cc = 1024; } else { $cc = $c; } $cylsize = $h*$s*512; if ( !$is_open ) { sysopen(OUTPUT, $file, O_CREAT|O_RDWR|O_TRUNC, 0666) or die "$0: Cannot open: $file\n"; } binmode OUTPUT; # Print out DOSEMU header, if requested if ( $opt{'d'} ) { $emuhdr = "DOSEMU\0" . pack("VVVV", $h, $s, $c, 128); $emuhdr .= "\0" x (128 - length($emuhdr)); print OUTPUT $emuhdr; } # Print the MBR and partition table $mbr = ''; while ( $line = ) { chomp $line; foreach $byte ( split(/\s+/, $line) ) { $mbr .= chr(hex($byte)); } } if ( length($mbr) > 440 ) { die "$0: Bad MBR code\n"; } $mbr .= "\0" x (440 - length($mbr)); if (defined($id)) { $id = to_int($id); } else { $id = get_random(); } $mbr .= pack("V", $id); # Offset 440: MBR ID $mbr .= "\0\0"; # Offset 446: actual partition table print OUTPUT $mbr; # Print partition table $psize = $c*$h*$s-$s; $bhead = ($h > 1) ? 1 : 0; $bsect = 1; $bcyl = ($h > 1) ? 0 : 1; $ehead = $h-1; $esect = $s + ((($cc-1) & 0x300) >> 2); $ecyl = ($cc-1) & 0xff; if ( $c > 1024 ) { $fstype = 0x0e; } elsif ( $psize > 65536 ) { $fstype = 0x06; } else { $fstype = 0x04; } for ( $i = 1 ; $i <= 4 ; $i++ ) { if ( $i == $pentry ) { print OUTPUT pack("CCCCCCCCVV", 0x80, $bhead, $bsect, $bcyl, $fstype, $ehead, $esect, $ecyl, $s, $psize); } else { print OUTPUT "\0" x 16; } } print OUTPUT "\x55\xaa"; # Output blank file $totalsize = $c*$h*$s; $tracks = $c*$h; $track = "\0" x (512*$s); # Print fractional track print OUTPUT "\0" x (512 * ($s-1)); for ( $i = 1 ; $i < $tracks ; $i++ ) { print OUTPUT $track; } # Print mtools temp file $n = 0; while ( !defined($tmpdir) ) { $tmpdir = "/tmp/mkdiskimage.$$.".($n++); if ( !mkdir($tmpdir, 0700) ) { die "$0: Failed to make temp directory: $tmpdir\n" if ( $! != EEXIST ); undef $tmpdir; } } $cfgfile = $tmpdir.'/mtools.conf'; $imglink = $tmpdir.'/disk.img'; die "$0: Failed to create symlink $imglink\n" if ( !symlink(absolute_path($file), $imglink) ); $header_size = ($opt{'d'} ? 128 : 0); # Start of filesystem $offset = $s*512 + $header_size; # Start of partition table entry $pstart = $header_size + 446 + 16*($pentry-1); open(MCONFIG, "> ${cfgfile}") or die "$0: Cannot make mtools config\n"; print MCONFIG "drive z:\n"; print MCONFIG "file=\"${imglink}\"\n"; print MCONFIG "cylinders=${c}\n"; print MCONFIG "heads=${h}\n"; print MCONFIG "sectors=${s}\n"; print MCONFIG "offset=${offset}\n"; print MCONFIG "mformat_only\n"; close(MCONFIG); # Output the filesystem offset to stdout if appropriate if ( $opt{'o'} ) { print $offset, "\n"; } $ENV{'MTOOLSRC'} = $cfgfile; if ( $opt{'F'} ) { system('mformat', '-F', 'z:'); } else { system('mformat', 'z:'); } # Clean up in /tmp unlink($cfgfile); unlink($imglink); rmdir($tmpdir); # MTOOLS doesn't write the bsHiddenSecs field correctly seek(OUTPUT, $offset + 0x1c, 0); print OUTPUT pack("V", ($offset-$header_size)>>9); # Set the partition type if ( $opt{'F'} ) { if ( $c > 1024 ) { $fstype = 0x0c; # FAT32 LBA } else { $fstype = 0x0b; } } else { if ( $c > 1024 ) { $fstype = 0x0e; # FAT16 LBA } elsif ( $psize > 65536 ) { $fstype = 0x06; # FAT16 > 32MB } else { $fstype = 0x04; # FAT16 <= 32MB } seek(OUTPUT, $offset + 0x36, 0); read(OUTPUT, $fsname, 8); # FAT12: adjust partition type if ( $fsname eq 'FAT12 ' ) { $fstype = 0x01; # FAT12 } } seek(OUTPUT, $pstart+4, 0); print OUTPUT pack("C", $fstype); flush OUTPUT; # Just in case this is a block device, try to flush the partition table if ( $is_linux ) { ioctl(OUTPUT, $BLKRRPART, 0); }; exit 0; __END__ syslinux-legacy-3.63+dfsg/rllpack.inc0000664000175000017500000000544510777447273016347 0ustar evanevan; -*- fundamental -*- --------------------------------------------------- ; ; Copyright 2004-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Boston MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; ----------------------------------------------------------------------- ; ; rllpack.inc ; ; Very simple RLL compressor/decompressor, used to pack binary structures ; together. ; ; Format of leading byte ; 1-128 = x verbatim bytes follow ; 129-223 = (x-126) times subsequent byte ; 224-255 = (x-224)*256+(next byte) times the following byte ; 0 = end of data ; ; These structures are stored *in reverse order* in high memory. ; High memory pointers point to one byte beyond the end. ; section .text ; ; rllpack: ; Pack CX bytes from SI into EDI. ; Returns updated SI and EDI. ; rllpack: push word .pmentry call simple_pm_call ret .pmentry: push cx push ebx push edx .startseq: xor ax,ax ; Zero byte xor ebx,ebx ; Run length zero dec edi mov edx,edi ; Pointer to header byte mov [edi],al ; Create header byte jcxz .done ; If done, this was the terminator .stdbyte: lodsb dec edi mov [edi],al dec cx cmp ah,al je .same .diff: mov ah,al xor bx,bx .plainbyte: inc bx inc byte [edx] jcxz .startseq jns .stdbyte jmp .startseq .same: cmp bl,2 jb .plainbyte ; 3 bytes or more in a row, time to convert sequence sub [edx],bl jnz .normal inc edi ; We killed a whole stretch, ; drop start byte .normal: inc bx add edi,ebx ; Remove the stored run bytes .getrun: jcxz .nomatch lodsb cmp al,ah jne .nomatch cmp bx,(256-224)*256-1 ; Maximum run size jae .nomatch inc bx dec cx jmp .getrun .nomatch: cmp bx,224-126 jae .twobyte .onebyte: add bl,126 dec edi mov [edi],bl jmp .storebyte .twobyte: add bh,224 sub edi,2 mov [edi],bx .storebyte: dec edi mov [edi],ah dec si ; Reload subsequent byte jmp .startseq .done: pop edx pop ebx pop cx ret ; ; rllunpack: ; Unpack bytes from ESI into DI ; On return ESI, DI are updated and CX contains number of bytes output. ; rllunpack: push word .pmentry call simple_pm_call ret .pmentry: push di xor cx,cx .header: dec esi mov cl,[esi] jcxz .done cmp cl,129 jae .isrun ; Not a run .copy: dec esi mov al,[esi] stosb loop .copy jmp .header .isrun: cmp cl,224 jae .longrun sub cl,126 .dorun: dec esi mov al,[esi] rep stosb jmp .header .longrun: sub cl,224 mov ch,cl dec esi mov cl,[esi] jmp .dorun .done: pop cx sub cx,di neg cx ret syslinux-legacy-3.63+dfsg/ppmtolss160000775000175000017500000002260210777447273016174 0ustar evanevan#!/usr/bin/perl ## ----------------------------------------------------------------------- ## ## Copyright 2004-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- ## ## ppmtolss16 ## ## Convert a PNM file with max 16 colors to a simple RLE-based format: ## ## uint32 0x1413f33d ; magic (littleendian) ## uint16 xsize ; littleendian ## uint16 ysize ; littleendian ## 16 x uint8 r,g,b ; color map, in 6-bit format (each byte is 0..63) ## ## Then, a sequence of nybbles: ## ## N ... if N is != previous pixel, one pixel of color N ## ... otherwise run sequence follows ... ## M ... if M > 0 then run length is M+1 ## ... otherwise run sequence is encoded in two nybbles, ## littleendian, +17 ## ## The nybble sequences are on a per-row basis; runs may not extend ## across rows and odd-nybble rows are zero-padded. ## ## At the start of row, the "previous pixel" is assumed to be zero. ## ## Usage: ## ## ppmtolss16 [#rrggbb=i ...] < input.ppm > output.rle ## ## Command line options of the form #rrggbb=i indicate that ## the color #rrggbb (hex) should be assigned index i (decimal) ## eval { use bytes; }; eval { binmode STDIN; }; eval { binmode STDOUT; }; $magic = 0x1413f33d; # Get a token from the PPM header. Ignore comments and leading # and trailing whitespace, as is required by the spec. # This routine eats exactly one character of trailing whitespace, # unless it is a comment (in which case it eats the comment up # to and including the end of line.) sub get_token() { my($token, $ch); my($ch); do { $ch = getc(STDIN); return undef if ( !defined($ch) ); # EOF if ( $ch eq '#' ) { do { $ch = getc(STDIN); return undef if ( !defined($ch) ); } while ( $ch ne "\n" ); } } while ( $ch =~ /^[ \t\n\v\f\r]$/ ); $token = $ch; while ( 1 ) { $ch = getc(STDIN); last if ( $ch =~ /^[ \t\n\v\f\r\#]$/ ); $token .= $ch; } if ( $ch eq '#' ) { do { $ch = getc(STDIN); } while ( defined($ch) && $ch ne "\n" ); } return $token; } # Get a token, and make sure it is numeric (and exists) sub get_numeric_token() { my($token) = get_token(); if ( $token !~ /^[0-9]+$/ ) { print STDERR "Format error on input\n"; exit 1; } return $token + 0; } # Must be called before each pixel row is read sub start_new_row() { $getrgb_leftover_bit_cnt = 0; $getrgb_leftover_bit_val = 0; } # Get a single RGB token depending on the PNM type sub getrgb($) { my($form) = @_; my($rgb,$r,$g,$b); if ( $form == 6 ) { # Raw PPM, most common return undef unless ( read(STDIN,$rgb,3) == 3 ); return unpack("CCC", $rgb); } elsif ( $form == 3 ) { # Plain PPM $r = get_numeric_token(); $g = get_numeric_token(); $b = get_numeric_token(); return ($r,$g,$b); } elsif ( $form == 5 ) { # Raw PGM return undef unless ( read(STDIN,$rgb,1) == 1 ); $r = unpack("C", $rgb); return ($r,$r,$r); } elsif ( $form == 2 ) { # Plain PGM $r = get_numeric_token(); return ($r,$r,$r); } elsif ( $form == 4 ) { # Raw PBM if ( !$getrgb_leftover_bit_cnt ) { return undef unless ( read(STDIN,$rgb,1) == 1 ); $getrgb_leftover_bit_val = unpack("C", $rgb); $getrgb_leftover_bit_cnt = 8; } $r = ( $getrgb_leftover_bit_val & 0x80 ) ? 0x00 : 0xff; $getrgb_leftover_bit_val <<= 1; $getrgb_leftover_bit_cnt--; return ($r,$r,$r); } elsif ( $form == 1 ) { # Plain PBM my($ch); do { $ch = getc(STDIN); return undef if ( !defined($ch) ); return (255,255,255) if ( $ch eq '0' ); # White return (0,0,0) if ( $ch eq '1'); # Black if ( $ch eq '#' ) { do { $ch = getc(STDIN); return undef if ( !defined($ch) ); } while ( $ch ne "\n" ); } } while ( $ch =~ /^[ \t\n\v\f\r]$/ ); return undef; } else { die "Internal error: unknown format: $form\n"; } } sub rgbconvert($$$$) { my($r,$g,$b,$maxmult) = @_; my($rgb); $r = int($r*$maxmult); $g = int($g*$maxmult); $b = int($b*$maxmult); $rgb = pack("CCC", $r, $g, $b); return $rgb; } foreach $arg ( @ARGV ) { if ( $arg =~ /^\#([0-9a-f])([0-9a-f])([0-9a-f])=([0-9]+)$/i ) { $r = hex($1) << 4; $g = hex($2) << 4; $b = hex($3) << 4; $i = $4 + 0; } elsif ( $arg =~ /^\#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})=([0-9]+)$/i ) { $r = hex($1); $g = hex($2); $b = hex($3); $i = $4 + 0; } elsif ( $arg =~ /^\#([0-9a-f]{3})([0-9a-f]{3})([0-9a-f]{3})=([0-9]+)$/i ) { $r = hex($1) >> 4; $g = hex($2) >> 4; $b = hex($3) >> 4; $i = $4 + 0; } elsif ( $arg =~ /^\#([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})=([0-9]+)$/i ) { $r = hex($1) >> 8; $g = hex($2) >> 8; $b = hex($3) >> 8; $i = $4 + 0; } else { print STDERR "$0: Unknown argument: $arg\n"; next; } if ( $i > 15 ) { print STDERR "$0: Color index out of range: $arg\n"; next; } $rgb = rgbconvert($r, $g, $b, 64/256); if ( defined($index_forced{$i}) ) { print STDERR "$0: More than one color index $i\n"; exit(1); } $index_forced{$i} = $rgb; $force_index{$rgb} = $i; } $form = get_token(); die "$0: stdin is not a PNM file" if ( $form !~ /^P([1-6])$/ ); $form = $1+0; $xsize = get_numeric_token(); $ysize = get_numeric_token(); if ( $form == 1 || $form == 4 ) { $maxcol = 255; # Internal convention } else { $maxcol = get_numeric_token(); } $maxmult = 64/($maxcol+1); # Equal buckets conversion @data = (); for ( $y = 0 ; $y < $ysize ; $y++ ) { start_new_row(); for ( $x = 0 ; $x < $xsize ; $x++ ) { die "$0: Premature EOF at ($x,$y) of ($xsize,$ysize)\n" if ( !defined(@pnmrgb = getrgb($form)) ); # Convert to 6-bit representation $rgb = rgbconvert($pnmrgb[0], $pnmrgb[1], $pnmrgb[2], $maxmult); $color_count{$rgb}++; push(@data, $rgb); } } # Sort list of colors according to freqency @colors = sort { $color_count{$b} <=> $color_count{$a} } keys(%color_count); # Now we have our pick of colors. Sort according to intensity; # this is more or less an ugly hack to cover for the fact that # using PPM as input doesn't let the user set the color map, # which the user really needs to be able to do. sub by_intensity() { my($ra,$ga,$ba) = unpack("CCC", $a); my($rb,$gb,$bb) = unpack("CCC", $b); my($ia) = $ra*0.299 + $ga*0.587 + $ba*0.114; my($ib) = $rb*0.299 + $gb*0.587 + $bb*0.114; return ( $ia <=> $ib ) if ( $ia != $ib ); # If same, sort based on RGB components, # with highest priority given to G, then R, then B. return ( $ga <=> $gb ) if ( $ga != $gb ); return ( $ra <=> $rb ) if ( $ra != $rb ); return ( $ba <=> $bb ); } @icolors = sort by_intensity @colors; # Insert forced colors into "final" array @colors = (undef) x 16; foreach $rgb ( keys(%force_index) ) { $i = $force_index{$rgb}; $colors[$i] = $rgb; $color_index{$rgb} = $i; } undef %force_index; # Insert remaining colors in the remaining slots, # in luminosity-sorted order $nix = 0; while ( scalar(@icolors) ) { # Advance to the next free slot $nix++ while ( defined($colors[$nix]) && $nix < 16 ); last if ( $nix >= 16 ); $rgb = shift @icolors; if ( !defined($color_index{$rgb}) ) { $colors[$nix] = $rgb; $color_index{$rgb} = $nix; } } while ( scalar(@icolors) ) { $rgb = shift @icolors; $lost++ if ( !defined($color_index{$rgb}) ); } if ( $lost ) { printf STDERR "$0: Warning: color palette truncated (%d colors ignored)\n", $lost; } undef @icolors; # Output header print pack("Vvv", $magic, $xsize, $ysize); # Output color map for ( $i = 0 ; $i < 16 ; $i++ ) { if ( defined($colors[$i]) ) { print $colors[$i]; } else { # Padding for unused color entries print pack("CCC", 63*$i/15, 63*$i/15, 63*$i/15); } } sub output_nybble($) { my($ny) = @_; if ( !defined($ny) ) { if ( defined($nybble_tmp) ) { $ny = 0; # Force the last byte out } else { return; } } $ny = $ny & 0x0F; if ( defined($nybble_tmp) ) { $ny = ($ny << 4) | $nybble_tmp; print chr($ny); $bytes++; undef $nybble_tmp; } else { $nybble_tmp = $ny; } } sub output_run($$$) { my($last,$this,$run) = @_; if ( $this != $last ) { output_nybble($this); $run--; } while ( $run ) { if ( $run >= 16 ) { output_nybble($this); output_nybble(0); if ( $run > 271 ) { $erun = 255; $run -= 271; } else { $erun = $run-16; $run = 0; } output_nybble($erun); output_nybble($erun >> 4); } else { output_nybble($this); output_nybble($run); $run = 0; } } } $bytes = 0; undef $nybble_tmp; for ( $y = 0 ; $y < $ysize ; $y++ ) { $last = $prev = 0; $run = 0; for ( $x = 0 ; $x < $xsize ; $x++ ) { $rgb = shift(@data); $i = $color_index{$rgb} + 0; if ( $i == $last ) { $run++; } else { output_run($prev, $last, $run); $prev = $last; $last = $i; $run = 1; } } # Output final datum for row; we're always at least one pixel behind output_run($prev, $last, $run); output_nybble(undef); # Flush row } $pixels = $xsize * $ysize; $size = ($pixels+1)/2; printf STDERR "%d pixels, %d bytes, (%2.2f%% compression)\n", $pixels, $bytes, 100*($size-$bytes)/$size; syslinux-legacy-3.63+dfsg/adv.inc0000664000175000017500000002147210777447271015465 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 2007-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, ;; Boston MA 02110-1301, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; adv.inc ;; ;; The auxillary data vector and its routines ;; ;; The auxillary data vector is a 512-byte aligned block that on the ;; disk-based derivatives can be part of the syslinux file itself. It ;; exists in two copies; when written, both copies are written (with a ;; sync in between, if from the operating system.) The first two ;; dwords are magic number and inverse checksum, then follows the data ;; area as a tagged array similar to BOOTP/DHCP, finally a tail ;; signature. ;; ;; Note that unlike BOOTP/DHCP, zero terminates the chain, and FF ;; has no special meaning. ;; ;; ;; List of ADV tags... ;; ADV_BOOTONCE equ 1 ;; ;; Other ADV data... ;; ADV_MAGIC1 equ 0x5a2d2fa5 ; Head signature ADV_MAGIC2 equ 0xa3041767 ; Total checksum ADV_MAGIC3 equ 0xdd28bf64 ; Tail signature ADV_LEN equ 500 ; Data bytes adv_retries equ 6 ; Disk retries section .adv ; Introduce the ADVs to valid but blank adv0: .head resd 1 .csum resd 1 .data resb ADV_LEN .tail resd 1 .end equ $ adv1: .head resd 1 .csum resd 1 .data resb ADV_LEN .tail resd 1 .end equ $ section .text ; ; This is called after config file parsing, so we know ; the intended location of the ADV ; adv_init: cmp byte [ADVDrive],-1 jne adv_read ;%if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX %if IS_EXTLINUX ; Not yet implemented for the other derivatives ; ; Update pointers to default ADVs... ; mov bx,[LDLSectors] shl bx,2 mov ecx,[bsHidden] mov eax,[bx+SectorPtrs-8] mov edx,[bx+SectorPtrs-4] add eax,ecx add edx,ecx mov [ADVSec0],eax mov [ADVSec1],edx mov al,[DriveNumber] mov [ADVDrive],al %endif ; ** fall through to adv_verify ** ; ; Initialize the ADV data structure in memory ; adv_verify: cmp byte [ADVDrive],-1 ; No ADV configured, still? je .reset ; Then unconditionally reset mov si,adv0 call .check_adv jz .ok ; Primary ADV okay mov si,adv1 call .check_adv jz .adv1ok ; Neither ADV is usable; initialize to blank .reset: mov di,adv0 mov eax,ADV_MAGIC1 stosd mov eax,ADV_MAGIC2 stosd xor eax,eax mov cx,ADV_LEN/4 rep stosd mov eax,ADV_MAGIC3 stosd .ok: ret ; The primary ADV is bad, but the backup is OK .adv1ok: mov di,adv0 mov cx,512/4 rep movsd ret ; SI points to the putative ADV; unchanged by routine ; ZF=1 on return if good .check_adv: push si lodsd cmp eax,ADV_MAGIC1 jne .done ; ZF=0, i.e. bad xor edx,edx mov cx,ADV_LEN/4+1 ; Remaining dwords .csum: lodsd add edx,eax loop .csum cmp edx,ADV_MAGIC2 jne .done lodsd cmp eax,ADV_MAGIC3 .done: pop si ret ; ; adv_get: find an ADV string if present ; ; Input: DL = ADV ID ; Output: CX = byte count (zero on not found) ; SI = pointer to data ; DL = unchanged ; ; Assumes CS == DS. ; adv_get: push ax mov si,adv0.data xor ax,ax ; Keep AH=0 at all times .loop: lodsb ; Read ID cmp al,dl je .found and al,al jz .end lodsb ; Read length add si,ax cmp si,adv0.tail jb .loop jmp .end .found: lodsb mov cx,ax add ax,si ; Make sure it fits cmp ax,adv0.tail jbe .ok .end: xor cx,cx .ok: pop ax ret ; ; adv_set: insert a string into the ADV in memory ; ; Input: DL = ADV ID ; FS:BX = input buffer ; CX = byte count (max = 255!) ; Output: CF=1 on error ; CX clobbered ; ; Assumes CS == DS == ES. ; adv_set: push ax push si push di and ch,ch jnz .overflow push cx mov si,adv0.data xor ax,ax .loop: lodsb cmp al,dl je .found and al,al jz .endz lodsb add si,ax cmp si,adv0.tail jb .loop jmp .end .found: ; Found, need to delete old copy lodsb lea di,[si-2] push di add si,ax mov cx,adv0.tail sub cx,si jb .nukeit rep movsb ; Remove the old one mov [di],ah ; Termination zero pop si jmp .loop .nukeit: pop si jmp .end .endz: dec si .end: ; Now SI points to where we want to put our data pop cx mov di,si jcxz .empty add si,cx cmp si,adv0.tail-2 jae .overflow ; CF=0 mov si,bx mov al,dl stosb mov al,cl stosb fs rep movsb .empty: mov cx,adv0.tail sub cx,di xor ax,ax rep stosb ; Zero-fill remainder clc .done: pop di pop si pop ax ret .overflow: stc jmp .done ; ; adv_cleanup: checksum adv0 and copy to adv1 ; Assumes CS == DS == ES. ; adv_cleanup: pushad mov si,adv0.data mov cx,ADV_LEN/4 xor edx,edx .loop: lodsd add edx,eax loop .loop mov eax,ADV_MAGIC2 sub eax,edx lea di,[si+4] ; adv1 mov si,adv0 mov [si+4],eax ; Store checksum mov cx,(ADV_LEN+12)/4 rep movsd popad ret ; ; adv_write: write the ADV to disk. ; ; Location is in memory variables. ; Assumes CS == DS == ES. ; ; Returns CF=1 if the ADV cannot be written. ; adv_write: cmp dword [ADVSec0],0 je .bad cmp dword [ADVSec1],0 je .bad cmp byte [ADVDrive],-1 je .bad push ax call adv_cleanup mov ah,3 ; Write call adv_read_write pop ax clc ret .bad: ; No location for ADV set stc ret ; ; adv_read: read the ADV from disk ; ; Location is in memory variables. ; Assumes CS == DS == ES. ; adv_read: push ax mov ah,2 ; Read call adv_read_write call adv_verify pop ax ret ; ; adv_read_write: disk I/O for the ADV ; ; On input, AH=2 for read, AH=3 for write. ; Assumes CS == DS == ES. ; adv_read_write: mov [ADVOp],ah pushad mov dl,[ADVDrive] and dl,dl ; Floppies: can't trust INT 13h 08h, we better know ; the geometry a priori, which means it better be our ; boot device. Handle that later. ; jns .floppy ; Floppy drive... urk mov ah,08h ; Get disk parameters int 13h jc .noparm and ah,ah jnz .noparm shr dx,8 inc dx mov [ADVHeads],dx and cx,3fh mov [ADVSecPerTrack],cx .noparm: ; Check for EDD mov bx,55AAh mov ah,41h ; EDD existence query mov dl,[ADVDrive] int 13h mov si,.cbios jc .noedd mov si,.ebios .noedd: mov eax,[ADVSec0] mov bx,adv0 call .doone mov eax,[ADVSec1] mov bx,adv1 call .doone popad ret .doone: xor edx,edx ; Zero-extend LBA push si jmp si .ebios: mov cx,adv_retries .eb_retry: ; Form DAPA on stack push edx push eax push es push bx push word 1 ; Sector count push word 16 ; DAPA size mov si,sp pushad mov dl,[ADVDrive] mov ax,4080h or ah,[ADVOp] push ds push ss pop ds int 13h pop ds popad lea sp,[si+16] ; Remove DAPA jc .eb_error pop si ret .eb_error: loop .eb_retry stc pop si ret .cbios: push edx push eax push bp movzx esi,word [ADVSecPerTrack] movzx edi,word [ADVHeads] ; ; Dividing by sectors to get (track,sector): we may have ; up to 2^18 tracks, so we need to use 32-bit arithmetric. ; div esi xor cx,cx xchg cx,dx ; CX <- sector index (0-based) ; EDX <- 0 ; eax = track # div edi ; Convert track to head/cyl ; Watch out for overflow, we might be writing! cmp eax,1023 ja .cb_overflow ; ; Now we have AX = cyl, DX = head, CX = sector (0-based), ; BP = sectors to transfer, SI = bsSecPerTrack, ; ES:BX = data target ; shl ah,6 ; Because IBM was STOOPID ; and thought 8 bits were enough ; then thought 10 bits were enough... inc cx ; Sector numbers are 1-based, sigh or cl,ah mov ch,al mov dh,dl mov dl,[ADVDrive] xchg ax,bp ; Sector to transfer count mov ah,[ADVOp] ; Operation mov bp,adv_retries .cb_retry: pushad int 13h popad jc .cb_error .cb_done: pop bp pop eax pop edx ret .cb_error: dec bp jnz .cb_retry .cb_overflow: stc jmp .cb_done section .data align 4, db 0 ADVSec0 dd 0 ; Not specified ADVSec1 dd 0 ; Not specified ADVDrive db -1 ; No ADV defined section .bss alignb 4 ADVSecPerTrack resw 1 ADVHeads resw 1 ADVOp resb 1 syslinux-legacy-3.63+dfsg/plaincon.inc0000664000175000017500000000072310777447273016514 0ustar evanevan; ; writechr: Write a single character in AL to the console without ; mangling any registers; handle video pages correctly. ; section .text writechr: call write_serial ; write to serial port if needed pushfd test byte [cs:UsingVGA], 08h jz .videook call vgaclearmode .videook: test byte [cs:DisplayCon], 01h jz .nothing pushad mov ah,0Eh mov bl,07h ; attribute mov bh,[cs:BIOS_page] ; current page int 10h popad .nothing: popfd ret syslinux-legacy-3.63+dfsg/BUGS0000664000175000017500000000021210777447271014670 0ustar evanevanKnown bugs that have not yet been fixed: - PXELINUX: Some PXE stacks fail with routing enabled, some with routing disabled. Try both? syslinux-legacy-3.63+dfsg/syslinux.spec0000664000175000017500000001726510777447273017001 0ustar evanevan# -*- rpm -*- %define RPMVERSION 3.63 %define VERSION 3.63 Summary: Kernel loader which uses a FAT, ext2/3 or iso9660 filesystem or a PXE network Name: syslinux Version: %{RPMVERSION} Release: 1 License: GPL Group: System/Boot Source0: ftp://ftp.kernel.org/pub/linux/utils/boot/syslinux/%{name}-%{VERSION}.tar.gz ExclusiveArch: i386 i486 i586 i686 athlon pentium4 x86_64 Packager: H. Peter Anvin Buildroot: %{_tmppath}/%{name}-%{VERSION}-root BuildPrereq: nasm >= 0.98.39, perl Autoreq: 0 %ifarch x86_64 Requires: mtools, libc.so.6()(64bit) %define my_cc gcc %else Requires: mtools, libc.so.6 %define my_cc gcc -m32 %endif # NOTE: extlinux belongs in /sbin, not in /usr/sbin, since it is typically # a system bootloader, and may be necessary for system recovery. %define _sbindir /sbin %package devel Summary: Development environment for SYSLINUX add-on modules Group: Development/Libraries Requires: syslinux %description SYSLINUX is a suite of bootloaders, currently supporting DOS FAT filesystems, Linux ext2/ext3 filesystems (EXTLINUX), PXE network boots (PXELINUX), or ISO 9660 CD-ROMs (ISOLINUX). It also includes a tool, MEMDISK, which loads legacy operating systems from these media. %description devel The SYSLINUX boot loader contains an API, called COM32, for writing sophisticated add-on modules. This package contains the libraries necessary to compile such modules. %package extlinux Summary: The EXTLINUX bootloader, for booting the local system. Group: System/Boot Requires: syslinux %description extlinux The EXTLINUX bootloader, for booting the local system, as well as all the SYSLINUX/PXELINUX modules in /boot. %package tftpboot Summary: SYSLINUX modules in /tftpboot, available for network booting Group: Applications/Internet Requires: syslinux %description tftpboot All the SYSLINUX/PXELINUX modules directly available for network booting in the /tftpboot directory. %prep %setup -q -n syslinux-%{VERSION} %build make CC='%{my_cc}' clean make CC='%{my_cc}' installer make CC='%{my_cc}' -C sample tidy %install rm -rf %{buildroot} mkdir -p %{buildroot}%{_bindir} mkdir -p %{buildroot}%{_sbindir} mkdir -p %{buildroot}%{_datadir}/syslinux mkdir -p %{buildroot}%{_includedir} mkdir -p %{buildroot}/boot/extlinux %{buildroot}/etc mkdir -p %{buildroot}/tftpboot/pxelinux.cfg make CC='%{my_cc}' install-all \ INSTALLROOT=%{buildroot} BINDIR=%{_bindir} SBINDIR=%{_sbindir} \ LIBDIR=%{_datadir} MANDIR=%{_mandir} INCDIR=%{_includedir} make CC='%{my_cc}' -C sample tidy cp mkdiskimage syslinux2ansi.pl keytab-lilo.pl %{buildroot}%{_datadir}/syslinux cp %{buildroot}%{_datadir}/syslinux/*.c32 %{buildroot}/boot/extlinux cp %{buildroot}%{_datadir}/syslinux/memdisk %{buildroot}/boot/extlinux ( cd %{buildroot}/etc && ln -s ../boot/extlinux/extlinux.conf . ) cp %{buildroot}%{_datadir}/syslinux/*.c32 %{buildroot}/tftpboot cp %{buildroot}%{_datadir}/syslinux/pxelinux.0 %{buildroot}/tftpboot cp %{buildroot}%{_datadir}/syslinux/memdisk %{buildroot}/tftpboot %clean rm -rf %{buildroot} %files %defattr(-,root,root) %doc COPYING NEWS doc/* %doc sample %{_mandir}/man*/* %{_bindir}/syslinux %{_bindir}/ppmtolss16 %{_bindir}/lss16toppm %{_bindir}/gethostip %{_bindir}/sha1pass %{_bindir}/md5pass %{_datadir}/syslinux/*.com %{_datadir}/syslinux/*.exe %{_datadir}/syslinux/*.c32 %{_datadir}/syslinux/*.bin %{_datadir}/syslinux/*.0 %{_datadir}/syslinux/memdisk %{_datadir}/syslinux/*.pl %{_datadir}/syslinux/mkdiskimage %files devel %{_datadir}/syslinux/com32 %files extlinux %{_sbindir}/extlinux /boot/extlinux %config /etc/extlinux.conf %files tftpboot /tftpboot %post extlinux # If we have a /boot/extlinux.conf file, assume extlinux is our bootloader # and update it. if [ -f /boot/extlinux/extlinux.conf ]; then \ extlinux --update /boot/extlinux ; \ elif [ -f /boot/extlinux.conf ]; then \ mkdir -p /boot/extlinux && \ mv /boot/extlinux.conf /boot/extlinux/extlinux.conf && \ extlinux --update /boot/extlinux ; \ fi %postun %changelog * Thu Jan 10 2008 H. Peter Anvin - Add man pages. * Mon Nov 19 2007 Bernard Li - Added netpbm-progs (provides pngtopnm) to BuildPrereq (this should be changed to BuildRequires since it is deprecated...) * Thu Mar 15 2007 H. Peter Anvin - Move extlinux /boot stuff into /boot/extlinux. * Thu Jan 25 2007 H. Peter Anvin - Hacks to make the 32-bit version build correctly on 64-bit machines. * Mon Sep 19 2006 H. Peter Anvin - Add a syslinux-tftpboot module. - Factor extlinux into its own package. - Move to %{_datadir} (/usr/share). * Wed Sep 21 2005 H. Peter Anvin - If /boot/extlinux.conf exist, run extlinux --update. * Fri Sep 9 2005 H. Peter Anvin - Copy, don't link, *.c32 into /boot; rpm doesn't like breaking links. * Tue Aug 23 2005 H. Peter Anvin - Put *.c32 into /boot. * Thu Dec 30 2004 H. Peter Anvin - libsyslinux dropped in syslinux 3.00. - Additional documentation. - Add extlinux. * Tue Dec 14 2004 H. Peter Anvin - Add a devel package for the com32 library added in 2.12. * Wed Apr 16 2003 H. Peter Anvin 2.04-1 - 2.04 release - Add support for libsyslinux.so* - Templatize for inclusion in CVS tree * Thu Apr 10 2003 H. Peter Anvin - 2.03 release - Add support for libsyslinux.a - Add keytab-lilo.pl to the /usr/lib/syslinux directory - Modernize syntax - Support building on x86-64 * Thu Feb 13 2003 H. Peter Anvin - 2.02 release; no longer setuid * Thu Jan 30 2003 H. Peter Anvin - Prepare for 2.01 release; make /usr/bin/syslinux setuid root * Fri Oct 25 2002 H. Peter Anvin - Upgrade to 2.00. * Tue Aug 27 2002 H. Peter Anvin - Upgrade to 1.76. * Fri Jun 14 2002 H. Peter Anvin - Upgrade to 1.75. * Sat Jun 1 2002 H. Peter Anvin - Upgrade to 1.74. * Sun May 26 2002 H. Peter Anvin - Upgrade to 1.73. * Tue Apr 23 2002 H. Peter Anvin - Upgrade to 1.72. * Wed Apr 17 2002 H. Peter Anvin - Upgrade to 1.71. - Update the title. * Wed Apr 17 2002 H. Peter Anvin - Upgrade to 1.70. * Sat Feb 3 2002 H. Peter Anvin - Upgrade to 1.67. * Tue Jan 1 2002 H. Peter Anvin - Upgrade to 1.66. * Sat Dec 15 2001 H. Peter Anvin - Upgrade to 1.65; make appropriate changes. * Sat Aug 24 2001 H. Peter Anvin - Upgrade to 1.64. * Mon Aug 6 2001 H. Peter Anvin - Upgrade to 1.63. - Use make install since the stock SYSLINUX distribution now supports INSTALLROOT. * Sat Apr 24 2001 H. Peter Anvin - Upgrade to 1.62. * Sat Apr 14 2001 H. Peter Anvin - Fix missing %files; correct modes. * Fri Apr 13 2001 H. Peter Anvin - Upgrade to 1.61 - Install auxilliary programs in /usr/lib/syslinux * Sat Feb 10 2001 Matt Wilson - 1.52 * Wed Jan 24 2001 Matt Wilson - 1.51pre7 * Mon Jan 22 2001 Matt Wilson - 1.51pre5 * Fri Jan 19 2001 Matt Wilson - 1.51pre3, with e820 detection * Tue Dec 12 2000 Than Ngo - rebuilt with fixed fileutils * Thu Nov 9 2000 Than Ngo - update to 1.49 - update ftp site - clean up specfile - add some useful documents * Tue Jul 18 2000 Nalin Dahyabhai - add %%defattr (release 4) * Wed Jul 12 2000 Prospector - automatic rebuild * Thu Jul 06 2000 Trond Eivind Glomsrd - use %%{_tmppath} - change application group (Applications/Internet doesn't seem right to me) - added BuildRequires * Tue Apr 04 2000 Erik Troan - initial packaging syslinux-legacy-3.63+dfsg/dummy.c0000664000175000017500000000014310777447273015511 0ustar evanevan/* * Trivial C program to test the compiler */ int main(int argc, char *argv[]) { return 0; } syslinux-legacy-3.63+dfsg/extlinux.asm0000664000175000017500000011063210777447273016601 0ustar evanevan; -*- fundamental -*- (asm-mode sucks) ; **************************************************************************** ; ; extlinux.asm ; ; A program to boot Linux kernels off an ext2/ext3 filesystem. ; ; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Boston MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; **************************************************************************** %define IS_EXTLINUX 1 %include "head.inc" %include "ext2_fs.inc" ; ; Some semi-configurable constants... change on your own risk. ; my_id equ extlinux_id ; NASM 0.98.38 croaks if these are equ's rather than macros... FILENAME_MAX_LG2 equ 8 ; log2(Max filename size Including final null) FILENAME_MAX equ (1 << FILENAME_MAX_LG2) ; Max mangled filename size NULLFILE equ 0 ; Null character == empty filename NULLOFFSET equ 0 ; Position in which to look retry_count equ 16 ; How patient are we with the disk? %assign HIGHMEM_SLOP 0 ; Avoid this much memory near the top LDLINUX_MAGIC equ 0x3eb202fe ; A random number to identify ourselves with MAX_OPEN_LG2 equ 6 ; log2(Max number of open files) MAX_OPEN equ (1 << MAX_OPEN_LG2) SECTOR_SHIFT equ 9 SECTOR_SIZE equ (1 << SECTOR_SHIFT) MAX_SYMLINKS equ 64 ; Maximum number of symlinks per lookup SYMLINK_SECTORS equ 2 ; Max number of sectors in a symlink ; (should be >= FILENAME_MAX) ; ; This is what we need to do when idle ; %macro RESET_IDLE 0 ; Nothing %endmacro %macro DO_IDLE 0 ; Nothing %endmacro ; ; The following structure is used for "virtual kernels"; i.e. LILO-style ; option labels. The options we permit here are `kernel' and `append ; Since there is no room in the bottom 64K for all of these, we ; stick them in high memory and copy them down before we need them. ; struc vkernel vk_vname: resb FILENAME_MAX ; Virtual name **MUST BE FIRST!** vk_rname: resb FILENAME_MAX ; Real name vk_appendlen: resw 1 vk_type: resb 1 ; Type of file alignb 4 vk_append: resb max_cmd_len+1 ; Command line alignb 4 vk_end: equ $ ; Should be <= vk_size endstruc ; ; Segment assignments in the bottom 640K ; Stick to the low 512K in case we're using something like M-systems flash ; which load a driver into low RAM (evil!!) ; ; 0000h - main code/data segment (and BIOS segment) ; real_mode_seg equ 3000h cache_seg equ 2000h ; 64K area for metadata cache xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem comboot_seg equ real_mode_seg ; COMBOOT image loading zone ; ; File structure. This holds the information for each currently open file. ; struc open_file_t file_left resd 1 ; Number of sectors left (0 = free) file_sector resd 1 ; Next linear sector to read file_in_sec resd 1 ; Sector where inode lives file_in_off resw 1 file_mode resw 1 endstruc %ifndef DEPEND %if (open_file_t_size & (open_file_t_size-1)) %error "open_file_t is not a power of 2" %endif %endif ; --------------------------------------------------------------------------- ; BEGIN CODE ; --------------------------------------------------------------------------- ; ; Memory below this point is reserved for the BIOS and the MBR ; section .earlybss trackbufsize equ 8192 trackbuf resb trackbufsize ; Track buffer goes here ; ends at 2800h section .bss SuperBlock resb 1024 ; ext2 superblock SuperInfo resq 16 ; DOS superblock expanded ClustSize resd 1 ; Bytes/cluster ("block") SecPerClust resd 1 ; Sectors/cluster ClustMask resd 1 ; Sectors/cluster - 1 PtrsPerBlock1 resd 1 ; Pointers/cluster PtrsPerBlock2 resd 1 ; (Pointers/cluster)^2 DriveNumber resb 1 ; BIOS drive number ClustShift resb 1 ; Shift count for sectors/cluster ClustByteShift resb 1 ; Shift count for bytes/cluster alignb open_file_t_size Files resb MAX_OPEN*open_file_t_size section .text ; ; Some of the things that have to be saved very early are saved ; "close" to the initial stack pointer offset, in order to ; reduce the code size... ; StackBuf equ $-44-32 ; Start the stack here (grow down - 4K) PartInfo equ StackBuf ; Saved partition table entry FloppyTable equ PartInfo+16 ; Floppy info table (must follow PartInfo) OrigFDCTabPtr equ StackBuf-8 ; The 2nd high dword on the stack OrigESDI equ StackBuf-4 ; The high dword on the stack ; ; Primary entry point. Tempting as though it may be, we can't put the ; initial "cli" here; the jmp opcode in the first byte is part of the ; "magic number" (using the term very loosely) for the DOS superblock. ; bootsec equ $ jmp short start ; 2 bytes nop ; 1 byte ; ; "Superblock" follows -- it's in the boot sector, so it's already ; loaded and ready for us ; bsOemName db 'EXTLINUX' ; The SYS command sets this, so... ; ; These are the fields we actually care about. We end up expanding them ; all to dword size early in the code, so generate labels for both ; the expanded and unexpanded versions. ; %macro superb 1 bx %+ %1 equ SuperInfo+($-superblock)*8+4 bs %+ %1 equ $ zb 1 %endmacro %macro superw 1 bx %+ %1 equ SuperInfo+($-superblock)*8 bs %+ %1 equ $ zw 1 %endmacro %macro superd 1 bx %+ %1 equ $ ; no expansion for dwords bs %+ %1 equ $ zd 1 %endmacro superblock equ $ superw BytesPerSec superb SecPerClust superw ResSectors superb FATs superw RootDirEnts superw Sectors superb Media superw FATsecs superw SecPerTrack superw Heads superinfo_size equ ($-superblock)-1 ; How much to expand superd Hidden superd HugeSectors ; ; This is as far as FAT12/16 and FAT32 are consistent ; zb 54 ; FAT12/16 need 26 more bytes, ; FAT32 need 54 more bytes superblock_len equ $-superblock ; ; Note we don't check the constraints above now; we did that at install ; time (we hope!) ; start: cli ; No interrupts yet, please cld ; Copy upwards ; ; Set up the stack ; xor ax,ax mov ss,ax mov sp,StackBuf ; Just below BSS push es ; Save initial ES:DI -> $PnP pointer push di mov es,ax ; ; DS:SI may contain a partition table entry. Preserve it for us. ; mov cx,8 ; Save partition info mov di,PartInfo rep movsw mov ds,ax ; Now we can initialize DS... ; ; Now sautee the BIOS floppy info block to that it will support decent- ; size transfers; the floppy block is 11 bytes and is stored in the ; INT 1Eh vector (brilliant waste of resources, eh?) ; ; Of course, if BIOSes had been properly programmed, we wouldn't have ; had to waste precious space with this code. ; mov bx,fdctab lfs si,[bx] ; FS:SI -> original fdctab push fs ; Save on stack in case we need to bail push si ; Save the old fdctab even if hard disk so the stack layout ; is the same. The instructions above do not change the flags mov [DriveNumber],dl ; Save drive number in DL and dl,dl ; If floppy disk (00-7F), assume no ; partition table js harddisk floppy: mov cl,6 ; 12 bytes (CX == 0) ; es:di -> FloppyTable already ; This should be safe to do now, interrupts are off... mov [bx],di ; FloppyTable mov [bx+2],ax ; Segment 0 fs rep movsw ; Faster to move words mov cl,[bsSecPerTrack] ; Patch the sector count mov [di-8],cl ; AX == 0 here int 13h ; Some BIOSes need this jmp short not_harddisk ; ; The drive number and possibly partition information was passed to us ; by the BIOS or previous boot loader (MBR). Current "best practice" is to ; trust that rather than what the superblock contains. ; ; Would it be better to zero out bsHidden if we don't have a partition table? ; ; Note: di points to beyond the end of PartInfo ; harddisk: test byte [di-16],7Fh ; Sanity check: "active flag" should jnz no_partition ; be 00 or 80 mov eax,[di-8] ; Partition offset (dword) mov [bsHidden],eax no_partition: ; ; Get disk drive parameters (don't trust the superblock.) Don't do this for ; floppy drives -- INT 13:08 on floppy drives will (may?) return info about ; what the *drive* supports, not about the *media*. Fortunately floppy disks ; tend to have a fixed, well-defined geometry which is stored in the superblock. ; ; DL == drive # still mov ah,08h int 13h jc no_driveparm and ah,ah jnz no_driveparm shr dx,8 inc dx ; Contains # of heads - 1 mov [bsHeads],dx and cx,3fh mov [bsSecPerTrack],cx no_driveparm: not_harddisk: ; ; Ready to enable interrupts, captain ; sti ; ; Do we have EBIOS (EDD)? ; eddcheck: mov bx,55AAh mov ah,41h ; EDD existence query mov dl,[DriveNumber] int 13h jc .noedd cmp bx,0AA55h jne .noedd test cl,1 ; Extended disk access functionality set jz .noedd ; ; We have EDD support... ; mov byte [getlinsec.jmp+1],(getlinsec_ebios-(getlinsec.jmp+2)) .noedd: ; ; Load the first sector of LDLINUX.SYS; this used to be all proper ; with parsing the superblock and root directory; it doesn't fit ; together with EBIOS support, unfortunately. ; mov eax,[FirstSector] ; Sector start mov bx,ldlinux_sys ; Where to load it call getonesec ; Some modicum of integrity checking cmp dword [ldlinux_magic+4],LDLINUX_MAGIC^HEXDATE jne kaboom ; Go for it... jmp ldlinux_ent ; ; getonesec: get one disk sector ; getonesec: mov bp,1 ; One sector ; Fall through ; ; getlinsec: load a sequence of BP floppy sector given by the linear sector ; number in EAX into the buffer at ES:BX. We try to optimize ; by loading up to a whole track at a time, but the user ; is responsible for not crossing a 64K boundary. ; (Yes, BP is weird for a count, but it was available...) ; ; On return, BX points to the first byte after the transferred ; block. ; ; This routine assumes CS == DS, and trashes most registers. ; ; Stylistic note: use "xchg" instead of "mov" when the source is a register ; that is dead from that point; this saves space. However, please keep ; the order to dst,src to keep things sane. ; getlinsec: add eax,[bsHidden] ; Add partition offset xor edx,edx ; Zero-extend LBA (eventually allow 64 bits) .jmp: jmp strict short getlinsec_cbios ; ; getlinsec_ebios: ; ; getlinsec implementation for EBIOS (EDD) ; getlinsec_ebios: .loop: push bp ; Sectors left .retry2: call maxtrans ; Enforce maximum transfer size movzx edi,bp ; Sectors we are about to read mov cx,retry_count .retry: ; Form DAPA on stack push edx push eax push es push bx push di push word 16 mov si,sp pushad mov dl,[DriveNumber] push ds push ss pop ds ; DS <- SS mov ah,42h ; Extended Read int 13h pop ds popad lea sp,[si+16] ; Remove DAPA jc .error pop bp add eax,edi ; Advance sector pointer sub bp,di ; Sectors left shl di,SECTOR_SHIFT ; 512-byte sectors add bx,di ; Advance buffer pointer and bp,bp jnz .loop ret .error: ; Some systems seem to get "stuck" in an error state when ; using EBIOS. Doesn't happen when using CBIOS, which is ; good, since some other systems get timeout failures ; waiting for the floppy disk to spin up. pushad ; Try resetting the device xor ax,ax mov dl,[DriveNumber] int 13h popad loop .retry ; CX-- and jump if not zero ;shr word [MaxTransfer],1 ; Reduce the transfer size ;jnz .retry2 ; Total failure. Try falling back to CBIOS. mov byte [getlinsec.jmp+1],(getlinsec_cbios-(getlinsec.jmp+2)) ;mov byte [MaxTransfer],63 ; Max possibe CBIOS transfer pop bp ; ... fall through ... ; ; getlinsec_cbios: ; ; getlinsec implementation for legacy CBIOS ; getlinsec_cbios: .loop: push edx push eax push bp push bx movzx esi,word [bsSecPerTrack] movzx edi,word [bsHeads] ; ; Dividing by sectors to get (track,sector): we may have ; up to 2^18 tracks, so we need to use 32-bit arithmetric. ; div esi xor cx,cx xchg cx,dx ; CX <- sector index (0-based) ; EDX <- 0 ; eax = track # div edi ; Convert track to head/cyl ; We should test this, but it doesn't fit... ; cmp eax,1023 ; ja .error ; ; Now we have AX = cyl, DX = head, CX = sector (0-based), ; BP = sectors to transfer, SI = bsSecPerTrack, ; ES:BX = data target ; call maxtrans ; Enforce maximum transfer size ; Must not cross track boundaries, so BP <= SI-CX sub si,cx cmp bp,si jna .bp_ok mov bp,si .bp_ok: shl ah,6 ; Because IBM was STOOPID ; and thought 8 bits were enough ; then thought 10 bits were enough... inc cx ; Sector numbers are 1-based, sigh or cl,ah mov ch,al mov dh,dl mov dl,[DriveNumber] xchg ax,bp ; Sector to transfer count mov ah,02h ; Read sectors mov bp,retry_count .retry: pushad int 13h popad jc .error .resume: movzx ecx,al ; ECX <- sectors transferred shl ax,SECTOR_SHIFT ; Convert sectors in AL to bytes in AX pop bx add bx,ax pop bp pop eax pop edx add eax,ecx sub bp,cx jnz .loop ret .error: dec bp jnz .retry xchg ax,bp ; Sectors transferred <- 0 shr word [MaxTransfer],1 jnz .resume ; Fall through to disk_error ; ; kaboom: write a message and bail out. ; disk_error: kaboom: xor si,si mov ss,si mov sp,StackBuf-4 ; Reset stack mov ds,si ; Reset data segment pop dword [fdctab] ; Restore FDC table .patch: ; When we have full code, intercept here mov si,bailmsg ; Write error message, this assumes screen page 0 .loop: lodsb and al,al jz .done mov ah,0Eh ; Write to screen as TTY mov bx,0007h ; Attribute int 10h jmp short .loop .done: cbw ; AH <- 0 .again: int 16h ; Wait for keypress ; NB: replaced by int 18h if ; chosen at install time.. int 19h ; And try once more to boot... .norge: jmp short .norge ; If int 19h returned; this is the end ; ; Truncate BP to MaxTransfer ; maxtrans: cmp bp,[MaxTransfer] jna .ok mov bp,[MaxTransfer] .ok: ret ; ; Error message on failure ; bailmsg: db 'Boot error', 0Dh, 0Ah, 0 ; This fails if the boot sector overflows zb 1F8h-($-$$) FirstSector dd 0xDEADBEEF ; Location of sector 1 MaxTransfer dw 0x007F ; Max transfer size ; This field will be filled in 0xAA55 by the installer, but we abuse it ; to house a pointer to the INT 16h instruction at ; kaboom.again, which gets patched to INT 18h in RAID mode. bootsignature dw kaboom.again-bootsec ; ; =========================================================================== ; End of boot sector ; =========================================================================== ; Start of LDLINUX.SYS ; =========================================================================== ldlinux_sys: syslinux_banner db 0Dh, 0Ah db 'EXTLINUX ' db version_str, ' ', date, ' ', 0 db 0Dh, 0Ah, 1Ah ; EOF if we "type" this in DOS align 8, db 0 ldlinux_magic dd LDLINUX_MAGIC dd LDLINUX_MAGIC^HEXDATE ; ; This area is patched by the installer. It is found by looking for ; LDLINUX_MAGIC, plus 8 bytes. ; patch_area: LDLDwords dw 0 ; Total dwords starting at ldlinux_sys, ; not including ADVs LDLSectors dw 0 ; Number of sectors, not including ; bootsec & this sec, but including the two ADVs CheckSum dd 0 ; Checksum starting at ldlinux_sys ; value = LDLINUX_MAGIC - [sum of dwords] CurrentDir dd 2 ; "Current" directory inode number ; Space for up to 64 sectors, the theoretical maximum SectorPtrs times 64 dd 0 ldlinux_ent: ; ; Note that some BIOSes are buggy and run the boot sector at 07C0:0000 ; instead of 0000:7C00 and the like. We don't want to add anything ; more to the boot sector, so it is written to not assume a fixed ; value in CS, but we don't want to deal with that anymore from now ; on. ; jmp 0:.next .next: ; ; Tell the user we got this far ; mov si,syslinux_banner call writestr ; ; Tell the user if we're using EBIOS or CBIOS ; print_bios: mov si,cbios_name cmp byte [getlinsec.jmp+1],(getlinsec_ebios-(getlinsec.jmp+2)) jne .cbios mov si,ebios_name .cbios: mov [BIOSName],si call writestr section .bss %define HAVE_BIOSNAME 1 BIOSName resw 1 section .text ; ; Now we read the rest of LDLINUX.SYS. Don't bother loading the first ; sector again, though. ; load_rest: mov si,SectorPtrs mov bx,7C00h+2*SECTOR_SIZE ; Where we start loading mov cx,[LDLSectors] .get_chunk: jcxz .done xor bp,bp lodsd ; First sector of this chunk mov edx,eax .make_chunk: inc bp dec cx jz .chunk_ready inc edx ; Next linear sector cmp [si],edx ; Does it match jnz .chunk_ready ; If not, this is it add si,4 ; If so, add sector to chunk jmp short .make_chunk .chunk_ready: call getlinsecsr shl bp,SECTOR_SHIFT add bx,bp jmp .get_chunk .done: ; ; All loaded up, verify that we got what we needed. ; Note: the checksum field is embedded in the checksum region, so ; by the time we get to the end it should all cancel out. ; verify_checksum: mov si,ldlinux_sys mov cx,[LDLDwords] mov edx,-LDLINUX_MAGIC .checksum: lodsd add edx,eax loop .checksum and edx,edx ; Should be zero jz all_read ; We're cool, go for it! ; ; Uh-oh, something went bad... ; mov si,checksumerr_msg call writestr jmp kaboom ; ; ----------------------------------------------------------------------------- ; Subroutines that have to be in the first sector ; ----------------------------------------------------------------------------- ; ; ; writestr: write a null-terminated string to the console ; This assumes we're on page 0. This is only used for early ; messages, so it should be OK. ; writestr: .loop: lodsb and al,al jz .return mov ah,0Eh ; Write to screen as TTY mov bx,0007h ; Attribute int 10h jmp short .loop .return: ret ; getlinsecsr: save registers, call getlinsec, restore registers ; getlinsecsr: pushad call getlinsec popad ret ; ; Checksum error message ; checksumerr_msg db ' Load error - ', 0 ; Boot failed appended ; ; BIOS type string ; cbios_name db 'CBIOS', 0 ebios_name db 'EBIOS', 0 ; ; Debug routine ; %ifdef debug safedumpregs: cmp word [Debug_Magic],0D00Dh jnz nc_return jmp dumpregs %endif rl_checkpt equ $ ; Must be <= 8000h rl_checkpt_off equ ($-$$) %ifndef DEPEND %if rl_checkpt_off > 400h %error "Sector 1 overflow" %endif %endif ; ---------------------------------------------------------------------------- ; End of code and data that have to be in the first sector ; ---------------------------------------------------------------------------- all_read: ; ; Let the user (and programmer!) know we got this far. This used to be ; in Sector 1, but makes a lot more sense here. ; mov si,copyright_str call writestr ; ; Insane hack to expand the DOS superblock to dwords ; expand_super: xor eax,eax mov si,superblock mov di,SuperInfo mov cx,superinfo_size .loop: lodsw dec si stosd ; Store expanded word xor ah,ah stosd ; Store expanded byte loop .loop ; ; Load the real (ext2) superblock; 1024 bytes long at offset 1024 ; mov bx,SuperBlock mov eax,1024 >> SECTOR_SHIFT mov bp,ax call getlinsec ; ; Compute some values... ; xor edx,edx inc edx ; s_log_block_size = log2(blocksize) - 10 mov cl,[SuperBlock+s_log_block_size] add cl,10 mov [ClustByteShift],cl mov eax,edx shl eax,cl mov [ClustSize],eax sub cl,SECTOR_SHIFT mov [ClustShift],cl shr eax,SECTOR_SHIFT mov [SecPerClust],eax dec eax mov [ClustMask],eax add cl,SECTOR_SHIFT-2 ; 4 bytes/pointer shl edx,cl mov [PtrsPerBlock1],edx shl edx,cl mov [PtrsPerBlock2],edx ; ; Common initialization code ; %include "init.inc" %include "cpuinit.inc" ; ; Initialize the metadata cache ; call initcache ; ; Now, everything is "up and running"... patch kaboom for more ; verbosity and using the full screen system ; ; E9 = JMP NEAR mov dword [kaboom.patch],0e9h+((kaboom2-(kaboom.patch+3)) << 8) ; ; Now we're all set to start with our *real* business. First load the ; configuration file (if any) and parse it. ; ; In previous versions I avoided using 32-bit registers because of a ; rumour some BIOSes clobbered the upper half of 32-bit registers at ; random. I figure, though, that if there are any of those still left ; they probably won't be trying to install Linux on them... ; ; The code is still ripe with 16-bitisms, though. Not worth the hassle ; to take'm out. In fact, we may want to put them back if we're going ; to boot ELKS at some point. ; ; ; Load configuration file ; load_config: mov si,config_name ; Save config file name mov di,ConfigName call strcpy mov di,ConfigName call open jz no_config_file ; ; Now we have the config file open. Parse the config file and ; run the user interface. ; %include "ui.inc" ; ; getlinsec_ext: same as getlinsec, except load any sector from the zero ; block as all zeros; use to load any data derived ; from an ext2 block pointer, i.e. anything *except the ; superblock.* ; getonesec_ext: mov bp,1 getlinsec_ext: cmp eax,[SecPerClust] jae getlinsec ; Nothing fancy ; If we get here, at least part of what we want is in the ; zero block. Zero one sector at a time and loop. push eax push cx xchg di,bx xor eax,eax mov cx,SECTOR_SIZE >> 2 rep stosd xchg di,bx pop cx pop eax inc eax dec bp jnz getlinsec_ext ret ; ; allocate_file: Allocate a file structure ; ; If successful: ; ZF set ; BX = file pointer ; In unsuccessful: ; ZF clear ; allocate_file: TRACER 'a' push cx mov bx,Files mov cx,MAX_OPEN .check: cmp dword [bx], byte 0 je .found add bx,open_file_t_size ; ZF = 0 loop .check ; ZF = 0 if we fell out of the loop .found: pop cx ret ; ; open_inode: ; Open a file indicated by an inode number in EAX ; ; NOTE: This file considers finding a zero-length file an ; error. This is so we don't have to deal with that special ; case elsewhere in the program (most loops have the test ; at the end). ; ; If successful: ; ZF clear ; SI = file pointer ; DX:AX = EAX = file length in bytes ; ThisInode = the first 128 bytes of the inode ; If unsuccessful ; ZF set ; ; Assumes CS == DS == ES. ; open_inode.allocate_failure: xor eax,eax pop bx pop di ret open_inode: push di push bx call allocate_file jnz .allocate_failure push cx push gs ; First, get the appropriate inode group and index dec eax ; There is no inode 0 xor edx,edx mov [bx+file_sector],edx div dword [SuperBlock+s_inodes_per_group] ; EAX = inode group; EDX = inode within group push edx ; Now, we need the block group descriptor. ; To get that, we first need the relevant descriptor block. shl eax, ext2_group_desc_lg2size ; Get byte offset in desc table xor edx,edx div dword [ClustSize] ; eax = block #, edx = offset in block add eax,dword [SuperBlock+s_first_data_block] inc eax ; s_first_data_block+1 mov cl,[ClustShift] shl eax,cl push edx shr edx,SECTOR_SHIFT add eax,edx pop edx and dx,SECTOR_SIZE-1 call getcachesector ; Get the group descriptor add si,dx mov esi,[gs:si+bg_inode_table] ; Get inode table block # pop eax ; Get inode within group movzx edx, word [SuperBlock+s_inode_size] mul edx ; edx:eax = byte offset in inode table div dword [ClustSize] ; eax = block # versus inode table, edx = offset in block add eax,esi shl eax,cl ; Turn into sector push dx shr edx,SECTOR_SHIFT add eax,edx mov [bx+file_in_sec],eax pop dx and dx,SECTOR_SIZE-1 mov [bx+file_in_off],dx call getcachesector add si,dx mov cx,EXT2_GOOD_OLD_INODE_SIZE >> 2 mov di,ThisInode gs rep movsd mov ax,[ThisInode+i_mode] mov [bx+file_mode],ax mov eax,[ThisInode+i_size] push eax add eax,SECTOR_SIZE-1 shr eax,SECTOR_SHIFT mov [bx+file_left],eax pop eax mov si,bx mov edx,eax shr edx,16 ; 16-bitism, sigh and eax,eax ; ZF clear unless zero-length file pop gs pop cx pop bx pop di ret section .bss alignb 4 ThisInode resb EXT2_GOOD_OLD_INODE_SIZE ; The most recently opened inode section .text ; ; close_file: ; Deallocates a file structure (pointer in SI) ; Assumes CS == DS. ; close_file: and si,si jz .closed mov dword [si],0 ; First dword == file_left .closed: ret ; ; searchdir: ; Search the root directory for a pre-mangled filename in DS:DI. ; ; NOTE: This file considers finding a zero-length file an ; error. This is so we don't have to deal with that special ; case elsewhere in the program (most loops have the test ; at the end). ; ; If successful: ; ZF clear ; SI = file pointer ; DX:AX = EAX = file length in bytes ; If unsuccessful ; ZF set ; ; Assumes CS == DS == ES; *** IS THIS CORRECT ***? ; searchdir: push bx push cx push bp mov byte [SymlinkCtr],MAX_SYMLINKS mov eax,[CurrentDir] .begin_path: .leadingslash: cmp byte [di],'/' ; Absolute filename? jne .gotdir mov eax,EXT2_ROOT_INO inc di ; Skip slash jmp .leadingslash .gotdir: ; At this point, EAX contains the directory inode, ; and DS:DI contains a pathname tail. .open: push eax ; Save directory inode call open_inode jz .missing ; If error, done mov cx,[si+file_mode] shr cx,S_IFSHIFT ; Get file type cmp cx,T_IFDIR je .directory add sp,4 ; Drop directory inode cmp cx,T_IFREG je .file cmp cx,T_IFLNK je .symlink ; Otherwise, something bad... .err: call close_file .err_noclose: xor eax,eax xor si,si cwd ; DX <- 0 .done: and eax,eax ; Set/clear ZF pop bp pop cx pop bx ret .missing: add sp,4 ; Drop directory inode jmp .done ; ; It's a file. ; .file: cmp byte [di],0 ; End of path? je .done ; If so, done jmp .err ; Otherwise, error ; ; It's a directory. ; .directory: pop dword [ThisDir] ; Remember what directory we're searching cmp byte [di],0 ; More path? je .err ; If not, bad .skipslash: ; Skip redundant slashes cmp byte [di],'/' jne .readdir inc di jmp .skipslash .readdir: mov cx,[SecPerClust] push cx shl cx,SECTOR_SHIFT mov bx,trackbuf add cx,bx mov [EndBlock],cx pop cx push bx call getfssec pop bx pushf ; Save EOF flag push si ; Save filesystem pointer .getent: cmp bx,[EndBlock] jae .endblock push di cmp dword [bx+d_inode],0 ; Zero inode = void entry je .nope movzx cx,byte [bx+d_name_len] lea si,[bx+d_name] repe cmpsb je .maybe .nope: pop di add bx,[bx+d_rec_len] jmp .getent .endblock: pop si popf jnc .readdir ; There is more jmp .err ; Otherwise badness... .maybe: mov eax,[bx+d_inode] ; Does this match the end of the requested filename? cmp byte [di],0 je .finish cmp byte [di],'/' jne .nope ; We found something; now we need to open the file .finish: pop bx ; Adjust stack (di) pop si call close_file ; Close directory pop bx ; Adjust stack (flags) jmp .open ; ; It's a symlink. We have to determine if it's a fast symlink ; (data stored in the inode) or not (data stored as a regular ; file.) Either which way, we start from the directory ; which we just visited if relative, or from the root directory ; if absolute, and append any remaining part of the path. ; .symlink: dec byte [SymlinkCtr] jz .err ; Too many symlink references cmp eax,SYMLINK_SECTORS*SECTOR_SIZE jae .err ; Symlink too long ; Computation for fast symlink, as defined by ext2/3 spec xor ecx,ecx cmp [ThisInode+i_file_acl],ecx setne cl ; ECX <- i_file_acl ? 1 : 0 cmp [ThisInode+i_blocks],ecx jne .slow_symlink ; It's a fast symlink .fast_symlink: call close_file ; We've got all we need mov si,ThisInode+i_block push di mov di,SymlinkTmpBuf mov ecx,eax rep movsb pop si .symlink_finish: cmp byte [si],0 je .no_slash mov al,'/' stosb .no_slash: mov bp,SymlinkTmpBufEnd call strecpy jc .err_noclose ; Buffer overflow ; Now copy it to the "real" buffer; we need to have ; two buffers so we avoid overwriting the tail on the ; next copy mov si,SymlinkTmpBuf mov di,SymlinkBuf push di call strcpy pop di mov eax,[ThisDir] ; Resume searching previous directory jmp .begin_path .slow_symlink: mov bx,SymlinkTmpBuf mov cx,SYMLINK_SECTORS call getfssec ; The EOF closed the file mov si,di ; SI = filename tail mov di,SymlinkTmpBuf add di,ax ; AX = file length jmp .symlink_finish section .bss alignb 4 SymlinkBuf resb SYMLINK_SECTORS*SECTOR_SIZE+64 SymlinkTmpBuf equ trackbuf SymlinkTmpBufEnd equ trackbuf+SYMLINK_SECTORS*SECTOR_SIZE+64 ThisDir resd 1 EndBlock resw 1 SymlinkCtr resb 1 section .text ; ; mangle_name: Mangle a filename pointed to by DS:SI into a buffer pointed ; to by ES:DI; ends on encountering any whitespace. ; DI is preserved. ; ; This verifies that a filename is < FILENAME_MAX characters, ; doesn't contain whitespace, zero-pads the output buffer, ; and removes redundant slashes, ; so "repe cmpsb" can do a compare, and the ; path-searching routine gets a bit of an easier job. ; ; FIX: we may want to support \-escapes here (and this would ; be the place.) ; mangle_name: push di push bx xor ax,ax mov cx,FILENAME_MAX-1 mov bx,di .mn_loop: lodsb cmp al,' ' ; If control or space, end jna .mn_end cmp al,ah ; Repeated slash? je .mn_skip xor ah,ah cmp al,'/' jne .mn_ok mov ah,al .mn_ok stosb .mn_skip: loop .mn_loop .mn_end: cmp bx,di ; At the beginning of the buffer? jbe .mn_zero cmp byte [di-1],'/' ; Terminal slash? jne .mn_zero .mn_kill: dec di ; If so, remove it inc cx jmp short .mn_end .mn_zero: inc cx ; At least one null byte xor ax,ax ; Zero-fill name rep stosb pop bx pop di ret ; Done ; ; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled ; filename to the conventional representation. This is needed ; for the BOOT_IMAGE= parameter for the kernel. ; ; DS:SI -> input mangled file name ; ES:DI -> output buffer ; ; On return, DI points to the first byte after the output name, ; which is set to a null byte. ; unmangle_name: call strcpy dec di ; Point to final null byte ret ; ; ; kaboom2: once everything is loaded, replace the part of kaboom ; starting with "kaboom.patch" with this part kaboom2: mov si,err_bootfailed call cwritestr cmp byte [kaboom.again+1],18h ; INT 18h version? je .int18 call getchar call vgaclearmode int 19h ; And try once more to boot... .norge: jmp short .norge ; If int 19h returned; this is the end .int18: call vgaclearmode int 18h .noreg: jmp short .noreg ; Nynorsk ; ; linsector: Convert a linear sector index in a file to a linear sector number ; EAX -> linear sector number ; DS:SI -> open_file_t ; ; Returns next sector number in EAX; CF on EOF (not an error!) ; linsector: push gs push ebx push esi push edi push ecx push edx push ebp push eax ; Save sector index mov cl,[ClustShift] shr eax,cl ; Convert to block number push eax mov eax,[si+file_in_sec] mov bx,si call getcachesector ; Get inode add si,[bx+file_in_off] ; Get *our* inode pop eax lea ebx,[i_block+4*eax] cmp eax,EXT2_NDIR_BLOCKS jb .direct mov ebx,i_block+4*EXT2_IND_BLOCK sub eax,EXT2_NDIR_BLOCKS mov ebp,[PtrsPerBlock1] cmp eax,ebp jb .ind1 mov ebx,i_block+4*EXT2_DIND_BLOCK sub eax,ebp mov ebp,[PtrsPerBlock2] cmp eax,ebp jb .ind2 mov ebx,i_block+4*EXT2_TIND_BLOCK sub eax,ebp .ind3: ; Triple indirect; eax contains the block no ; with respect to the start of the tind area; ; ebx contains the pointer to the tind block. xor edx,edx div dword [PtrsPerBlock2] ; EAX = which dind block, EDX = pointer within dind block push ax shr eax,SECTOR_SHIFT-2 mov ebp,[gs:si+bx] shl ebp,cl add eax,ebp call getcachesector pop bx and bx,(SECTOR_SIZE >> 2)-1 shl bx,2 mov eax,edx ; The ind2 code wants the remainder... .ind2: ; Double indirect; eax contains the block no ; with respect to the start of the dind area; ; ebx contains the pointer to the dind block. xor edx,edx div dword [PtrsPerBlock1] ; EAX = which ind block, EDX = pointer within ind block push ax shr eax,SECTOR_SHIFT-2 mov ebp,[gs:si+bx] shl ebp,cl add eax,ebp call getcachesector pop bx and bx,(SECTOR_SIZE >> 2)-1 shl bx,2 mov eax,edx ; The int1 code wants the remainder... .ind1: ; Single indirect; eax contains the block no ; with respect to the start of the ind area; ; ebx contains the pointer to the ind block. push ax shr eax,SECTOR_SHIFT-2 mov ebp,[gs:si+bx] shl ebp,cl add eax,ebp call getcachesector pop bx and bx,(SECTOR_SIZE >> 2)-1 shl bx,2 .direct: mov ebx,[gs:bx+si] ; Get the pointer pop eax ; Get the sector index again shl ebx,cl ; Convert block number to sector and eax,[ClustMask] ; Add offset within block add eax,ebx pop ebp pop edx pop ecx pop edi pop esi pop ebx pop gs ret ; ; getfssec: Get multiple sectors from a file ; ; Same as above, except SI is a pointer to a open_file_t ; ; ES:BX -> Buffer ; DS:SI -> Pointer to open_file_t ; CX -> Sector count (0FFFFh = until end of file) ; Must not exceed the ES segment ; Returns CF=1 on EOF (not necessarily error) ; All arguments are advanced to reflect data read. ; getfssec: push ebp push eax push edx push edi movzx ecx,cx cmp ecx,[si] ; Number of sectors left jbe .lenok mov cx,[si] .lenok: .getfragment: mov eax,[si+file_sector] ; Current start index mov edi,eax call linsector push eax ; Fragment start sector mov edx,eax xor ebp,ebp ; Fragment sector count .getseccnt: inc bp dec cx jz .do_read xor eax,eax mov ax,es shl ax,4 add ax,bx ; Now DI = how far into 64K block we are not ax ; Bytes left in 64K block inc eax shr eax,SECTOR_SHIFT ; Sectors left in 64K block cmp bp,ax jnb .do_read ; Unless there is at least 1 more sector room... inc edi ; Sector index inc edx ; Linearly next sector mov eax,edi call linsector ; jc .do_read cmp edx,eax je .getseccnt .do_read: pop eax ; Linear start sector pushad call getlinsec_ext popad push bp shl bp,9 add bx,bp ; Adjust buffer pointer pop bp add [si+file_sector],ebp ; Next sector index sub [si],ebp ; Sectors consumed jcxz .done jnz .getfragment ; Fall through .done: cmp dword [si],1 ; Did we run out of file? ; CF set if [SI] < 1, i.e. == 0 pop edi pop edx pop eax pop ebp ret ; ----------------------------------------------------------------------------- ; Common modules ; ----------------------------------------------------------------------------- %include "getc.inc" ; getc et al %include "conio.inc" ; Console I/O %include "plaincon.inc" ; writechr %include "writestr.inc" ; String output %include "configinit.inc" ; Initialize configuration %include "parseconfig.inc" ; High-level config file handling %include "parsecmd.inc" ; Low-level config file handling %include "bcopy32.inc" ; 32-bit bcopy %include "loadhigh.inc" ; Load a file into high memory %include "font.inc" ; VGA font stuff %include "graphics.inc" ; VGA graphics %include "highmem.inc" ; High memory sizing %include "strcpy.inc" ; strcpy() %include "strecpy.inc" ; strcpy with end pointer check %include "cache.inc" ; Metadata disk cache %include "adv.inc" ; Auxillary Data Vector ; ----------------------------------------------------------------------------- ; Begin data section ; ----------------------------------------------------------------------------- section .data copyright_str db ' Copyright (C) 1994-', year, ' H. Peter Anvin' db CR, LF, 0 err_bootfailed db CR, LF, 'Boot failed: please change disks and press ' db 'a key to continue.', CR, LF, 0 config_name db 'extlinux.conf',0 ; Unmangled form ; ; Command line options we'd like to take a look at ; ; mem= and vga= are handled as normal 32-bit integer values initrd_cmd db 'initrd=' initrd_cmd_len equ 7 ; ; Config file keyword table ; %include "keywords.inc" ; ; Extensions to search for (in *forward* order). ; align 4, db 0 exten_table: db '.cbt' ; COMBOOT (specific) db '.img' ; Disk image db '.bs', 0 ; Boot sector db '.com' ; COMBOOT (same as DOS) db '.c32' ; COM32 exten_table_end: dd 0, 0 ; Need 8 null bytes here ; ; Misc initialized (data) variables ; %ifdef debug ; This code for debugging only debug_magic dw 0D00Dh ; Debug code sentinel %endif alignb 4, db 0 BufSafe dw trackbufsize/SECTOR_SIZE ; Clusters we can load into trackbuf BufSafeBytes dw trackbufsize ; = how many bytes? %ifndef DEPEND %if ( trackbufsize % SECTOR_SIZE ) != 0 %error trackbufsize must be a multiple of SECTOR_SIZE %endif %endif syslinux-legacy-3.63+dfsg/version.gen0000664000175000017500000000010010777447305016357 0ustar evanevan%define VERSION "3.63" %define VER_MAJOR 3 %define VER_MINOR 63 syslinux-legacy-3.63+dfsg/memdisk/0000775000175000017500000000000010777447345015645 5ustar evanevansyslinux-legacy-3.63+dfsg/memdisk/testdata30000664000175000017500000000072510777447273017470 0ustar evanevan0000000000000000 000000000009bc00 1 000000000009bc00 0000000000004400 2 00000000000e9800 0000000000016800 2 0000000000100000 0000000006ee0000 1 0000000006fe0000 000000000000fc00 3 0000000006fefc00 0000000000000400 4 0000002000000000 0000001000000000 1 0000000006ff0000 0000000000002000 2 0000000006ff2000 000000000000e000 1 0000000007000000 0000000000100000 2 00000000fff00000 0000000000100000 2 0000000000586000 0000000000168000 2 000000000009ba00 0000000000000200 2 syslinux-legacy-3.63+dfsg/memdisk/memcpy.S0000664000175000017500000000054010777447273017262 0ustar evanevan# # memcpy.S # # Simple memcpy() implementation # .text .globl memcpy .type memcpy, @function memcpy: cld pushl %edi pushl %esi movl 12(%esp),%edi movl 16(%esp),%esi movl 20(%esp),%eax movl %eax,%ecx shrl $2,%ecx rep ; movsl movl %eax,%ecx andl $3,%ecx rep ; movsb movl 12(%esp),%eax popl %esi popl %edi ret .size memcpy,.-memcpy syslinux-legacy-3.63+dfsg/memdisk/e820.h0000664000175000017500000000175010777447273016477 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * e820.h * * Common routines for e820 memory map management */ #include struct e820range { uint64_t start; uint32_t type; } __attribute__((packed)); extern struct e820range ranges[]; extern int nranges; extern uint32_t dos_mem, low_mem, high_mem; extern void e820map_init(void); extern void insertrange(uint64_t, uint64_t, uint32_t); extern void get_mem(void); extern void parse_mem(void); syslinux-legacy-3.63+dfsg/memdisk/e820data0000664000175000017500000000066110777447273017103 0ustar evanevan0000000000000000 000000000009bc00 1 000000000009bc00 0000000000004400 2 00000000000e9800 0000000000016800 2 0000000000100000 0000000006ee0000 1 0000000006fe0000 000000000000fc00 3 0000000006fefc00 0000000000000400 4 0000000006ff0000 0000000000002000 2 0000000006ff2000 000000000000e000 1 0000000007000000 0000000000100000 2 00000000fff00000 0000000000100000 2 0000000000586000 0000000000168000 2 000000000009ba00 0000000000000200 2 syslinux-legacy-3.63+dfsg/memdisk/memdisk16.asm0000664000175000017500000004060510777447273020154 0ustar evanevan;; -*- fundamental -*- ;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; init16.asm ;; ;; Routine to initialize and to trampoline into 32-bit ;; protected memory. This code is derived from bcopy32.inc and ;; com32.inc in the main SYSLINUX distribution. ;; MY_CS equ 0x0800 ; Segment address to use CS_BASE equ (MY_CS << 4) ; Corresponding address ; Low memory bounce buffer BOUNCE_SEG equ (MY_CS+0x1000) %define DO_WBINVD 0 %define STACK_HEAP_SIZE (128*1024) section .rodata align=16 section .data align=16 section .bss align=16 ;; ----------------------------------------------------------------------- ;; Kernel image header ;; ----------------------------------------------------------------------- section .text ; Must be first in image bits 16 cmdline times 497 db 0 ; We put the command line here setup_sects db 0 root_flags dw 0 syssize dw 0 swap_dev dw 0 ram_size dw 0 vid_mode dw 0 root_dev dw 0 boot_flag dw 0xAA55 _start: jmp short start db "HdrS" ; Header signature dw 0x0203 ; Header version number realmode_swtch dw 0, 0 ; default_switch, SETUPSEG start_sys_seg dw 0x1000 ; obsolete version_ptr dw memdisk_version-0x200 ; version string ptr type_of_loader db 0 ; Filled in by boot loader loadflags db 1 ; Please load high setup_move_size dw 0 ; Unused code32_start dd 0x100000 ; 32-bit start address ramdisk_image dd 0 ; Loaded ramdisk image address ramdisk_size dd 0 ; Size of loaded ramdisk bootsect_kludge dw 0, 0 heap_end_ptr dw 0 pad1 dw 0 cmd_line_ptr dd 0 ; Command line ramdisk_max dd 0xffffffff ; Highest allowed ramdisk address ; ; These fields aren't real setup fields, they're poked in by the ; 32-bit code. ; b_esdi dd 0 ; ES:DI for boot sector invocation b_edx dd 0 ; EDX for boot sector invocation section .rodata memdisk_version: db "MEMDISK ", VERSION, " ", DATE, 0 ;; ----------------------------------------------------------------------- ;; End kernel image header ;; ----------------------------------------------------------------------- ; ; Move ourselves down into memory to reduce the risk of conflicts; ; then canonicalize CS to match the other segments. ; section .text bits 16 start: mov ax,MY_CS mov es,ax movzx cx,byte [setup_sects] inc cx ; Add one for the boot sector shl cx,7 ; Convert to dwords xor si,si xor di,di mov fs,si ; fs <- 0 cld rep movsd mov ds,ax mov ss,ax xor esp,esp ; Stack at top of 64K segment jmp MY_CS:.next .next: ; ; Copy the command line, if there is one ; copy_cmdline: xor di,di ; Bottom of our own segment (= "boot sector") mov eax,[cmd_line_ptr] and eax,eax jz .endcmd ; No command line mov si,ax shr eax,4 ; Convert to segment and si,0x000F ; Starting offset only mov gs,ax mov cx,496 ; Max number of bytes .copycmd: gs lodsb and al,al jz .endcmd stosb loop .copycmd .endcmd: xor al,al stosb ; ; Now jump to 32-bit code ; sti call init32 ; ; When init32 returns, we have been set up, the new boot sector loaded, ; and we should go and and run the newly loaded boot sector. ; ; The setup function will have poked values into the setup area. ; movzx edi,word [cs:b_esdi] mov es,word [cs:b_esdi+2] mov edx,[cs:b_edx] cli xor esi,esi ; No partition table involved mov ds,si ; Make all the segments consistent mov fs,si mov gs,si mov ss,si mov esp,0x7C00 ; Good place for SP to start out call 0:0x7C00 int 18h ; A far return -> INT 18h ; ; We enter protected mode, set up a flat 32-bit environment, run rep movsd ; and then exit. IMPORTANT: This code assumes cs == MY_CS. ; ; This code is probably excessively anal-retentive in its handling of ; segments, but this stuff is painful enough as it is without having to rely ; on everything happening "as it ought to." ; section .rodata ; desc base, limit, flags %macro desc 3 dd (%2 & 0xffff) | ((%1 & 0xffff) << 16) dd (%1 & 0xff000000) | (%2 & 0xf0000) | ((%3 & 0xf0ff) << 8) | ((%1 & 0x00ff0000) >> 16) %endmacro align 8, db 0 call32_gdt: dw call32_gdt_size-1 ; Null descriptor - contains GDT .adj1: dd call32_gdt+CS_BASE ; pointer for LGDT instruction dw 0 ; 0008: Code segment, use16, readable, dpl 0, base CS_BASE, 64K desc CS_BASE, 0xffff, 0x009b ; 0010: Data segment, use16, read/write, dpl 0, base CS_BASE, 64K desc CS_BASE, 0xffff, 0x0093 ; 0018: Data segment, use16, read/write, dpl 0, base 0, 4G desc 0, 0xfffff, 0x809b ; 0020: Code segment, use32, read/write, dpl 0, base 0, 4G desc 0, 0xfffff, 0xc09b ; 0028: Data segment, use32, read/write, dpl 0, base 0, 4G desc 0, 0xfffff, 0xc093 call32_gdt_size: equ $-call32_gdt err_a20: db 'ERROR: A20 gate not responding!',13,10,0 section .bss alignb 4 SavedSSSP resd 1 ; Place to save SS:SP Return resd 1 ; Return value A20Test resw 1 ; Space to test A20 A20Tries resb 1 section .data alignb 4 Target dd 0 ; Target address Target_Seg dw 20h ; Target CS A20Type dw 0 ; Default = unknown section .text bits 16 ; ; Routines to enable and disable (yuck) A20. These routines are gathered ; from tips from a couple of sources, including the Linux kernel and ; http://www.x86.org/. The need for the delay to be as large as given here ; is indicated by Donnie Barnes of RedHat, the problematic system being an ; IBM ThinkPad 760EL. ; ; We typically toggle A20 twice for every 64K transferred. ; %define io_delay call _io_delay %define IO_DELAY_PORT 80h ; Invalid port (we hope!) %define disable_wait 32 ; How long to wait for a disable %define A20_DUNNO 0 ; A20 type unknown %define A20_NONE 1 ; A20 always on? %define A20_BIOS 2 ; A20 BIOS enable %define A20_KBC 3 ; A20 through KBC %define A20_FAST 4 ; A20 through port 92h align 2, db 0 A20List dw a20_dunno, a20_none, a20_bios, a20_kbc, a20_fast A20DList dw a20d_dunno, a20d_none, a20d_bios, a20d_kbc, a20d_fast a20_adjust_cnt equ ($-A20List)/2 slow_out: out dx, al ; Fall through _io_delay: out IO_DELAY_PORT,al out IO_DELAY_PORT,al ret enable_a20: pushad mov byte [A20Tries],255 ; Times to try to make this work try_enable_a20: ; ; Flush the caches ; %if DO_WBINVD call try_wbinvd %endif ; ; If the A20 type is known, jump straight to type ; mov bp,[A20Type] add bp,bp ; Convert to word offset .adj4: jmp word [bp+A20List] ; ; First, see if we are on a system with no A20 gate ; a20_dunno: a20_none: mov byte [A20Type], A20_NONE call a20_test jnz a20_done ; ; Next, try the BIOS (INT 15h AX=2401h) ; a20_bios: mov byte [A20Type], A20_BIOS mov ax,2401h pushf ; Some BIOSes muck with IF int 15h popf call a20_test jnz a20_done ; ; Enable the keyboard controller A20 gate ; a20_kbc: mov dl, 1 ; Allow early exit call empty_8042 jnz a20_done ; A20 live, no need to use KBC mov byte [A20Type], A20_KBC ; Starting KBC command sequence mov al,0D1h ; Command write out 064h, al call empty_8042_uncond mov al,0DFh ; A20 on out 060h, al call empty_8042_uncond ; Verify that A20 actually is enabled. Do that by ; observing a word in low memory and the same word in ; the HMA until they are no longer coherent. Note that ; we don't do the same check in the disable case, because ; we don't want to *require* A20 masking (SYSLINUX should ; work fine without it, if the BIOS does.) .kbc_wait: push cx xor cx,cx .kbc_wait_loop: call a20_test jnz a20_done_pop loop .kbc_wait_loop pop cx ; ; Running out of options here. Final attempt: enable the "fast A20 gate" ; a20_fast: mov byte [A20Type], A20_FAST ; Haven't used the KBC yet in al, 092h or al,02h and al,~01h ; Don't accidentally reset the machine! out 092h, al .fast_wait: push cx xor cx,cx .fast_wait_loop: call a20_test jnz a20_done_pop loop .fast_wait_loop pop cx ; ; Oh bugger. A20 is not responding. Try frobbing it again; eventually give up ; and report failure to the user. ; dec byte [A20Tries] jnz try_enable_a20 ; Error message time mov si,err_a20 print_err: lodsb and al,al jz die mov bx,7 mov ah,0xe int 10h jmp print_err die: sti .hlt: hlt jmp short .hlt ; ; A20 unmasked, proceed... ; a20_done_pop: pop cx a20_done: popad ret ; ; This routine tests if A20 is enabled (ZF = 0). This routine ; must not destroy any register contents. ; a20_test: push es push cx push ax mov cx,0FFFFh ; HMA = segment 0FFFFh mov es,cx mov cx,32 ; Loop count mov ax,[A20Test] .a20_wait: inc ax mov [A20Test],ax io_delay ; Serialize, and fix delay cmp ax,[es:A20Test+CS_BASE+10h] loopz .a20_wait .a20_done: pop ax pop cx pop es ret disable_a20: pushad ; ; Flush the caches ; %if DO_WBINVD call try_wbinvd %endif mov bp,[A20Type] add bp,bp ; Convert to word offset .adj5: jmp word [bp+A20DList] a20d_bios: mov ax,2400h pushf ; Some BIOSes muck with IF int 15h popf jmp short a20d_snooze ; ; Disable the "fast A20 gate" ; a20d_fast: in al, 092h and al,~03h out 092h, al jmp short a20d_snooze ; ; Disable the keyboard controller A20 gate ; a20d_kbc: call empty_8042_uncond mov al,0D1h out 064h, al ; Command write call empty_8042_uncond mov al,0DDh ; A20 off out 060h, al call empty_8042_uncond ; Wait a bit for it to take effect a20d_snooze: push cx mov cx, disable_wait .delayloop: call a20_test jz .disabled loop .delayloop .disabled: pop cx a20d_dunno: a20d_none: popad ret ; ; Routine to empty the 8042 KBC controller. If dl != 0 ; then we will test A20 in the loop and exit if A20 is ; suddenly enabled. ; empty_8042_uncond: xor dl,dl empty_8042: call a20_test jz .a20_on and dl,dl jnz .done .a20_on: io_delay in al, 064h ; Status port test al,1 jz .no_output io_delay in al, 060h ; Read input jmp short empty_8042 .no_output: test al,2 jnz empty_8042 io_delay .done: ret ; ; Execute a WBINVD instruction if possible on this CPU ; %if DO_WBINVD try_wbinvd: wbinvd ret %endif section .bss alignb 4 PMESP resd 1 ; Protected mode %esp section .idt nobits align=4096 alignb 4096 pm_idt resb 4096 ; Protected-mode IDT, followed by interrupt stubs pm_entry: equ 0x100000 section .rodata align 4, db 0 call32_pmidt: dw 8*256 ; Limit dd pm_idt+CS_BASE ; Address call32_rmidt: dw 0ffffh ; Limit dd 0 ; Address section .text ; ; This is the main entrypoint in this function ; init32: mov ebx,call32_call_start+CS_BASE ; Where to go in PM call32_enter_pm: mov ax,cs mov ds,ax cli mov [SavedSSSP],sp mov [SavedSSSP+2],ss cld call a20_test jnz .a20ok call enable_a20 .a20ok: lgdt [call32_gdt] ; Set up GDT lidt [call32_pmidt] ; Set up the IDT mov eax,cr0 or al,1 mov cr0,eax ; Enter protected mode jmp 20h:dword .in_pm+CS_BASE bits 32 .in_pm: xor eax,eax ; Available for future use... mov fs,eax mov gs,eax mov al,28h ; Set up data segments mov es,eax mov ds,eax mov ss,eax mov esp,[PMESP+CS_BASE] ; Load protmode %esp if available jmp ebx ; Go to where we need to go ; ; This is invoked before first dispatch of the 32-bit code, in 32-bit mode ; call32_call_start: ; ; Point the stack into low memory ; We have: this segment, bounce buffer, then stack+heap ; mov esp, CS_BASE + 0x20000 + STACK_HEAP_SIZE and esp, ~0xf ; ; Set up the protmode IDT and the interrupt jump buffers ; mov edi,pm_idt+CS_BASE ; Form an interrupt gate descriptor ; WARNING: This is broken if pm_idt crosses a 64K boundary; ; however, it can't because of the alignment constraints. mov ebx,pm_idt+CS_BASE+8*256 mov eax,0x0020ee00 xchg ax,bx xor ecx,ecx inc ch ; ecx <- 256 push ecx .make_idt: stosd add eax,8 xchg eax,ebx stosd xchg eax,ebx loop .make_idt pop ecx ; Each entry in the interrupt jump buffer contains ; the following instructions: ; ; 00000000 60 pushad ; 00000001 B0xx mov al, ; 00000003 E9xxxxxxxx jmp call32_handle_interrupt mov eax,0xe900b060 mov ebx,call32_handle_interrupt+CS_BASE sub ebx,edi .make_ijb: stosd sub [edi-2],cl ; Interrupt # xchg eax,ebx sub eax,8 stosd xchg eax,ebx loop .make_ijb ; Now everything is set up for interrupts... push dword (BOUNCE_SEG << 4) ; Bounce buffer address push dword call32_syscall+CS_BASE ; Syscall entry point sti ; Interrupts OK now call pm_entry-CS_BASE ; Run the program... ; ... on return ... mov [Return+CS_BASE],eax ; ... fall through to call32_exit ... call32_exit: mov bx,call32_done ; Return to command loop call32_enter_rm: cli cld mov [PMESP+CS_BASE],esp ; Save exit %esp xor esp,esp ; Make sure the high bits are zero jmp 08h:.in_pm16 ; Return to 16-bit mode first bits 16 .in_pm16: mov ax,10h ; Real-mode-like segment mov es,ax mov ds,ax mov ss,ax mov fs,ax mov gs,ax lidt [call32_rmidt] ; Real-mode IDT (rm needs no GDT) mov eax,cr0 and al,~1 mov cr0,eax jmp MY_CS:.in_rm .in_rm: ; Back in real mode mov ax,cs ; Set up sane segments mov ds,ax mov es,ax mov fs,ax mov gs,ax lss sp,[SavedSSSP] ; Restore stack jmp bx ; Go to whereever we need to go... call32_done: call disable_a20 sti mov ax,[Return] ret ; ; 16-bit support code ; bits 16 ; ; 16-bit interrupt-handling code ; call32_int_rm: pushf ; Flags on stack push cs ; Return segment push word .cont ; Return address push dword edx ; Segment:offset of IVT entry retf ; Invoke IVT routine .cont: ; ... on resume ... mov ebx,call32_int_resume+CS_BASE jmp call32_enter_pm ; Go back to PM ; ; 16-bit system call handling code ; call32_sys_rm: pop gs pop fs pop es pop ds popad popfd retf ; Invoke routine .return: pushfd pushad push ds push es push fs push gs mov ebx,call32_sys_resume+CS_BASE jmp call32_enter_pm ; ; 32-bit support code ; bits 32 ; ; This is invoked on getting an interrupt in protected mode. At ; this point, we need to context-switch to real mode and invoke ; the interrupt routine. ; ; When this gets invoked, the registers are saved on the stack and ; AL contains the register number. ; call32_handle_interrupt: movzx eax,al xor ebx,ebx ; Actually makes the code smaller mov edx,[ebx+eax*4] ; Get the segment:offset of the routine mov bx,call32_int_rm jmp call32_enter_rm ; Go to real mode call32_int_resume: popad iret ; ; Syscall invocation. We manifest a structure on the real-mode stack, ; containing the call32sys_t structure from as well as ; the following entries (from low to high address): ; - Target offset ; - Target segment ; - Return offset ; - Return segment (== real mode cs) ; - Return flags ; call32_syscall: pushfd ; Save IF among other things... pushad ; We only need to save some, but... cld movzx edi,word [SavedSSSP+CS_BASE] movzx eax,word [SavedSSSP+CS_BASE+2] sub edi,54 ; Allocate 54 bytes mov [SavedSSSP+CS_BASE],di shl eax,4 add edi,eax ; Create linear address mov esi,[esp+11*4] ; Source regs xor ecx,ecx mov cl,11 ; 44 bytes to copy rep movsd movzx eax,byte [esp+10*4] ; Interrupt number ; ecx == 0 here; adding it to the EA makes the ; encoding smaller mov eax,[ecx+eax*4] ; Get IVT entry stosd ; Save in stack frame mov eax,call32_sys_rm.return + (MY_CS << 16) ; Return seg:offs stosd ; Save in stack frame mov eax,[edi-12] ; Return flags and eax,0x200cd7 ; Mask (potentially) unsafe flags mov [edi-12],eax ; Primary flags entry stosw ; Return flags mov bx,call32_sys_rm jmp call32_enter_rm ; Go to real mode ; On return, the 44-byte return structure is on the ; real-mode stack. call32_sys_resume: movzx esi,word [SavedSSSP+CS_BASE] movzx eax,word [SavedSSSP+CS_BASE+2] mov edi,[esp+12*4] ; Dest regs shl eax,4 add esi,eax ; Create linear address and edi,edi ; NULL pointer? jnz .do_copy .no_copy: mov edi,esi ; Do a dummy copy-to-self .do_copy: xor ecx,ecx mov cl,11 ; 44 bytes rep movsd ; Copy register block add dword [SavedSSSP+CS_BASE],44 ; Remove from stack popad popfd ret ; Return to 32-bit program syslinux-legacy-3.63+dfsg/memdisk/start32.S0000664000175000017500000000021710777447273017273 0ustar evanevan# # Simple stub to get us to the right point in the 32-bit code; # this module must be linked first # .text .globl _start _start: jmp setup syslinux-legacy-3.63+dfsg/memdisk/e820func.c0000664000175000017500000000471110777447273017346 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * e820func.c * * E820 range database manager */ #include #include "memdisk.h" /* For memset() */ #include "e820.h" #define MAXRANGES 1024 /* All of memory starts out as one range of "indeterminate" type */ struct e820range ranges[MAXRANGES]; int nranges; void e820map_init(void) { memset(ranges, 0, sizeof(ranges)); nranges = 1; ranges[1].type = -1; } static void insertrange_at(int where, uint64_t start, uint32_t type) { int i; for ( i = nranges ; i > where ; i-- ) ranges[i] = ranges[i-1]; ranges[where].start = start; ranges[where].type = type; nranges++; ranges[nranges].start = 0ULL; ranges[nranges].type = (uint32_t)-1; } void insertrange(uint64_t start, uint64_t len, uint32_t type) { uint64_t last; uint32_t oldtype; int i, j; /* Remove this to make len == 0 mean all of memory */ if ( len == 0 ) return; /* Nothing to insert */ last = start+len-1; /* May roll over */ i = 0; oldtype = -2; while ( start > ranges[i].start && ranges[i].type != -1 ) { oldtype = ranges[i].type; i++; } /* Consider the replacement policy. This current one is "overwrite." */ if ( start < ranges[i].start || ranges[i].type == -1 ) insertrange_at(i++, start, type); while ( i == 0 || last > ranges[i].start-1 ) { oldtype = ranges[i].type; ranges[i].type = type; i++; } if ( last < ranges[i].start-1 ) insertrange_at(i, last+1, oldtype); /* Now the map is correct, but quite possibly not optimal. Scan the map for ranges which are redundant and remove them. */ i = j = 1; oldtype = ranges[0].type; while ( i < nranges ) { if ( ranges[i].type == oldtype ) { i++; } else { oldtype = ranges[i].type; if ( i != j ) ranges[j] = ranges[i]; i++; j++; } } if ( i != j ) { ranges[j] = ranges[i]; /* Termination sentinel copy */ nranges -= (i-j); } } syslinux-legacy-3.63+dfsg/memdisk/msetup.c0000664000175000017500000000720510777447273017332 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * msetup.c * * Initialization code for memory-based disk */ #include #include "memdisk.h" #include "conio.h" #include "e820.h" static inline int get_e820(void) { struct e820_info { uint64_t base; uint64_t len; uint32_t type; } *buf = sys_bounce; uint32_t copied; int range_count = 0; com32sys_t regs; memset(®s, 0, sizeof regs); do { regs.eax.l = 0x0000e820; regs.ecx.l = sizeof(*buf); regs.edx.l = 0x534d4150; regs.edi.w[0] = OFFS(buf); regs.es = SEG(buf); syscall(0x15, ®s, ®s); copied = (regs.eflags.l & 1) ? 0 : regs.ecx.l; if ( regs.eax.l != 0x534d4150 || copied < 20 ) break; printf("e820: %08x%08x %08x%08x %d\n", (uint32_t)(buf->base >> 32), (uint32_t)buf->base, (uint32_t)(buf->len >> 32), (uint32_t)buf->len, buf->type); insertrange(buf->base, buf->len, buf->type); range_count++; } while ( regs.ebx.l ); return !range_count; } static inline void get_dos_mem(void) { com32sys_t regs; memset(®s, 0, sizeof regs); syscall(0x12, ®s, ®s); insertrange(0, (uint64_t)((uint32_t)regs.eax.w[0] << 10), 1); printf(" DOS: %d K\n", regs.eax.w[0]); } static inline int get_e801(void) { int err; com32sys_t regs; memset(®s, 0, sizeof regs); regs.eax.w[0] = 0xe801; syscall(0x15, ®s, ®s); if ( !(err = regs.eflags.l & 1) ) { if ( regs.eax.w[0] ) { insertrange(0x100000, (uint64_t)((uint32_t)regs.eax.w[0] << 10), 1); } if ( regs.ebx.w[0] ) { insertrange(0x1000000, (uint64_t)((uint32_t)regs.ebx.w[0] << 16), 1); } printf("e801: %04x %04x\n", regs.eax.w[0], regs.ebx.w[0]); } return err; } static inline int get_88(void) { com32sys_t regs; int err; memset(®s, 0, sizeof regs); regs.eax.b[1] = 0x88; syscall(0x15, ®s, ®s); if ( !(err = regs.eflags.l & 1) ) { if ( regs.eax.w[0] ) { insertrange(0x100000, (uint64_t)((uint32_t)regs.eax.w[0] << 10), 1); } printf(" 88: %04x\n", regs.eax.w[0]); } return err; } uint32_t dos_mem = 0; /* 0-1MB */ uint32_t low_mem = 0; /* 1-16MB */ uint32_t high_mem = 0; /* 16+ MB */ void get_mem(void) { if ( get_e820() ) { get_dos_mem(); if ( get_e801() ) { if ( get_88() ) { puts("MEMDISK: Unable to obtain memory map\n"); die(); } } } } #define PW(x) (1ULL << (x)) void parse_mem(void) { struct e820range *ep; dos_mem = low_mem = high_mem = 0; /* Derive "dos mem", "high mem", and "low mem" from the range array */ for ( ep = ranges ; ep->type != -1 ; ep++ ) { if ( ep->type == 1 ) { /* Only look at memory ranges */ if ( ep->start == 0 ) { if ( ep[1].start > PW(20) ) dos_mem = PW(20); else dos_mem = ep[1].start; } if ( ep->start <= PW(20) && ep[1].start > PW(20) ) { if ( ep[1].start > PW(24) ) low_mem = PW(24) - PW(20); else low_mem = ep[1].start - PW(20); } if ( ep->start <= PW(24) && ep[1].start > PW(24) ) { if ( ep[1].start > PW(32) ) high_mem = PW(32) - PW(24); else high_mem = ep[1].start - PW(24); } } } } syslinux-legacy-3.63+dfsg/memdisk/memdisk.h0000664000175000017500000000374010777447273017453 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * memdisk.h * * Miscellaneous header definitions */ #ifndef MEMDISK_H #define MEMDISK_H /* We use the com32 interface for calling 16-bit code */ #include /* The real-mode segment */ #define LOW_SEG 0x0800 typedef void (*syscall_t)(uint8_t, com32sys_t *, com32sys_t *); extern syscall_t syscall; extern void *sys_bounce; /* What to call when we're dead */ extern void __attribute__((noreturn)) die(void); /* Standard routines */ #define memcpy(a,b,c) __builtin_memcpy(a,b,c) #define memset(a,b,c) __builtin_memset(a,b,c) #define strcpy(a,b) __builtin_strcpy(a,b) #define strlen(a) __builtin_strlen(a) /* memcpy() but returns a pointer to end of buffer */ static inline void * memcpy_endptr(void *__d, const void *__s, unsigned int __n) { memcpy(__d, __s, __n); return (void *)((char *)__d + __n); } /* memcmp() */ static inline int memcmp(const void *__a, const void *__b, unsigned int __n) { const unsigned char *__aa = __a; const unsigned char *__bb = __b; int __d; while ( __n-- ) { __d = *__bb++ - *__aa++; if ( __d ) return __d; } return 0; } /* Decompression */ extern int check_zip(void *indata, uint32_t size, uint32_t *zbytes_p, uint32_t *dbytes_p, uint32_t *orig_crc, uint32_t *offset_p); extern void *unzip(void *indata, uint32_t zbytes, uint32_t dbytes, uint32_t orig_crc, void *target); #endif syslinux-legacy-3.63+dfsg/memdisk/testdata20000664000175000017500000000055010777447273017463 0ustar evanevan0000000000000000 000000000009bc00 1 000000000009bc00 0000000000004400 2 00000000000e9800 0000000000016800 2 0000000000100000 0000000006ee0000 1 0000000006fe0000 000000000000fc00 3 0000000006fefc00 0000000000000400 4 0000000006ff0000 0000000000002000 2 0000000006ff2000 000000000000e000 1 0000000007000000 0000000000100000 2 00000000fff00000 0000000000100000 2 syslinux-legacy-3.63+dfsg/memdisk/postprocess.pl0000775000175000017500000000262210777447273020573 0ustar evanevan#!/usr/bin/perl ## ----------------------------------------------------------------------- ## ## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- # # Postprocess the memdisk binary. # eval { use bytes; }; ($out,$file16,$file32) = @ARGV; open(OUT, "> $out\0") or die "$0: Cannot create file: $out\n"; eval { binmode OUT; }; open(FILE, "< $file16\0") or die "$0: Cannot open file: $file16\n"; eval { binmode FILE }; @info = stat(FILE); $size = $info[7]; $sectors = ($size + 511) >> 9; $xsize = $sectors << 9; read(FILE, $f16, $size); print OUT $f16; if ( $size != $xsize ) { # Pad to a sector boundary print OUT "\0" x ($xsize-$size); } seek(OUT, 0x1f1, SEEK_SET); # setup_sects # All sectors are setup except the first print OUT pack("C", $sectors-1); seek(OUT, $xsize, SEEK_SET); close(FILE); open(FILE, "+< $file32\0") or die "$0: Cannot open file: $file32\n"; while ( ($n = read(FILE, $f32, 65536)) > 0 ) { print OUT $f32; } close(FILE); close(OUT); syslinux-legacy-3.63+dfsg/memdisk/setup.c0000664000175000017500000006137310777447273017163 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include #include "e820.h" #include "conio.h" #include "version.h" #include "memdisk.h" const char memdisk_version[] = "MEMDISK " VERSION " " DATE; const char copyright[] = "Copyright " FIRSTYEAR "-" COPYYEAR " H. Peter Anvin"; extern const char _binary_memdisk_bin_start[], _binary_memdisk_bin_end[]; extern const char _binary_memdisk_bin_size[]; /* Weird, I know */ struct memdisk_header { uint16_t int13_offs; uint16_t int15_offs; uint16_t patch_offs; uint16_t total_size; uint16_t iret_offs; }; /* The Disk Parameter Table may be required */ typedef union { struct hd_dpt { uint16_t max_cyl; /* Max cylinder */ uint8_t max_head; /* Max head */ uint8_t junk1[5]; /* Obsolete junk, leave at zero */ uint8_t ctrl; /* Control byte */ uint8_t junk2[7]; /* More obsolete junk */ } hd; struct fd_dpt { uint8_t specify1; /* "First specify byte" */ uint8_t specify2; /* "Second specify byte" */ uint8_t delay; /* Delay until motor turn off */ uint8_t sectors; /* Sectors/track */ uint8_t bps; /* Bytes/sector (02h = 512) */ uint8_t isgap; /* Length of intersector gap */ uint8_t dlen; /* Data length (0FFh) */ uint8_t fgap; /* Formatting gap */ uint8_t ffill; /* Format fill byte */ uint8_t settle; /* Head settle time (ms) */ uint8_t mstart; /* Motor start time */ uint8_t _pad1; /* Padding */ uint32_t old_fd_dpt; /* Extension: pointer to old INT 1Eh */ } fd; } dpt_t; /* EDD disk parameter table */ struct edd_dpt { uint16_t len; /* Length of table */ uint16_t flags; /* Information flags */ uint32_t c; /* Physical cylinders (count!) */ uint32_t h; /* Physical heads (count!) */ uint32_t s; /* Physical sectors/track (count!) */ uint64_t sectors; /* Total sectors */ uint16_t bytespersec; /* Bytes/sector */ uint16_t dpte_off, dpte_seg; /* DPTE pointer */ }; struct patch_area { uint32_t diskbuf; uint32_t disksize; uint16_t cmdline_off, cmdline_seg; uint32_t oldint13; uint32_t oldint15; uint16_t olddosmem; uint8_t bootloaderid; uint8_t maxint13func; #define MAXINT13_NOEDD 0x16 uint8_t _pad[2]; uint16_t memint1588; uint16_t cylinders; uint16_t heads; uint32_t sectors; uint32_t mem1mb; uint32_t mem16mb; uint8_t driveno; uint8_t drivetype; uint8_t drivecnt; uint8_t configflags; #define CONFIG_READONLY 0x01 #define CONFIG_RAW 0x02 #define CONFIG_SAFEINT 0x04 #define CONFIG_BIGRAW 0x08 /* MUST be 8! */ uint16_t mystack; uint16_t statusptr; dpt_t dpt; struct edd_dpt edd_dpt; }; /* This is the header in the boot sector/setup area */ struct setup_header { char cmdline[0x1f1]; uint8_t setup_secs; uint16_t syssize; uint16_t swap_dev; uint16_t ram_size; uint16_t vid_mode; uint16_t root_dev; uint16_t boot_flag; uint16_t jump; char header[4]; uint16_t version; uint32_t realmode_swtch; uint32_t start_sys; uint8_t type_of_loader; uint8_t loadflags; uint16_t setup_move_size; uint32_t code32_start; uint32_t ramdisk_image; uint32_t ramdisk_size; uint32_t bootsect_kludge; uint16_t head_end_ptr; uint16_t pad1; uint32_t cmd_line_ptr; uint32_t initrd_addr_max; uint32_t esdi; uint32_t edx; }; struct setup_header * const shdr = (struct setup_header *)(LOW_SEG << 4); /* Access to high memory */ /* Access to objects in the zero page */ static inline void wrz_8(uint32_t addr, uint8_t data) { *((uint8_t *)addr) = data; } static inline void wrz_16(uint32_t addr, uint16_t data) { *((uint16_t *)addr) = data; } static inline void wrz_32(uint32_t addr, uint32_t data) { *((uint32_t *)addr) = data; } static inline uint8_t rdz_8(uint32_t addr) { return *((uint8_t *)addr); } static inline uint16_t rdz_16(uint32_t addr) { return *((uint16_t *)addr); } static inline uint32_t rdz_32(uint32_t addr) { return *((uint32_t *)addr); } /* Addresses in the zero page */ #define BIOS_INT13 (0x13*4) /* INT 13h vector */ #define BIOS_INT15 (0x15*4) /* INT 15h vector */ #define BIOS_INT1E (0x1E*4) /* INT 1Eh vector */ #define BIOS_INT40 (0x40*4) /* INT 13h vector */ #define BIOS_INT41 (0x41*4) /* INT 41h vector */ #define BIOS_INT46 (0x46*4) /* INT 46h vector */ #define BIOS_BASEMEM 0x413 /* Amount of DOS memory */ #define BIOS_EQUIP 0x410 /* BIOS equipment list */ #define BIOS_HD_COUNT 0x475 /* Number of hard drives present */ /* * Routine to seek for a command-line item and return a pointer * to the data portion, if present */ /* Magic return values */ #define CMD_NOTFOUND ((char *)-1) /* Not found */ #define CMD_BOOL ((char *)-2) /* Found boolean option */ #define CMD_HASDATA(X) ((int)(X) >= 0) const char *getcmditem(const char *what) { const char *p; const char *wp = what; int match = 0; for ( p = shdr->cmdline ; *p ; p++ ) { switch ( match ) { case 0: /* Ground state */ if ( *p == ' ' ) break; wp = what; match = 1; /* Fall through */ case 1: /* Matching */ if ( *wp == '\0' ) { if ( *p == '=' ) return p+1; else if ( *p == ' ' ) return CMD_BOOL; else { match = 2; break; } } if ( *p != *wp++ ) match = 2; break; case 2: /* Mismatch, skip rest of option */ if ( *p == ' ' ) match = 0; /* Next option */ break; } } /* Check for matching string at end of line */ if ( match == 1 && *wp == '\0' ) return CMD_BOOL; return CMD_NOTFOUND; } /* * Check to see if this is a gzip image */ #define UNZIP_ALIGN 512 extern void _end; /* Symbol signalling end of data */ void unzip_if_needed(uint32_t *where_p, uint32_t *size_p) { uint32_t where = *where_p; uint32_t size = *size_p; uint32_t zbytes; uint32_t startrange, endrange; uint32_t gzdatasize, gzwhere; uint32_t orig_crc, offset; uint32_t target = 0; int i, okmem; /* Is it a gzip image? */ if (check_zip ((void *)where, size, &zbytes, &gzdatasize, &orig_crc, &offset) == 0) { if (offset + zbytes > size) { /* Assertion failure; check_zip is supposed to guarantee this never happens. */ puts("internal error: check_zip returned nonsense\n"); die(); } /* Find a good place to put it: search memory ranges in descending order until we find one that is legal and fits */ okmem = 0; for ( i = nranges-1 ; i >= 0 ; i-- ) { /* We can't use > 4G memory (32 bits only.) Truncate to 2^32-1 so we don't have to deal with funny wraparound issues. */ /* Must be memory */ if ( ranges[i].type != 1 ) continue; /* Range start */ if ( ranges[i].start >= 0xFFFFFFFF ) continue; startrange = (uint32_t)ranges[i].start; /* Range end (0 for end means 2^64) */ endrange = ((ranges[i+1].start >= 0xFFFFFFFF || ranges[i+1].start == 0) ? 0xFFFFFFFF : (uint32_t)ranges[i+1].start); /* Make sure we don't overwrite ourselves */ if ( startrange < (uint32_t)&_end ) startrange = (uint32_t)&_end; /* Allow for alignment */ startrange = (ranges[i].start + (UNZIP_ALIGN-1)) & ~(UNZIP_ALIGN-1); /* In case we just killed the whole range... */ if ( startrange >= endrange ) continue; /* Must be large enough... don't rely on gzwhere for this (wraparound) */ if ( endrange-startrange < gzdatasize ) continue; /* This is where the gz image should be put if we put it in this range */ gzwhere = (endrange - gzdatasize) & ~(UNZIP_ALIGN-1); /* Cast to uint64_t just in case we're flush with the top byte */ if ( (uint64_t)where+size >= gzwhere && where < endrange ) { /* Need to move source data to avoid compressed/uncompressed overlap */ uint32_t newwhere; if ( gzwhere-startrange < size ) continue; /* Can't fit both old and new */ newwhere = (gzwhere - size) & ~(UNZIP_ALIGN-1); printf("Moving compressed data from 0x%08x to 0x%08x\n", where, newwhere); /* Our memcpy() is OK, because we always move from a higher address to a lower one */ memcpy((void *)newwhere, (void *)where, size); where = newwhere; } target = gzwhere; okmem = 1; break; } if ( !okmem ) { printf("Not enough memory to decompress image (need 0x%08x bytes)\n", gzdatasize); die(); } printf("gzip image: decompressed addr 0x%08x, len 0x%08x: ", target, gzdatasize); *size_p = gzdatasize; *where_p = (uint32_t)unzip((void *)(where + offset), zbytes, gzdatasize, orig_crc, (void *)target); } } /* * Figure out the "geometry" of the disk in question */ struct geometry { uint32_t sectors; /* 512-byte sector count */ uint32_t c, h, s; /* C/H/S geometry */ uint32_t offset; /* Byte offset for disk */ uint8_t type; /* Type byte for INT 13h AH=08h */ uint8_t driveno; /* Drive no */ }; static const struct geometry geometries[] = { { 360*2, 40, 2, 9, 0, 0x01, 0 }, /* 360 K */ { 720*2, 80, 2, 9, 0, 0x03, 0 }, /* 720 K*/ { 1200*2, 80, 2, 15, 0, 0x02, 0 }, /* 1200 K */ { 1440*2, 80, 2, 18, 0, 0x04, 0 }, /* 1440 K */ { 1680*2, 80, 2, 21, 0, 0x04, 0 }, /* 1680 K */ { 1722*2, 82, 2, 21, 0, 0x04, 0 }, /* 1722 K */ { 2880*2, 80, 2, 36, 0, 0x06, 0 }, /* 2880 K */ { 3840*2, 80, 2, 48, 0, 0x06, 0 }, /* 3840 K */ }; #define known_geometries (sizeof(geometries)/sizeof(struct geometry)) /* Format of a DOS partition table entry */ struct ptab_entry { uint8_t active; uint8_t start_h, start_s, start_c; uint8_t type; uint8_t end_h, end_s, end_c; uint32_t start; uint32_t size; }; /* Format of a DOSEMU header */ struct dosemu_header { uint8_t magic[7]; /* DOSEMU\0 */ uint32_t h; uint32_t s; uint32_t c; uint32_t offset; uint8_t pad[105]; } __attribute__((packed)); #define FOUR(a,b,c,d) (((a) << 24)|((b) << 16)|((c) << 8)|(d)) const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size) { static struct geometry hd_geometry = { 0, 0, 0, 0, 0, 0, 0x80 }; struct ptab_entry ptab[4]; /* Partition table buffer */ struct dosemu_header dosemu; unsigned int sectors, v; unsigned int max_c, max_h, max_s; unsigned int c, h, s, offset; int i; int drive_specified; const char *p; printf("command line: %s\n", shdr->cmdline); offset = 0; if ( CMD_HASDATA(p = getcmditem("offset")) && (v = atou(p)) ) offset = v; sectors = (size-offset) >> 9; for ( i = 0 ; i < known_geometries ; i++ ) { if ( sectors == geometries[i].sectors ) { hd_geometry = geometries[i]; break; } } hd_geometry.sectors = sectors; hd_geometry.offset = offset; /* Do we have a DOSEMU header? */ memcpy(&dosemu, (char *)where+hd_geometry.offset, sizeof dosemu); if ( !memcmp("DOSEMU", dosemu.magic, 7) ) { /* Always a hard disk unless overruled by command-line options */ hd_geometry.driveno = 0x80; hd_geometry.type = 0; hd_geometry.c = dosemu.c; hd_geometry.h = dosemu.h; hd_geometry.s = dosemu.s; hd_geometry.offset += dosemu.offset; sectors = (size-hd_geometry.offset) >> 9; } if ( CMD_HASDATA(p = getcmditem("c")) && (v = atou(p)) ) hd_geometry.c = v; if ( CMD_HASDATA(p = getcmditem("h")) && (v = atou(p)) ) hd_geometry.h = v; if ( CMD_HASDATA(p = getcmditem("s")) && (v = atou(p)) ) hd_geometry.s = v; if ( (p = getcmditem("floppy")) != CMD_NOTFOUND ) { hd_geometry.driveno = CMD_HASDATA(p) ? atou(p) & 0x7f : 0; if ( hd_geometry.type == 0 ) hd_geometry.type = 0x10; /* ATAPI floppy, e.g. LS-120 */ drive_specified = 1; } else if ( (p = getcmditem("harddisk")) != CMD_NOTFOUND ) { hd_geometry.driveno = CMD_HASDATA(p) ? atou(p) | 0x80 : 0x80; hd_geometry.type = 0; drive_specified = 1; } if ( (hd_geometry.c == 0) || (hd_geometry.h == 0) || (hd_geometry.s == 0) ) { /* Hard disk image, need to examine the partition table for geometry */ memcpy(&ptab, (char *)where+hd_geometry.offset+(512-2-4*16), sizeof ptab); max_c = max_h = 0; max_s = 1; for ( i = 0 ; i < 4 ; i++ ) { if ( ptab[i].type ) { c = ptab[i].start_c + (ptab[i].start_s >> 6); s = (ptab[i].start_s & 0x3f); h = ptab[i].start_h; if ( max_c < c ) max_c = c; if ( max_h < h ) max_h = h; if ( max_s < s ) max_s = s; c = ptab[i].end_c + (ptab[i].end_s >> 6); s = (ptab[i].end_s & 0x3f); h = ptab[i].end_h; if ( max_c < c ) max_c = c; if ( max_h < h ) max_h = h; if ( max_s < s ) max_s = s; } } max_c++; max_h++; /* Convert to count (1-based) */ if ( !hd_geometry.h ) hd_geometry.h = max_h; if ( !hd_geometry.s ) hd_geometry.s = max_s; if ( !hd_geometry.c ) hd_geometry.c = sectors/(hd_geometry.h*hd_geometry.s); } if ( (size-hd_geometry.offset) & 0x1ff ) { puts("MEMDISK: Image has fractional end sector\n"); } if ( sectors % (hd_geometry.h*hd_geometry.s) ) { puts("MEMDISK: Image seems to have fractional end cylinder\n"); } if ( (hd_geometry.c*hd_geometry.h*hd_geometry.s) > sectors ) { puts("MEMDISK: Image appears to be truncated\n"); } return &hd_geometry; } /* * Jump here if all hope is gone... */ void __attribute__((noreturn)) die(void) { asm volatile("sti"); for(;;) asm volatile("hlt"); } /* * Find a $PnP installation check structure; return (ES << 16) + DI value */ static uint32_t pnp_install_check(void) { uint32_t *seg; unsigned char *p, csum; int i, len; for (seg = (uint32_t *)0xf0000; seg < (uint32_t *)0x100000; seg += 4) { if (*seg == ('$'+('P' << 8)+('n' << 16)+('P' << 24))) { p = (unsigned char *)seg; len = p[5]; if (len < 0x21) continue; csum = 0; for (i = len; i; i--) csum += *p++; if (csum != 0) continue; return (0xf000 << 16) + (uint16_t)(unsigned long)seg; } } return 0; } #define STACK_NEEDED 512 /* Number of bytes of stack */ /* * Actual setup routine * Returns the drive number (which is then passed in %dl to the * called routine.) */ syscall_t syscall; void *sys_bounce; void setup(syscall_t cs_syscall, void *cs_bounce) { unsigned int bin_size = (int) &_binary_memdisk_bin_size; struct memdisk_header *hptr; struct patch_area *pptr; uint16_t driverseg; uint32_t driverptr, driveraddr; uint16_t dosmem_k; uint32_t stddosmem; const struct geometry *geometry; int total_size, cmdlinelen; com32sys_t regs; uint32_t ramdisk_image, ramdisk_size; int bios_drives; int do_edd = -1; /* -1 = default, 0 = no, 1 = yes */ /* Set up global variables */ syscall = cs_syscall; sys_bounce = cs_bounce; /* Show signs of life */ printf("%s %s\n", memdisk_version, copyright); if ( !shdr->ramdisk_image || !shdr->ramdisk_size ) { puts("MEMDISK: No ramdisk image specified!\n"); die(); } ramdisk_image = shdr->ramdisk_image; ramdisk_size = shdr->ramdisk_size; e820map_init(); /* Initialize memory data structure */ get_mem(); /* Query BIOS for memory map */ parse_mem(); /* Parse memory map */ printf("Ramdisk at 0x%08x, length 0x%08x\n", ramdisk_image, ramdisk_size); unzip_if_needed(&ramdisk_image, &ramdisk_size); geometry = get_disk_image_geometry(ramdisk_image, ramdisk_size); if (getcmditem("edd") != CMD_NOTFOUND || getcmditem("ebios") != CMD_NOTFOUND) do_edd = 1; else if (getcmditem("noedd") != CMD_NOTFOUND || getcmditem("noebios") != CMD_NOTFOUND || getcmditem("cbios") != CMD_NOTFOUND) do_edd = 0; else do_edd = (geometry->driveno & 0x80) ? 1 : 0; printf("Disk is %s %d, %u K, C/H/S = %u/%u/%u, EDD %s\n", (geometry->driveno & 0x80) ? "hard disk" : "floppy", geometry->driveno & 0x7f, geometry->sectors >> 1, geometry->c, geometry->h, geometry->s, do_edd ? "on" : "off"); /* Reserve the ramdisk memory */ insertrange(ramdisk_image, ramdisk_size, 2); parse_mem(); /* Recompute variables */ /* Figure out where it needs to go */ hptr = (struct memdisk_header *) &_binary_memdisk_bin_start; pptr = (struct patch_area *)(_binary_memdisk_bin_start + hptr->patch_offs); dosmem_k = rdz_16(BIOS_BASEMEM); pptr->olddosmem = dosmem_k; stddosmem = dosmem_k << 10; /* If INT 15 E820 and INT 12 disagree, go with the most conservative */ if ( stddosmem > dos_mem ) stddosmem = dos_mem; pptr->driveno = geometry->driveno; pptr->drivetype = geometry->type; pptr->cylinders = geometry->c; pptr->heads = geometry->h; pptr->sectors = geometry->s; pptr->disksize = geometry->sectors; pptr->diskbuf = ramdisk_image + geometry->offset; pptr->statusptr = (geometry->driveno & 0x80) ? 0x474 : 0x441; pptr->bootloaderid = shdr->type_of_loader; pptr->configflags = 0; /* Set config flags */ if ( getcmditem("ro") != CMD_NOTFOUND ) { puts("Marking disk readonly\n"); pptr->configflags |= CONFIG_READONLY; } if ( getcmditem("raw") != CMD_NOTFOUND ) { puts("Using raw access to high memory\n"); pptr->configflags &= ~CONFIG_SAFEINT|CONFIG_BIGRAW; pptr->configflags |= CONFIG_RAW; } if ( getcmditem("safeint") != CMD_NOTFOUND ) { puts("Using safe INT 15h access to high memory\n"); pptr->configflags &= ~CONFIG_RAW|CONFIG_BIGRAW; pptr->configflags |= CONFIG_SAFEINT; } if ( getcmditem("bigraw") != CMD_NOTFOUND ) { puts("Using raw access to high memory - assuming big real mode\n"); pptr->configflags &= ~CONFIG_SAFEINT; pptr->configflags |= CONFIG_BIGRAW|CONFIG_RAW; } /* pptr->maxint13func defaults to EDD enabled, if compiled in */ if (!do_edd) pptr->maxint13func = MAXINT13_NOEDD; /* Set up a drive parameter table */ if ( geometry->driveno & 0x80 ) { /* Hard disk */ pptr->dpt.hd.max_cyl = geometry->c-1; pptr->dpt.hd.max_head = geometry->h-1; pptr->dpt.hd.ctrl = (geometry->h > 8) ? 0x08: 0; } else { /* Floppy - most of these fields are bogus and mimic a 1.44 MB floppy drive */ pptr->dpt.fd.specify1 = 0xdf; pptr->dpt.fd.specify2 = 0x02; pptr->dpt.fd.delay = 0x25; pptr->dpt.fd.sectors = geometry->s; pptr->dpt.fd.bps = 0x02; pptr->dpt.fd.isgap = 0x12; pptr->dpt.fd.dlen = 0xff; pptr->dpt.fd.fgap = 0x6c; pptr->dpt.fd.ffill = 0xf6; pptr->dpt.fd.settle = 0x0f; pptr->dpt.fd.mstart = 0x05; pptr->dpt.fd.old_fd_dpt = rdz_32(BIOS_INT1E); } /* Set up an EDD drive parameter table */ pptr->edd_dpt.sectors = geometry->sectors; /* The EDD spec has this as <= 15482880 sectors (1024x240x63); this seems to make very little sense. Try for something saner. */ if (geometry->c <= 1024 && geometry->h <= 255 && geometry->s <= 63) { pptr->edd_dpt.c = geometry->c; pptr->edd_dpt.h = geometry->h; pptr->edd_dpt.s = geometry->s; pptr->edd_dpt.flags |= 0x0002; /* Geometry valid */ } if (!(geometry->driveno & 0x80)) { /* Floppy drive. Mark it as a removable device with media change notification; media is present. */ pptr->edd_dpt.flags |= 0x0014; } /* The size is given by hptr->total_size plus the size of the E820 map -- 12 bytes per range; we may need as many as 2 additional ranges (each insertrange() can worst-case turn 1 area into 3) plus the terminating range, over what nranges currently show. */ cmdlinelen = strlen(shdr->cmdline)+1; total_size = hptr->total_size; /* Actual memdisk code */ total_size += (nranges+3)*sizeof(ranges[0]); /* E820 memory ranges */ total_size += cmdlinelen; /* Command line */ total_size += STACK_NEEDED; /* Stack */ printf("Total size needed = %u bytes, allocating %uK\n", total_size, (total_size+0x3ff) >> 10); if ( total_size > dos_mem ) { puts("MEMDISK: Insufficient low memory\n"); die(); } driveraddr = stddosmem - total_size; driveraddr &= ~0x3FF; printf("Old dos memory at 0x%05x (map says 0x%05x), loading at 0x%05x\n", stddosmem, dos_mem, driveraddr); /* Reserve this range of memory */ wrz_16(BIOS_BASEMEM, driveraddr >> 10); insertrange(driveraddr, dos_mem-driveraddr, 2); parse_mem(); pptr->mem1mb = low_mem >> 10; pptr->mem16mb = high_mem >> 16; if ( low_mem == (15 << 20) ) { /* lowmem maxed out */ uint32_t int1588mem = (high_mem >> 10)+(low_mem >> 10); pptr->memint1588 = (int1588mem > 0xffff) ? 0xffff : int1588mem; } else { pptr->memint1588 = low_mem >> 10; } printf("1588: 0x%04x 15E801: 0x%04x 0x%04x\n", pptr->memint1588, pptr->mem1mb, pptr->mem16mb); driverseg = driveraddr >> 4; driverptr = driverseg << 16; /* Anything beyond the end is for the stack */ pptr->mystack = (uint16_t)(stddosmem-driveraddr); pptr->oldint13 = rdz_32(BIOS_INT13); pptr->oldint15 = rdz_32(BIOS_INT15); /* Adjust the E820 table: if there are null ranges (type 0) at the end, change them to type end of list (-1). This is necessary for the driver to be able to report end of list correctly. */ while ( nranges && ranges[nranges-1].type == 0 ) { ranges[--nranges].type = -1; } if (getcmditem("nopass") != CMD_NOTFOUND) { /* nopass specified - we're the only drive by definition */ printf("nopass specified - we're the only drive\n"); bios_drives = 0; pptr->drivecnt = 0; pptr->oldint13 = driverptr+hptr->iret_offs; } else { /* Query drive parameters of this type */ memset(®s, 0, sizeof regs); regs.es = 0; regs.eax.b[1] = 0x08; regs.edx.b[0] = geometry->driveno & 0x80; syscall(0x13, ®s, ®s); if ( regs.eflags.l & 1 ) { printf("INT 13 08: Failure, assuming this is the only drive\n"); pptr->drivecnt = 0; } else { printf("INT 13 08: Success, count = %u, BPT = %04x:%04x\n", regs.edx.b[0], regs.es, regs.edi.w[0]); pptr->drivecnt = regs.edx.b[0]; } /* Compare what INT 13h returned with the appropriate equipment byte */ if ( geometry->driveno & 0x80 ) { bios_drives = rdz_8(BIOS_HD_COUNT); } else { uint8_t equip = rdz_8(BIOS_EQUIP); if (equip & 1) bios_drives = (equip >> 6)+1; else bios_drives = 0; } if (pptr->drivecnt > bios_drives) { printf("BIOS equipment byte says count = %d, go with that\n", bios_drives); pptr->drivecnt = bios_drives; } } /* Add ourselves to the drive count */ pptr->drivecnt++; /* Discontiguous drive space. There is no really good solution for this. */ if ( pptr->drivecnt <= (geometry->driveno & 0x7f) ) pptr->drivecnt = (geometry->driveno & 0x7f) + 1; /* Pointer to the command line */ pptr->cmdline_off = bin_size + (nranges+1)*sizeof(ranges[0]); pptr->cmdline_seg = driverseg; /* Copy driver followed by E820 table followed by command line */ { unsigned char *dpp = (unsigned char *)(driverseg << 4); dpp = memcpy_endptr(dpp, &_binary_memdisk_bin_start, bin_size); dpp = memcpy_endptr(dpp, ranges, (nranges+1)*sizeof(ranges[0])); dpp = memcpy_endptr(dpp, shdr->cmdline, cmdlinelen+1); } /* Install the interrupt handlers */ printf("old: int13 = %08x int15 = %08x\n", rdz_32(BIOS_INT13), rdz_32(BIOS_INT15)); wrz_32(BIOS_INT13, driverptr+hptr->int13_offs); wrz_32(BIOS_INT15, driverptr+hptr->int15_offs); printf("new: int13 = %08x int15 = %08x\n", rdz_32(BIOS_INT13), rdz_32(BIOS_INT15)); /* Update various BIOS magic data areas (gotta love this shit) */ if ( geometry->driveno & 0x80 ) { /* Update BIOS hard disk count */ uint8_t nhd = pptr->drivecnt; if ( nhd > 128 ) nhd = 128; wrz_8(BIOS_HD_COUNT, nhd); } else { /* Update BIOS floppy disk count */ uint8_t equip = rdz_8(BIOS_EQUIP); uint8_t nflop = pptr->drivecnt; if ( nflop > 4 ) /* Limit of equipment byte */ nflop = 4; equip &= 0x3E; if ( nflop ) equip |= ((nflop-1) << 6) | 0x01; wrz_8(BIOS_EQUIP, equip); } /* Reboot into the new "disk"; this is also a test for the interrupt hooks */ puts("Loading boot sector... "); memset(®s, 0, sizeof regs); // regs.es = 0; regs.eax.w[0] = 0x0201; /* Read sector */ regs.ebx.w[0] = 0x7c00; /* 0000:7C00 */ regs.ecx.w[0] = 1; /* One sector */ regs.edx.w[0] = geometry->driveno; syscall(0x13, ®s, ®s); if ( regs.eflags.l & 1 ) { puts("MEMDISK: Failed to load new boot sector\n"); die(); } if ( getcmditem("pause") != CMD_NOTFOUND ) { puts("press any key to boot... "); regs.eax.w[0] = 0; syscall(0x16, ®s, NULL); } puts("booting...\n"); /* On return the assembly code will jump to the boot vector */ shdr->esdi = pnp_install_check(); shdr->edx = geometry->driveno; } syslinux-legacy-3.63+dfsg/memdisk/memdisk0000664000175000017500000004714410777447310017223 0ustar evanevanU6HdrSA11f؎f1\1f(f!tfe t0M.f>0.2.f4f1ގf||~f`.ouj$^uYuRd`Q1<u6Y $Q1$uYu t YfaQP @^&;(XYf`.$$d`Q tYfa0t udt`ufȎ&iu "f 1(؎Ћ% f1QY`)(Ohh{f%1؎Ў $"Ȏ؎&ÜhfRffafff`fQ1ۋfwaϜ`=6f=Njt$,1ɱ D$(G% Gff&5|$0!u1ɱ ,aMEMDISK 3.63 2008-04-10/ERROR: A20 gate not responding!  WVS|$1?tt&u0 t+ u =t2 u$C8u  u 1FuHu;u F[^_fVSÉQRP؃[^ÐUWVS$hh@-XhR-Bx, Pjt2RjPh@'1$) 21;:tσ3u=@5@\$ D5VhPS3Y-CA9u`-+h`-[x Pt@hb-wYx Pt@h4SZx P}t @hd-/^t.y1 PP@=@u<@3hk-[t#y PȀ@@=@t=@t = @$-@Qj@PR1$;t.C?9sK?CS9s9s9s΃$9u=@uE@= @u5 @=@u @@1@@)$$t ht- @@1t h-@@ @9vZ h-eH@@D$@D$@D$ @@D$@$) @[^_]UWVS4D$HD$T$LT$D$$PD$,PD$4PD$xC@L$$ KTCX|$$G=w#w ?wCHGCLG CPfKFD$$xxfKF1щL$ @k  D$Q PWh0F9v hE0  9v)ׁWPVhg0} f$F)1RP1RW3 F k$ FC(u <=vfCfks(s$CPh0L$ l$ D$0f)fC0LC TC  ǁHtPk Ht h0Z@t$ h0~C. @D$0C t$< 1fD$@D$aT$$BD$XPVVjD$dt h0C.#D$DPD$DPD$`Ph01 D$hC.L$$yy =uu1 xC.9~PPWha1 C.C.@C.T$$Jʃ9 AC.k  LD fCL$fK L@k  @L$ AP5T5Lh1 @T$0L@D$0T PRh1 |$$C.yt H  h1d\$L 1fD$pfD$d|fD$ll$4fEfD$h SSjD$dt h1 h2]@t% h2fD$p jSj h729$PnPu.AD$/ ~1ZBD$/D9uu10T$$B4|[^_]D$(?)/D$(2у>UWVSFFF1111H@D u$LP= wp=w,LPwv=v wj=wc w8=w1LPw=vrwv H<y몉F5F=F[^_]ÍvUWVS5$D$ 1|$ 1DŽ$ DŽ$DŽ$PAMSf$f$P$PPj$t1$$PAMSuSvNFV ^WWvP1PQ1Qh3t vv vv6:E $;rD$tD$ ljS|$xWD$|Pj$$ 1RPjj$Ph3|$X|$fD$| |$LWD$PPjD$pu_D$lft j 1RPjhi D$`ft j1RPjhE QD$dPD$tPh3d|$<$D$AR|$ WD$$PjD$Du>D$@ft j 1RPjh PPD$HPh3 h3:[^_]ÐUWVSD$T$L$ - k 4@ZPj WVڃ ;T$kT$ L$\$ @DD$0HE k ǀ@ǀDǀH[^_]fUWVSD$0T$4D$T$ D$8T$< `t$|$ D$11EL$@D9T$ r0w9D$vH u9T$ rw9D$r k Hu] t$LT$L$݃k HT$L$@E tPH9wr9w9w!r9s t$ \H5 D$L2k H9uC 9t@Rj Pt$7CGD$ 9|9t(k k @@Qj PR))މ5 [^_]Ívh0jh@ TS8\$@ u j ÀfD$0PjD$Pj؃H[VSt$1 PC3uZ[^fVS1 k APЃ v[^ÍvST$1k BHЃ v[ÐUWVSÉ։͋$$@t D$(3D$(4tE"v1U0D$t.y ID$'-%tID$'+tID$' D$' T$ tuuIuD$>0D$,(D$,1ƋD$(D$,T>@D$,ut$,$9}։)u C@€|$'tL$' C|$ t u0Cu0L$(A!CuT$C@‰0CH9D$,|L$,L$,D >C|$, CH؁Č[^_]UWVS |$(t$ <%u D$2L$$AL$$€+t! t!#u1!-t0u%L$̃L$ŃL$뾃L$ 뷃L$밃0 w D$$z#*tAD$$G/y݃L$NjT$$:.t D$HBD$$J0 wD$$"D$*uBD$$D$|$yD$D$$htlt Lt@D$$D$$TBHu\ 1;\$$ @u=5DŽ$ t$$ P$ Ph8h7T$ Ãt(6l$ @uDŽ$ T$$ R$ Rh8h@81ɋT$<Ãt4u'6$ @u$ @ur $ $ $ $ $ @u$ @u=ك)M ƃv' ƃv%9\? ƃvFGuOf1Mủ=5DŽ@=DŽ  @=uDŽ @=u퍜$ @= uDŽ$ $ P$ Ph8h7 MÃ$ D@uDŽ$ $ P$ Ph8h@81ɺÃ$ ~ @uJ $ $ $ $ @u$ @uoT$t<tUIt6u?6Bw)УF 1oA6c6 66KL$ |$F 뎋D$뮋T$뛸Ĝ [^_]WVSt$|$ D$FD$=5F11ҹ+ 6 Buʀ1t1t1uAu=t 695Ft 69D$t 6 h6[^_command line: %s offsetDOSEMUchfloppyharddiskMEMDISK: Image has fractional end sector MEMDISK: Image seems to have fractional end cylinder MEMDISK: Image appears to be truncated internal error: check_zip returned nonsense Moving compressed data from 0x%08x to 0x%08x gzip image: decompressed addr 0x%08x, len 0x%08x: Not enough memory to decompress image (need 0x%08x bytes) %s %s MEMDISK: No ramdisk image specified! Ramdisk at 0x%08x, length 0x%08x noeddnoebioscbiosonoffhard diskDisk is %s %d, %u K, C/H/S = %u/%u/%u, EDD %s roMarking disk readonly Using raw access to high memory safeintUsing safe INT 15h access to high memory bigrawUsing raw access to high memory - assuming big real mode Total size needed = %u bytes, allocating %uK MEMDISK: Insufficient low memory Old dos memory at 0x%05x (map says 0x%05x), loading at 0x%05x 1588: 0x%04x 15E801: 0x%04x 0x%04x nopassnopass specified - we're the only drive INT 13 08: Failure, assuming this is the only drive INT 13 08: Success, count = %u, BPT = %04x:%04x BIOS equipment byte says count = %d, go with that old: int13 = %08x int15 = %08x new: int13 = %08x int15 = %08x Loading boot sector... MEMDISK: Failed to load new boot sector pausepress any key to boot... booting... MEMDISK 3.63 2008-04-10Copyright 2001-2007 H. Peter Anvin( P ` P@ P Pt RP$P0e820: %08x%08x %08x%08x %d DOS: %d K e801: %04x %04x 88: %04x MEMDISK: Unable to obtain memory map 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzfailed Decompression error: %s gzip file uses invalid methodgzip file is encrypted; not supportedgzip file is a continuation file; not supportedgzip file has unsupported flagsgzip file corruptpkzip file is encrypted; not supportedpkzip file uses data_descriptor field; not supportedpkzip file has unsupported flagspkzip file uses invalid methodpkzip file corruptoutput buffer overrunfailed Decompression error: ran out of input data malloc errorout of memory incomplete literal tree incomplete distance treeinvalid compressed format (err=1)invalid compressed format (err=2)invalid compressed format (other)uncompressed data length errorcrc errorok       ?? #+3;CScscc !1Aa  0@` |L{.f&B.H.FȎ.&RR.2 Zx tM.: r.H.U.>It.>IuFuVPfSF.fBGf[X].f&B؎Hf`:&w_0F1ێË&' fBGfa.f&B1x &tn&>uvdXfa.f&B..Z tCVN^X11'Fuf1ÊV uFN  ^H FHF~MEu1~MDu*~ISu#~K?uF!MFEMFDIFSKN F1Á~U5FUF0FX11f11ÎF"~$& r9rȫII1øfNfـ?fK;sOf~f9s@fff&f؋~N fffNfff f6f;wfXvF"&rf&f|t&f\&f|ffrD&f| uB&f\&f| u2&fL&ftffrf;wff f6føXø&dXøfPAMSfrcf!ufL fGf!t&fEfG&ffO&fMffOf+GfO&fE&fM fuf1ffF]F]U= z=t=tt(].....ff.ff.fPfSfRfUu 1>T|u 9Vuff1یffgf1H&3У&3У Ru$. "ێgfڎ$"Z!u$f]fVfWfQf@vf@fQf6f&f>f&fXfYf_f^rfg4fg Our drive, adjust drive # .nomatch: mov ax,[cs:SavedAX] pushf call far [cs:OldInt13] pushf push bp mov bp,sp cmp byte [cs:SavedAX+1],08h je .norestoredl cmp byte [cs:SavedAX+1],15h jne .restoredl test byte [bp+4],80h ; Hard disk? jnz .norestoredl .restoredl: mov dl,[bp+4] .norestoredl: push ax push ebx push ds mov ax,[bp+2] ; Flags lds ebx,[cs:Stack] mov [bx+4],al ; Arithmetric flags pop ds pop ebx pop ax pop bp lss esp,[cs:Stack] .iret: iret .our_drive: ; Set up standard entry frame push ds push es mov ds,ax mov es,ax mov ax,[SavedAX] pushad mov bp,sp ; Point BP to the entry stack frame TRACER 'F' ; Note: AH == P_AH here cmp ah,[Int13MaxFunc] ja Invalid_jump xor al,al ; AL = 0 is standard entry condition mov di,ax shr di,7 ; Convert AH to an offset in DI call [Int13Funcs+di] Done: ; Standard routine for return mov P_AX,ax DoneWeird: TRACER 'D' xor bx,bx mov es,bx mov bx,[StatusPtr] mov [es:bx],ah ; Save status and ah,ah lds ebx,[Stack] ; This sets the low byte (the arithmetric flags) of the ; FLAGS on stack to either 00h (no flags) or 01h (CF) ; depending on if AH was zero or not. setnz [bx+4] ; Set CF iff error popad pop es pop ds lss esp,[cs:Stack] iret Reset: ; Reset affects multiple drives, so we need to pass it on TRACER 'R' xor ax,ax ; Bottom of memory mov es,ax test dl,dl ; Always pass it on if we are resetting HD js .hard_disk ; Bit 7 set ; Some BIOSes get very unhappy if we pass a reset floppy ; command to them and don't actually have any floppies. ; This is a bug, but we have to deal with it nontheless. ; Therefore, if we are the *ONLY* floppy drive, and the ; user didn't request HD reset, then just drop the command. ; BIOS equipment byte, top two bits + 1 == total # of floppies test byte [es:0x410],0C0h jz success jmp .pass_on ; ... otherwise pass it to the BIOS .hard_disk: ; ... same thing for hard disks, sigh ... cmp byte [es:0x475],1 ; BIOS variable for number of hard disks jbe success .pass_on: pop ax ; Drop return address popad ; Restore all registers pop es pop ds lss esp,[cs:Stack] ; Restore the stack and dl,80h ; Clear all but the type bit jmp far [cs:OldInt13] Invalid: pop dx ; Drop return address Invalid_jump: TRACER 'I' mov ah,01h ; Unsupported function jmp short Done GetDriveType: test byte [DriveNo],80h mov bl,02h ; Type 02h = floppy with changeline jz .floppy ; Hard disks only... inc bx ; Type = 03h mov dx,[DiskSize] ; Return the disk size in sectors mov P_DX,dx mov cx,[DiskSize+2] mov P_CX,cx .floppy: mov P_AH,bl ; 02h floppy, 03h hard disk pop ax ; Drop return address xor ax,ax ; Success... jmp DoneWeird ; But don't stick it into P_AX GetStatus: xor ax,ax mov es,ax mov bx,[StatusPtr] mov ah,[bx] ; Copy last status ret ReadMult: TRACER 'm' Read: TRACER 'R' call setup_regs do_copy: TRACER '<' call bcopy TRACER '>' movzx ax,P_AL ; AH = 0, AL = transfer count ret WriteMult: TRACER 'M' Write: TRACER 'W' test byte [ConfigFlags],CONFIG_READONLY jnz .readonly call setup_regs xchg esi,edi ; Opposite direction of a Read! jmp short do_copy .readonly: mov ah,03h ; Write protected medium ret ; Verify integrity; just bounds-check Seek: Verify: call setup_regs ; Returns error if appropriate ; And fall through to success CheckIfReady: ; These are always-successful noop functions Recalibrate: InitWithParms: DetectChange: EDDDetectChange: EDDLock: SetMode: success: xor ax,ax ; Always successful ret GetParms: TRACER 'G' mov dl,[DriveCnt] ; Cached data mov P_DL,dl test byte [DriveNo],80h jnz .hd mov P_DI,DPT mov P_ES,cs mov bl,[DriveType] mov P_BL,bl .hd: mov ax,[Cylinders] dec ax ; We report the highest #, not the count xchg al,ah shl al,6 or al,[Sectors] mov P_CX,ax mov ax,[Heads] dec ax mov P_DH,al ; ; Is this MEMDISK installation check? ; cmp P_HAX,'ME' jne .notic cmp P_HCX,'MD' jne .notic cmp P_HDX,'IS' jne .notic cmp P_HBX,'K?' jne .notic ; MEMDISK installation check... mov P_HAX,'!M' mov P_HCX,'EM' mov P_HDX,'DI' mov P_HBX,'SK' mov P_ES,cs mov P_DI,MemDisk_Info .notic: xor ax,ax ret ; ; EDD functions -- only if enabled ; %if EDD EDDPresence: TRACER 'E' TRACER 'c' cmp P_BX,55AAh jne Invalid mov P_BX,0AA55h ; EDD signature mov P_AX,03000h ; EDD 3.0 mov P_CX,0003h ; Bit 0 - Fixed disk access subset ; Bit 1 - Locking and ejecting subset pop ax ; Drop return address xor ax,ax ; Success jmp DoneWeird ; Success, but AH != 0, sigh... EDDRead: TRACER 'E' TRACER 'r' call edd_setup_regs call bcopy xor ax,ax ret EDDWrite: TRACER 'E' TRACER 'w' call edd_setup_regs xchg esi,edi call bcopy xor ax,ax ret EDDVerify: EDDSeek: call edd_setup_regs ; Just bounds checking xor ax,ax ret EDDGetParms: TRACER 'E' TRACER 'p' mov es,P_DS mov di,P_SI mov si,EDD_DPT lodsw ; Length of our DPT mov cx,[es:di] cmp cx,26 ; Minimum size jb .overrun cmp cx,ax jb .oksize mov cx,ax .oksize: mov ax,cx stosw dec cx dec cx rep movsb xor ax,ax ret .overrun: mov ax,0100h ret %endif ; EDD ; Set up registers as for a "Read", and compares against disk size. ; WARNING: This fails immediately, even if we can transfer some ; sectors. This isn't really the correct behaviour. setup_regs: ; Convert a CHS address in P_CX/P_DH into an LBA in eax ; CH = cyl[7:0] ; CL[0:5] = sector (1-based) CL[7:6] = cyl[9:8] ; DH = head movzx ecx,P_CX movzx ebx,cl ; Sector number and bl,3Fh dec ebx ; Sector number is 1-based cmp bx,[Sectors] jae .overrun movzx edi,P_DH ; Head number movzx eax,word [Heads] cmp di,ax jae .overrun shr cl,6 xchg cl,ch ; Now (E)CX <- cylinder number mul ecx ; eax <- Heads*cyl# (edx <- 0) add eax,edi mul dword [Sectors] add eax,ebx ; Now eax = LBA, edx = 0 ; ; setup_regs continues... ; ; Note: edi[31:16] and ecx[31:16] = 0 already mov di,P_BX ; Get linear address of target buffer mov cx,P_ES shl ecx,4 add edi,ecx ; EDI = address to fetch to movzx ecx,P_AL ; Sector count mov esi,eax add eax,ecx ; LBA of final sector + 1 shl esi,SECTORSIZE_LG2 ; LBA -> byte offset add esi,[DiskBuf] ; Get address in high memory cmp eax,[DiskSize] ; Check the high mark against limit ja .overrun shl ecx,SECTORSIZE_LG2-2 ; Convert count to dwords ret .overrun: pop ax ; Drop setup_regs return address mov ax,0200h ; Missing address mark ret ; Return to Done ; Set up registers as for an EDD Read, and compares against disk size. %if EDD edd_setup_regs: push es mov si,P_SI ; DS:SI -> DAPA mov es,P_DS mov dx,[es:si] cmp dx,16 jb .baddapa cmp dword [es:si+4],-1 je .linear_address movzx ebx,word [es:si+4] ; Offset movzx edi,word [es:si+6] ; Segment shl edi,4 add ebx,edi jmp .got_address .linear_address: cmp dx,24 ; Must be large enough to hold ; linear address jb .baddapa cmp dword [es:si+20],0 ; > 4 GB addresses not supported mov ax,0900h ; "Data boundary error" - bogus, but ; no really better code available jne .error mov ebx,[es:si+16] .got_address: cmp dword [es:si+12],0 ; LBA too large? jne .overrun movzx ecx, word [es:si+2] ; Sectors to transfer mov esi,[es:si+8] ; Starting sector mov eax,esi add eax,ecx jc .overrun cmp eax,[DiskSize] ja .overrun shl ecx,SECTORSIZE_LG2-2 ; Convert to dwords shl esi,SECTORSIZE_LG2 ; Convert to an offset add esi,[DiskBuf] mov edi,ebx pop es ret .baddapa: mov ax,0100h ; Invalid command pop es pop ax ; Drop setup_regs return address ret .overrun: mov ax,0200h ; "Address mark not found" = ; LBA beyond end of disk .error: and word [es:si+2],0 ; No sectors transferred pop es pop ax ret EDDEject: mov ax,0B200h ; Volume Not Removable ret %endif ; EDD ; ; INT 15h intercept routines ; int15_e820: cmp edx,534D4150h ; "SMAP" jne near oldint15 cmp ecx,20 ; Need 20 bytes jb err86 push ds push cs pop ds and ebx,ebx jne .renew mov ebx,E820Table .renew: add bx,12 ; Advance to next mov eax,[bx-4] ; Type and eax,eax ; Null type? jz .renew ; If so advance to next mov [es:di+16],eax mov eax,[bx-12] ; Start addr (low) mov [es:di],eax mov ecx,[bx-8] ; Start addr (high) mov [es:di+4],ecx mov eax,[bx] ; End addr (low) mov ecx,[bx+4] ; End addr (high) sub eax,[bx-12] ; Derive the length sbb ecx,[bx-8] mov [es:di+8],eax ; Length (low) mov [es:di+12],ecx ; Length (high) cmp dword [bx+8],-1 ; Type of next = end? jne .notdone xor ebx,ebx ; Done with table .notdone: mov eax,edx ; "SMAP" pop ds mov ecx,20 ; Bytes loaded int15_success: mov byte [bp+6], 02h ; Clear CF pop bp iret err86: mov byte [bp+6], 03h ; Set CF mov ah,86h pop bp iret Int15Start: push bp mov bp,sp cmp ax,0E820h je near int15_e820 cmp ax,0E801h je int15_e801 cmp ax,0E881h je int15_e881 cmp ah,88h je int15_88 oldint15: pop bp jmp far [cs:OldInt15] int15_e801: mov ax,[cs:Mem1MB] mov cx,ax mov bx,[cs:Mem16MB] mov dx,bx jmp short int15_success int15_e881: mov eax,[cs:Mem1MB] mov ecx,eax mov ebx,[cs:Mem16MB] mov edx,ebx jmp short int15_success int15_88: mov ax,[cs:MemInt1588] jmp short int15_success ; ; Routine to copy in/out of high memory ; esi = linear source address ; edi = linear target address ; ecx = 32-bit word count ; ; Assumes cs = ds = es ; bcopy: push eax push ebx push edx push ebp mov bx, real_int15_stub test byte [ConfigFlags], CONFIG_RAW|CONFIG_SAFEINT jz .anymode smsw ax ; Unprivileged! test al,01h jnz .protmode .realmode: test byte [ConfigFlags], CONFIG_RAW jnz .raw ; We're in real mode with CONFIG_SAFEINT, invoke INT 15h ; directly if the vector is unchanged, otherwise invoke ; the *old* INT 15h vector. push ds xor ax, ax mov fs,ax cmp word [4*0x15], Int15Start jne .changed mov ax, cs cmp word [4*0x15+2], ax jne .changed pop ds jmp .anymode ; INT 15h unchanged, safe to execute .changed: ; INT 15h modified, execute *old* INT 15h pop ds mov bx, fake_int15_stub jmp .anymode .raw: TRACER 'r' ; We're in real mode, do it outselves pushfd ; push ds ; push es ; cli cld xor ebx,ebx mov bx,cs shl ebx,4 lea edx,[Shaker+ebx] mov [Shaker+2],edx ; Test to see if A20 is enabled or not xor ax,ax mov ds,ax dec ax mov es,ax mov ax,[0] mov bx,ax xor bx,[es:10h] not ax mov [0],ax mov dx,ax xor dx,[es:10h] not ax mov [0],ax or dx,bx push dx ; Save A20 status jnz .skip_a20e mov ax,2401h ; Enable A20 int 15h .skip_a20e: mov dl,[ConfigFlags] and dx,CONFIG_BIGRAW add dx,8 ; DX = 16 for BIGRAW, 8 for RAW ; 8 is selector for a 64K flat segment, ; 16 is selector for a 4GB flat segment. lgdt [cs:Shaker] mov eax,cr0 or al,01h mov cr0,eax mov bx,16 ; Large flat segment mov ds,bx mov es,bx a32 rep movsd ; DX has the appropriate value to put in ; the registers on return mov ds,dx mov es,dx and al,~01h mov cr0,eax pop dx ; A20 status pop es ; pop ds ; and dx,dx jnz .skip_a20d mov ax,2400h ; Disable A20 int 15h .skip_a20d: popfd ; jmp .done .protmode: TRACER 'p' .anymode: .copy_loop: push esi push edi push ecx cmp ecx,4000h jna .safe_size mov ecx,4000h .safe_size: push ecx ; Transfer size this cycle mov eax, esi mov [Mover_src1], si shr eax, 16 mov [Mover_src1+2], al mov [Mover_src2], ah mov eax, edi mov [Mover_dst1], di shr eax, 16 mov [Mover_dst1+2], al mov [Mover_dst2], ah mov si,Mover mov ah, 87h shl cx,1 ; Convert to 16-bit words call bx ; INT 15h stub pop eax ; Transfer size this cycle pop ecx pop edi pop esi jc .error lea esi,[esi+4*eax] lea edi,[edi+4*eax] sub ecx, eax jnz .copy_loop ; CF = 0 .error: .done: pop ebp pop edx pop ebx pop eax ret real_int15_stub: int 15h cli ; Some BIOSes enable interrupts on INT 15h ret fake_int15_stub: pushf call far [OldInt15] cli ret %ifdef DEBUG_TRACERS debug_tracer: pushad pushfd mov bp,sp mov bx,[bp+9*4] mov al,[cs:bx] inc word [bp+9*4] mov ah,0Eh mov bx,7 int 10h popfd popad ret %endif section .data alignb 2 Int13Funcs dw Reset ; 00h - RESET dw GetStatus ; 01h - GET STATUS dw Read ; 02h - READ dw Write ; 03h - WRITE dw Verify ; 04h - VERIFY dw Invalid ; 05h - FORMAT TRACK dw Invalid ; 06h - FORMAT TRACK AND SET BAD FLAGS dw Invalid ; 07h - FORMAT DRIVE AT TRACK dw GetParms ; 08h - GET PARAMETERS dw InitWithParms ; 09h - INITIALIZE CONTROLLER WITH DRIVE PARAMETERS dw Invalid ; 0Ah dw Invalid ; 0Bh dw Seek ; 0Ch - SEEK TO CYLINDER dw Reset ; 0Dh - RESET HARD DISKS dw Invalid ; 0Eh dw Invalid ; 0Fh dw CheckIfReady ; 10h - CHECK IF READY dw Recalibrate ; 11h - RECALIBRATE dw Invalid ; 12h dw Invalid ; 13h dw Invalid ; 14h dw GetDriveType ; 15h - GET DRIVE TYPE dw DetectChange ; 16h - DETECT DRIVE CHANGE %if EDD dw Invalid ; 17h dw Invalid ; 18h dw Invalid ; 19h dw Invalid ; 1Ah dw Invalid ; 1Bh dw Invalid ; 1Ch dw Invalid ; 1Dh dw Invalid ; 1Eh dw Invalid ; 1Fh dw Invalid ; 20h dw ReadMult ; 21h - READ MULTIPLE dw WriteMult ; 22h - WRITE MULTIPLE dw SetMode ; 23h - SET CONTROLLER FEATURES dw SetMode ; 24h - SET MULTIPLE MODE dw Invalid ; 25h - IDENTIFY DRIVE dw Invalid ; 26h dw Invalid ; 27h dw Invalid ; 28h dw Invalid ; 29h dw Invalid ; 2Ah dw Invalid ; 2Bh dw Invalid ; 2Ch dw Invalid ; 2Dh dw Invalid ; 2Eh dw Invalid ; 2Fh dw Invalid ; 30h dw Invalid ; 31h dw Invalid ; 32h dw Invalid ; 33h dw Invalid ; 34h dw Invalid ; 35h dw Invalid ; 36h dw Invalid ; 37h dw Invalid ; 38h dw Invalid ; 39h dw Invalid ; 3Ah dw Invalid ; 3Bh dw Invalid ; 3Ch dw Invalid ; 3Dh dw Invalid ; 3Eh dw Invalid ; 3Fh dw Invalid ; 40h dw EDDPresence ; 41h - EDD PRESENCE DETECT dw EDDRead ; 42h - EDD READ dw EDDWrite ; 43h - EDD WRITE dw EDDVerify ; 44h - EDD VERIFY dw EDDLock ; 45h - EDD LOCK/UNLOCK MEDIA dw EDDEject ; 46h - EDD EJECT dw EDDSeek ; 47h - EDD SEEK dw EDDGetParms ; 48h - EDD GET PARAMETERS dw EDDDetectChange ; 49h - EDD MEDIA CHANGE STATUS %endif Int13FuncsEnd equ $ Int13FuncsCnt equ (Int13FuncsEnd-Int13Funcs) >> 1 alignb 8, db 0 Shaker dw ShakerEnd-$ dd 0 ; Pointer to self dw 0 Shaker_RMDS: dd 0x0000ffff ; 64K data segment dd 0x00009300 Shaker_DS: dd 0x0000ffff ; 4GB data segment dd 0x008f9300 ShakerEnd equ $ alignb 8, db 0 Mover dd 0, 0, 0, 0 ; Must be zero dw 0ffffh ; 64 K segment size Mover_src1: db 0, 0, 0 ; Low 24 bits of source addy db 93h ; Access rights db 00h ; Extended access rights Mover_src2: db 0 ; High 8 bits of source addy dw 0ffffh ; 64 K segment size Mover_dst1: db 0, 0, 0 ; Low 24 bits of target addy db 93h ; Access rights db 00h ; Extended access rights Mover_dst2: db 0 ; High 8 bits of source addy Mover_dummy2: dd 0, 0, 0, 0 ; More space for the BIOS alignb 4, db 0 MemDisk_Info equ $ ; Pointed to by installation check MDI_Bytes dw 27 ; Total bytes in MDI structure MDI_Version db VER_MINOR, VER_MAJOR ; MEMDISK version PatchArea equ $ ; This gets filled in by the installer DiskBuf dd 0 ; Linear address of high memory disk DiskSize dd 0 ; Size of disk in blocks CommandLine dw 0, 0 ; Far pointer to saved command line OldInt13 dd 0 ; INT 13h in chain OldInt15 dd 0 ; INT 15h in chain OldDosMem dw 0 ; Old position of DOS mem end BootLoaderID db 0 ; Boot loader ID from header ; ---- MDI structure ends here --- Int13MaxFunc db Int13FuncsCnt-1 ; Max INT 13h function (to disable EDD) db 0, 0 ; pad MemInt1588 dw 0 ; 1MB-65MB memory amount (1K) Cylinders dw 0 ; Cylinder count Heads dw 0 ; Head count Sectors dd 0 ; Sector count (zero-extended) Mem1MB dd 0 ; 1MB-16MB memory amount (1K) Mem16MB dd 0 ; 16MB-4G memory amount (64K) DriveNo db 0 ; Our drive number DriveType db 0 ; Our drive type (floppies) DriveCnt db 0 ; Drive count (from the BIOS) ConfigFlags db 0 ; Bit 0 - readonly MyStack dw 0 ; Offset of stack StatusPtr dw 0 ; Where to save status (zeroseg ptr) DPT times 16 db 0 ; BIOS parameter table pointer (floppies) %if EDD EDD_DPT: .length dw 30 .info dw 0029h ; Bit 0 - DMA boundaries handled transparently ; Bit 3 - Device supports write verify ; Bit 5 - Media is lockable .cylinders dd 0 ; Filled in by installer .heads dd 0 ; Filled in by installer .sectors dd 0 ; Filled in by installer .totalsize dd 0, 0 ; Filled in by installer .bytespersec dw SECTORSIZE .eddtable dw -1, -1 ; Invalid DPTE pointer %endif ; End patch area Stack dd 0 ; Saved SS:ESP on invocation dw 0 SavedAX dw 0 ; AX saved on invocation alignb 4, db 0 ; We *MUST* end on a dword boundary E820Table equ $ ; The installer loads the E820 table here TotalSize equ $ ; End pointer syslinux-legacy-3.63+dfsg/memdisk/Makefile0000664000175000017500000000677210777447273017321 0ustar evanevan## ----------------------------------------------------------------------- ## ## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- VERSION := $(shell cat ../version) TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \ then echo $(1); else echo $(2); fi; rm -f $$tmpf) M32 := $(call gcc_ok,-m32,) ALIGN := $(call gcc_ok,-falign-functions=0 -falign-jumps=0 -falign-loops=0,-malign-functions=0 -malign-jumps=0 -malign-loops=0) FREE := $(call gcc_ok,-ffreestanding,) $(call gcc_ok,-fno-stack-protector,) CC = gcc CFLAGS = $(M32) $(FREE) -g -W -Wall -Wno-sign-compare \ -Os -fomit-frame-pointer -march=i386 $(ALIGN) \ -DVERSION='"$(VERSION)"' -DDATE='"$(DATE)"' SFLAGS = $(M32) -march=i386 -D__ASSEMBLY__ LDFLAGS = $(M32) -g INCLUDE = -I../com32/include LD = ld -m elf_i386 NASM = nasm NASMOPT = -O9999 NFLAGS = -dVERSION='"$(VERSION)"' -dDATE='"$(DATE)"' -dWITH_EDD NINCLUDE = OBJCOPY = objcopy PERL = perl # Important: init.o16 must be first!! OBJS16 = init.o16 init32.o OBJS32 = start32.o setup.o msetup.o e820func.o conio.o memcpy.o memset.o \ unzip.o memdisk.o CSRC = setup.c msetup.c e820func.c conio.c unzip.c SSRC = start32.S memcpy.S memset.S NASMSRC = memdisk.asm memdisk16.asm all: memdisk # e820test # tidy, clean removes everything except the final binary tidy: rm -f *.o *.s *.o16 *.s16 *.bin *.lst *.elf e820test clean: tidy # spotless also removes the product binary spotless: clean rm -f memdisk .depend %.o: %.asm $(NASM) $(NASMOPT) $(NFLAGS) $(NINCLUDE) -f elf -l $*.lst -o $@ $< %.o: %.s $(CC) $(SFLAGS) -c -o $@ $< %.o: %.S $(CC) $(INCLUDE) $(SFLAGS) -c -o $@ $< %.o16: %.s16 $(CC) $(SFLAGS) -x assembler -c -o $@ $< %.o: %.c $(CC) $(INCLUDE) $(CFLAGS) -c -o $@ $< %.s16: %.s echo '.code16gcc' | cat - $< > $@ %.s: %.S $(CC) $(INCLUDE) $(SFLAGS) -E -o $@ $< %.s16: %.S16 $(CC) $(INCLUDE) $(SFLAGS) -x assembler-with-cpp -E -o $@ $< %.s: %.c $(CC) $(INCLUDE) $(CFLAGS) -S -o $@ $< %.i: %.c $(CC) $(INCLUDE) $(CFLAGS) -E -o $@ $< # Cancel default rule %.o: %.c %.bin: %.asm $(NASM) -f bin $(NASMOPT) $(NFLAGS) $(NINCLUDE) -o $@ -l $*.lst $< memdisk16.elf: $(OBJS16) $(LD) -Ttext 0 -o $@ $^ memdisk32.elf: $(OBJS32) $(LD) -Ttext 0x100000 -o $@ $^ %.bin: %.elf $(OBJCOPY) -O binary $< $@ memdisk: memdisk16.bin memdisk32.bin postprocess.pl $(PERL) postprocess.pl $@ memdisk16.bin memdisk32.bin e820test: e820func.o msetup.o e820test.o memdisk.o $(CC) $(LDFLAGS) -o $@ $^ memdisk.o: memdisk.bin $(LD) -r -b binary -o $@ $< .depend: rm -f .depend for csrc in *.c ; do $(CC) $(INCLUDE) $(CFLAGS) -MM $$csrc >> .depend ; done for ssrc in *.S ; do $(CC) $(INCLUDE) $(SFLAGS) -MM $$ssrc >> .depend ; done for nsrc in $(NASMSRC) ; do $(NASM) -DDEPEND $(NINCLUDE) -o `echo $$nsrc | sed -e 's/\.asm/\.bin/'` -M $$nsrc >> .depend ; done depend: rm -f .depend $(MAKE) .depend # This file contains the version number, so add a dependency for it setup.s: ../version # Include dependencies file include .depend syslinux-legacy-3.63+dfsg/memdisk/version.h0000664000175000017500000000134710777447273017510 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2002-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * version.h * * MEMDISK version data */ #ifndef MEMDISK_VERSION_H #define MEMDISK_VERSION_H #define FIRSTYEAR "2001" #define COPYYEAR "2007" #endif syslinux-legacy-3.63+dfsg/memdisk/conio.c0000664000175000017500000001636010777447273017126 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * conio.c * * Output to the screen */ #include #include "memdisk.h" #include "conio.h" int putchar(int ch) { com32sys_t regs; if ( ch == '\n' ) { /* \n -> \r\n */ putchar('\r'); } regs.eax.w[0] = 0x0e00|(ch&0xff); syscall(0x10, ®s, NULL); return ch; } int puts(const char *s) { int count = 0; while ( *s ) { putchar(*s); count++; s++; } return count; } /* * Oh, it's a waste of space, but oh-so-yummy for debugging. It's just * initialization code anyway, so it doesn't take up space when we're * actually running. This version of printf() does not include 64-bit * support. "Live with it." * * Most of this code was shamelessly snarfed from the Linux kernel, then * modified. */ static inline int isdigit(int ch) { return (ch >= '0') && (ch <= '9'); } static int skip_atoi(const char **s) { int i=0; while (isdigit(**s)) i = i*10 + *((*s)++) - '0'; return i; } unsigned int atou(const char *s) { unsigned int i = 0; while (isdigit(*s)) i = i*10 + (*s++ - '0'); return i; } static int strnlen(const char *s, int maxlen) { const char *es = s; while ( *es && maxlen ) { es++; maxlen--; } return (es-s); } #define ZEROPAD 1 /* pad with zero */ #define SIGN 2 /* unsigned/signed long */ #define PLUS 4 /* show plus */ #define SPACE 8 /* space if plus */ #define LEFT 16 /* left justified */ #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ #define do_div(n,base) ({ \ int __res; \ __res = ((unsigned long) n) % (unsigned) base; \ n = ((unsigned long) n) / (unsigned) base; \ __res; }) static char * number(char * str, long num, int base, int size, int precision ,int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; int i; if (type & LARGE) digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (type & LEFT) type &= ~ZEROPAD; if (base < 2 || base > 36) return 0; c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if (type & SIGN) { if (num < 0) { sign = '-'; num = -num; size--; } else if (type & PLUS) { sign = '+'; size--; } else if (type & SPACE) { sign = ' '; size--; } } if (type & SPECIAL) { if (base == 16) size -= 2; else if (base == 8) size--; } i = 0; if (num == 0) tmp[i++]='0'; else while (num != 0) tmp[i++] = digits[do_div(num,base)]; if (i > precision) precision = i; size -= precision; if (!(type&(ZEROPAD+LEFT))) while(size-->0) *str++ = ' '; if (sign) *str++ = sign; if (type & SPECIAL) { if (base==8) *str++ = '0'; else if (base==16) { *str++ = '0'; *str++ = digits[33]; } } if (!(type & LEFT)) while (size-- > 0) *str++ = c; while (i < precision--) *str++ = '0'; while (i-- > 0) *str++ = tmp[i]; while (size-- > 0) *str++ = ' '; return str; } /* Forward decl. needed for IP address printing stuff... */ int sprintf(char * buf, const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args) { int len; unsigned long num; int i, base; char * str; const char *s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ for (str=buf ; *fmt ; ++fmt) { if (*fmt != '%') { *str++ = *fmt; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (isdigit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (isdigit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); } if (precision < 0) precision = 0; } /* get the conversion qualifier */ qualifier = -1; if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { qualifier = *fmt; ++fmt; } /* default base */ base = 10; switch (*fmt) { case 'c': if (!(flags & LEFT)) while (--field_width > 0) *str++ = ' '; *str++ = (unsigned char) va_arg(args, int); while (--field_width > 0) *str++ = ' '; continue; case 's': s = va_arg(args, char *); len = strnlen(s, precision); if (!(flags & LEFT)) while (len < field_width--) *str++ = ' '; for (i = 0; i < len; ++i) *str++ = *s++; while (len < field_width--) *str++ = ' '; continue; case 'p': if (field_width == -1) { field_width = 2*sizeof(void *); flags |= ZEROPAD; } str = number(str, (unsigned long) va_arg(args, void *), 16, field_width, precision, flags); continue; case 'n': if (qualifier == 'l') { long * ip = va_arg(args, long *); *ip = (str - buf); } else { int * ip = va_arg(args, int *); *ip = (str - buf); } continue; case '%': *str++ = '%'; continue; /* integer number formats - set up the flags and "break" */ case 'o': base = 8; break; case 'X': flags |= LARGE; case 'x': base = 16; break; case 'd': case 'i': flags |= SIGN; case 'u': break; default: *str++ = '%'; if (*fmt) *str++ = *fmt; else --fmt; continue; } if (qualifier == 'l') num = va_arg(args, unsigned long); else if (qualifier == 'h') { num = (unsigned short) va_arg(args, int); if (flags & SIGN) num = (short) num; } else if (flags & SIGN) num = va_arg(args, int); else num = va_arg(args, unsigned int); str = number(str, num, base, field_width, precision, flags); } *str = '\0'; return str-buf; } int sprintf(char * buf, const char *fmt, ...) { va_list args; int i; va_start(args, fmt); i=vsprintf(buf,fmt,args); va_end(args); return i; } int printf(const char *fmt, ...) { char printf_buf[1024]; va_list args; int printed; va_start(args, fmt); printed = vsprintf(printf_buf, fmt, args); va_end(args); puts(printf_buf); return printed; } syslinux-legacy-3.63+dfsg/memdisk/conio.h0000664000175000017500000000150510777447273017126 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * conio.h * * Limited console I/O */ #ifndef CONIO_H #define CONIO_H #include #include #include int putchar(int); int puts(const char *); int printf(const char *, ...); unsigned int atou(const char *); #endif syslinux-legacy-3.63+dfsg/memdisk/memset.S0000664000175000017500000000057210777447273017267 0ustar evanevan# # memset.S # # Simple memset() implementation # .text .globl memset .type memset, @function memset: cld pushl %edi pushl %esi movl 12(%esp),%edi movzbl 16(%esp),%eax movl 20(%esp),%esi imull $0x01010101,%eax movl %esi,%ecx shrl $2,%ecx rep ; stosl movl %esi,%ecx andl $3,%ecx rep ; stosb movl 12(%esp),%eax popl %esi popl %edi ret .size memcpy,.-memcpy syslinux-legacy-3.63+dfsg/memdisk/testdata10000664000175000017500000000066110777447273017465 0ustar evanevan0000000000000000 000000000009bc00 1 000000000009bc00 0000000000004400 2 00000000000e9800 0000000000016800 2 0000000000100000 0000000006ee0000 1 0000000006fe0000 000000000000fc00 3 0000000006fefc00 0000000000000400 4 0000000006ff0000 0000000000002000 2 0000000006ff2000 000000000000e000 1 0000000007000000 0000000000100000 2 00000000fff00000 0000000000100000 2 0000000000586000 0000000000168000 2 000000000009ba00 0000000000000200 2 syslinux-legacy-3.63+dfsg/memdisk/unzip.c0000664000175000017500000002354710777447273017171 0ustar evanevan/* * unzip.c * * This is a collection of several routines from gzip-1.0.3 * adapted for Linux. * * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 * puts by Nick Holloway 1993, better puts by Martin Mares 1995 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 * * Adapted for MEMDISK by H. Peter Anvin, April 2003 */ #include #include "memdisk.h" #include "conio.h" /* * gzip declarations */ #define OF(args) args #define STATIC static #define memzero(s, n) memset ((s), 0, (n)) typedef uint8_t uch; typedef uint16_t ush; typedef uint32_t ulg; #define WSIZE 0x8000 /* Window size must be at least 32k, */ /* and a power of two */ static uch *inbuf; /* input pointer */ static uch window[WSIZE]; /* sliding output window buffer */ static unsigned insize; /* total input bytes read */ static unsigned inbytes; /* valid bytes in inbuf */ static unsigned outcnt; /* bytes in output buffer */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ #define RESERVED 0xC0 /* bit 6,7: reserved */ /* Diagnostic functions */ #ifdef DEBUG # define Assert(cond,msg) {if(!(cond)) error(msg);} # define Trace(x) fprintf x # define Tracev(x) {if (verbose) fprintf x ;} # define Tracevv(x) {if (verbose>1) fprintf x ;} # define Tracec(c,x) {if (verbose && (c)) fprintf x ;} # define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} #else # define Assert(cond,msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) #endif static int fill_inbuf(void); static void flush_window(void); static void error(char *m); static void gzip_mark(void **); static void gzip_release(void **); static ulg crc_32_tab[256]; /* Get byte from input buffer */ static inline uch get_byte(void) { if ( inbytes ) { uch b = *inbuf++; inbytes--; return b; } else { return fill_inbuf(); /* Input buffer underrun */ } } /* Unget byte from input buffer */ static inline void unget_byte(void) { inbytes++; inbuf--; } static ulg bytes_out = 0; /* Number of bytes output */ static uch *output_data; /* Output data pointer */ static ulg output_size; /* Number of output bytes expected */ static void *malloc(int size); static void free(void *where); static ulg free_mem_ptr, free_mem_end_ptr; #include "inflate.c" static void *malloc(int size) { void *p; if (size < 0) error("malloc error"); free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ p = (void *)free_mem_ptr; free_mem_ptr += size; if (free_mem_ptr >= free_mem_end_ptr) error("out of memory"); return p; } static void free(void *where) { /* Don't care */ (void)where; } static void gzip_mark(void **ptr) { *ptr = (void *) free_mem_ptr; } static void gzip_release(void **ptr) { free_mem_ptr = (long) *ptr; } /* =========================================================================== * Fill the input buffer. This is called only when the buffer is empty * and at least one byte is really needed. */ static int fill_inbuf(void) { /* This should never happen. We have already pointed the algorithm to all the data we have. */ printf("failed\nDecompression error: ran out of input data\n"); die(); } /* =========================================================================== * Write the output window window[0..outcnt-1] and update crc and bytes_out. * (Used for the decompressed data only.) */ static void flush_window(void) { ulg c = crc; /* temporary variable */ unsigned n; uch *in, *out, ch; if ( bytes_out+outcnt > output_size ) error("output buffer overrun"); in = window; out = output_data; for (n = 0; n < outcnt; n++) { ch = *out++ = *in++; c = crc_32_tab[(c ^ ch) & 0xff] ^ (c >> 8); } crc = c; output_data = out; bytes_out += (ulg)outcnt; outcnt = 0; } static void error(char *x) { printf("failed\nDecompression error: %s\n", x); die(); } /* GZIP header */ struct gzip_header { uint16_t magic; uint8_t method; uint8_t flags; uint32_t timestamp; uint8_t extra_flags; uint8_t os_type; } __attribute__ ((packed)); /* (followed by optional and variable length "extra", "original name", and "comment" fields) */ struct gzip_trailer { uint32_t crc; uint32_t dbytes; } __attribute__ ((packed)); /* PKZIP header. See * . */ struct pkzip_header { uint32_t magic; uint16_t version; uint16_t flags; uint16_t method; uint16_t modified_time; uint16_t modified_date; uint32_t crc; uint32_t zbytes; uint32_t dbytes; uint16_t filename_len; uint16_t extra_len; } __attribute__ ((packed)); /* (followed by optional and variable length "filename" and "extra" fields) */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ #define RESERVED 0xC0 /* bit 6,7: reserved */ /* pkzip flag byte */ #define PK_ENCRYPTED 0x01 /* bit 0 set: file is encrypted */ #define PK_DATADESC 0x08 /* bit 3 set: file has trailing "data descriptor" */ #define PK_UNSUPPORTED 0xFFF0 /* All other bits must be zero */ /* Return 0 if (indata, size) points to a ZIP file, and fill in compressed data size, uncompressed data size, CRC, and offset of data. If indata is not a ZIP file, return -1. */ int check_zip(void *indata, uint32_t size, uint32_t *zbytes_p, uint32_t *dbytes_p, uint32_t *orig_crc, uint32_t *offset_p) { struct gzip_header *gzh = (struct gzip_header *)indata; struct pkzip_header *pkzh = (struct pkzip_header *)indata; uint32_t offset; if (gzh->magic == 0x8b1f) { struct gzip_trailer *gzt = indata + size - sizeof (struct gzip_trailer); /* We only support method #8, DEFLATED */ if (gzh->method != 8) { error("gzip file uses invalid method"); return -1; } if (gzh->flags & ENCRYPTED) { error("gzip file is encrypted; not supported"); return -1; } if (gzh->flags & CONTINUATION) { error("gzip file is a continuation file; not supported"); return -1; } if (gzh->flags & RESERVED) { error("gzip file has unsupported flags"); return -1; } offset = sizeof (*gzh); if (gzh->flags & EXTRA_FIELD) { /* Skip extra field */ unsigned len = *(unsigned *)(indata + offset); offset += 2 + len; } if (gzh->flags & ORIG_NAME) { /* Discard the old name */ uint8_t *p = indata; while (p[offset] != 0 && offset < size) { offset++; } offset++; } if (gzh->flags & COMMENT) { /* Discard the comment */ uint8_t *p = indata; while (p[offset] != 0 && offset < size) { offset++; } offset++; } if (offset > size) { error ("gzip file corrupt"); return -1; } *zbytes_p = size - offset - sizeof (struct gzip_trailer); *dbytes_p = gzt->dbytes; *orig_crc = gzt->crc; *offset_p = offset; return 0; } else if (pkzh->magic == 0x04034b50UL) { /* Magic number matches pkzip file. */ offset = sizeof (*pkzh); if (pkzh->flags & PK_ENCRYPTED) { error("pkzip file is encrypted; not supported"); return -1; } if (pkzh->flags & PK_DATADESC) { error("pkzip file uses data_descriptor field; not supported"); return -1; } if (pkzh->flags & PK_UNSUPPORTED) { error("pkzip file has unsupported flags"); return -1; } /* We only support method #8, DEFLATED */ if (pkzh->method != 8) { error("pkzip file uses invalid method"); return -1; } /* skip header */ offset = sizeof (*pkzh); /* skip filename */ offset += pkzh->filename_len; /* skip extra field */ offset += pkzh->extra_len; if (offset + pkzh->zbytes > size) { error ("pkzip file corrupt"); return -1; } *zbytes_p = pkzh->zbytes; *dbytes_p = pkzh->dbytes; *orig_crc = pkzh->crc; *offset_p = offset; return 0; } else { /* Magic number does not match. */ return -1; } error ("Internal error in check_zip"); return -1; } /* * Decompress the image, trying to flush the end of it as close * to end_mem as possible. Return a pointer to the data block, * and change datalen. */ extern void _end; void *unzip(void *indata, uint32_t zbytes, uint32_t dbytes, uint32_t orig_crc, void *target) { /* Set up the heap; it's the 64K after the bounce buffer */ free_mem_ptr = (ulg)sys_bounce + 0x10000; free_mem_end_ptr = free_mem_ptr + 0x10000; /* Set up input buffer */ inbuf = indata; /* Sometimes inflate() looks beyond the end of the compressed data, but it always backs up before it is done. So we give it 4 bytes of slack. */ insize = inbytes = zbytes + 4; /* Set up output buffer */ outcnt = 0; output_data = target; output_size = dbytes; bytes_out = 0; makecrc(); gunzip(); /* Verify that gunzip() consumed the entire input. */ if (inbytes != 4) error("compressed data length error"); /* Check the uncompressed data length and CRC. */ if ( bytes_out != dbytes ) error("uncompressed data length error"); if (orig_crc != CRC_VALUE) error("crc error"); puts("ok\n"); return target; } syslinux-legacy-3.63+dfsg/memdisk/inflate.c0000664000175000017500000010366510777447273017446 0ustar evanevan#define DEBG(x) #define DEBG1(x) /* inflate.c -- Not copyrighted 1992 by Mark Adler version c10p1, 10 January 1993 */ /* * Adapted for booting Linux by Hannu Savolainen 1993 * based on gzip-1.0.3 * * Nicolas Pitre , 1999/04/14 : * Little mods for all variable to reside either into rodata or bss segments * by marking constant variables with 'const' and initializing all the others * at run-time only. This allows for the kernel uncompressor to run * directly from Flash or ROM memory on embedded systems. * * Adapted for MEMDISK by H. Peter Anvin, April 2003 */ /* Inflate deflated (PKZIP's method 8 compressed) data. The compression method searches for as much of the current string of bytes (up to a length of 258) in the previous 32 K bytes. If it doesn't find any matches (of at least length 3), it codes the next byte. Otherwise, it codes the length of the matched string and its distance backwards from the current position. There is a single Huffman code that codes both single bytes (called "literals") and match lengths. A second Huffman code codes the distance information, which follows a length code. Each length or distance code actually represents a base value and a number of "extra" (sometimes zero) bits to get to add to the base value. At the end of each deflated block is a special end-of-block (EOB) literal/ length code. The decoding process is basically: get a literal/length code; if EOB then done; if a literal, emit the decoded byte; if a length then get the distance and emit the referred-to bytes from the sliding window of previously emitted data. There are (currently) three kinds of inflate blocks: stored, fixed, and dynamic. The compressor deals with some chunk of data at a time, and decides which method to use on a chunk-by-chunk basis. A chunk might typically be 32 K or 64 K. If the chunk is incompressible, then the "stored" method is used. In this case, the bytes are simply stored as is, eight bits per byte, with none of the above coding. The bytes are preceded by a count, since there is no longer an EOB code. If the data is compressible, then either the fixed or dynamic methods are used. In the dynamic method, the compressed data is preceded by an encoding of the literal/length and distance Huffman codes that are to be used to decode this block. The representation is itself Huffman coded, and so is preceded by a description of that code. These code descriptions take up a little space, and so for small blocks, there is a predefined set of codes, called the fixed codes. The fixed method is used if the block codes up smaller that way (usually for quite small chunks), otherwise the dynamic method is used. In the latter case, the codes are customized to the probabilities in the current block, and so can code it much better than the pre-determined fixed codes. The Huffman codes themselves are decoded using a multi-level table lookup, in order to maximize the speed of decoding plus the speed of building the decoding tables. See the comments below that precede the lbits and dbits tuning parameters. */ /* Notes beyond the 1.93a appnote.txt: 1. Distance pointers never point before the beginning of the output stream. 2. Distance pointers can point back across blocks, up to 32k away. 3. There is an implied maximum of 7 bits for the bit length table and 15 bits for the actual data. 4. If only one code exists, then it is encoded using one bit. (Zero would be more efficient, but perhaps a little confusing.) If two codes exist, they are coded using one bit each (0 and 1). 5. There is no way of sending zero distance codes--a dummy must be sent if there are none. (History: a pre 2.0 version of PKZIP would store blocks with no distance codes, but this was discovered to be too harsh a criterion.) Valid only for 1.93a. 2.04c does allow zero distance codes, which is sent as one code of zero bits in length. 6. There are up to 286 literal/length codes. Code 256 represents the end-of-block. Note however that the static length tree defines 288 codes just to fill out the Huffman codes. Codes 286 and 287 cannot be used though, since there is no length base or extra bits defined for them. Similarly, there are up to 30 distance codes. However, static trees define 32 codes (all 5 bits) to fill out the Huffman codes, but the last two had better not show up in the data. 7. Unzip can check dynamic Huffman blocks for complete code sets. The exception is that a single code would not be complete (see #4). 8. The five bits following the block type is really the number of literal codes sent minus 257. 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits (1+6+6). Therefore, to output three times the length, you output three codes (1+1+1), whereas to output four times the same length, you only need two codes (1+3). Hmm. 10. In the tree reconstruction algorithm, Code = Code + Increment only if BitLength(i) is not zero. (Pretty obvious.) 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) 12. Note: length code 284 can represent 227-258, but length code 285 really is 258. The last length deserves its own, short code since it gets used a lot in very redundant files. The length 258 is special since 258 - 3 (the min match length) is 255. 13. The literal/length and distance code bit lengths are read as a single stream of lengths. It is possible (and advantageous) for a repeat code (16, 17, or 18) to go across the boundary between the two sets of lengths. */ #ifdef RCSID static char rcsid[] = "#Id: inflate.c,v 0.14 1993/06/10 13:27:04 jloup Exp #"; #endif #define slide window /* Huffman code lookup table entry--this entry is four bytes for machines that have 16-bit pointers (e.g. PC's in the small or medium model). Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 means that v is a literal, 16 < e < 32 means that v is a pointer to the next table, which codes e - 16 bits, and lastly e == 99 indicates an unused code. If a code with e == 99 is looked up, this implies an error in the data. */ struct huft { uch e; /* number of extra bits or operation */ uch b; /* number of bits in this code or subcode */ union { ush n; /* literal, length base, or distance base */ struct huft *t; /* pointer to next level of table */ } v; }; /* Function prototypes */ STATIC int huft_build OF((unsigned *, unsigned, unsigned, const ush *, const ush *, struct huft **, int *)); STATIC int huft_free OF((struct huft *)); STATIC int inflate_codes OF((struct huft *, struct huft *, int, int)); STATIC int inflate_stored OF((void)); STATIC int inflate_fixed OF((void)); STATIC int inflate_dynamic OF((void)); STATIC int inflate_block OF((int *)); STATIC int inflate OF((void)); /* The inflate algorithm uses a sliding 32 K byte window on the uncompressed stream to find repeated byte strings. This is implemented here as a circular buffer. The index is updated simply by incrementing and then ANDing with 0x7fff (32K-1). */ /* It is left to other modules to supply the 32 K area. It is assumed to be usable as if it were declared "uch slide[32768];" or as just "uch *slide;" and then malloc'ed in the latter case. The definition must be in unzip.h, included above. */ /* unsigned wp; current position in slide */ #define wp outcnt #define flush_output(w) (wp=(w),flush_window()) /* Tables for deflate from PKZIP's appnote.txt. */ static const unsigned border[] = { /* Order of the bit length code lengths */ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; static const ush cplens[] = { /* Copy lengths for literal codes 257..285 */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; /* note: see note #13 above about the 258 in this list. */ static const ush cplext[] = { /* Extra bits for literal codes 257..285 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ static const ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; static const ush cpdext[] = { /* Extra bits for distance codes */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; /* Macros for inflate() bit peeking and grabbing. The usage is: NEEDBITS(j) x = b & mask_bits[j]; DUMPBITS(j) where NEEDBITS makes sure that b has at least j bits in it, and DUMPBITS removes the bits from b. The macros use the variable k for the number of bits in b. Normally, b and k are register variables for speed, and are initialized at the beginning of a routine that uses these macros from a global bit buffer and count. If we assume that EOB will be the longest code, then we will never ask for bits with NEEDBITS that are beyond the end of the stream. So, NEEDBITS should not read any more bytes than are needed to meet the request. Then no bytes need to be "returned" to the buffer at the end of the last block. However, this assumption is not true for fixed blocks--the EOB code is 7 bits, but the other literal/length codes can be 8 or 9 bits. (The EOB code is shorter than other codes because fixed blocks are generally short. So, while a block always has an EOB, many other literal/length codes have a significantly lower probability of showing up at all.) However, by making the first table have a lookup of seven bits, the EOB code will be found in that first lookup, and so will not require that too many bits be pulled from the stream. */ STATIC ulg bb; /* bit buffer */ STATIC unsigned bk; /* bits in bit buffer */ STATIC const ush mask_bits[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff }; #define NEXTBYTE() (uch)get_byte() #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<>=(n);k-=(n);} /* Huffman code decoding is performed using a multi-level table lookup. The fastest way to decode is to simply build a lookup table whose size is determined by the longest code. However, the time it takes to build this table can also be a factor if the data being decoded is not very long. The most common codes are necessarily the shortest codes, so those codes dominate the decoding time, and hence the speed. The idea is you can have a shorter table that decodes the shorter, more probable codes, and then point to subsidiary tables for the longer codes. The time it costs to decode the longer codes is then traded against the time it takes to make longer tables. This results of this trade are in the variables lbits and dbits below. lbits is the number of bits the first level table for literal/ length codes can decode in one step, and dbits is the same thing for the distance codes. Subsequent tables are also less than or equal to those sizes. These values may be adjusted either when all of the codes are shorter than that, in which case the longest code length in bits is used, or when the shortest code is *longer* than the requested table size, in which case the length of the shortest code in bits is used. There are two different values for the two tables, since they code a different number of possibilities each. The literal/length table codes 286 possible values, or in a flat code, a little over eight bits. The distance table codes 30 possible values, or a little less than five bits, flat. The optimum values for speed end up being about one bit more than those, so lbits is 8+1 and dbits is 5+1. The optimum values may differ though from machine to machine, and possibly even between compilers. Your mileage may vary. */ STATIC const int lbits = 9; /* bits in base literal/length lookup table */ STATIC const int dbits = 6; /* bits in base distance lookup table */ /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ #define BMAX 16 /* maximum bit length of any code (16 for explode) */ #define N_MAX 288 /* maximum number of codes in any set */ STATIC unsigned hufts; /* track memory usage */ STATIC int huft_build(b, n, s, d, e, t, m) unsigned *b; /* code lengths in bits (all assumed <= BMAX) */ unsigned n; /* number of codes (assumed <= N_MAX) */ unsigned s; /* number of simple-valued codes (0..s-1) */ const ush *d; /* list of base values for non-simple codes */ const ush *e; /* list of extra bits for non-simple codes */ struct huft **t; /* result: starting table */ int *m; /* maximum lookup bits, returns actual */ /* Given a list of code lengths and a maximum table size, make a set of tables to decode that set of codes. Return zero on success, one if the given code set is incomplete (the tables are still built in this case), two if the input is invalid (all zero length codes or an oversubscribed set of lengths), and three if not enough memory. */ { unsigned a; /* counter for codes of length k */ unsigned c[BMAX+1]; /* bit length count table */ unsigned f; /* i repeats in table every f entries */ int g; /* maximum code length */ int h; /* table level */ register unsigned i; /* counter, current code */ register unsigned j; /* counter */ register int k; /* number of bits in current code */ int l; /* bits per table (returned in m) */ register unsigned *p; /* pointer into c[], b[], or v[] */ register struct huft *q; /* points to current table */ struct huft r; /* table entry for structure assignment */ struct huft *u[BMAX]; /* table stack */ unsigned v[N_MAX]; /* values in order of bit length */ register int w; /* bits before this table == (l * h) */ unsigned x[BMAX+1]; /* bit offsets, then code stack */ unsigned *xp; /* pointer into x */ int y; /* number of dummy codes added */ unsigned z; /* number of entries in current table */ DEBG("huft1 "); /* Generate counts for each bit length */ memzero(c, sizeof(c)); p = b; i = n; do { Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), n-i, *p)); c[*p]++; /* assume all entries <= BMAX */ p++; /* Can't combine with above line (Solaris bug) */ } while (--i); if (c[0] == n) /* null input--all zero length codes */ { *t = (struct huft *)NULL; *m = 0; return 0; } DEBG("huft2 "); /* Find minimum and maximum length, bound *m by those */ l = *m; for (j = 1; j <= BMAX; j++) if (c[j]) break; k = j; /* minimum code length */ if ((unsigned)l < j) l = j; for (i = BMAX; i; i--) if (c[i]) break; g = i; /* maximum code length */ if ((unsigned)l > i) l = i; *m = l; DEBG("huft3 "); /* Adjust last length count to fill out codes, if needed */ for (y = 1 << j; j < i; j++, y <<= 1) if ((y -= c[j]) < 0) return 2; /* bad input: more codes than bits */ if ((y -= c[i]) < 0) return 2; c[i] += y; DEBG("huft4 "); /* Generate starting offsets into the value table for each length */ x[1] = j = 0; p = c + 1; xp = x + 2; while (--i) { /* note that i == g from above */ *xp++ = (j += *p++); } DEBG("huft5 "); /* Make a table of values in order of bit lengths */ p = b; i = 0; do { if ((j = *p++) != 0) v[x[j]++] = i; } while (++i < n); DEBG("h6 "); /* Generate the Huffman codes and for each, make the table entries */ x[0] = i = 0; /* first Huffman code is zero */ p = v; /* grab values in bit order */ h = -1; /* no tables yet--level -1 */ w = -l; /* bits decoded == (l * h) */ u[0] = (struct huft *)NULL; /* just to keep compilers happy */ q = (struct huft *)NULL; /* ditto */ z = 0; /* ditto */ DEBG("h6a "); /* go through the bit lengths (k already is bits in shortest code) */ for (; k <= g; k++) { DEBG("h6b "); a = c[k]; while (a--) { DEBG("h6b1 "); /* here i is the Huffman code of length k bits for value *p */ /* make tables up to required level */ while (k > w + l) { DEBG1("1 "); h++; w += l; /* previous table always l bits */ /* compute minimum size table less than or equal to l bits */ z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ { /* too few codes for k-w bit table */ DEBG1("2 "); f -= a + 1; /* deduct codes from patterns left */ xp = c + k; while (++j < z) /* try smaller tables up to z bits */ { if ((f <<= 1) <= *++xp) break; /* enough codes to use up j bits */ f -= *xp; /* else deduct codes from patterns */ } } DEBG1("3 "); z = 1 << j; /* table entries for j-bit table */ /* allocate and link in new table */ if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) == (struct huft *)NULL) { if (h) huft_free(u[0]); return 3; /* not enough memory */ } DEBG1("4 "); hufts += z + 1; /* track memory usage */ *t = q + 1; /* link to list for huft_free() */ *(t = &(q->v.t)) = (struct huft *)NULL; u[h] = ++q; /* table starts after link */ DEBG1("5 "); /* connect to last table, if there is one */ if (h) { x[h] = i; /* save pattern for backing up */ r.b = (uch)l; /* bits to dump before this table */ r.e = (uch)(16 + j); /* bits in this table */ r.v.t = q; /* pointer to this table */ j = i >> (w - l); /* (get around Turbo C bug) */ u[h-1][j] = r; /* connect to last table */ } DEBG1("6 "); } DEBG("h6c "); /* set up table entry in r */ r.b = (uch)(k - w); if (p >= v + n) r.e = 99; /* out of values--invalid code */ else if (*p < s) { r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ r.v.n = (ush)(*p); /* simple code is just the value */ p++; /* one compiler does not like *p++ */ } else { r.e = (uch)e[*p - s]; /* non-simple--look up in lists */ r.v.n = d[*p++ - s]; } DEBG("h6d "); /* fill code-like entries with r */ f = 1 << (k - w); for (j = i >> w; j < z; j += f) q[j] = r; /* backwards increment the k-bit code i */ for (j = 1 << (k - 1); i & j; j >>= 1) i ^= j; i ^= j; /* backup over finished tables */ while ((i & ((1 << w) - 1)) != x[h]) { h--; /* don't need to update q */ w -= l; } DEBG("h6e "); } DEBG("h6f "); } DEBG("huft7 "); /* Return true (1) if we were given an incomplete table */ return y != 0 && g != 1; } STATIC int huft_free(t) struct huft *t; /* table to free */ /* Free the malloc'ed tables built by huft_build(), which makes a linked list of the tables it made, with the links in a dummy first entry of each table. */ { register struct huft *p, *q; /* Go through linked list, freeing from the malloced (t[-1]) address. */ p = t; while (p != (struct huft *)NULL) { q = (--p)->v.t; free((char*)p); p = q; } return 0; } STATIC int inflate_codes(tl, td, bl, bd) struct huft *tl, *td; /* literal/length and distance decoder tables */ int bl, bd; /* number of bits decoded by tl[] and td[] */ /* inflate (decompress) the codes in a deflated (compressed) block. Return an error code or zero if it all goes ok. */ { register unsigned e; /* table entry flag/number of extra bits */ unsigned n, d; /* length and index for copy */ unsigned w; /* current window position */ struct huft *t; /* pointer to table entry */ unsigned ml, md; /* masks for bl and bd bits */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ /* make local copies of globals */ b = bb; /* initialize bit buffer */ k = bk; w = wp; /* initialize window position */ /* inflate the coded data */ ml = mask_bits[bl]; /* precompute masks for speed */ md = mask_bits[bd]; for (;;) /* do until end of block */ { NEEDBITS((unsigned)bl) if ((e = (t = tl + ((unsigned)b & ml))->e) > 16) do { if (e == 99) return 1; DUMPBITS(t->b) e -= 16; NEEDBITS(e) } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); DUMPBITS(t->b) if (e == 16) /* then it's a literal */ { slide[w++] = (uch)t->v.n; Tracevv((stderr, "%c", slide[w-1])); if (w == WSIZE) { flush_output(w); w = 0; } } else /* it's an EOB or a length */ { /* exit if end of block */ if (e == 15) break; /* get length of block to copy */ NEEDBITS(e) n = t->v.n + ((unsigned)b & mask_bits[e]); DUMPBITS(e); /* decode distance of block to copy */ NEEDBITS((unsigned)bd) if ((e = (t = td + ((unsigned)b & md))->e) > 16) do { if (e == 99) return 1; DUMPBITS(t->b) e -= 16; NEEDBITS(e) } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); DUMPBITS(t->b) NEEDBITS(e) d = w - t->v.n - ((unsigned)b & mask_bits[e]); DUMPBITS(e) Tracevv((stderr,"\\[%d,%d]", w-d, n)); /* do the copy */ do { n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); #if !defined(NOMEMCPY) && !defined(DEBUG) if (w - d >= e) /* (this test assumes unsigned comparison) */ { memcpy(slide + w, slide + d, e); w += e; d += e; } else /* do it slow to avoid memcpy() overlap */ #endif /* !NOMEMCPY */ do { slide[w++] = slide[d++]; Tracevv((stderr, "%c", slide[w-1])); } while (--e); if (w == WSIZE) { flush_output(w); w = 0; } } while (n); } } /* restore the globals from the locals */ wp = w; /* restore global window pointer */ bb = b; /* restore global bit buffer */ bk = k; /* done */ return 0; } STATIC int inflate_stored() /* "decompress" an inflated type 0 (stored) block. */ { unsigned n; /* number of bytes in block */ unsigned w; /* current window position */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ DEBG(""); return 0; } STATIC int inflate_fixed() /* decompress an inflated type 1 (fixed Huffman codes) block. We should either replace this with a custom decoder, or at least precompute the Huffman tables. */ { int i; /* temporary variable */ struct huft *tl; /* literal/length code table */ struct huft *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ unsigned l[288]; /* length list for huft_build */ DEBG(" 1) { huft_free(tl); DEBG(">"); return i; } /* decompress until an end-of-block code */ if (inflate_codes(tl, td, bl, bd)) return 1; /* free the decoding tables, return */ huft_free(tl); huft_free(td); return 0; } STATIC int inflate_dynamic() /* decompress an inflated type 2 (dynamic Huffman codes) block. */ { int i; /* temporary variables */ unsigned j; unsigned l; /* last length */ unsigned m; /* mask for bit lengths table */ unsigned n; /* number of lengths to get */ struct huft *tl; /* literal/length code table */ struct huft *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ unsigned nb; /* number of bit length codes */ unsigned nl; /* number of literal/length codes */ unsigned nd; /* number of distance codes */ #ifdef PKZIP_BUG_WORKAROUND unsigned ll[288+32]; /* literal/length and distance code lengths */ #else unsigned ll[286+30]; /* literal/length and distance code lengths */ #endif register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ DEBG(" 288 || nd > 32) #else if (nl > 286 || nd > 30) #endif return 1; /* bad lengths */ DEBG("dyn1 "); /* read in bit-length-code lengths */ for (j = 0; j < nb; j++) { NEEDBITS(3) ll[border[j]] = (unsigned)b & 7; DUMPBITS(3) } for (; j < 19; j++) ll[border[j]] = 0; DEBG("dyn2 "); /* build decoding table for trees--single level, 7 bit lookup */ bl = 7; if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) { if (i == 1) huft_free(tl); return i; /* incomplete code set */ } DEBG("dyn3 "); /* read in literal and distance code lengths */ n = nl + nd; m = mask_bits[bl]; i = l = 0; while ((unsigned)i < n) { NEEDBITS((unsigned)bl) j = (td = tl + ((unsigned)b & m))->b; DUMPBITS(j) j = td->v.n; if (j < 16) /* length of code in bits (0..15) */ ll[i++] = l = j; /* save last length in l */ else if (j == 16) /* repeat last length 3 to 6 times */ { NEEDBITS(2) j = 3 + ((unsigned)b & 3); DUMPBITS(2) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = l; } else if (j == 17) /* 3 to 10 zero length codes */ { NEEDBITS(3) j = 3 + ((unsigned)b & 7); DUMPBITS(3) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = 0; l = 0; } else /* j == 18: 11 to 138 zero length codes */ { NEEDBITS(7) j = 11 + ((unsigned)b & 0x7f); DUMPBITS(7) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = 0; l = 0; } } DEBG("dyn4 "); /* free decoding table for trees */ huft_free(tl); DEBG("dyn5 "); /* restore the global bit buffer */ bb = b; bk = k; DEBG("dyn5a "); /* build the decoding tables for literal/length and distance codes */ bl = lbits; if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) { DEBG("dyn5b "); if (i == 1) { error(" incomplete literal tree"); huft_free(tl); } return i; /* incomplete code set */ } DEBG("dyn5c "); bd = dbits; if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) { DEBG("dyn5d "); if (i == 1) { error(" incomplete distance tree"); #ifdef PKZIP_BUG_WORKAROUND i = 0; } #else huft_free(td); } huft_free(tl); return i; /* incomplete code set */ #endif } DEBG("dyn6 "); /* decompress until an end-of-block code */ if (inflate_codes(tl, td, bl, bd)) return 1; DEBG("dyn7 "); /* free the decoding tables, return */ huft_free(tl); huft_free(td); DEBG(">"); return 0; } STATIC int inflate_block(e) int *e; /* last block flag */ /* decompress an inflated block */ { unsigned t; /* block type */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ DEBG(""); /* bad block type */ return 2; } STATIC int inflate() /* decompress an inflated entry */ { int e; /* last block flag */ int r; /* result code */ unsigned h; /* maximum struct huft's malloc'ed */ void *ptr; /* initialize window, bit buffer */ wp = 0; bk = 0; bb = 0; /* decompress until the last block */ h = 0; do { hufts = 0; gzip_mark(&ptr); if ((r = inflate_block(&e)) != 0) { gzip_release(&ptr); return r; } gzip_release(&ptr); if (hufts > h) h = hufts; } while (!e); /* Undo too much lookahead. The next read will be byte aligned so we * can discard unused bits in the last meaningful byte. */ while (bk >= 8) { bk -= 8; unget_byte(); } /* flush out slide */ flush_output(wp); /* return success */ #ifdef DEBUG fprintf(stderr, "<%u> ", h); #endif /* DEBUG */ return 0; } /********************************************************************** * * The following are support routines for inflate.c * **********************************************************************/ static ulg crc_32_tab[256]; static ulg crc; /* initialized in makecrc() so it'll reside in bss */ #define CRC_VALUE (crc ^ 0xffffffffL) /* * Code to compute the CRC-32 table. Borrowed from * gzip-1.0.3/makecrc.c. */ static void makecrc(void) { /* Not copyrighted 1990 Mark Adler */ unsigned long c; /* crc shift register */ unsigned long e; /* polynomial exclusive-or pattern */ int i; /* counter for all possible eight bit values */ int k; /* byte being shifted into crc apparatus */ /* terms of polynomial defining this crc (except x^32): */ static const int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; /* Make exclusive-or pattern from polynomial */ e = 0; for (i = 0; i < sizeof(p)/sizeof(int); i++) e |= 1L << (31 - p[i]); crc_32_tab[0] = 0; for (i = 1; i < 256; i++) { c = 0; for (k = i | 256; k != 1; k >>= 1) { c = c & 1 ? (c >> 1) ^ e : c >> 1; if (k & 1) c ^= e; } crc_32_tab[i] = c; } /* this is initialized here so this code could reside in ROM */ crc = (ulg)0xffffffffL; /* shift register contents */ } /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ #define RESERVED 0xC0 /* bit 6,7: reserved */ /* * Do the uncompression! */ int gunzip() { int res; /* Decompress */ if ((res = inflate())) { switch (res) { case 0: break; case 1: error("invalid compressed format (err=1)"); break; case 2: error("invalid compressed format (err=2)"); break; case 3: error("out of memory"); break; default: error("invalid compressed format (other)"); } return -1; } return 0; } syslinux-legacy-3.63+dfsg/memdisk/e820test.c0000664000175000017500000000427110777447273017373 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * e820hack.c * * Test of INT 15:E820 canonicalization/manipulation routine */ #include #include #include #include #include "e820.h" void *sys_bounce; /* Dummy */ extern void parse_mem(void); extern uint32_t dos_mem, low_mem, high_mem; void __attribute__((noreturn)) die(void) { abort(); } void printranges(void) { int i; for ( i = 0 ; i < nranges ; i++ ) { printf("%016llx %016llx %d\n", ranges[i].start, ranges[i+1].start - ranges[i].start, ranges[i].type); } } int main(void) { uint64_t start, len; uint32_t type; char line[BUFSIZ], *p; e820map_init(); printranges(); while ( fgets(line, BUFSIZ, stdin) ) { p = strchr(line, ':'); p = p ? p+1 : line; if ( sscanf(p, " %llx %llx %d", &start, &len, &type) == 3 ) { putchar('\n'); printf("%016llx %016llx %d <-\n", start, len, type); putchar('\n'); insertrange(start, len, type); printranges(); } } parse_mem(); putchar('\n'); printf("DOS mem = %#10x (%u K)\n", dos_mem, dos_mem >> 10); printf("Low mem = %#10x (%u K)\n", low_mem, low_mem >> 10); printf("High mem = %#10x (%u K)\n", high_mem, high_mem >> 10); putchar('\n'); /* Now, steal a chunk (2K) of DOS memory and make sure it registered OK */ insertrange(dos_mem-2048, 2048, 2); /* Type 2 = reserved */ printranges(); parse_mem(); putchar('\n'); printf("DOS mem = %#10x (%u K)\n", dos_mem, dos_mem >> 10); printf("Low mem = %#10x (%u K)\n", low_mem, low_mem >> 10); printf("High mem = %#10x (%u K)\n", high_mem, high_mem >> 10); putchar('\n'); return 0; } syslinux-legacy-3.63+dfsg/dnsresolv.inc0000664000175000017500000001717210777447273016736 0ustar evanevan; -*- fundamental -*- ; ----------------------------------------------------------------------- ; ; Copyright 2004-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Bostom MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; ----------------------------------------------------------------------- ; ; dnsresolv.inc ; ; Very simple DNS resolver (assumes recursion-enabled DNS server; ; this should be the normal thing for client-serving DNS servers.) ; DNS_PORT equ htons(53) ; Default DNS port DNS_MAX_PACKET equ 512 ; Defined by protocol ; TFTP uses the range 49152-57343 DNS_LOCAL_PORT equ htons(60053) ; All local DNS queries come from this port # DNS_MAX_SERVERS equ 4 ; Max no of DNS servers section .text ; ; Turn a string in DS:SI into a DNS "label set" in ES:DI. ; On return, DI points to the first byte after the label set, ; and SI to the terminating byte. ; ; On return, DX contains the number of dots encountered. ; dns_mangle: push ax push bx xor dx,dx .isdot: inc dx xor al,al mov bx,di stosb .getbyte: lodsb and al,al jz .endstring cmp al,':' jz .endstring cmp al,'.' je .isdot inc byte [es:bx] stosb jmp .getbyte .endstring: dec si dec dx ; We always counted one high cmp byte [es:bx],0 jz .done xor al,al stosb .done: pop bx pop ax ret ; ; Compare two sets of DNS labels, in DS:SI and ES:DI; the one in SI ; is allowed pointers relative to a packet in DNSRecvBuf. ; ; Assumes DS == ES. ZF = 1 if same; no registers changed. ; (Note: change reference to [di] to [es:di] to remove DS == ES assumption) ; dns_compare: pusha %if 0 .label: lodsb cmp al,0C0h jb .noptr and al,03Fh ; Get pointer value mov ah,al ; ... in network byte order! lodsb mov si,DNSRecvBuf add si,ax jmp .label .noptr: cmp al,[di] jne .done ; Mismatch inc di movzx cx,al ; End label? and cx,cx ; ZF = 1 if match jz .done ; We have a string of bytes that need to match now repe cmpsb je .label .done: %else xor ax,ax %endif popa ret ; ; Skip past a DNS label set in DS:SI. ; dns_skiplabel: push ax xor ax,ax ; AH == 0 .loop: lodsb cmp al,0C0h ; Pointer? jae .ptr and al,al jz .done add si,ax jmp .loop .ptr: inc si ; Pointer is two bytes .done: pop ax ret ; DNS header format struc dnshdr .id: resw 1 .flags: resw 1 .qdcount: resw 1 .ancount: resw 1 .nscount: resw 1 .arcount: resw 1 endstruc ; DNS query struc dnsquery .qtype: resw 1 .qclass: resw 1 endstruc ; DNS RR struc dnsrr .type: resw 1 .class: resw 1 .ttl: resd 1 .rdlength: resw 1 .rdata: equ $ endstruc section .bss2 alignb 2 DNSSendBuf resb DNS_MAX_PACKET DNSRecvBuf resb DNS_MAX_PACKET LocalDomain resb 256 ; Max possible length DNSServers resd DNS_MAX_SERVERS section .data pxe_udp_write_pkt_dns: .status: dw 0 ; Status .sip: dd 0 ; Server IP .gip: dd 0 ; Gateway IP .lport: dw DNS_LOCAL_PORT ; Local port .rport: dw DNS_PORT ; Remote port .buffersize: dw 0 ; Size of packet .buffer: dw DNSSendBuf, 0 ; off, seg of buffer pxe_udp_read_pkt_dns: .status: dw 0 ; Status .sip: dd 0 ; Source IP .dip: dd 0 ; Destination (our) IP .rport: dw DNS_PORT ; Remote port .lport: dw DNS_LOCAL_PORT ; Local port .buffersize: dw DNS_MAX_PACKET ; Max packet size .buffer: dw DNSRecvBuf, 0 ; off, seg of buffer LastDNSServer dw DNSServers ; Actual resolver function ; Points to a null-terminated or :-terminated string in DS:SI ; and returns the name in EAX if it exists and can be found. ; If EAX = 0 on exit, the lookup failed. ; ; No segment assumptions permitted. ; section .text dns_resolv: push ds push es push di push cx push dx push cs pop es ; ES <- CS ; First, build query packet mov di,DNSSendBuf+dnshdr.flags inc word [es:di-2] ; New query ID mov ax,htons(0100h) ; Recursion requested stosw mov ax,htons(1) ; One question stosw xor ax,ax ; No answers, NS or ARs stosw stosw stosw call dns_mangle ; Convert name to DNS labels push cs ; DS <- CS pop ds push si ; Save pointer to after DNS string ; Initialize... mov eax,[MyIP] mov [pxe_udp_read_pkt_dns.dip],eax and dx,dx jnz .fqdn ; If we have dots, assume it's FQDN dec di ; Remove final null mov si,LocalDomain call strcpy ; Uncompressed DNS label set so it ends in null .fqdn: mov ax,htons(1) stosw ; QTYPE = 1 = A stosw ; QCLASS = 1 = IN sub di,DNSSendBuf mov [pxe_udp_write_pkt_dns.buffersize],di ; Now, send it to the nameserver(s) ; Outer loop: exponential backoff ; Inner loop: scan the various DNS servers mov dx,PKT_TIMEOUT mov cx,PKT_RETRY .backoff: mov si,DNSServers .servers: cmp si,[LastDNSServer] jb .moreservers .nomoreservers: add dx,dx ; Exponential backoff loop .backoff xor eax,eax ; Nothing... .done: pop si pop dx pop cx pop di pop es pop ds ret .moreservers: lodsd ; EAX <- next server push si push cx push dx mov word [pxe_udp_write_pkt_dns.status],0 mov [pxe_udp_write_pkt_dns.sip],eax mov [pxe_udp_read_pkt_dns.sip],eax xor eax,[MyIP] and eax,[Netmask] jz .nogw mov eax,[Gateway] .nogw: mov [pxe_udp_write_pkt_dns.gip],eax mov di,pxe_udp_write_pkt_dns mov bx,PXENV_UDP_WRITE call pxenv jc .timeout ; Treat failed transmit as timeout cmp word [pxe_udp_write_pkt_dns.status],0 jne .timeout mov cx,[BIOS_timer] .waitrecv: mov ax,[BIOS_timer] sub ax,cx cmp ax,dx jae .timeout mov word [pxe_udp_read_pkt_dns.status],0 mov word [pxe_udp_read_pkt_dns.buffersize],DNS_MAX_PACKET mov di,pxe_udp_read_pkt_dns mov bx,PXENV_UDP_READ call pxenv and ax,ax jnz .waitrecv cmp [pxe_udp_read_pkt_dns.status],ax jnz .waitrecv ; Got a packet, deal with it... mov si,DNSRecvBuf lodsw cmp ax,[DNSSendBuf] ; ID jne .waitrecv ; Not ours lodsw ; flags xor al,80h ; Query#/Answer bit test ax,htons(0F80Fh) jnz .badness lodsw xchg ah,al ; ntohs mov cx,ax ; Questions echoed lodsw xchg ah,al ; ntohs push ax ; Replies lodsw ; NS records lodsw ; Authority records jcxz .qskipped .skipq: call dns_skiplabel ; Skip name add si,4 ; Skip question trailer loop .skipq .qskipped: pop cx ; Number of replies jcxz .badness .parseanswer: mov di,DNSSendBuf+dnshdr_size call dns_compare pushf call dns_skiplabel mov ax,[si+8] ; RDLENGTH xchg ah,al ; ntohs popf jnz .notsame cmp dword [si],htons(1)*0x10001 ; TYPE = A, CLASS = IN? jne .notsame cmp ax,4 ; RDLENGTH = 4? jne .notsame ; ; We hit paydirt here... ; mov eax,[si+10] .gotresult: add sp,6 ; Drop timeout information jmp .done .notsame: add si,10 add si,ax loop .parseanswer .badness: ; We got back no data from this server. Unfortunately, for a recursive, ; non-authoritative query there is no such thing as an NXDOMAIN reply, ; which technically means we can't draw any conclusions. However, ; in practice that means the domain doesn't exist. If this turns out ; to be a problem, we may want to add code to go through all the servers ; before giving up. ; If the DNS server wasn't capable of recursion, and isn't capable ; of giving us an authoritative reply (i.e. neither AA or RA set), ; then at least try a different setver... test word [DNSRecvBuf+dnshdr.flags],htons(0480h) jz .timeout xor eax,eax jmp .gotresult .timeout: pop dx pop cx pop si jmp .servers syslinux-legacy-3.63+dfsg/debian/0000775000175000017500000000000011730614544015421 5ustar evanevansyslinux-legacy-3.63+dfsg/debian/compat0000664000175000017500000000000211730614544016617 0ustar evanevan6 syslinux-legacy-3.63+dfsg/debian/docs0000664000175000017500000000004611730614544016274 0ustar evanevanBUGS README README.gfxboot TODO doc/* syslinux-legacy-3.63+dfsg/debian/changelog0000664000175000017500000007027311730614544017304 0ustar evanevansyslinux (2:3.63+dfsg-2ubuntu3) intrepid; urgency=low * Drop mtools back to Recommends now that recommended packages are installed by default. -- Colin Watson Tue, 15 Jul 2008 13:39:32 +0100 syslinux (2:3.63+dfsg-2ubuntu2) intrepid; urgency=low * 13-ubuntu_com32_gfxboot.dpatch: Turn progress operations into no-ops unless gfx_progress_init has been called. Fixes a crash when both com32 and gfxboot are used, since loading a com32 object calls load_high which calls gfx_progress_update. * 14-ubuntu_gfxboot_force_prompt.dpatch: Always prompt if a gfxboot menu is set up. -- Colin Watson Thu, 19 Jun 2008 14:55:26 +0100 syslinux (2:3.63+dfsg-2ubuntu1) intrepid; urgency=low * Resynchronise with Debian. Remaining changes: - debian/control: + Build package for lpia. + Don't build-depend on mingw32. + Depend on mtools. - debian/docs: + Add README.gfxboot. - debian/rules: + Make sure add_crc is executable. + Regenerate keyword hash. - debian/patches/10-ubuntu_makefile.dpatch: + Don't build syslinux.exe. - debian/patches/11-suse_gfxboot.dpatch + Add gfxboot, updated from openSUSE 3.63-13. - debian/patches/12-ubuntu_localboot-gfxdone.dpatch: + Make sure screen is cleared when using gfxboot. * Add descriptions for Ubuntu-specific patches. -- Colin Watson Fri, 13 Jun 2008 15:41:30 +0100 syslinux (2:3.63+dfsg-2) unstable; urgency=medium * Adding patch from Ryan Finnie to extend 64bit autodetection to vesamenu.c32 (Closes: #485656). * Removing watch file. * Bumping policy. -- Daniel Baumann Tue, 10 Jun 2008 21:08:00 +0200 syslinux (2:3.63+dfsg-1) unstable; urgency=high * New upstream release: - Fixes problem with extlinux, which refuses to boot if there are some deleted files on the ext2 filesystem (see upstream changelog for more information). -- Daniel Baumann Thu, 10 Apr 2008 21:17:00 +0200 syslinux (2:3.70~pre8+dfsg-1) experimental; urgency=low * New upstream release. -- Daniel Baumann Mon, 31 Mar 2008 21:33:00 +0200 syslinux (2:3.70~pre7+dfsg-1) experimental; urgency=low * New upstream release. -- Daniel Baumann Mon, 31 Mar 2008 13:42:00 +0200 syslinux (2:3.62+dfsg-2) unstable; urgency=medium * Applied patch from morph to fix clean target (Closes: #424225). -- Daniel Baumann Sat, 5 Apr 2008 08:02:00 +0200 syslinux (2:3.62+dfsg-1) unstable; urgency=medium * New upstream release. * Rediffed 02-64bit-autodetection.dpatch. * Disabled 03-define-clk-tck.dpatch for now, seems to introduce strange behaviour with TIMEOUT on pxelinux, needs further investigation. -- Daniel Baumann Mon, 31 Mar 2008 13:24:00 +0200 syslinux (2:3.61+dfsg-1) unstable; urgency=medium * Rebuild upstream tarball without non-free RFC document (Closes: #463930). -- Daniel Baumann Tue, 5 Feb 2008 07:28:00 +0100 syslinux (2:3.61-1) unstable; urgency=low * New upstream release. * Bumping package to debhelper 6. -- Daniel Baumann Mon, 4 Feb 2008 07:16:00 +0100 syslinux (2:3.60-2) experimental; urgency=low * Applied update of 02-64bit-autodetection.dpatch from Robert Millan (Closes: #462157). -- Daniel Baumann Thu, 24 Jan 2008 07:34:00 +0100 syslinux (2:3.55-2) unstable; urgency=medium * Applied update of 02-64bit-autodetection.dpatch from Robert Millan (Closes: #462157). -- Daniel Baumann Tue, 22 Jan 2008 23:21:00 +0100 syslinux (2:3.60-1) experimental; urgency=low * New upstream release. -- Daniel Baumann Sat, 12 Jan 2008 20:04:00 +0100 syslinux (2:3.55-1) unstable; urgency=low * New upstream release. * Don't hide make errors in clean call of rules. -- Daniel Baumann Sat, 12 Jan 2008 19:59:00 +0100 syslinux (2:3.60~pre6-1) experimental; urgency=low * New upstream release. * Removed manpages, went upstream. -- Daniel Baumann Thu, 20 Dec 2007 08:22:00 +0100 syslinux (2:3.54-1) unstable; urgency=low * New upstream release. -- Daniel Baumann Thu, 13 Dec 2007 09:45:00 +0100 syslinux (2:3.53-1ubuntu2) hardy; urgency=low * isolinux.asm: Remove reference to non-existent CD2 (LP: #62950). -- Evan Dandrea Tue, 11 Dec 2007 12:12:38 -0500 syslinux (2:3.53-1ubuntu1) hardy; urgency=low * Merge from debian unstable, remaining changes: - debian/control: + DebianMaintainerField. + Build package for lpia. + Don't build-depend on mingw32. - debian/docs: + Add README.gfxboot - debian/rules: + Make sure add_crc is executable. + Regenerate keyword hash. - debian/patches/02-64bit-autodetection: + Fix up to apply cleanly again. - debian/patches/10-ubuntu_makefile.dpatch: + Don't build syslinux.exe - debian/patches/11-suse_gfxboot.dpatch + The infamous gfxboot patch. Lovingly updated to match current syslinux. - debian/patches/13-ubuntu_localboot-gfxdone.dpatch: + Make sure screen is cleared when using gfxboot. -- Soren Hansen Mon, 10 Dec 2007 21:03:58 +0100 syslinux (2:3.53-1) unstable; urgency=low * New upstream release. -- Daniel Baumann Sun, 18 Nov 2007 17:26:00 +0100 syslinux (1:3.60~pre3-2) unstable; urgency=low * Only build-depending on gcc-multilib on amd64. * Removing old build-dependency against ia32-libs-dev. * Versioning build-depends against nasm. -- Daniel Baumann Fri, 16 Nov 2007 11:42:00 +0100 syslinux (1:3.60~pre3-1) unstable; urgency=low * New upstream release. -- Daniel Baumann Mon, 12 Nov 2007 09:18:00 +0100 syslinux (1:3.60~pre2-1) unstable; urgency=low * New upstream release. -- Daniel Baumann Wed, 26 Aug 2007 11:16:00 +0200 syslinux (1:3.60~pre1-1) unstable; urgency=low * New upstream release. * Works well with nasm 0.99.02 (Closes: #439418). -- Daniel Baumann Sat, 25 Aug 2007 08:01:00 +0200 syslinux (1:3.52~pre5-1) experimental; urgency=low * New upstream release. -- Daniel Baumann Sun, 29 Jul 2007 20:55:00 +0200 syslinux (1:3.52~pre3-1) experimental; urgency=low * New upstream release. -- Daniel Baumann Sun, 15 Jul 2007 19:40:00 +0200 syslinux (1:3.51-1) unstable; urgency=low * New upstream release. * Temporarily disabled 02-64bit-autodetection.dpatch; doesn't build anymore. * Added Otavio as co-maintainer. -- Daniel Baumann Mon, 18 Jun 2007 19:04:00 +0200 syslinux (1:3.36-5) unstable; urgency=low * Added patch from Otavio Salvador to add support to change menu vertical and horizontal shifting. * Added define-clk-tck patch from Timo Aaltonen . It defines CLK_TCK, since the com32 libc API does not have any idea about it, and its include files shadow /usr/include/time.h (which would provide CLOCKS_PER_SEC). -- Daniel Baumann Thu, 31 May 2007 07:43:00 +0200 syslinux (1:3.36-4ubuntu5) gutsy; urgency=low * Only build-depend on gcc-multilib on amd64. -- Matthias Klose Thu, 30 Aug 2007 10:26:35 +0000 syslinux (1:3.36-4ubuntu4) gutsy; urgency=low * Build package for lpia. -- Matthias Klose Thu, 23 Aug 2007 18:29:28 +0000 syslinux (1:3.36-4ubuntu3) gutsy; urgency=low * Restore old Ubuntu changelog entries. * debian/patches/13-ubuntu_localboot-gfxdone.dpatch: - Restore; only a small part of this was applied upstream. Call vgasetmode when switching back to text mode, to make sure that the screen gets cleared. -- Colin Watson Tue, 07 Aug 2007 02:11:21 +0100 syslinux (1:3.36-4ubuntu2) gutsy; urgency=low * mtools changed from recommended package to dependency (LP: #75765) -- Nathan Handler Fri, 20 Jul 2007 15:37:24 +0200 syslinux (1:3.36-4ubuntu1) gutsy; urgency=low * Merge from Debian unstable, remaining changes: - debian/control: + Drop ia32-libs-dev build-dependency. + Drop mingw32 build-dependency. - debian/docs: + Install README.gfxboot from gfxboot. - debian/rules: + chmod add_crc from gfxboot. + Don't install syslinux.exe. - debian/patches: + 10-ubuntu_makefile.dpatch: Don't build win32-stuff. + 11-suse_gfxboot.dpatch: SuSE gfxboot. Updated from OpenSuSE 10.2. + 12-define_clk_tck.dpatch: com32/samples/keytest.c, com32/libutil/include/libutil.h, com32/include/time.h: Define CLK_TCK, since the com32 libc API does not have any idea about it, and its include files shadow /usr/include/time.h (which would provide CLOCKS_PER_SEC). * Change Maintainer address. * debian/patches: - 12-ubuntu_localboot-gfxdone.dpatch 13-ubuntu_gfxboot-cpio-swab.dpatch Dropped because the new gfxboot-patch supercedes them. - 14-gentoo_nossp.dpatch Obsolete, upstream has applied -fno-stack-protector to the relevant bits. -- Timo Aaltonen Tue, 29 May 2007 17:14:02 +0300 syslinux (1:3.36-4) unstable; urgency=medium * Added build-depends on gcc-multilib (Closes: #423514). -- Daniel Baumann Sat, 12 May 2007 20:33:00 +0200 syslinux (1:3.36-3) unstable; urgency=medium * Rebuild because glibc. -- Daniel Baumann Wed, 9 May 2007 10:36:00 +0200 syslinux (1:3.50~pre6-1) experimental; urgency=low * New upstream release. -- Daniel Baumann Tue, 1 May 2007 12:18:00 +0200 syslinux (1:3.50~pre5-1) experimental; urgency=low * New upstream release. -- Daniel Baumann Wed, 11 Apr 2007 10:11:00 +0200 syslinux (1:3.36-2) unstable; urgency=low * Re-uploading previous 3.36-1. -- Daniel Baumann Wed, 11 Apr 2007 10:09:00 +0200 syslinux (1:3.31-4) unstable; urgency=medium * Uploading 3.31-3 from etch again to unstable, to not break debian-installer. -- Daniel Baumann Fri, 9 Mar 2007 00:57:00 +0100 syslinux (3.40~pre9-1) experimental; urgency=low * New upstream release. -- Daniel Baumann Mon, 5 Mar 2007 02:05:00 +0100 syslinux (3.36-1) unstable; urgency=low * New upstream release. * Rediffed 02-64bit-autodetection.dpatch. -- Daniel Baumann Mon, 5 Mar 2007 01:32:00 +0100 syslinux (3.31-3) unstable; urgency=medium * Added patch from Robert Millan to fix 02-64bit-autodetection.dpatch (Closes: #410729). -- Daniel Baumann Tue, 13 Feb 2007 23:17:00 +0100 syslinux (3.31-2) unstable; urgency=medium * Including all *.c32 modules (Closes: #391152). * Added patch from Byron Stanoszek to autodetect 64bit CPUs (Closes: #408138). -- Daniel Baumann Sun, 4 Feb 2007 16:52:00 +0100 syslinux (3.35-1) experimental; urgency=low * New upstream release. -- Daniel Baumann Sun, 4 Feb 2007 16:43:00 +0100 syslinux (3.31-1) unstable; urgency=low * New upstream release. -- Daniel Baumann Thu, 28 Sep 2006 20:11:00 +0200 syslinux (3.20-2) unstable; urgency=low * Including mbr.bin (Closes: #357146). -- Daniel Baumann Tue, 19 Sep 2006 03:30:00 +0200 syslinux (3.30~pre4-1) experimental; urgency=low * New upstream pre-release. -- Daniel Baumann Wed, 6 Sep 2006 22:51:00 +0200 syslinux (3.20-1) unstable; urgency=low * New upstream release. * Taking over the package, Juan Cespedes is MIA. -- Daniel Baumann Tue, 5 Sep 2006 23:21:00 +0200 syslinux (3.11+3.20pre11-1) experimental; urgency=low * New upstream pre-release. -- Daniel Baumann Thu, 10 Aug 2006 11:31:00 +0200 syslinux (3.11+3.20pre10-1) experimental; urgency=low * New upstream pre-release. * Added myself as co-maintainer. * Redone debian directory based on current debhelper templates, additionally: - added watch file. - cleaned up copyright files. - including all manpages as plain files, dropping docbook-to-man. - including com32/modules/menu.c32 into the package. - not using binaries from upstream, building everything from source. - using dpatch for upstream modifications now. -- Daniel Baumann Sun, 30 Jul 2006 09:43:00 +0200 syslinux (3.11-3ubuntu4) feisty; urgency=low * Build with -fno-stack-protector, since package does not link against libc. * com32/samples/keytest.c, com32/libutil/include/libutil.h, com32/include/time.h: Define CLK_TCK, since the com32 libc API does not have any idea about it, and its include files shadow /usr/include/time.h (which would provide CLOCKS_PER_SEC). -- Martin Pitt Mon, 12 Mar 2007 13:40:50 +0100 syslinux (3.11-3ubuntu3) feisty; urgency=low * debian/control: Update maintainer fields according to debian- maintainer-field spec. -- Martin Pitt Fri, 9 Mar 2007 11:58:28 +0000 syslinux (3.11-3ubuntu2) dapper; urgency=low * Drop ia32-libs-dev build dependency. -- Matthias Klose Thu, 16 Mar 2006 15:37:14 +0000 syslinux (3.11-3ubuntu1) dapper; urgency=low * Resynchronise with Debian. -- Colin Watson Tue, 17 Jan 2006 23:07:52 +0000 syslinux (3.11-3) unstable; urgency=low * Fixed FTBFS bug with latest "make" (closes: #343619) * Added "mkdiskimage" to Debian package (closes: #343617) -- Juan Cespedes Sun, 18 Dec 2005 16:54:26 +0100 syslinux (3.11-2ubuntu5) dapper; urgency=low * Fix debian/applied-patches/localboot-gfxdone.diff filename. * debian/applied-patches/gfxboot-cpio-swab.diff: Make gfxboot check for byte-swapped cpio archives, so that it's easier to develop gfxboot themes on a powerpc system with qemu. * debian/applied-patches/localboot-gfxdone.diff: Call vgasetmode when switching back to text mode, to make sure that the screen gets cleared. * Makefile: Just export DATE and HEXDATE rather than playing with $(MAKE); current make applies an extra shell evaluation pass to the latter approach and so fails. -- Colin Watson Wed, 11 Jan 2006 16:02:06 +0000 syslinux (3.11-2ubuntu4) dapper; urgency=low * debian/applied-patches/localboot-gfxdone.diff: Turn gfxboot off before booting from a local disk with LOCALBOOT. -- Colin Watson Tue, 13 Dec 2005 12:43:29 +0000 syslinux (3.11-2ubuntu3) dapper; urgency=low * Apply SuSE's gfxboot patch (debian/applied-patches/gfxboot.diff); thanks to Steffen Winterfeldt for technical support. See README.gfxboot for details. -- Colin Watson Wed, 7 Dec 2005 17:01:51 +0000 syslinux (3.11-2ubuntu2) dapper; urgency=low * Install menu.c32 in /usr/lib/syslinux. -- Colin Watson Wed, 23 Nov 2005 14:55:12 +0000 syslinux (3.11-2ubuntu1) dapper; urgency=low * Resynchronise with Debian. -- Colin Watson Wed, 23 Nov 2005 10:34:54 +0000 syslinux (3.11-2) unstable; urgency=low * Added correct build-depends for amd64 (Andreas Jochens ) (Closes: Bug#306123, Bug#249506, Bug#298940) * Acknowledged old NMU (Closes: #269424) -- Juan Cespedes Wed, 19 Oct 2005 16:00:38 +0200 syslinux (3.11-1) unstable; urgency=low * New upstream version * Updated to new FSF postal address -- Juan Cespedes Tue, 18 Oct 2005 16:19:49 +0200 syslinux (2.11-0.1ubuntu4) breezy; urgency=low * Make the package build again (Ubuntu: #14605) * sample/chain.c: Replace memcpy() call with a loop since memcpy() is not available (-nostdlib). * memdisk/setup.c: Replace memcmp() call with a per-char comparison since memcmp() is not available. * memdisk/inflate.c: Fix declaration of crc_32_tab[256]. -- Martin Pitt Wed, 7 Sep 2005 17:29:49 +0200 syslinux (2.11-0.1ubuntu3) hoary; urgency=low * Don't build or install syslinux.exe; don't build-depend on mingw32 (closes: Ubuntu #3416). -- Colin Watson Thu, 9 Dec 2004 17:30:06 +0100 syslinux (2.11-0.1ubuntu2) hoary; urgency=low * Fix amd64 compilation (thanks, Tollef Fog Heen and LaMont Jones). -- Daniel Stone Wed, 3 Nov 2004 16:13:25 +0100 syslinux (2.11-0.1ubuntu1) hoary; urgency=low * Merge changes from Debian back in. * debian/rules: + Stop attempting to back up sample/*.elf when they are not shipped in the orig. -- Daniel Stone Mon, 1 Nov 2004 18:16:33 +0100 syslinux (2.11-0.1) unstable; urgency=low * NMU with new upstream release. - ALL: Add an API call to get the configuration file name. - SYSLINUX: Fix bug in 2.10 that prevented it from working correctly for a lot of people. Closes: #269424 - SYSLINUX: In the installer, make mtools a bit less fussy. - Make the menu system compile with newer gcc's. -- Joey Hess Fri, 10 Sep 2004 12:18:43 -0400 syslinux (2.10-1) unstable; urgency=medium * New upstream version, fixing many bugs, among them a problem which prevented syslinux from booting large kernels (thanks to Torsten Knodt ) (closes: Bug#224606, Bug#242547) (closes: Bug#258940) * New Standards-Version (3.6.1) * Removed dependency on lilo (closes: Bug#235439) * syslinux now uses mtools to install the image, it no longer requires msdos or vfat filesystem in the kernel (closes: Bug#72124) * Added a "Recommend: mtools" control line (closes: Bug#201354) -- Juan Cespedes Sat, 17 Jul 2004 10:32:37 +0200 syslinux (2.04-1) unstable; urgency=low * New upstream version, needed for debian-installer (closes: #186356) * This new upstream version of syslinux already uses mcopy to generate disk images (closes: Bug#180660) * New Standards-Version: + Get rid of /usr/doc/syslinux symlink * Replaced all all # comments with /* */ to get rid of gcc-3.3 preprocessor errors (closes: Bug#196532) -- Juan Cespedes Wed, 11 Jun 2003 11:52:06 +0200 syslinux (2.00-2) unstable; urgency=low * Fixed typo in description (closes: Bug#178582) -- Juan Cespedes Mon, 27 Jan 2003 13:26:42 +0100 syslinux (2.00-1) unstable; urgency=low * New upstream version (closes: Bug#174565) (thanks to Andrea Bedini ) * Added note about PXE in the description (closes: Bug#151700) * Added man pages for gethostip, lss16toppm, ppmtolss16 (thanks to dann frazier ) (closes: Bug#107539) -- Juan Cespedes Sun, 26 Jan 2003 13:49:44 +0100 syslinux (1.75-1) unstable; urgency=low * New upstream release * Added "memdisk" to the package (closes: Bug#141605, Bug#143773) * Added "syslinux-debug.bin" to the package (closes: Bug#143772) -- Juan Cespedes Thu, 20 Jun 2002 13:18:22 +0200 syslinux (1.66-1) unstable; urgency=low * New upstream version * Boot images shorter than 64K, including memtest86 (closes: Bug#45133) -- Juan Cespedes Mon, 21 Jan 2002 01:56:55 +0100 syslinux (1.63-1) unstable; urgency=low * New upstream release, fixing "No setup signature found" bug found with some newer kernels (closes: Bug#107345) * Reverted mtools patch for installer (it fails with some high-capacity floppy formats) (closes: Bug#108096) -- Juan Cespedes Wed, 22 Aug 2001 01:42:58 +0200 syslinux (1.62-5) unstable; urgency=low * Added "Build-Depends: netpbm" (closes: Bug#97497) -- Juan Cespedes Mon, 14 May 2001 23:38:29 +0200 syslinux (1.62-4) unstable; urgency=low * Yet another version of `ppmtolss16' from the author (hpa), fixing a bug regarding color space conversion -- Juan Cespedes Sun, 13 May 2001 17:21:02 +0200 syslinux (1.62-3) unstable; urgency=low * New version of `ppmtolss16' from the author (hpa) -- Juan Cespedes Tue, 8 May 2001 21:39:45 +0200 syslinux (1.62-2) unstable; urgency=medium * Changed small typo in manual page names (sylinux -> syslinux) (closes: Bug#96553) -- Juan Cespedes Mon, 7 May 2001 00:30:09 +0200 syslinux (1.62-1) unstable; urgency=medium * New upstream version (closes: Bug#77269) * This version could fix Bug#56983 and Bug#69140, but I have no way to test it * Added Build-Depends (closes: Bug#60729) * New Standards-Version: 3.5.3 * Fixed lintian error "copyright-refers-to-old-directory" * Fixed lintian warnings "no-priority-field" and "no-section-field" * Change the installer a bit so that it is no longer needed to run it as root, using mtools (closes: Bug#30982) * Added manual page for `syslinux', provided by Arthur Korn (closes: Bug#18432) * Added manual page for `syslinux2ansi', provided by Kevin Kreamer (closes: Bug#35264) -- Juan Cespedes Tue, 1 May 2001 17:12:49 +0200 syslinux (1.48-2) unstable; urgency=medium * New Standards-Version (3.1.1) * Fixed lintian bugs * Note in the package description that filesystem type `msdos' is needed in order to use this program (closes: Bug#23265) -- Juan Cespedes Sun, 19 Dec 1999 14:25:45 +0100 syslinux (1.48-1) unstable; urgency=medium * New upstream version: + Changed HIGHMEM_MAX to 38000000h + Serial console support + New program PXELINUX to do network booting * FHS support * New Standards-Version: 3.0.1 * Almost all the bugs regarding boot problems should be fixed with this upstream version: (closes: Bug#18271, Bug#22366, Bug#22700, Bug#22845, Bug#23181) (closes: Bug#23936, Bug#27755, Bug#28846, Bug#29296, Bug#32138) * Fixed copyright notice in "copybs.asm" (closes: Bug#35531) * "syslinux.com" is now included (closes: Bug#31460) -- Juan Cespedes Mon, 25 Oct 1999 11:09:02 +0200 syslinux (1.43-1) unstable; urgency=medium * New upstream version: + Add syslinux2ansi script to display the contents of a colorized SYSLINUX file. + Changed the io_delay once again, after a report that the old delay port causes hangs on some systems. + Should fix: Bug#18271, Bug#22366, Bug#22845, Bug#23181, Bug#23936, Bug#27755, Bug#28846, Bug#29296, Bug#32138 * Include "syslinux.com": Bug#31460 -- Juan Cespedes Tue, 30 Mar 1999 12:53:48 +0200 syslinux (1.42-2) frozen unstable; urgency=HIGH * Reverted patch for installer (it fails with some mtools versions) (Fixes grave bug: Bug#30791) -- Juan Cespedes Thu, 17 Dec 1998 10:33:37 +0100 syslinux (1.42-1) frozen unstable; urgency=medium * New upstream version. Mostly A20 bug fixes. * This should fix at least the following syslinux bugs: Bug#22845, Bug#23181, Bug#23936, Bug#27755, Bug#28846, Bug#29296. * Change the installer a bit so that it is no longer needed to run it as root -- Juan Cespedes Tue, 8 Dec 1998 21:20:31 +0100 syslinux (1.40-3) frozen unstable; urgency=medium * Added "img1743k.gz" as suggested by Enrique Zanardi -- Juan Cespedes Mon, 9 Nov 1998 21:23:21 +0100 syslinux (1.40-2) frozen unstable; urgency=medium * Added "safe, slow and stupid" option to the version for the boot floppies to be able to boot even on very buggy bioses. (Bug#23157, Bug#23181). * Increased A20M delay even a bit more, as suggested by Enrique Zanardi. * Changed the aspect of the syslinux banner a bit -- Juan Cespedes Sat, 6 Jun 1998 01:05:34 +0200 syslinux (1.40-1) unstable; urgency=low * New upstream release: * Increase A20M delay and put in a test to avoid problems on certain IBM Thinkpads (thanks to Donnie Barnes of RedHat for vital info on this one.) * Support COMBOOT style boot command images. * Support chain loading (foreign operating systems, e.g. DOS). * Include a new "copybs" DOS utility to copy a boot sector to a file (under Linux, use "dd".) * Fix the DOS installer to work for disks over 32 MB. * SYSLINUX should now handle disks with more than 65536 tracks. * Changed section from "misc" to "base", to be in sync with then FTP archive -- Juan Cespedes Fri, 8 May 1998 11:22:46 +0200 syslinux (1.37-1) frozen unstable; urgency=medium * New upstream version (Bug fixes only): + Fix a bug that caused "label" statements in syslinux.cfg to not be handled properly. + Updated the documentation. Among other things, we now allow up to 128 "label" statements. -- Juan Cespedes Tue, 21 Apr 1998 00:19:18 +0200 syslinux (1.36-2) frozen unstable; urgency=medium * Re-built for frozen (it fixes the "LABEL" behaviour, required for the boot floppies) -- Juan Cespedes Mon, 20 Apr 1998 19:25:13 +0200 syslinux (1.36-1) unstable; urgency=medium * Applied patch to make all the "LABEL" keywords in config file work * New upstream version (bug fixes + new option "KBDMAP") -- Juan Cespedes Mon, 20 Apr 1998 02:30:58 +0200 syslinux (1.34-2) unstable; urgency=low * Install files as imgk.gz instead of img.gz -- Juan Cespedes Fri, 6 Mar 1998 20:04:59 +0100 syslinux (1.34-1) unstable; urgency=low * New upstream version -- Juan Cespedes Thu, 5 Mar 1998 17:50:14 +0100 syslinux (1.33-2) unstable; urgency=low * Fixed minor packaging bugs -- Juan Cespedes Sat, 28 Feb 1998 22:50:35 +0100 syslinux (1.33-1) unstable; urgency=low * New upstream version (fixes:Bug#18654) -- Juan Cespedes Fri, 27 Feb 1998 10:42:05 +0100 syslinux (1.32-1) unstable; urgency=low * New upstream release * Pristine source * Fixed author email address (hpa@zytor.com instead of hpa@linux.org) * New Standards-Version: 2.4.0.0 * gzipped only big files in /usr/doc/syslinux * Changed architecture from all to i386 -- Juan Cespedes Fri, 20 Feb 1998 22:16:20 +0100 syslinux (1.30-6) unstable; urgency=low * New maintainer * New Standards-Version (2.3.0.0) * Changed rules file to no longer use debstd -- Juan Cespedes Sat, 1 Nov 1997 16:22:57 +0100 syslinux (1.30-5) unstable; urgency=low * Install changelog correctly * #8532: Filed a bug report against ftp.debian.org because the package priorities and section are overridden on master. -- Christoph Lameter Wed, 29 Oct 1997 18:47:17 -0800 syslinux (1.30-4) unstable; urgency=low * Changed architecture to all * Note in description that syslinux generates Intel Boot disks (from whatever platform you install it on) -- Christoph Lameter Thu, 4 Sep 1997 11:16:34 -0700 syslinux (1.30-3) unstable; urgency=low * Include Images for 1.44K and 720K to boot Linux on an Atari Computer -- Christoph Lameter Tue, 25 Feb 1997 09:27:55 -0800 syslinux (1.30-2) unstable; urgency=low * Control file: Priority set to optional and put into section "misc" where loadlin is also. (Bug #5424) * clean up debian directory -- Christoph Lameter Mon, 4 Nov 1996 10:42:17 -0800 syslinux (1.30-1) unstable; urgency=low * Upstream update. Package made conformant to newest standards. -- Christoph Lameter Mon, 4 Nov 1996 10:26:25 -0800 syslinux-legacy-3.63+dfsg/debian/copyright0000664000175000017500000000245011730614544017355 0ustar evanevanThis package was debianized by Daniel Baumann on Sun, 30 Jul 2006 09:43:00 +0200. It was downloaded from . Upstream Author: H. Peter Anvin Upstream tarball has been rebuild without non-free RFC documents. License: Copyright (C) 1994-2008 H. Peter Anvin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL file. The Debian packaging is (C) 2006-2008, Daniel Baumann and is licensed under the GPL, see /usr/share/common-licenses/GPL-2. syslinux-legacy-3.63+dfsg/debian/rules0000775000175000017500000000427311730614544016507 0ustar evanevan#!/usr/bin/make -f # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 include /usr/share/dpatch/dpatch.make DATE=$(shell date +%Y-%m-%d) VERSION=$(shell cat version) upstream: rm -f doc/rfc5071.txt build: build-stamp build-stamp: patch-stamp dh_testdir # gfxboot chmod +x add_crc perl genhash.pl < keywords > kwdhash.gen # Building package $(MAKE) DATE="Debian-$(DATE)" VERSION="$(VERSION)" # Building images install -d -m 0755 build for SIZE in 720 1200 1440 1743; \ do \ dd if=/dev/zero of=build/img$${SIZE}k bs=1k count=$$SIZE || exit 1; \ done for DRIVE in a: b: c: d:;\ do \ MTOOLSRC=debian/config/mtoolsrc mformat $$DRIVE || exit 1; \ done for SIZE in 720 1200 1440 1743; \ do \ mtools/syslinux -s build/img$${SIZE}k || exit 1; \ done gzip -9 build/* touch build-stamp clean: unpatch dh_testdir dh_testroot rm -f build-stamp # Cleaning package [ ! -f Makefile ] || $(MAKE) clean rm -f .depend memdisk/.depend rm -f dos/syslinux.com extlinux.bin extlinux.bss extlinux.sys isolinux-debug.bin isolinux.bin ldlinux.bin ldlinux.bss ldlinux.sys memdisk/memdisk memdump/memdump.com pxelinux.0 rm -rf build dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs # Installing package install -d -m 0755 debian/syslinux/usr/bin install -m 0755 gethostip lss16toppm mkdiskimage ppmtolss16 syslinux2ansi.pl mtools/syslinux extlinux/extlinux debian/syslinux/usr/bin install -d -m 0755 debian/syslinux/usr/lib/syslinux install -m 0644 build/* debian/syslinux/usr/lib/syslinux install -m 0644 copybs.com isolinux.bin isolinux-debug.bin ldlinux.bss ldlinux.sys pxelinux.0 com32/modules/*.c32 com32/menu/*.c32 dos/syslinux.com mbr/mbr.bin memdisk/memdisk debian/syslinux/usr/lib/syslinux # Renaming files mv debian/syslinux/usr/bin/syslinux2ansi.pl debian/syslinux/usr/bin/syslinux2ansi binary-indep: build install binary-arch: build install dh_testdir dh_testroot dh_installchangelogs NEWS dh_installdocs dh_install dh_installman dh_link dh_strip dh_compress dh_fixperms dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install syslinux-legacy-3.63+dfsg/debian/control0000664000175000017500000000206211730614544017024 0ustar evanevanSource: syslinux Section: utils Priority: optional Maintainer: Ubuntu Core Developers XSBC-Original-Maintainer: Daniel Baumann Uploaders: Otavio Salvador Build-Depends: debhelper (>= 6), dpatch, gcc-multilib [amd64], libc6-dev-i386 [amd64], nasm (>= 0.99.06), netpbm, mtools Standards-Version: 3.8.0 Homepage: http://syslinux.zytor.com/ Package: syslinux Architecture: amd64 i386 lpia Depends: ${shlibs:Depends}, ${misc:Depends} Recommends: mtools Description: Bootloader for Linux/i386 using MS-DOS floppies SYSLINUX is a boot loader for the Linux/i386 operating system which operates off an MS-DOS/Windows FAT filesystem. It is intended to simplify first-time installation of Linux, and for creation of rescue and other special-purpose boot disks. . It can also be used as a PXE bootloader during network boots. . SYSLINUX is probably not suitable as a general purpose boot loader. However, SYSLINUX has shown itself to be quite useful in a number of special-purpose applications. syslinux-legacy-3.63+dfsg/debian/patches/0000775000175000017500000000000011730614544017050 5ustar evanevansyslinux-legacy-3.63+dfsg/debian/patches/13-ubuntu_com32_gfxboot.dpatch0000664000175000017500000000326611730614544024542 0ustar evanevan#! /bin/sh /usr/share/dpatch/dpatch-run ## 13-ubuntu_com32_gfxboot.dpatch by Colin Watson ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Turn progress operations into no-ops unless gfx_progress_init has ## DP: been called. Fixes a crash when both com32 and gfxboot are used, ## DP: since loading a com32 object calls load_high which calls ## DP: gfx_progress_update. @DPATCH@ diff -urNad syslinux-3.63+dfsg~/gfxboot.inc syslinux-3.63+dfsg/gfxboot.inc --- syslinux-3.63+dfsg~/gfxboot.inc 2008-06-19 02:16:18.000000000 +0100 +++ syslinux-3.63+dfsg/gfxboot.inc 2008-06-19 02:20:01.000000000 +0100 @@ -296,6 +296,7 @@ gfx_save_area1 dd 0 ; 64k gfx_save_area1_used db 0 ; != 0 if area1 is in use +gfx_progress_inited db 0 ; != 0 if gfx_progress_init called ; interface to loadable gfx extension (seg:ofs values) gfx_bc_jt dd 0 @@ -786,6 +787,7 @@ cmp byte [gfx_ok],0 jz gfx_progress_init_90 call far [gfx_bc_progress_init] + mov byte [gfx_progress_inited],1 gfx_progress_init_90: popad ret @@ -797,6 +799,8 @@ pushad cmp byte [gfx_ok],0 jz gfx_progress_done_90 + cmp byte [gfx_progress_inited],0 + jz gfx_progress_done_90 call far [gfx_bc_progress_done] gfx_progress_done_90: popad @@ -809,6 +813,8 @@ pushad cmp byte [gfx_ok],0 jz gfx_progress_update_90 + cmp byte [gfx_progress_inited],0 + jz gfx_progress_update_90 movzx eax,cx call far [gfx_bc_progress_update] gfx_progress_update_90: @@ -822,6 +828,8 @@ pushad cmp byte [gfx_ok],0 jz gfx_progress_limit_90 + cmp byte [gfx_progress_inited],0 + jz gfx_progress_limit_90 movzx eax,ax movzx edx,dx call far [gfx_bc_progress_limit] syslinux-legacy-3.63+dfsg/debian/patches/01-flags.dpatch0000664000175000017500000000134711730614544021554 0ustar evanevan#!/bin/sh /usr/share/dpatch/dpatch-run ## 01-flags.dpatch ## ## DP: Using mingw cross-compiler. @DPATCH@ diff -Naur syslinux-3.50-pre15.orig/win32/Makefile syslinux-3.50-pre15/win32/Makefile --- syslinux-3.50-pre15.orig/win32/Makefile 2007-05-23 06:28:22.000000000 +0000 +++ syslinux-3.50-pre15/win32/Makefile 2007-05-31 06:50:30.000000000 +0000 @@ -19,9 +19,9 @@ OSTYPE = $(shell uname -msr) ifeq ($(findstring CYGWIN,$(OSTYPE)),CYGWIN) -WINCC = gcc -WINAR = ar -WINRANLIB = ranlib +WINCC = i586-mingw32msvc-gcc +WINAR = i586-mingw32msvc-ar +WINRANLIB = i586-mingw32msvc-ranlib WINCFLAGS = -mno-cygwin -W -Wall -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64 WINPIC = WINLDFLAGS = -mno-cygwin -Os -s syslinux-legacy-3.63+dfsg/debian/patches/10-ubuntu_makefile.dpatch0000664000175000017500000000213011730614544023626 0ustar evanevan#! /bin/sh /usr/share/dpatch/dpatch-run ## 10-makefile.dpatch ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Don't build Win32 components, in order that mingw32 doesn't have to ## DP: be in Ubuntu main. @DPATCH@ diff -urNad syslinux-3.53-1ubuntu1~/Makefile syslinux-3.53-1ubuntu1/Makefile --- syslinux-3.53-1ubuntu1~/Makefile 2007-11-21 19:08:18.000000000 +0100 +++ syslinux-3.53-1ubuntu1/Makefile 2007-12-10 18:56:01.603469789 +0100 @@ -70,11 +70,12 @@ # syslinux.exe is BTARGET so as to not require everyone to have the # mingw suite installed +# (Removed from Ubuntu so that we don't need mingw32 in main.) BTARGET = kwdhash.gen version.gen version.h \ ldlinux.bss ldlinux.sys ldlinux.bin \ pxelinux.0 isolinux.bin isolinux-debug.bin \ extlinux.bin extlinux.bss extlinux.sys -BOBJECTS = $(BTARGET) mbr/mbr.bin dos/syslinux.com win32/syslinux.exe \ +BOBJECTS = $(BTARGET) mbr/mbr.bin dos/syslinux.com \ memdisk/memdisk memdump/memdump.com # BESUBDIRS and IESUBDIRS are "early", i.e. before the root; BSUBDIRS # and ISUBDIRS are "late", after the root. syslinux-legacy-3.63+dfsg/debian/patches/00list0000664000175000017500000000035211730614544020106 0ustar evanevan01-flags.dpatch 02-64bit-autodetection.dpatch 03-64bit-autodetection-menu.dpatch 10-ubuntu_makefile.dpatch 11-suse_gfxboot.dpatch 12-ubuntu_localboot-gfxdone.dpatch 13-ubuntu_com32_gfxboot.dpatch 14-ubuntu_gfxboot_force_prompt.dpatch syslinux-legacy-3.63+dfsg/debian/patches/12-ubuntu_localboot-gfxdone.dpatch0000664000175000017500000000146111730614544025467 0ustar evanevan#! /bin/sh /usr/share/dpatch/dpatch-run ## 13-ubuntu_localboot-gfxdone.dpatch by Colin Watson ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Make sure the screen gets cleared when switching back to text mode ## DP: from gfxboot. @DPATCH@ diff -urNad syslinux-3.53-1ubuntu1~/gfxboot.inc syslinux-3.53-1ubuntu1/gfxboot.inc --- syslinux-3.53-1ubuntu1~/gfxboot.inc 2007-12-10 19:12:14.068488931 +0100 +++ syslinux-3.53-1ubuntu1/gfxboot.inc 2007-12-10 19:12:14.220491002 +0100 @@ -548,6 +548,17 @@ call far [gfx_bc_done] mov byte [gfx_ok],0 + ; make sure the screen gets cleared + pusha + push ds + push es + mov ax,cs + mov ds,ax + call vgasetmode + pop es + pop ds + popa + ; reactivate 'cwritestr' mov al,[gfx_cwritestr_old] cmp al,0c3h syslinux-legacy-3.63+dfsg/debian/patches/11-suse_gfxboot.dpatch0000664000175000017500000014631711730614544023177 0ustar evanevan#! /bin/sh /usr/share/dpatch/dpatch-run ## 11-suse_gfxboot.dpatch by Colin Watson ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Add gfxboot hooks. The original patch was from openSUSE: ## DP: http://download.opensuse.org/distribution/SL-OSS-factory/inst-source/suse/src/syslinux-3.63-13.src.rpm @DPATCH@ diff -urNad syslinux-3.63+dfsg~/Makefile syslinux-3.63+dfsg/Makefile --- syslinux-3.63+dfsg~/Makefile 2008-04-10 18:30:33.000000000 +0100 +++ syslinux-3.63+dfsg/Makefile 2008-06-13 15:08:24.000000000 +0100 @@ -146,15 +146,16 @@ $(PERL) genhash.pl < keywords > kwdhash.gen # Standard rule for {isolinux,isolinux-debug}.bin -iso%.bin: iso%.asm kwdhash.gen version.gen +iso%.bin: iso%.asm kwdhash.gen version.gen gfxboot.inc $(NASM) $(NASMOPT) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \ -DMAP=$(@:.bin=.map) -l $(@:.bin=.lsr) -o $@ $< $(PERL) lstadjust.pl $(@:.bin=.lsr) $(@:.bin=.map) $(@:.bin=.lst) $(PERL) checksumiso.pl $@ $(PERL) checkov.pl $(@:.bin=.map) $@ + -./add_crc $@ # Standard rule for {ldlinux,pxelinux,extlinux}.bin -%.bin: %.asm kwdhash.gen version.gen +%.bin: %.asm kwdhash.gen version.gen gfxboot.inc $(NASM) $(NASMOPT) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \ -DMAP=$(@:.bin=.map) -l $(@:.bin=.lsr) -o $@ $< $(PERL) lstadjust.pl $(@:.bin=.lsr) $(@:.bin=.map) $(@:.bin=.lst) diff -urNad syslinux-3.63+dfsg~/README.gfxboot syslinux-3.63+dfsg/README.gfxboot --- syslinux-3.63+dfsg~/README.gfxboot 1970-01-01 01:00:00.000000000 +0100 +++ syslinux-3.63+dfsg/README.gfxboot 2008-06-13 15:08:24.000000000 +0100 @@ -0,0 +1,41 @@ +Graphical boot screen +===================== + + syslinux/isolinux support a graphical boot screen using VESA BIOS + extensions. (Note that this is different from the graphics support that + syslinux comes with). + + To use it you have to prepare a special boot logo file and put a line like + this into syslinux.cfg/isolinux.cfg: + + gfxboot foo + + The tools to create 'foo' from the above example are in the gfxboot + package. Please _do_ have a look at its documentation before you begin. + + Note that you cannot use comboot images and graphics at the same time as + the memory used overlaps the comboot loading area. + + If you encouter problems with the graphics code, hold down SHIFT while + syslinux starts. This will put it into 'failsafe' mode that lets you + interactively skip critical parts (like monitor detection). + + + +Spread boot images over several floppy disks (syslinux) +======================================================= + + You can prepare boot disks with a file system that spans several disks. + The 'mkbootdisk' script from the openSUSE project can create a suitable + file system. + + syslinux will ask you for disk changes if necessary. To enable this + feature, use + + disksize + + Note that every individual disk must have at least a valid FAT boot + sector. syslinux will use the serial number stored there to verify that + the correct disk has been inserted (its last hex digit is the zero based + disk number). + diff -urNad syslinux-3.63+dfsg~/abort.inc syslinux-3.63+dfsg/abort.inc --- syslinux-3.63+dfsg~/abort.inc 2008-04-10 18:30:33.000000000 +0100 +++ syslinux-3.63+dfsg/abort.inc 2008-06-13 15:08:24.000000000 +0100 @@ -21,6 +21,11 @@ ; abort_check: let the user abort with or ; abort_check: +%ifdef WITH_GFX + ; don't + cmp byte [gfx_ok],0 + jnz .ret1 +%endif call pollchar jz .ret1 pusha diff -urNad syslinux-3.63+dfsg~/add_crc syslinux-3.63+dfsg/add_crc --- syslinux-3.63+dfsg~/add_crc 1970-01-01 01:00:00.000000000 +0100 +++ syslinux-3.63+dfsg/add_crc 2008-06-13 15:08:24.000000000 +0100 @@ -0,0 +1,57 @@ +#! /usr/bin/perl + +use integer; + +# for isolinux +# +# Ensure checksum over (first sector - 64 bytes) [internally: FirstSecSum] +# is 0 by adjusting the variable csum_value. +# +# Though isolinux checks the integrity with a separate checksum after all +# data has been loaded this does not help with BIOSes that don't get even +# the first 2k right. Hence this additional check. :-( +# + +$file = shift; +$list = "$file"; +$list =~ s/\.bin$/.lsr/; + +open F, $list; + +while() { + if(/^\s*\d+\s*(\S+)\s*0+\s*(\<\d+\>\s*)?csum_value\s*dd\s*0/) { + $ofs = hex $1; + } +} +close F; + +die "oops 1\n" unless $ofs && !($ofs & 3); + +# print "$ofs\n"; + +open F, $file or die "$file: $!\n"; + +$file_size = -s $file; + +sysread F, $buf, $file_size; + +close F; + +die "oops 1\n" if $file_size != length($buf); + +@x = unpack "V512", $buf; + +for ($sum = 0, $i = 16; $i < 512; $i++) { + $sum += $x[$i]; +} + +# printf "0x%08x\n", $sum; + +$ns = pack "V", -$sum; + +substr($buf, $ofs, 4) = $ns; + +open F, ">$file" or die "$file: $!\n"; + +syswrite F, $buf; + diff -urNad syslinux-3.63+dfsg~/com32/libutil/get_key.c syslinux-3.63+dfsg/com32/libutil/get_key.c --- syslinux-3.63+dfsg~/com32/libutil/get_key.c 2008-04-10 18:30:34.000000000 +0100 +++ syslinux-3.63+dfsg/com32/libutil/get_key.c 2008-06-13 15:08:24.000000000 +0100 @@ -42,6 +42,10 @@ #include #include +#ifndef CLK_TCK +# define CLK_TCK __sysconf(2) +#endif + struct keycode { int code; int seqlen; diff -urNad syslinux-3.63+dfsg~/com32/modules/cpuid.c syslinux-3.63+dfsg/com32/modules/cpuid.c --- syslinux-3.63+dfsg~/com32/modules/cpuid.c 2008-04-10 18:30:35.000000000 +0100 +++ syslinux-3.63+dfsg/com32/modules/cpuid.c 2008-06-13 15:08:24.000000000 +0100 @@ -254,7 +254,7 @@ static int smp_scan_config (unsigned long base, unsigned long length) { - unsigned long *bp = base; + unsigned long *bp = (unsigned long *) base; struct intel_mp_floating *mpf; // printf("Scan SMP from %p for %ld bytes.\n", bp,length); diff -urNad syslinux-3.63+dfsg~/com32/samples/keytest.c syslinux-3.63+dfsg/com32/samples/keytest.c --- syslinux-3.63+dfsg~/com32/samples/keytest.c 2008-04-10 18:30:35.000000000 +0100 +++ syslinux-3.63+dfsg/com32/samples/keytest.c 2008-06-13 15:08:24.000000000 +0100 @@ -25,6 +25,10 @@ #include /* Provided by libutil */ #include +#ifndef CLK_TCK +# define CLK_TCK __sysconf(2) +#endif + static void cooked_keys(void) { int key; diff -urNad syslinux-3.63+dfsg~/conio.inc syslinux-3.63+dfsg/conio.inc --- syslinux-3.63+dfsg~/conio.inc 2008-04-10 18:30:35.000000000 +0100 +++ syslinux-3.63+dfsg/conio.inc 2008-06-13 15:08:24.000000000 +0100 @@ -49,6 +49,14 @@ ; Assumes CS == DS == ES. ; get_msg_file: +%ifdef WITH_GFX + ; don't load if graphics code is active + cmp byte [gfx_ok],0 + jz .nogfx + jmp close +.nogfx: +%endif + mov byte [TextAttribute],07h ; Default grey on white mov byte [DisplayMask],07h ; Display text in all modes call msg_initvars diff -urNad syslinux-3.63+dfsg~/doc/syslinux.txt syslinux-3.63+dfsg/doc/syslinux.txt --- syslinux-3.63+dfsg~/doc/syslinux.txt 2008-04-10 18:30:35.000000000 +0100 +++ syslinux-3.63+dfsg/doc/syslinux.txt 2008-06-13 15:08:24.000000000 +0100 @@ -230,7 +230,7 @@ Append nothing. APPEND with a single hyphen as argument in a LABEL section can be used to override a global APPEND. - LOCALBOOT type [ISOLINUX, PXELINUX] + LOCALBOOT type [ISOLINUX, SYSLINUX, PXELINUX] On PXELINUX, specifying "LOCALBOOT 0" instead of a "KERNEL" option means invoking this particular label will cause a local disk boot instead of booting a kernel. @@ -244,12 +244,11 @@ UNDI or PXE stacks are, don't worry -- you don't want them, just specify 0. - On ISOLINUX, the "type" specifies the local drive number to - boot from; 0x00 is the primary floppy drive and 0x80 is the - primary hard drive. The special value -1 causes ISOLINUX to - report failure to the BIOS, which, on recent BIOSes, should - mean that the next boot device in the boot sequence should be - activated. + On ISOLINUX and SYSLINUX, the "type" specifies the local drive + number to boot from; 0x00 is the primary floppy drive and 0x80 is + the primary hard drive. The special value -1 causes them to report + failure to the BIOS, which, on recent BIOSes, should mean that the + next boot device in the boot sequence should be activated. IMPLICIT flag_val If flag_val is 0, do not load a kernel image unless it has been diff -urNad syslinux-3.63+dfsg~/gfxboot.inc syslinux-3.63+dfsg/gfxboot.inc --- syslinux-3.63+dfsg~/gfxboot.inc 1970-01-01 01:00:00.000000000 +0100 +++ syslinux-3.63+dfsg/gfxboot.inc 2008-06-13 15:08:24.000000000 +0100 @@ -0,0 +1,1357 @@ + section .text + +load_gfx_msg db 'Loading...', 0 +no_msg db 0 + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; do a reboot +; +do_reboot: + call gfx_done + mov word [472h],1234h + push word 0ffffh + push word 0 + retf + int 19h + jmp $ + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; wait for 'enter' key pressed +; +wait_for_key: + pusha +wait_for_key_10: + mov ah,0 + int 16h + cmp al,13 + jnz wait_for_key_10 + popa + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; read gfx data +get_gfx_file: + push si + mov si,load_gfx_msg + call cwritestr + pop si + mov word [gfx_mem_start_seg],first_free_seg + push ds + push 40h + pop ds + mov bx,[13h] ; mem size in kb + pop ds + shl bx,6 + mov word [gfx_mem_end_seg],bx + + call gfx_init ; Load and display file + cmp byte [gfx_ok],0 + jz .done + mov si,crlf_msg + call cwritestr +.done: + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; read from disk, ask for disk change, if necessary + +; EAX - Linear sector number +; ES:BX - Target buffer +; BP - Sector count +; +; (es:)bx gets updated + +%if IS_SYSLINUX + +; %define DEBUG_XXX + +getlinsec3: +%ifdef DEBUG_XXX + mov si,txt0 + call dump_params + call crlf +%endif + mov cx,[DiskSize] + or cx,cx + jz getlinsec3_70 ; unlimited + + xor dx,dx + div cx + xchg ax,dx + movzx eax,ax + + mov si,ax + add si,bp + sub si,cx + jbe getlinsec3_40 + ; split + + sub bp,si + movzx ebp,bp + push ebp + push eax + push si + push dx + call getlinsec3_40 + pop dx + pop bp + pop eax + pop esi + add eax,esi + movzx ebp,bp + inc dl + +getlinsec3_40: + push es + pushad + call disk_change + popad + pop es + jc kaboom +getlinsec3_70: +%ifdef DEBUG_XXX + mov si,txt1 + call dump_params + mov si,txt3 + call cwritestr + push ax + mov al,[CurrentDisk] + call writehex2 + pop ax + call crlf + pushad + call getchar + popad +%endif + xor edx,edx + call getlinsec.jmp + ret + +%ifdef DEBUG_XXX +dump_params: + push eax + call cwritestr + mov ax,es + call writehex4 + mov si,txt2 + call cwritestr + mov ax,bx + call writehex4 + mov si,txt3 + call cwritestr + pop eax + push eax + call writehex8 + mov si,txt3 + call cwritestr + mov ax,bp + call writehex4 + pop eax + ret + +txt0 db 'linsec3: ', 0 +txt1 db 'linsec: ', 0 +txt2 db ':', 0 +txt3 db ', ', 0 + +%include "writehex.inc" + +%endif + + +; dl: new disk +; return: CF = 1 -> error +disk_change: + cmp dl,[CurrentDisk] + jz disk_change_90 + + mov [CurrentDisk],dl + movzx eax,dl + mov [gfx_user_info_0],eax + add dl,'1' + mov [boot_disk_msg0],dl + mov [boot_ndisk_msg0],dl + +disk_change_20: + cmp byte [gfx_ok],0 + jz disk_change_40 + mov al,3 + xor di,di + xor si,si + call gfx_infobox + + jmp disk_change_50 +disk_change_40: + mov si,clrln_msg + call cwritestr + mov si,boot_disk_msg + call cwritestr + call wait_for_key + mov si,clrln_msg + call cwritestr +disk_change_50: + xor eax,eax + mov bp,1 + push bx + xor edx,edx + call getlinsec.jmp + pop bx + mov eax,[es:bx+27h] + sub eax,[bsVolumeID] + movzx edx,byte [CurrentDisk] + cmp eax,edx + jz disk_change_90 + mov [gfx_user_info_1],eax + + cmp byte [gfx_ok],0 + jz disk_change_70 + mov al,4 + xor di,di + xor si,si + call gfx_infobox + + jmp disk_change_50 +disk_change_70: + mov si,clrln_msg + call cwritestr + mov si,boot_ndisk_msg + call cwritestr +; mov eax,[es:bx+27h] +; call writehex8 + call wait_for_key + mov si,clrln_msg + call cwritestr + + jmp disk_change_20 +disk_change_90: + ret + + +bsVolumeID equ bsHugeSectors+7 + +boot_disk_msg db 'Please insert boot disk ' +boot_disk_msg0 db '0; then press ENTER to continue.', 0 +boot_ndisk_msg db 'This is not boot disk ' +boot_ndisk_msg0 db '0. Press ENTER to continue.', 0 + +DiskSize dw 0 ; unlimited +CurrentDisk db 0 ; current disk + +clrln_msg db 0dh, ' ', 0dh, 0 + + +cache_metadata: + cmp word [DiskSize],0 + jz cache_md_90 + + mov eax,[FAT] + mov ecx,[bxFATsecs] +cache_md_20: + push eax + push cx + call getcachesector + pop cx + pop eax + inc eax + loop cache_md_20 + + mov eax,[RootDir] +cache_md_40: + push eax + call getcachesector + pop eax + call nextsector + jnc cache_md_40 + +cache_md_90: + ret + + +%endif + + + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; gfx stuff +; +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +; != 0 -> graphics active +gfx_ok db 0 +gfx_cwritestr_old db 0c3h ; 'ret' +gfx_cpio_swab db 0 +gfx_cd_changed db 0 + +gfx_mem_start_seg dw 0 +gfx_mem_end_seg dw 0 + + align 4, db 0 +; the memory area we are working with +gfx_mem dd 0 ; linear address + +gfx_save_area1 dd 0 ; 64k +gfx_save_area1_used db 0 ; != 0 if area1 is in use + +; interface to loadable gfx extension (seg:ofs values) +gfx_bc_jt dd 0 + +gfx_bc_init dd 0 +gfx_bc_done dd 0 +gfx_bc_input dd 0 +gfx_bc_menu_init dd 0 +gfx_bc_infobox_init dd 0 +gfx_bc_infobox_done dd 0 +gfx_bc_progress_init dd 0 +gfx_bc_progress_done dd 0 +gfx_bc_progress_update dd 0 +gfx_bc_progress_limit dd 0 +gfx_bc_password_init dd 0 +gfx_bc_password_done dd 0 + +; menu entry descriptor +menu_entries equ 0 +menu_default equ 2 ; seg:ofs +menu_ent_list equ 6 ; seg:ofs +menu_ent_size equ 10 +menu_arg_list equ 12 ; seg:ofs +menu_arg_size equ 16 +sizeof_menu_desc equ 18 + +menu_desc zb sizeof_menu_desc + +; system config data (52 bytes) +gfx_sysconfig equ $ +gfx_bootloader db 1 ; 0: boot loader type (0: lilo, 1: syslinux, 2: grub) +gfx_sector_shift db SECTOR_SHIFT ; 1: sector shift +gfx_media_type db 0 ; 2: media type (0: disk, 1: floppy, 2: cdrom) +gfx_failsafe db 0 ; 3: turn on failsafe mode (bitmask) + ; 0: SHIFT pressed + ; 1: skip gfxboot + ; 2: skip monitor detection +gfx_sysconfig_size db gfx_sysconfig_end-gfx_sysconfig ; 4: size of sysconfig data +gfx_boot_drive db 0 ; 5: BIOS boot drive +gfx_callback dw gfx_cb ; 6: offset to callback handler +gfx_bootloader_seg dw 0 ; 8: code/data segment used by bootloader; must follow gfx_callback +gfx_reserved_1 dw 0 ; 10 +gfx_user_info_0 dd 0 ; 12: data for info box +gfx_user_info_1 dd 0 ; 16: data for info box +gfx_bios_mem_size dd 0 ; 20: BIOS memory size (in bytes) +gfx_xmem_0 dw 0 ; 24: extended mem area 0 (start:size in MB; 12:4 bits) +gfx_xmem_1 dw 0 ; 26: extended mem area 1 +gfx_xmem_2 dw 0 ; 28: extended mem area 2 +gfx_xmem_3 dw 0 ; 20: extended mem area 3 +gfx_file dd 0 ; 32: start of gfx file +gfx_archive_start dd 0 ; 36: start of cpio archive +gfx_archive_end dd 0 ; 40: end of cpio archive +gfx_mem0_start dd 0 ; 44: low free memory start +gfx_mem0_end dd 0 ; 48: low free memory end +gfx_sysconfig_end equ $ + +gfx_slash db '/', 0 + +%macro lin2segofs 3 + push %1 + call gfx_l2so + pop %3 + pop %2 +%endmacro + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; must not change registers! +; +gfx_get_sysconfig: + push ax + mov al,[DriveNumber] + mov [gfx_boot_drive],al + +%if IS_ISOLINUX + mov ah,2 +%else + mov ah,0 +%endif + cmp al,80h ; floppy ? + jae gfx_get_sysconfig_20 + mov ah,1 +gfx_get_sysconfig_20: + + mov [gfx_media_type],ah + + mov [gfx_bootloader_seg],cs + + pop ax + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Initialize graphics code. Load and display graphics data. +; +; dx:ax file length +; si start cluster +; +; return: [gfx_ok] = 0/1 +; +gfx_init: + push es + + test byte [KbdFlags],3 + jz gfx_init_10 + mov byte [gfx_failsafe],1 + call ask_user +gfx_init_10: + + test byte [gfx_failsafe],2 + jnz gfx_init_80 + + call highmemsize + + ; setup extended memory areas + pusha + mov eax,[HighMemSize] + mov [gfx_bios_mem_size],eax + mov eax,[VKernelEnd] + shr eax,20 + cmp ax,16 + jb gfx_init_40 ; at least 16MB + mov word [gfx_xmem_0], 81h ; 1MB at 8MB + mov word [gfx_xmem_1],0a1h ; 1MB at 10MB + mov word [gfx_xmem_2],0c1h ; 1MB at 12MB + mov word [gfx_xmem_3],0e1h ; 1MB at 14MB + + mov dword [gfx_save_area1],7f0000h ; 8MB-64k +gfx_init_40: + popa + + cld + + movzx ebx,word [gfx_mem_start_seg] + shl ebx,4 + jz gfx_init_80 + + movzx ecx,word [gfx_mem_end_seg] + shl ecx,4 + jz gfx_init_80 + + cmp ecx,ebx + jbe gfx_init_80 + + ; define our memory area + ; gfx_mem _must_ be 16-byte aligned + mov dword [gfx_mem],ebx + mov dword [gfx_mem0_start],ebx + mov dword [gfx_mem0_end],ecx + + call gfx_read_file + cmp byte [gfx_ok],0 + jz near gfx_init_90 + + call gfx_get_sysconfig + + ; align 4 + mov eax,[gfx_mem0_start] + add eax,3 + and eax,~3 + mov [gfx_mem0_start],eax + + ; setup jump table + les bx,[gfx_bc_jt] + + mov ax,[es:bx] + mov [gfx_bc_init],ax + mov [gfx_bc_init+2],es + + mov ax,[es:bx+2] + mov [gfx_bc_done],ax + mov [gfx_bc_done+2],es + + mov ax,[es:bx+4] + mov [gfx_bc_input],ax + mov [gfx_bc_input+2],es + + mov ax,[es:bx+6] + mov [gfx_bc_menu_init],ax + mov [gfx_bc_menu_init+2],es + + mov ax,[es:bx+8] + mov [gfx_bc_infobox_init],ax + mov [gfx_bc_infobox_init+2],es + + mov ax,[es:bx+10] + mov [gfx_bc_infobox_done],ax + mov [gfx_bc_infobox_done+2],es + + mov ax,[es:bx+12] + mov [gfx_bc_progress_init],ax + mov [gfx_bc_progress_init+2],es + + mov ax,[es:bx+14] + mov [gfx_bc_progress_done],ax + mov [gfx_bc_progress_done+2],es + + mov ax,[es:bx+16] + mov [gfx_bc_progress_update],ax + mov [gfx_bc_progress_update+2],es + + mov ax,[es:bx+18] + mov [gfx_bc_progress_limit],ax + mov [gfx_bc_progress_limit+2],es + + mov ax,[es:bx+20] + mov [gfx_bc_password_init],ax + mov [gfx_bc_password_init+2],es + + mov ax,[es:bx+22] + mov [gfx_bc_password_done],ax + mov [gfx_bc_password_done+2],es + + mov esi,cs + shl esi,4 + add esi,gfx_sysconfig + call far [gfx_bc_init] + jc gfx_init_80 + + mov byte [gfx_ok],1 + + ; turn off 'cwritestr' + mov al,[cwritestr] + cmp al,0c3h + jz gfx_init_90 + mov [gfx_cwritestr_old],al + mov byte [cwritestr],0c3h + + jmp gfx_init_90 + +gfx_init_80: + mov byte [gfx_ok],0 +gfx_init_90: + pop es + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Back to text mode. +; +; return: [gfx_ok] = 0 +; +gfx_done: + push ax + cmp byte [gfx_ok],0 + jz gfx_done_90 + call far [gfx_bc_done] + mov byte [gfx_ok],0 + + ; reactivate 'cwritestr' + mov al,[gfx_cwritestr_old] + cmp al,0c3h + jz gfx_done_90 + mov [cwritestr],al +gfx_done_90: + pop ax + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +gfx_input: + cmp byte [gfx_ok],0 + jz gfx_input_90 + cmp byte [gfx_save_area1_used],0 + jz gfx_input_10 + ; recover saved menu layout, gfxboot has references into it + pushad + mov esi,[gfx_save_area1] + mov edi,gfx_menu_seg << 4 + mov ecx,10000h + call bcopy + popad +gfx_input_10: + call far [gfx_bc_input] + jnc gfx_input_50 + mov ax,1 +gfx_input_50: + cmp ax,1 + jnz gfx_input_90 + push ax + call gfx_done + pop ax +gfx_input_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; es:di string +; return: +; cx length +gfx_strlen: + mov cx,-1 + mov al,0 + repnz scasb + not cx + dec cx + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +gfx_setup_menu: + push es + cmp byte [gfx_ok],0 + jz gfx_setup_menu_90 + + mov dword [menu_desc+menu_default],gfx_menu_seg << 16 + + push ds + pop es + mov si,default_cmd + mov di,trackbuf + call mangle_name + mov si,trackbuf + les di,[menu_desc+menu_default] + call unmangle_name + inc di + + mov [menu_desc+menu_ent_list],di + mov [menu_desc+menu_ent_list+2],es + mov [menu_desc+menu_arg_list],di + mov [menu_desc+menu_arg_list+2],es + + ; first, count entries and find max kernel and append length + + push ds + pop es + + mov esi,[HighMemSize] + jmp gfx_setup_menu_20 +gfx_setup_menu_10: + mov di,VKernelBuf + call rllunpack + + ; count only non empty entries + cmp byte [VKernelBuf],0 + jz gfx_setup_menu_20 + + inc word [menu_desc+menu_entries] + + push esi + mov si,VKernelBuf + mov di,KernelCName + push di + call unmangle_name + pop di + pop esi + + call gfx_strlen + + cmp cx,[menu_desc+menu_ent_size] + jbe gfx_setup_menu_15 + mov [menu_desc+menu_ent_size],cx +gfx_setup_menu_15: + mov ax,[VKernelBuf+vk_appendlen] + cmp ax,[menu_desc+menu_arg_size] + jbe gfx_setup_menu_20 + mov [menu_desc+menu_arg_size],ax + +gfx_setup_menu_20: + cmp esi,[VKernelEnd] + ja gfx_setup_menu_10 + + inc word [menu_desc+menu_ent_size] + mov ax,[menu_desc+menu_ent_size] + inc ax + add [menu_desc+menu_arg_size],ax + + ; ...and again, but this time copy entries + + mov word [menu_desc+menu_entries],0 + + mov esi,[HighMemSize] + jmp gfx_setup_menu_60 +gfx_setup_menu_30: + mov di,VKernelBuf + call rllunpack + + ; count only non empty entries + cmp byte [VKernelBuf],0 + jz gfx_setup_menu_60 + + mov di,[menu_desc+menu_arg_list] + add di,[menu_desc+menu_arg_size] + jc gfx_setup_menu_60 + + inc word [menu_desc+menu_entries] + + push esi + + mov si,VKernelBuf + mov di,KernelCName + push di + call unmangle_name + pop si + mov cx,[menu_desc+menu_ent_size] + les di,[menu_desc+menu_arg_list] + + rep movsb + + mov cx,[VKernelBuf+vk_appendlen] + mov si,VKernelBuf+vk_append + rep movsb + mov byte [es:di],0 + + pop esi + + push ds + pop es + + mov ax,[menu_desc+menu_arg_size] + add [menu_desc+menu_arg_list],ax + +gfx_setup_menu_60: + cmp esi,[VKernelEnd] + ja gfx_setup_menu_30 + + mov ax,[menu_desc+menu_ent_size] + mov bx,[menu_desc+menu_arg_size] + mov [menu_desc+menu_ent_size],bx + add ax,[menu_desc+menu_ent_list] + mov [menu_desc+menu_arg_list],ax + + mov esi,ds + shl esi,4 + add esi,menu_desc + + call far [gfx_bc_menu_init] + + ; save menu structure, gfxboot uses references into it + mov edi,[gfx_save_area1] + or edi,edi + jz gfx_setup_menu_90 + mov esi,gfx_menu_seg << 4 + mov ecx,10000h + call bcopy + mov byte [gfx_save_area1_used],1 + +gfx_setup_menu_90: + pop es + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +gfx_infobox: + pushad + cmp byte [gfx_ok],0 + jz gfx_infobox_90 + mov ecx,ds + shl ecx,4 + movzx esi,si + movzx edi,di + or si,si + jz gfx_infobox_20 + add esi,ecx +gfx_infobox_20: + or di,di + jz gfx_infobox_30 + add edi,ecx +gfx_infobox_30: + call far [gfx_bc_infobox_init] + xor edi,edi + xor eax,eax + call far [gfx_bc_input] + call far [gfx_bc_infobox_done] +gfx_infobox_90: + popad + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +gfx_progress_init: + pushad + cmp byte [gfx_ok],0 + jz gfx_progress_init_90 + call far [gfx_bc_progress_init] +gfx_progress_init_90: + popad + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +gfx_progress_done: + pushad + cmp byte [gfx_ok],0 + jz gfx_progress_done_90 + call far [gfx_bc_progress_done] +gfx_progress_done_90: + popad + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +gfx_progress_update: + pushad + cmp byte [gfx_ok],0 + jz gfx_progress_update_90 + movzx eax,cx + call far [gfx_bc_progress_update] +gfx_progress_update_90: + popad + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +gfx_progress_limit: + pushad + cmp byte [gfx_ok],0 + jz gfx_progress_limit_90 + movzx eax,ax + movzx edx,dx + call far [gfx_bc_progress_limit] +gfx_progress_limit_90: + popad + ret + + +%if 0 +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +gfx_password: + pushad + cmp byte [gfx_ok],0 + stc + jz gfx_password_90 + call far [gfx_bc_password_init] + mov edi,ds + shl edi,4 + add edi,gfx_password_buf + mov ecx,32 + xor eax,eax + call far [gfx_bc_input] + mov esi,ds + shl esi,4 + add esi,gfx_password_buf + call far [gfx_bc_password_done] + jnc gfx_password_90 + mov esi,ds + shl esi,4 + add esi,gfx_msg_wrong_password + xor edi,edi + mov al,0 + call far [gfx_bc_infobox_init] + xor edi,edi + xor eax,eax + call far [gfx_bc_input] + call far [gfx_bc_infobox_done] + stc +gfx_password_90: + popad + ret +%endif + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Read graphics data and store them at [gfx_mem]. +; +; dx:ax file length +; si start cluster +; +; return: [gfx_ok] = 0/1 +; +gfx_read_file: + push es + mov byte [gfx_ok],0 + mov edi,[gfx_mem] + push dx ; DX:AX = length of file + push ax + pop edx + mov [gfx_archive_end],edx + mov eax,[gfx_mem0_start] + lea eax,[eax+edx+0fh] ; add space for alignment + cmp eax,[gfx_mem0_end] ; max. length + ja near gfx_read_file_90 + mov [gfx_mem0_start],eax + +gfx_read_file_10: + mov bx,trackbuf + mov cx,[BufSafe] + push edi + push edx + call getfssec + pop edx + pop edi + movzx ecx,word [BufSafeBytes] + cmp edx,ecx + jae gfx_read_file_20 + mov ecx,edx +gfx_read_file_20: + push ecx + push edi + push si ; Save current cluster + push es + mov si,trackbuf + push edi + call gfx_l2so + pop di + pop es + rep movsb + pop es + pop si + pop edi + pop ecx + add edi,ecx + sub edx,ecx + ja gfx_read_file_10 + + call find_file + or eax,eax + jz gfx_read_file_90 + push edi + push eax + add eax,edi + call align_it + pop eax + pop edi + sub edi,[gfx_mem] + mov ecx,[gfx_archive_start] + add edi,ecx + mov [gfx_file],edi + add [gfx_archive_end],ecx + add eax,edi + shr eax,4 + mov [gfx_bc_jt+2],ax + + mov byte [gfx_ok],1 + +gfx_read_file_90: + pop es + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; locate graphics file +; +; return: eax: code offset (0 -> no file found) +; edi: gfx file start +; +find_file: + mov edi,[gfx_mem] + lin2segofs edi,es,bx + call magic_ok + or eax,eax + jnz find_file_90 + + ; ok, maybe it's a cpio archive + + ; note: edi must be properly aligned (2)! + +find_file_20: + mov ecx,[gfx_mem0_start] + sub ecx,26 + 12 ; min cpio header + gfx header + cmp edi,ecx + jae find_file_90 + + lin2segofs edi,es,bx + cmp word [es:bx],71c7h + jz find_file_30 ; normal cpio record + cmp word [es:bx],0c771h ; maybe byte-swapped? + jnz find_file_90 ; no cpio record + mov byte [gfx_cpio_swab],1 + +find_file_30: + mov ax,[es:bx+20] ; file name size + call cpio_swab + movzx esi,ax + + inc si + and si,~1 ; align + + mov eax,[es:bx+22] ; data size + call cpio_swab + rol eax,16 ; get word order right + call cpio_swab + mov ecx,eax + + inc ecx + and ecx,byte ~1 ; align + + add si,26 ; skip header + + add edi,esi + add bx,si + call magic_ok + or eax,eax + jnz find_file_90 + + add edi,ecx + jmp find_file_20 + +find_file_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; byte-swap cpio data if appropriate +; +; ax: word to swap +; +; return: ax: swapped if [gfx_cpio_swab], otherwise same as input +; +cpio_swab: + cmp byte [gfx_cpio_swab],0 + jz cpio_swab_90 + xchg ah,al + +cpio_swab_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; es:bx file start +; +; return: eax: offset to code entry +; +; Notes: +; - changes no regs except eax +; +magic_ok: + xor eax,eax + cmp dword [es:bx],0b2d97f00h ; header.magic_id + jnz magic_ok_90 + cmp byte [es:bx+4],8 ; header.version + jnz magic_ok_90 + mov eax,[es:bx+8] +magic_ok_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; eax address to be aligned +; +align_it: + push dword [gfx_mem] + pop dword [gfx_archive_start] + neg al + and eax,byte 0fh + jz align_it_90 + add [gfx_archive_start],eax + mov esi,[gfx_mem] + mov ebx,[gfx_mem0_start] + sub ebx,esi + sub ebx,byte 0fh + add esi,ebx + dec esi + + std + +align_it_30: + or ebx,ebx + jz align_it_60 + mov ecx,ebx + cmp ebx,8000h + jb align_it_40 + mov ecx,8000h +align_it_40: + push esi + sub ebx,ecx + sub [esp],ecx + push esi + call gfx_l2so + pop si + add si,8000h + sub word [esp],(8000h >> 4) + pop es + mov di,si + add di,ax + es rep movsb + pop esi + jmp align_it_30 +align_it_60: + + cld + +align_it_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Ask user whether to continue. +; +; don't change regs +; +ask_user: + pushad + + mov si,failsafe_msg_0 + call cwritestr + + mov dx,2 + mov si,failsafe_msg_1 + call ask_question + + test byte [gfx_failsafe],2 + jnz ask_user_90 + + mov dx,4 + mov si,failsafe_msg_2 + call ask_question + +ask_user_90: + + popad + ret + + +; si: text +; dh: 'yes'-mask +; dl: 'no'-mask +ask_question: + push dx + call cwritestr + mov si,failsafe_msg_q + call cwritestr + pop dx + +ask_question_20: + push dx + mov ah,0 + int 16h + pop dx + + cmp al,13 + jnz ask_question_30 + mov al,'y' +ask_question_30: + or al,20h ; force lower case + + cmp al,'y' + jz ask_question_40 + cmp al,'n' + jnz ask_question_20 + or byte [gfx_failsafe],dl + jmp ask_question_50 +ask_question_40: + or byte [gfx_failsafe],dh +ask_question_50: + + mov si,failsafe_key + mov [si],al + call cwritestr + + ret + +failsafe_msg_q db ' (y/n)? y', 8, 0 + +failsafe_msg_0 db 13, 10, 10, 10, 0 +failsafe_msg_1 db 'Load boot graphics', 0 +failsafe_msg_2 db 'Detect display size', 0 + +failsafe_key db 0, 13, 10, 0 + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Convert 32bit linear address to seg:ofs. +; +; dword [esp + 2]: linear address +; +; return: +; dword [esp + 2]: seg:ofs +; +; Notes: +; - changes no regs +; +gfx_l2so: + push eax + mov eax,[esp + 6] + shr eax,4 + mov [esp + 8],ax + and word [esp + 6],byte 0fh + pop eax + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +cb_table dw cb_status + dw cb_fopen + dw cb_fread + dw cb_getcwd + dw cb_chdir + dw cb_readsector +cb_len equ ($-cb_table)/2 + +f_handle dw 0 +f_size dd 0 +fname_buf times 64 db 0 +fname_buf_len equ $ - fname_buf + + +gfx_cb: + push cs + pop ds + + cmp al,cb_len + jae gfx_cb_80 + + movzx bx,al + add bx,bx + call word [bx+cb_table] + jmp gfx_cb_90 + +gfx_cb_80: + mov al,0ffh +gfx_cb_90: + retf + + +; Return status info. +; +; return: +; edx filename buffer (64 bytes) +; +cb_status: + mov edx,cs + shl edx,4 + add edx,fname_buf + + xor al,al + ret + +; Open file. +; +; return: +; al 0: ok, 1: file not found +; ecx file length (al = 0) +; +cb_fopen: + mov si,fname_buf + mov di,VGAFileMBuf ; we just need some space + push ds + pop es + push di + call mangle_name + pop di + call searchdir + xchg ax,bx + mov al,1 + jz cb_fopen_90 + mov [f_handle],si + mov cx,dx + shl ecx,16 + mov cx,bx + mov [f_size],ecx +cb_fopen_80: + xor al,al +cb_fopen_90: + ret + + +; Read next chunk. +; +; return: +; edx buffer address (linear) +; ecx data length (< 64k) +; +cb_fread: + cmp dword [f_size],0 + jz cb_fread_80 + push cs + pop es + mov bx,trackbuf + mov cx,[BufSafe] + mov si,[f_handle] + call getfssec + mov [f_handle],si + mov ecx,[f_size] + movzx edx,word [BufSafeBytes] + cmp ecx,edx + jbe cb_fread_50 + mov ecx,edx +cb_fread_50: + sub [f_size],ecx + mov edx,cs + shl edx,4 + add edx,trackbuf + +cb_fread_80: + xor al,al +cb_fread_90: + ret + + +; Return current working directory. +; +; return: +; edx filename +; +cb_getcwd: + mov edx,cs + shl edx,4 +%if IS_ISOLINUX + add edx,isolinux_dir +%else + add edx,gfx_slash +%endif + xor al,al + ret + + +; Set current working directory. +; +cb_chdir: +%if IS_ISOLINUX + + push cs + pop es + mov si,fname_buf + mov di,isolinux_dir +cb_chdir_20: + lodsb + stosb + or al,al + jz cb_chdir_60 + cmp di,config_name - 1 + jb cb_chdir_20 + xor al,al + stosb +cb_chdir_60: + call get_fs_structures + +%endif + xor al,al + ret + + +; read sector +; +; edx sector +; +; return: +; edx buffer (linear address) +; +; Note: does not return on error! +; +cb_readsector: + mov eax,edx + push ds + pop es + mov bx,trackbuf + call getonesec + mov edx,ds + shl edx,4 + add edx,trackbuf + xor al,al + ret + diff -urNad syslinux-3.63+dfsg~/isolinux.asm syslinux-3.63+dfsg/isolinux.asm --- syslinux-3.63+dfsg~/isolinux.asm 2008-04-10 18:30:35.000000000 +0100 +++ syslinux-3.63+dfsg/isolinux.asm 2008-06-13 15:08:24.000000000 +0100 @@ -19,6 +19,10 @@ ; **************************************************************************** %define IS_ISOLINUX 1 + +%define WITH_GFX 1 +; %define DEBUG_DISKIO + %include "head.inc" ; @@ -70,6 +74,8 @@ real_mode_seg equ 2000h xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem comboot_seg equ real_mode_seg ; COMBOOT image loading zone +gfx_menu_seg equ 3000h ; temporary storage to setup menu +first_free_seg equ 4000h ; end of isolinux used memory ; ; File structure. This holds the information for each currently open file. @@ -259,6 +265,21 @@ mov [FirstSecSum],edi mov [DriveNumber],dl + + ; check whether the BIOS did load us correctly + cmp dl,80h ; some BIOSes try to do floppy emulation... + jb bios_err + cmp dword [FirstSecSum], byte 0 + jz bios_ok +bios_err: + mov si,broken_bios_msg + call writemsg + jmp short $ +broken_bios_msg db 13, 10, 'Cannot boot from this CD. Please try a BIOS update.', 13, 10, 0 + align 4 +csum_value dd 0 +bios_ok: + %ifdef DEBUG_MESSAGES mov si,startup_msg call writemsg @@ -283,6 +304,9 @@ ; Other nonzero fields inc word [dsp_sectors] +%if 0 + ; Some BIOSes don't like that call. + ; Now figure out what we're actually doing ; Note: use passed-in DL value rather than 7Fh because ; at least some BIOSes will get the wrong value otherwise @@ -303,6 +327,8 @@ call crlf %endif +%endif + found_drive: ; Alright, we have found the drive. Now, try to find the ; boot file itself. If we have a boot info table, life is @@ -427,6 +453,9 @@ %endif jmp all_read ; Jump to main code +%if 0 + ; doesn't work anyway, see above + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Start of BrokenAwardHack --- 10-nov-2002 Knut_Petersen@t-online.de ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -618,6 +647,7 @@ mov si,trysbm_msg call writemsg jmp .found_drive ; Pray that this works... +%endif fatal_error: mov si,nothing_msg @@ -694,10 +724,17 @@ ; getlinsec: mov si,dapa ; Load up the DAPA - mov [si+4],bx - mov bx,es - mov [si+6],bx mov [si+8],eax + ; seems that some BIOSes have problems if the target + ; segment is 0 (don't ask); to avoid this, we normalize + ; the buffer address here + ; -> seen on Acer TravelMate C102Ti + mov [si+4],bx + and word [si+4],0fh + mov ax,es + shr bx,4 + add ax,bx + mov [si+6],ax .loop: push bp ; Sectors left cmp bp,[MaxTransfer] @@ -724,15 +761,78 @@ ; INT 13h with retry xint13: mov byte [RetryCount],retry_count .try: pushad +%ifdef DEBUG_DISKIO + pushad + mov cx,16 +.zap: + lodsb + call writehex2 + mov al,' ' + call writechr + loop .zap + mov ah,0 + int 16h + popad +%endif + ; seen buggy bios that overwrites buffer address on error... + push dword [dapa + 4] call int13 + pop dword [dapa + 4] +%ifdef DEBUG_DISKIO + pushad + pushf + push ax + mov al,':' + call writechr + mov al,' ' + call writechr + pop ax + sbb al,al + call writehex4 + call crlf + mov ah,0 + int 16h + popf + popad +%endif jc .error +.noerror: add sp,byte 8*4 ; Clean up stack ret .error: + or ah,ah + jz .noerror mov [DiskError],ah ; Save error code popad mov [DiskSys],ax ; Save system call number - dec byte [RetryCount] + +%if 0 + ; eject currently not supported - doesn't work anyway with + ; most BIOSes + + test byte [gfx_user_note],1 + jz .noeject + cmp byte [RetryCount],4 + ja .noeject + cmp byte [DiskError],0aah ; drive not ready + jnz .noeject + ; might have been cdrom eject, wait a bit + cmp byte [gfx_ok],0 + jz .noeject + push si + push di + push ax + mov si,err_not_ready + xor di,di + mov al,0 + call gfx_infobox + pop ax + pop di + pop si +%endif +.noeject: + + dec byte [RetryCount] jz .real_error push ax mov al,[RetryCount] @@ -774,6 +874,17 @@ ; kaboom: RESET_STACK_AND_SEGS AX + + cmp byte [gfx_ok],0 + jz .nogfx + mov si,err_failed_gfx + xor di,di + mov al,1 + call gfx_infobox + call gfx_done + call do_reboot +.nogfx: + mov si,err_bootfailed call cwritestr call getchar @@ -825,6 +936,9 @@ crlf_msg db CR, LF null_msg db 0 +err_failed_gfx db 'Error reading boot CD.', 0 +err_not_ready db 'CDROM drive not ready.', 0 + alignb 4, db 0 MaxTransfer dw 32 ; Max sectors per transfer @@ -882,6 +996,9 @@ ; (which will be at 16 only for a single-session disk!); from the PVD ; we should be able to find the rest of what we need to know. ; + call get_fs_structures + jmp get_fs_struct_done + get_fs_structures: mov eax,[bi_pvd] mov bx,trackbuf @@ -907,10 +1024,15 @@ ; Look for an isolinux directory, and if found, ; make it the current directory instead of the root ; directory. + + cmp byte [gfx_ok],0 ; don't look at both + jnz .gfx + mov di,boot_dir ; Search for /boot/isolinux mov al,02h call searchdir_iso jnz .found_dir +.gfx: mov di,isolinux_dir mov al,02h ; Search for /isolinux call searchdir_iso @@ -931,6 +1053,9 @@ call crlf %endif .no_isolinux_dir: + ret + +get_fs_struct_done: ; ; Locate the configuration file @@ -1096,6 +1221,9 @@ ; 0xFFFF in case we should execute INT 18h ("next device.") ; local_boot: +%ifdef WITH_GFX + call gfx_done +%endif call vgaclearmode lss sp,[cs:Stack] ; Restore stack pointer xor dx,dx @@ -1113,7 +1241,7 @@ xor dh,dh push dx xor ax,ax ; Reset drive - call xint13 + int 13h ; we don't care about errors here... mov ax,0201h ; Read one sector mov cx,0001h ; C/H/S = 0/0/1 (first sector) mov bx,trackbuf @@ -1488,6 +1616,9 @@ %include "rawcon.inc" ; Console I/O w/o using the console functions %include "adv.inc" ; Auxillary Data Vector +%include "gfxboot.inc" ; add gfx things + + ; ----------------------------------------------------------------------------- ; Begin data section ; ----------------------------------------------------------------------------- @@ -1499,6 +1630,7 @@ default_len equ ($-default_str) boot_dir db '/boot' ; /boot/isolinux isolinux_dir db '/isolinux', 0 +zb 64 config_name db 'isolinux.cfg', 0 err_disk_image db 'Cannot load disk image (invalid file)?', CR, LF, 0 diff -urNad syslinux-3.63+dfsg~/keywords syslinux-3.63+dfsg/keywords --- syslinux-3.63+dfsg~/keywords 2008-06-13 15:07:39.000000000 +0100 +++ syslinux-3.63+dfsg/keywords 2008-06-13 15:08:24.000000000 +0100 @@ -43,3 +43,5 @@ f10 f11 f12 +gfxboot +disksize diff -urNad syslinux-3.63+dfsg~/keywords.inc syslinux-3.63+dfsg/keywords.inc --- syslinux-3.63+dfsg~/keywords.inc 2008-06-13 15:07:39.000000000 +0100 +++ syslinux-3.63+dfsg/keywords.inc 2008-06-13 15:08:24.000000000 +0100 @@ -91,8 +91,15 @@ %if IS_PXELINUX keyword ipappend, pc_ipappend %endif -%if IS_PXELINUX || IS_ISOLINUX +%if IS_PXELINUX || IS_ISOLINUX || IS_SYSLINUX keyword localboot, pc_localboot %endif +%ifdef WITH_GFX + keyword gfxboot, pc_filecmd, get_gfx_file +%if IS_SYSLINUX + keyword disksize, pc_disksize, DiskSize +%endif +%endif + keywd_count equ ($-keywd_table)/keywd_size diff -urNad syslinux-3.63+dfsg~/layout.inc syslinux-3.63+dfsg/layout.inc --- syslinux-3.63+dfsg~/layout.inc 2008-04-10 18:30:35.000000000 +0100 +++ syslinux-3.63+dfsg/layout.inc 2008-06-13 15:08:24.000000000 +0100 @@ -88,7 +88,11 @@ section .uibss nobits align=16 follows=.adv ; Normal bss... +%if IS_ISOLINUX + section .bss1 nobits align=16 follows=.bss2 +%else section .bss1 nobits align=16 follows=.uibss +%endif ; Reserve space for stack section .stack nobits align=16 start=STACK_START diff -urNad syslinux-3.63+dfsg~/ldlinux.asm syslinux-3.63+dfsg/ldlinux.asm --- syslinux-3.63+dfsg~/ldlinux.asm 2008-04-10 18:30:35.000000000 +0100 +++ syslinux-3.63+dfsg/ldlinux.asm 2008-06-13 15:08:24.000000000 +0100 @@ -24,6 +24,9 @@ %ifndef IS_MDSLINUX %define IS_SYSLINUX 1 %endif + +%define WITH_GFX 1 + %include "head.inc" ; @@ -82,6 +85,8 @@ cache_seg equ 2000h ; 64K area for metadata cache xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem comboot_seg equ real_mode_seg ; COMBOOT image loading zone +gfx_menu_seg equ 4000h ; temporary storage to setup menu +first_free_seg equ 5000h ; end of syslinux used memory ; ; File structure. This holds the information for each currently open file. @@ -357,6 +362,8 @@ add eax,[bsHidden] ; Add partition offset xor edx,edx ; Zero-extend LBA (eventually allow 64 bits) +.patch: jmp strict near .jmp + .jmp: jmp strict short getlinsec_cbios ; @@ -906,6 +913,48 @@ ; %include "ui.inc" +; Boot a specified local disk. AX specifies the BIOS disk number; or +; 0xFFFF in case we should execute INT 18h ("next device.") +; +local_boot: +%ifdef WITH_GFX + call gfx_done +%endif + call vgaclearmode + lss sp,[cs:Stack] ; Restore stack pointer + xor dx,dx + mov ds,dx + mov es,dx + mov fs,dx + mov gs,dx + mov si,localboot_msg + call cwritestr + cmp ax,-1 + je .int18 + + ; Load boot sector from the specified BIOS device and jump to it. + mov dl,al + xor dh,dh + push dx + xor ax,ax ; Reset drive + int 13h + mov ax,0201h ; Read one sector + mov cx,0001h ; C/H/S = 0/0/1 (first sector) + mov bx,trackbuf + int 13h + pop dx + cli ; Abandon hope, ye who enter here + mov si,trackbuf + mov di,07C00h + mov cx,512 ; Probably overkill, but should be safe + rep movsd + mov ss,cx + mov sp,7c00h + jmp 0:07C00h ; Jump to new boot sector +.int18: + int 18h ; Hope this does the right thing... + jmp kaboom ; If we returned, oh boy... + ; ; allocate_file: Allocate a file structure ; @@ -1126,6 +1175,15 @@ ; starting with "kaboom.patch" with this part kaboom2: + cmp byte [gfx_ok],0 + jz .nogfx + mov si,err_failed_gfx + xor di,di + mov al,1 + call gfx_infobox + call gfx_done + call do_reboot +.nogfx: mov si,err_bootfailed call cwritestr cmp byte [kaboom.again+1],18h ; INT 18h version? @@ -1530,6 +1588,8 @@ %include "cache.inc" ; Metadata disk cache %include "adv.inc" ; Auxillary Data Vector +%include "gfxboot.inc" ; add gfx things + ; ----------------------------------------------------------------------------- ; Begin data section ; ----------------------------------------------------------------------------- @@ -1539,6 +1599,8 @@ db CR, LF, 0 err_bootfailed db CR, LF, 'Boot failed: please change disks and press ' db 'a key to continue.', CR, LF, 0 +err_failed_gfx db 'Error reading from disk.', 0 +localboot_msg db 'Booting from local disk...', CR, LF, 0 syslinux_cfg1 db '/boot' ; /boot/syslinux/syslinux.cfg syslinux_cfg2 db '/syslinux' ; /syslinux/syslinux.cfg syslinux_cfg3 db '/' ; /syslinux.cfg diff -urNad syslinux-3.63+dfsg~/loadhigh.inc syslinux-3.63+dfsg/loadhigh.inc --- syslinux-3.63+dfsg~/loadhigh.inc 2008-04-10 18:30:35.000000000 +0100 +++ syslinux-3.63+dfsg/loadhigh.inc 2008-06-13 15:08:24.000000000 +0100 @@ -47,7 +47,12 @@ .read_loop: and si,si ; If SI == 0 then we have end of file jz .eof +%ifdef WITH_GFX + cmp byte [gfx_ok],0 + jnz .no_message +%endif call bx +.no_message: push bx ; Pausebird function push eax ; Total bytes to transfer @@ -63,7 +68,15 @@ push edi ; Target buffer mov cx,ax xor bx,bx ; ES:0 + +%ifdef WITH_GFX + call gfx_progress_update +%endif + + push dx call getfssec ; Load the data into xfer_buf_seg + ; getfssec destroys dx! + pop dx pop edi ; Target buffer pop ecx ; Byte count this round push ecx ; Byte count this round diff -urNad syslinux-3.63+dfsg~/parsecmd.inc syslinux-3.63+dfsg/parsecmd.inc --- syslinux-3.63+dfsg~/parsecmd.inc 2008-04-10 18:30:35.000000000 +0100 +++ syslinux-3.63+dfsg/parsecmd.inc 2008-06-13 15:08:24.000000000 +0100 @@ -107,6 +107,14 @@ FKeyName resb MAX_FKEYS*FILENAME_MAX ; File names for F-key help KernelCNameLen resw 1 ; Length of unmangled kernel name InitRDCNameLen resw 1 ; Length of unmangled initrd name + +%if IS_ISOLINUX +%ifdef DEBUG_MESSAGES +; we need to rearrange memory a bit to make isolinux-debug.bin fit + section .bss +%endif +%endif + %if IS_SYSLINUX KernelName resb FILENAME_MAX+1 ; Mangled name for kernel KernelCName resb FILENAME_MAX+2 ; Unmangled kernel name diff -urNad syslinux-3.63+dfsg~/parseconfig.inc syslinux-3.63+dfsg/parseconfig.inc --- syslinux-3.63+dfsg~/parseconfig.inc 2008-06-13 15:07:39.000000000 +0100 +++ syslinux-3.63+dfsg/parseconfig.inc 2008-06-13 15:08:24.000000000 +0100 @@ -94,7 +94,7 @@ ; ; "localboot" command (PXELINUX, ISOLINUX) ; -%if IS_PXELINUX || IS_ISOLINUX +%if IS_PXELINUX || IS_ISOLINUX || IS_SYSLINUX pc_localboot: call getint cmp byte [VKernel],0 ; ("label" section only) je .err @@ -299,6 +299,25 @@ mov [SerialPort], word 0 ret +%ifdef WITH_GFX +%if IS_SYSLINUX +; +; like pc_setint16, but patch sector read funtion, too +; +pc_disksize: + push ax + call getint + pop si + jc .err + mov [si],bx + mov word [getlinsec.patch+1], getlinsec3 - getlinsec.patch - 3 + or bx,bx + jz .err + call cache_metadata +.err: ret +%endif +%endif + ; ; "F"-key command ; diff -urNad syslinux-3.63+dfsg~/pxelinux.asm syslinux-3.63+dfsg/pxelinux.asm --- syslinux-3.63+dfsg~/pxelinux.asm 2008-04-10 18:30:35.000000000 +0100 +++ syslinux-3.63+dfsg/pxelinux.asm 2008-06-13 15:08:24.000000000 +0100 @@ -846,6 +846,9 @@ ; AX contains the appropriate return code. ; local_boot: +%ifdef WITH_GFX + call gfx_done +%endif push cs pop ds mov [LocalBootType],ax diff -urNad syslinux-3.63+dfsg~/runkernel.inc syslinux-3.63+dfsg/runkernel.inc --- syslinux-3.63+dfsg~/runkernel.inc 2008-04-10 18:30:35.000000000 +0100 +++ syslinux-3.63+dfsg/runkernel.inc 2008-06-13 15:08:24.000000000 +0100 @@ -206,6 +206,15 @@ pop ds sub si,cmd_line_here mov [CmdLineLen],si ; Length including final null + +%ifdef WITH_GFX + mov eax,[KernelSects] + mov esi,ds + shl esi,4 + add esi,KernelCName + call gfx_progress_init +%endif + ; ; Now check if we have a large kernel, which needs to be loaded high ; @@ -312,6 +321,19 @@ jz nk_noinitrd call parse_load_initrd nk_noinitrd: + +%ifdef WITH_GFX + call gfx_progress_done + + cmp byte [gfx_cd_changed],0 + jz .no_cd_change + mov al,6 + xor si,si + xor di,di + call gfx_infobox +.no_cd_change: +%endif + ; ; Abandon hope, ye that enter here! We do no longer permit aborts. ; @@ -320,6 +342,10 @@ mov si,ready_msg call cwritestr +%ifdef WITH_GFX + call gfx_done +%endif + call vgaclearmode ; We can't trust ourselves after this UNLOAD_PREP ; Module-specific hook @@ -552,6 +578,34 @@ .got_start: push si + +%ifdef WITH_GFX + cmp byte [si],'+' + jnz .got_start_10 + mov byte [cs:gfx_cd_changed],1 + inc si + push es + push ds + push si + push cs + pop es + mov cx,100h + mov di,trackbuf + push di + rep movsb + mov byte [es:di],0 + pop si + xor di,di + mov al,5 ; ask for cd change + push cs + pop ds + call gfx_infobox + pop si + pop ds + pop es +.got_start_10: +%endif + mov di,InitRD ; Target buffer for mangled name call mangle_name call loadinitrd @@ -645,6 +699,20 @@ ret .notthere: + +%ifdef WITH_GFX + cmp byte [gfx_ok],0 + jz .nogfx + mov si,InitRDCName + xor di,di + mov al,2 + call gfx_infobox + call gfx_progress_done + mov si,no_msg + jmp abort_load +.nogfx: +%endif + mov si,err_noinitrd call cwritestr mov si,InitRDCName @@ -653,7 +721,21 @@ jmp abort_load no_high_mem: ; Error routine + +%ifdef WITH_GFX + cmp byte [gfx_ok],0 + jz .nogfx mov si,err_nohighmem + xor di,di + mov al,0 + call gfx_infobox + call gfx_progress_done + mov si,no_msg + jmp abort_load +.nogfx: +%endif + + mov si,err_nohighmem jmp abort_load ret @@ -666,7 +748,8 @@ ready_msg db 'ready.', CR, LF, 0 err_oldkernel db 'Cannot load a ramdisk with an old kernel image.' db CR, LF, 0 -err_noinitrd db CR, LF, 'Could not find ramdisk image: ', 0 +err_noinitrd db CR, LF +err_noinitrda db 'Could not find ramdisk image: ', 0 err_nohighmem db 'Not enough memory to load specified kernel.', CR, LF, 0 boot_image db 'BOOT_IMAGE=' diff -urNad syslinux-3.63+dfsg~/ui.inc syslinux-3.63+dfsg/ui.inc --- syslinux-3.63+dfsg~/ui.inc 2008-04-10 18:30:35.000000000 +0100 +++ syslinux-3.63+dfsg/ui.inc 2008-06-13 15:08:24.000000000 +0100 @@ -44,6 +44,11 @@ .no_bootonce: +%ifdef WITH_GFX + ; build gfx menu + call gfx_setup_menu +%endif + ; ; Check whether or not we are supposed to display the boot prompt. ; @@ -57,6 +62,21 @@ cmp word [NoEscape],0 ; If NOESCAPE, no prompt, jne auto_boot ; always run default cmd +%ifdef WITH_GFX + cmp byte [gfx_ok],0 + jz .nogfx + mov edi,ds + shl edi,4 + add edi,command_line + mov ecx,max_cmd_len + xor eax,eax + xchg eax,[KbdTimeout] ; only the first time + call gfx_input + cmp ax,1 + jnz load_kernel +.nogfx: +%endif + mov si,boot_prompt call cwritestr @@ -323,9 +343,21 @@ push word real_mode_seg pop es mov di,cmd_line_here + +%ifdef WITH_GFX + ; gfx code includes them + cmp byte [gfx_ok],0 + jnz .isgfx +%endif + mov si,VKernelBuf+vk_append mov cx,[VKernelBuf+vk_appendlen] rep movsb + +%ifdef WITH_GFX +.isgfx: +%endif + mov [CmdLinePtr],di ; Where to add rest of cmd pop es mov di,KernelName @@ -343,7 +375,7 @@ mov al, [VKernelBuf+vk_type] mov [KernelType], al -%if IS_PXELINUX || IS_ISOLINUX +%if IS_PXELINUX || IS_ISOLINUX || IS_SYSLINUX ; Is this a "localboot" pseudo-kernel? %if IS_PXELINUX cmp byte [VKernelBuf+vk_rname+4], 0 @@ -421,6 +453,19 @@ push di call unmangle_name ; Get human form mov si,err_notfound ; Complain about missing kernel + +%ifdef WITH_GFX + cmp byte [gfx_ok],0 + jz .nogfx + pop si + xor di,di + mov al,2 + call gfx_infobox + mov si,no_msg + jmp abort_load +.nogfx: +%endif + call cwritestr pop si ; KernelCName call cwritestr syslinux-legacy-3.63+dfsg/debian/patches/02-64bit-autodetection.dpatch0000664000175000017500000001025411730614544024253 0ustar evanevan#!/bin/sh /usr/share/dpatch/dpatch-run ## 02-64bit-autodetection.dpatch by Byron Stanoszek ## and updated by Robert Millan . ## ## DP: Allows auto-detection of 64bit CPUs (Closes: #408138), see ## DP: http://syslinux.zytor.com/archives/2007-January/007832.html @DPATCH@ diff -Naurp syslinux-3.62+dfsg.orig/cpuinit.inc syslinux-3.62+dfsg/cpuinit.inc --- syslinux-3.62+dfsg.orig/cpuinit.inc 2008-03-01 23:28:21.000000000 +0000 +++ syslinux-3.62+dfsg/cpuinit.inc 2008-03-31 11:26:04.000000000 +0000 @@ -48,30 +48,38 @@ skip_checks: rep movsd ; -; Check if we're 386 (as opposed to 486+); if so we need to blank out -; the WBINVD instruction +; Determine if we're running on a 64-bit CPU ; -; We check for 486 by setting EFLAGS.AC + +; +; Check if this CPU supports the CPUID command ; -%if DO_WBINVD - pushfd ; Save the good flags + pushfd ; Save the flags again pushfd pop eax mov ebx,eax - xor eax,(1 << 18) ; AC bit + xor eax,(1 << 21) ; CPUID bit push eax popfd pushfd pop eax popfd ; Restore the original flags xor eax,ebx - jnz is_486 + jz is_32bit ; -; 386 - Looks like we better blot out the WBINVD instruction +; Now check for the 64-bit flag (bit 29) in the CPU extended features byte ($8000_0001, edx) ; - mov byte [try_wbinvd],0c3h ; Near RET -is_486: -%endif ; DO_WBINVD + mov eax, 80000000h ; Find last AMD cpuid # + cpuid + cmp eax, 80000000h + jbe is_32bit + mov eax, 80000001h ; Read AMD CPU flags + cpuid + bt edx, 29 ; 64-bit if bit 29 is set + jnc is_32bit + +is_64bit: mov byte [Is64Bit],1 ; Flag that we're 64-bit +is_32bit: section .data err_noram db 'It appears your computer has less than ' diff -Naurp syslinux-3.62+dfsg.orig/keywords syslinux-3.62+dfsg/keywords --- syslinux-3.62+dfsg.orig/keywords 2008-03-01 23:28:21.000000000 +0000 +++ syslinux-3.62+dfsg/keywords 2008-03-31 11:26:04.000000000 +0000 @@ -4,6 +4,7 @@ include append config default +default64 display font implicit diff -Naurp syslinux-3.62+dfsg.orig/keywords.inc syslinux-3.62+dfsg/keywords.inc --- syslinux-3.62+dfsg.orig/keywords.inc 2008-03-01 23:28:21.000000000 +0000 +++ syslinux-3.62+dfsg/keywords.inc 2008-03-31 11:27:10.000000000 +0000 @@ -50,6 +50,7 @@ keywd_table: keyword include, pc_opencmd, pc_include keyword append, pc_append keyword default, pc_default + keyword default64, pc_default64 keyword display, pc_opencmd, get_msg_file keyword font, pc_filecmd, loadfont keyword implicit, pc_setint16, AllowImplicit diff -Naurp syslinux-3.62+dfsg.orig/kwdhash.gen syslinux-3.62+dfsg/kwdhash.gen --- syslinux-3.62+dfsg.orig/kwdhash.gen 2008-03-01 23:28:29.000000000 +0000 +++ syslinux-3.62+dfsg/kwdhash.gen 2008-03-31 11:26:04.000000000 +0000 @@ -4,6 +4,7 @@ hash_include equ 0x9a07d8ff hash_append equ 0xc53999a4 hash_config equ 0xc0c69547 hash_default equ 0xcc5159ed +hash_default64 equ 0x4567b1c5 hash_display equ 0xd509bc40 hash_font equ 0x0032b1b4 hash_implicit equ 0xa6f50207 diff -Naurp syslinux-3.62+dfsg.orig/parseconfig.inc syslinux-3.62+dfsg/parseconfig.inc --- syslinux-3.62+dfsg.orig/parseconfig.inc 2008-03-01 23:28:21.000000000 +0000 +++ syslinux-3.62+dfsg/parseconfig.inc 2008-03-31 11:26:04.000000000 +0000 @@ -20,7 +20,20 @@ ; ; "default" command ; -pc_default: mov di,default_cmd +pc_default: cmp byte [HasDefault64],0 ; Check if we accepted 'default64' + ja pc_getline ; If so, do nothing + mov di,default_cmd + call getline + mov byte [di-1],0 ; null-terminate + ret + +; +; "default64" command +; +pc_default64: cmp byte [Is64Bit],0 ; Make sure cpu is 64-bit + je pc_getline + mov byte [HasDefault64],1 ; Note that we saw a default64 + mov di,default_cmd call getline mov byte [di-1],0 ; null-terminate ret @@ -438,6 +451,8 @@ AllowOptions dw 1 ; User-specified opt IncludeLevel dw 1 ; Nesting level SerialPort dw 0 ; Serial port base (or 0 for no serial port) VKernel db 0 ; Have we seen any "label" statements? +Is64Bit db 0 ; Is this CPU 64-bit? +HasDefault64 db 0 ; We've seen a 'default64' statement %if IS_PXELINUX IPAppend db 0 ; Default IPAPPEND option syslinux-legacy-3.63+dfsg/debian/patches/03-64bit-autodetection-menu.dpatch0000664000175000017500000001100211730614544025206 0ustar evanevan#!/bin/sh /usr/share/dpatch/dpatch-run ## 03-64bit-autodetection-menu.dpatch by Ryan Finnie ## ## DP: Allows auto-detection of 64bit CPUs also in vesamenu.c32 ## DP: (Closes: #485656) @DPATCH@ diff -Naurp syslinux-3.63+dfsg.orig/com32/menu/menu.h syslinux-3.63+dfsg/com32/menu/menu.h --- syslinux-3.63+dfsg.orig/com32/menu/menu.h 2008-04-10 17:30:35.000000000 +0000 +++ syslinux-3.63+dfsg/com32/menu/menu.h 2008-06-10 19:03:17.000000000 +0000 @@ -163,6 +163,8 @@ struct menu { struct color_table *color_table; struct fkey_help fkeyhelp[12]; + + int has_default64; }; extern struct menu *root_menu, *start_menu, *hide_menu, *menu_list; diff -Naurp syslinux-3.63+dfsg.orig/com32/menu/readconfig.c syslinux-3.63+dfsg/com32/menu/readconfig.c --- syslinux-3.63+dfsg.orig/com32/menu/readconfig.c 2008-04-10 17:30:35.000000000 +0000 +++ syslinux-3.63+dfsg/com32/menu/readconfig.c 2008-06-10 19:03:17.000000000 +0000 @@ -67,6 +67,56 @@ const char * const kernel_types[] = { }; /* + * Test for long mode using cpuid instruction + * Based on plugins/cpuid/cpuid.c from win32-loader + * Copyright (C) 2007 Robert Millan + * Based on gcc/gcc/config/i386/driver-i386.c + * Copyright (C) 2006, 2007 Free Software Foundation, Inc. + */ + +#define cpuid(num,a,b,c,d) \ + asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \ + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ + : "0" (num)) + +#define bit_LM (1 << 29) + +int +check_64bit () +{ + unsigned int eax, ebx, ecx, edx; + unsigned int max_level; + unsigned int ext_level; + unsigned char has_longmode = 0; + + /* See if we can use cpuid. */ + asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;" + "pushl %0; popfl; pushfl; popl %0; popfl" + : "=&r" (eax), "=&r" (ebx) + : "i" (0x00200000)); + if (((eax ^ ebx) & 0x00200000) == 0) + goto done; + + /* Check the highest input value for eax. */ + cpuid (0, eax, ebx, ecx, edx); + /* We only look at the first four characters. */ + max_level = eax; + if (max_level == 0) + goto done; + + cpuid (0x80000000, eax, ebx, ecx, edx); + ext_level = eax; + if (ext_level < 0x80000000) + goto done; + + cpuid (0x80000001, eax, ebx, ecx, edx); + has_longmode = !!(edx & bit_LM); + +done: + return has_longmode; +} + +/* * Search the list of all menus for a specific label */ static struct menu * @@ -206,6 +256,7 @@ struct labeldata { unsigned int ipappend; unsigned int menuhide; unsigned int menudefault; + unsigned int menudefault64; unsigned int menuseparator; unsigned int menudisabled; unsigned int menuindent; @@ -273,6 +324,8 @@ record(struct menu *m, struct labeldata struct menu_entry *me; const struct syslinux_ipappend_strings *ipappend; + int is_64bit = check_64bit(); + if (!ld->label) return; /* Nothing defined */ @@ -361,8 +414,26 @@ record(struct menu *m, struct labeldata break; } - if ( ld->menudefault && me->action == MA_CMD ) + /* If this ld has DEFAULT on it, it's a candidate for the default entry. + * But if a 64-bit default has already been set, we know that A) the CPU + * is 64-bit, and B) a DEFAULT64 has already occurred, so we don't even + * want to attempt 32-bit defaults anymore. If it's a 64-bit CPU, + * regular DEFAULTs can of course be considered for the default, + * but any past or future DEFAULT64 (with a corresponding 64-bit CPU) + * will eventually win. + */ + if ( ld->menudefault && me->action == MA_CMD && !m->has_default64 ) + m->defentry = m->nentries-1; + + /* If the CPU is 64-bit and DEFAULT64 is set for this ld, set it as + * default. However, if DEFAULT64 is set and the CPU is NOT 64-bit, + * don't even consider it for a default. + */ + if ( ld->menudefault64 && me->action == MA_CMD && is_64bit ) { m->defentry = m->nentries-1; + m->has_default64 = 1; + } + } clear_label_data(ld); @@ -620,6 +691,8 @@ static void parse_config_file(FILE *f) } } else if ( looking_at(p, "default") ) { ld.menudefault = 1; + } else if ( looking_at(p, "default64") ) { + ld.menudefault64 = 1; } else if ( looking_at(p, "hide") ) { ld.menuhide = 1; } else if ( looking_at(p, "passwd") ) { @@ -875,6 +948,7 @@ static void parse_config_file(FILE *f) ld.ipappend = ipappend; ld.menudefault = ld.menuhide = ld.menuseparator = ld.menudisabled = ld.menuindent = 0; + ld.menudefault64 = 0; } else if ( (ep = is_kernel_type(p, &type)) ) { if ( ld.label ) { refstr_put(ld.kernel); syslinux-legacy-3.63+dfsg/debian/patches/14-ubuntu_gfxboot_force_prompt.dpatch0000664000175000017500000000113111730614544026304 0ustar evanevan#! /bin/sh /usr/share/dpatch/dpatch-run ## 14-gfxboot_force_prompt.dpatch by Colin Watson ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Always prompt if a gfxboot menu is set up. @DPATCH@ diff -urNad syslinux-3.63+dfsg~/gfxboot.inc syslinux-3.63+dfsg/gfxboot.inc --- syslinux-3.63+dfsg~/gfxboot.inc 2008-06-19 13:55:06.000000000 +0100 +++ syslinux-3.63+dfsg/gfxboot.inc 2008-06-19 13:57:12.000000000 +0100 @@ -749,6 +749,8 @@ gfx_setup_menu_90: pop es + ; if we set up a gfxboot menu, always prompt + mov word [ForcePrompt],1 ret syslinux-legacy-3.63+dfsg/debian/manpages0000664000175000017500000000000611730614544017133 0ustar evanevanman/* syslinux-legacy-3.63+dfsg/debian/config/0000775000175000017500000000000011730614544016666 5ustar evanevansyslinux-legacy-3.63+dfsg/debian/config/mtoolsrc0000664000175000017500000000045711730614544020461 0ustar evanevandrive a: file="build/img720k" cylinders=80 heads=2 sectors=9 mformat_only drive b: file="build/img1200k" cylinders=80 heads=2 sectors=15 mformat_only drive c: file="build/img1440k" cylinders=80 heads=2 sectors=18 mformat_only drive d: file="build/img1743k" cylinders=83 heads=2 sectors=21 mformat_only syslinux-legacy-3.63+dfsg/comboot.inc0000664000175000017500000004606110777447273016360 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; comboot.inc ;; ;; Common code for running a COMBOOT image ;; section .text ; Parameter registers definition; this is the definition ; of the stack frame used by INT 21h and INT 22h. %define P_FLAGS word [bp+44] %define P_FLAGSL byte [bp+44] %define P_FLAGSH byte [bp+45] %define P_CS word [bp+42] %define P_IP word [bp+40] %define P_DS word [bp+38] %define P_ES word [bp+36] %define P_FS word [bp+34] %define P_GS word [bp+32] %define P_EAX dword [bp+28] %define P_AX word [bp+28] %define P_HAX word [bp+30] %define P_AL byte [bp+28] %define P_AH byte [bp+29] %define P_ECX dword [bp+24] %define P_CX word [bp+24] %define P_HCX word [bp+26] %define P_CL byte [bp+24] %define P_CH byte [bp+25] %define P_EDX dword [bp+20] %define P_DX word [bp+20] %define P_HDX word [bp+22] %define P_DL byte [bp+20] %define P_DH byte [bp+21] %define P_EBX dword [bp+16] %define P_BX word [bp+16] %define P_HBX word [bp+18] %define P_BL byte [bp+16] %define P_BH byte [bp+17] %define P_EBP dword [bp+8] %define P_BP word [bp+8] %define P_HBP word [bp+10] %define P_ESI dword [bp+4] %define P_SI word [bp+4] %define P_HSI word [bp+6] %define P_EDI dword [bp] %define P_DI word [bp] %define P_HDI word [bp+2] ; Looks like a COMBOOT image but too large comboot_too_large: mov si,err_comlarge call cwritestr jmp enter_command ; ; Load a COMBOOT image. A COMBOOT image is basically a DOS .COM file, ; except that it may, of course, not contain any DOS system calls. We ; do, however, allow the execution of INT 20h to return to SYSLINUX. ; is_comboot_image: and dx,dx jnz comboot_too_large cmp ax,0ff00h ; Max size in bytes jae comboot_too_large push si ; Save file handle call make_plain_cmdline call comboot_setup_api mov cx,comboot_seg mov es,cx xor di,di mov cx,64 ; 256 bytes (size of PSP) xor eax,eax ; Clear PSP rep stosd mov word [es:0], 020CDh ; INT 20h instruction ; First non-free paragraph ; This is valid because comboot_seg == real_mode_seg ; == the highest segment used by all derivatives int 12h ; Get DOS memory size shl ax,6 ; Kilobytes -> paragraphs mov word [es:02h],ax %ifndef DEPEND %if real_mode_seg != comboot_seg %error "This code assumes real_mode_seg == comboot_seg" %endif %endif ; Copy the command line from high memory mov si,cmd_line_here mov cx,125 ; Max cmdline len (minus space and CR) mov di,081h ; Offset in PSP for command line mov al,' ' ; DOS command lines begin with a space stosb .loop: es lodsb and al,al jz .done stosb loop .loop .done: mov al,0Dh ; CR after last character stosb mov ax,di sub al,82h ; Include space but not CR mov [es:80h],al ; Store command line length ; Now actually load the file... pop si ; File handle mov bx,100h ; Load at :0100h mov cx,0FF00h >> SECTOR_SHIFT ; Absolute maximum # of sectors call getfssec ; And invoke the program... mov ax,es mov ds,ax mov ss,ax xor sp,sp push word 0 ; Return to address 0 -> exit jmp comboot_seg:100h ; Run it ; Proper return vector comboot_return: cli ; Don't trust anyone push enter_command ; Normal return to command prompt jmp comboot_exit ; ; Set up the COMBOOT API interrupt vectors. This is also used ; by the COM32 code. ; comboot_setup_api: mov di,4*0x20 ; DOS interrupt vectors mov eax,comboot_return ; INT 20h = exit stosd mov ax,comboot_int21 ; INT 21h = DOS-compatible syscalls stosd mov ax,comboot_int22 ; INT 22h = proprietary syscalls stosd mov ax,comboot_bogus mov cx,29 ; All remaining DOS vectors rep stosd ret ; INT 21h: generic DOS system call comboot_int21: cli push ds push es push fs push gs pushad cld mov bp,cs mov ds,bp mov es,bp mov bp,sp ; Set up stack frame call adjust_screen ; The COMBOOT program might have changed the screen mov cx,int21_count mov si,int21_table .again: lodsb cmp al,P_AH lodsw loopne .again ; The last function in the list is the ; "no such function" function clc call ax ; Call the invoked function comboot_resume: mov bp,sp ; In case the function clobbers BP setc P_FLAGSL ; Propagate CF->error popad pop gs pop fs pop es pop ds iret ; Attempted to execute non-21h DOS system call comboot_bogus: cli ; Don't trust anyone mov cx,err_notdos push enter_command jmp comboot_exit_msg ; ; Generic COMBOOT return to command line code ; stack -> where to go next ; CX -> message (for _msg version) ; comboot_exit: xor cx,cx comboot_exit_msg: pop bx ; Return address RESET_STACK_AND_SEGS AX call adjust_screen ; The COMBOOT program might have changed the screen jcxz .nomsg mov si,KernelCName call cwritestr mov si,cx call cwritestr .nomsg: jmp bx ; ; INT 21h system calls ; comboot_getkey: ; 01 = get key with echo call vgashowcursor call comboot_getchar call vgahidecursor call writechr clc ret comboot_writechr: ; 02 = writechr mov al,P_DL call writechr clc ret comboot_writeserial: ; 04 = write serial port mov al,P_DL call write_serial clc ret comboot_getkeynoecho: ; 08 = get key w/o echo call comboot_getchar clc ret comboot_writestr: ; 09 = write DOS string mov es,P_DS mov si,P_DX .loop: es lodsb cmp al,'$' ; End string with $ - bizarre je .done call writechr jmp short .loop .done: clc ret comboot_checkkey: ; 0B = check keyboard status cmp byte [APIKeyFlag],00h jnz .waiting call pollchar .waiting: setz al dec al ; AL = 0FFh if present, 0 if not mov P_AL,al clc ret comboot_checkver: ; 30 = check DOS version ; We return 0 in all DOS-compatible version registers, ; but the high part of eax-ebx-ecx-edx spell "SYSLINUX" mov P_EAX,'SY' << 16 mov P_EBX,'SL' << 16 mov P_ECX,'IN' << 16 mov P_EDX,'UX' << 16 ret comboot_getchar: cmp byte [APIKeyFlag],00h jne .queued call getchar ; If not queued get input and al,al ; Function key? (CF <- 0) jnz .done mov [APIKeyWait],ah ; High part of key inc byte [APIKeyFlag] ; Set flag .done: mov P_AL,al ret .queued: mov al,[APIKeyWait] dec byte [APIKeyFlag] jmp .done ; ; INT 22h - SYSLINUX-specific system calls ; System call number in ax ; comboot_int22: cli push ds push es push fs push gs pushad cld mov bp,cs mov ds,bp mov es,bp mov bp,sp ; Set up stack frame call adjust_screen ; The COMBOOT program might have changed the screen cmp ax,int22_count jb .ok xor ax,ax ; Function 0 -> unimplemented .ok: xchg ax,bx add bx,bx ; CF <- 0 call [bx+int22_table] jmp comboot_resume ; On return ; ; INT 22h AX=0000h Unimplemented call ; comapi_err: stc ret ; ; INT 22h AX=0001h Get SYSLINUX version ; comapi_get_version: ; Number of API functions supported mov P_AX,int22_count ; SYSLINUX version mov P_CX,(VER_MAJOR << 8)+VER_MINOR ; SYSLINUX derivative ID byte mov P_DX,my_id ; For future use mov P_BX,cs ; cs == 0 mov P_ES,ds ; ES:SI -> version banner mov P_SI,syslinux_banner ; ES:DI -> copyright string mov P_DI,copyright_str comapi_nop: clc ret ; ; INT 22h AX=0002h Write string ; ; Write null-terminated string in ES:BX ; comapi_writestr: mov ds,P_ES mov si,P_BX call writestr clc ret ; ; INT 22h AX=0003h Run command ; ; Terminates the COMBOOT program and executes the command line in ; ES:BX as if it had been entered by the user. ; comapi_run: mov ds,P_ES mov si,P_BX mov di,command_line call strcpy push load_kernel ; Run a new kernel jmp comboot_exit ; Terminate task, clean up ; ; INT 22h AX=0004h Run default command ; ; Terminates the COMBOOT program and executes the default command line ; as if a timeout had happened or the user pressed . ; comapi_run_default: push auto_boot jmp comboot_exit ; ; INT 22h AX=0005h Force text mode ; ; Puts the video in standard text mode ; comapi_textmode: call vgaclearmode clc ret ; ; INT 22h AX=0006h Open file ; comapi_open: push ds mov ds,P_ES mov si,P_SI mov di,InitRD call mangle_name pop ds call searchdir jz comapi_err mov P_AX,ax mov P_HAX,dx mov P_CX,SECTOR_SIZE mov P_SI,si clc ret ; ; INT 22h AX=0007h Read file ; comapi_read: mov es,P_ES mov bx,P_BX mov si,P_SI mov cx,P_CX call getfssec jnc .noteof xor si,si ; SI <- 0 on EOF, CF <- 0 .noteof: mov P_SI,si ret ; ; INT 22h AX=0008h Close file ; comapi_close: mov si,P_SI call close_file clc ret ; ; INT 22h AX=0009h Call PXE stack ; %if IS_PXELINUX comapi_pxecall: mov bx,P_BX mov es,P_ES mov di,P_DI call pxenv mov P_AX,ax clc ret %else comapi_pxecall equ comapi_err ; Not available %endif ; ; INT 22h AX=000Ah Get Derivative-Specific Info ; comapi_derinfo: mov P_AL,my_id %if IS_PXELINUX mov ax,[APIVer] mov P_DX,ax mov ax,[StrucPtr] mov P_BX,ax mov ax,[StrucPtr+2] mov P_ES,ax mov ax,[InitStack] mov P_SI,ax mov ax,[InitStack+2] mov P_FS,ax %else ; Physical medium... mov P_CL,SECTOR_SHIFT mov al,[DriveNumber] mov P_DL,al mov P_FS,cs mov P_SI,OrigESDI %if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX mov P_ES,cs mov P_BX,PartInfo %elif IS_ISOLINUX mov P_ES,cs mov P_BX,spec_packet %endif %endif clc ret ; ; INT 22h AX=000Bh Get Serial Console Configuration ; comapi_serialcfg: mov ax,[SerialPort] mov P_DX,ax mov ax,[BaudDivisor] mov P_CX,ax mov ax,[FlowControl] or al,ah mov ah,[FlowIgnore] shr ah,4 test byte [DisplayCon],01h jnz .normalconsole or ah,80h .normalconsole: mov P_BX,ax clc ret ; ; INT 22h AX=000Ch Perform final cleanup ; comapi_cleanup: %if IS_PXELINUX ; Unload PXE if requested test dl,3 setnz [KeepPXE] sub bp,sp ; unload_pxe may move the stack around call unload_pxe add bp,sp ; restore frame pointer... %elif IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX ; Restore original FDC table mov eax,[OrigFDCTabPtr] mov [fdctab],eax %endif ; Reset the floppy disk subsystem xor ax,ax xor dx,dx int 13h clc ret ; ; INT 22h AX=000Dh Clean up then replace bootstrap ; comapi_chainboot: call comapi_cleanup mov eax,P_EDI mov [trackbuf+4],eax ; Copy from mov eax,P_ECX mov [trackbuf+8],eax ; Total bytes mov eax,7C00h mov [trackbuf],eax ; Copy to mov [EntryPoint],eax ; CS:IP entry point mov esi,P_ESI mov edx,P_EBX mov bx,P_DS jmp replace_bootstrap_one ; ; INT 22h AX=000Eh Get configuration file name ; comapi_configfile: mov P_ES,cs mov P_BX,ConfigName clc ret ; ; INT 22h AX=000Fh Get IPAPPEND strings ; %if IS_PXELINUX comapi_ipappend: mov P_ES,cs mov P_CX,numIPAppends mov P_BX,IPAppends clc ret section .data alignb 2, db 0 IPAppends dw IPOption dw BOOTIFStr numIPAppends equ ($-IPAppends)/2 %else comapi_ipappend equ comapi_err %endif section .text ; ; INT 22h AX=0010h Resolve hostname ; %if IS_PXELINUX comapi_dnsresolv: mov ds,P_ES mov si,P_BX call dns_resolv mov P_EAX,eax clc ret %else comapi_dnsresolv equ comapi_err %endif section .text ; ; INT 22h AX=0011h Maximum number of shuffle descriptors ; comapi_maxshuffle: mov P_CX,trackbufsize/12 ret ; ; INT 22h AX=0012h Cleanup, shuffle and boot ; comapi_shuffle: cmp P_CX,(2*trackbufsize)/12 ja .error call comapi_cleanup mov cx, P_CX push cx ; On stack: descriptor count lea cx,[ecx+ecx*2] ; CX *= 3 mov fs,P_ES mov si,P_DI mov di,trackbuf push di ; On stack: descriptor list address fs rep movsd ; Copy the list mov eax,P_EBP mov [EntryPoint],eax ; CS:IP entry point mov esi,P_ESI mov edx,P_EBX mov bx,P_DS jmp replace_bootstrap .error: stc ret ; ; INT 22h AX=0013h Idle call ; ; ; *** FIX THIS *** ; The idle call seems to have detrimental effects on some machines when ; called from a COM32 context (WHY?) -- disable it for now. ; %if 0 ; def HAVE_IDLE comapi_idle: DO_IDLE clc ret %else comapi_idle equ comapi_err %endif ; ; INT 22h AX=0014h Local boot ; %if IS_PXELINUX || IS_ISOLINUX comapi_localboot: mov ax,P_DX jmp local_boot %else comapi_localboot equ comapi_err %endif ; ; INT 22h AX=0015h Feature flags ; comapi_features: mov P_ES,cs mov P_BX,feature_flags mov P_CX,feature_flags_len clc ret ; ; INT 22h AX=0016h Run kernel image ; comapi_runkernel: mov al,P_DL cmp al,VK_TYPES-1 ja .error mov [KernelType],al push ds mov ds,P_DS mov si,P_SI mov di,KernelName call mangle_name pop ds call searchdir jz comapi_err ; The kernel image was found, so we can load it... mov [Kernel_SI],si mov [Kernel_EAX],ax mov [Kernel_EAX+2],dx ; It's not just possible, but quite likely, that ES:BX ; points into real_mode_seg, so we need to exercise some ; special care here... use xfer_buf_seg as an intermediary push ds push es mov ax,xfer_buf_seg mov ds,P_ES mov si,P_BX mov es,ax xor di,di call strcpy pop es pop ds %if IS_PXELINUX mov al,P_CL mov [IPAppend],al %endif call comboot_exit .finish: ; Copy the command line into its proper place push ds push es mov ax,xfer_buf_seg mov dx,real_mode_seg mov ds,ax mov es,dx xor si,si mov di,cmd_line_here call strcpy mov byte [es:di-1],' ' ; Simulate APPEND pop es pop ds mov [CmdLinePtr],di mov word [CmdOptPtr],zero_string jmp kernel_good_saved .error equ comapi_shuffle.error ; ; INT 22h AX=0017h Report video mode change ; comapi_usingvga: mov ax,P_BX cmp ax,0Fh ; Unknown flags = failure ja .error mov [UsingVGA],al mov cx,P_CX mov dx,P_DX mov [GXPixCols],cx mov [GXPixRows],dx test al,08h jnz .notext call adjust_screen .notext: clc ret .error: stc ret ; ; INT 22h AX=0018h Query custom font ; comapi_userfont: mov al,[UserFont] and al,al jz .done mov al,[VGAFontSize] mov P_ES,ds mov P_BX,vgafontbuf .done: ; CF=0 here mov P_AL,al ret ; ; INT 22h AX=0019h Read disk ; %if IS_SYSLINUX || IS_MDSLINUX || IS_ISOLINUX || IS_EXTLINUX comapi_readdisk: mov esi,P_ESI ; Enforce ESI == EDI == 0, these or esi,P_EDI ; are reserved for future expansion jnz .err mov eax,P_EDX mov es,P_ES mov bx,P_BX mov bp,P_CX ; WE CANNOT use P_* after touching bp! call getlinsec clc ret .err: stc ret %else comapi_readdisk equ comapi_err %endif ; ; INT 22h AX=001Ah Cleanup, shuffle and boot to flat protected mode ; comapi_shufflepm: cmp P_CX,(2*trackbufsize)/12 ja .error call comapi_cleanup mov cx, P_CX push cx ; On stack: descriptor count lea cx,[ecx+ecx*2] ; CX *= 3 mov fs,P_ES mov si,P_DI mov di,trackbuf push di ; On stack: descriptor list address fs rep movsd ; Copy the list mov fs,P_DS mov si,P_SI mov edi,TrampolineBuf mov al,0B8h ; MOV EAX opcode mov cl,9 .maketramp: stosb ; MOV opcode inc ax ; Next register opcode fs movsd ; immediate value loop .maketramp mov byte [di-5],0E9h ; Last opcode is JMP sub [di-4],edi ; Make JMP target relative mov dword [EntryPoint],trampoline_to_pm xor bx,bx ; DS on entry jmp replace_bootstrap .error: stc ret ; ; INT 22h AX=001Bh Cleanup, shuffle and boot with register setting ; comapi_shufflerm: cmp P_CX,(2*trackbufsize)/12 ja .error call comapi_cleanup mov cx, P_CX push cx ; On stack: descriptor count lea cx,[ecx+ecx*2] ; CX *= 3 mov fs,P_ES mov si,P_DI mov di,trackbuf push di ; On stack: descriptor list address fs rep movsd ; Copy the list mov fs,P_DS mov si,P_SI mov di,TrampolineBuf ; Generate segment-loading instructions mov bx,0C08Eh ; MOV ES,AX mov cl,6 ; 6 segment registers (incl CS) .segtramp: mov al,0B8h stosb ; MOV AX,imm16 opcode fs movsw ; imm16 mov ax,bx add bh,8 stosw ; MOV xS,AX loop .segtramp ; Clobber the MOV CS,AX instruction. mov word [di-22], 9090h ; NOP NOP ; Generate GPR-loading instructions mov ax,0B866h ; MOV EAX,imm32 mov cl,8 ; 8 GPRs .gprtramp: stosw ; MOV ExX,imm32 opcode fs movsd ; imm32 inc ah loop .gprtramp mov al,0EAh ; JMP FAR imm16:imm16 opcode stosb fs movsd ; CS:IP mov dword [EntryPoint],TrampolineBuf jmp replace_bootstrap .error: stc ret ; ; INT 22h AX=001Ch Get pointer to auxillary data vector ; comapi_getadv: mov P_ES,ds mov P_BX,adv0.data mov P_CX,ADV_LEN ret ; ; INT 22h AX=001Dh Write auxillary data vector ; comapi_writeadv equ adv_write section .data %macro int21 2 db %1 dw %2 %endmacro int21_table: int21 00h, comboot_return int21 01h, comboot_getkey int21 02h, comboot_writechr int21 04h, comboot_writeserial int21 08h, comboot_getkeynoecho int21 09h, comboot_writestr int21 0Bh, comboot_checkkey int21 30h, comboot_checkver int21 4Ch, comboot_return int21 -1, comboot_bogus int21_count equ ($-int21_table)/3 align 2, db 0 int22_table: dw comapi_err ; 0000 unimplemented syscall dw comapi_get_version ; 0001 get SYSLINUX version dw comapi_writestr ; 0002 write string dw comapi_run ; 0003 run specified command dw comapi_run_default ; 0004 run default command dw comapi_textmode ; 0005 force text mode dw comapi_open ; 0006 open file dw comapi_read ; 0007 read file dw comapi_close ; 0008 close file dw comapi_pxecall ; 0009 call PXE stack dw comapi_derinfo ; 000A derivative-specific info dw comapi_serialcfg ; 000B get serial port config dw comapi_cleanup ; 000C perform final cleanup dw comapi_chainboot ; 000D clean up then bootstrap dw comapi_configfile ; 000E get name of config file dw comapi_ipappend ; 000F get ipappend strings dw comapi_dnsresolv ; 0010 resolve hostname dw comapi_maxshuffle ; 0011 maximum shuffle descriptors dw comapi_shuffle ; 0012 cleanup, shuffle and boot dw comapi_idle ; 0013 idle call dw comapi_localboot ; 0014 local boot dw comapi_features ; 0015 feature flags dw comapi_runkernel ; 0016 run kernel image dw comapi_usingvga ; 0017 report video mode change dw comapi_userfont ; 0018 query custom font dw comapi_readdisk ; 0019 read disk dw comapi_shufflepm ; 001A cleanup, shuffle and boot to pm dw comapi_shufflerm ; 001B cleanup, shuffle and boot to rm dw comapi_getadv ; 001C get pointer to ADV dw comapi_writeadv ; 001D write ADV to disk int22_count equ ($-int22_table)/2 APIKeyWait db 0 APIKeyFlag db 0 zero_string db 0 ; Empty, null-terminated string ; ; This is the feature flag array for INT 22h AX=0015h feature_flags: %if IS_PXELINUX db 1 ; Have local boot, idle not noop %elif IS_ISOLINUX db 3 ; Have local boot, idle is noop %else db 2 ; No local boot, idle is noop %endif feature_flags_len equ ($-feature_flags) err_notdos db ': attempted DOS system call', CR, LF, 0 err_comlarge db 'COMBOOT image too large.', CR, LF, 0 section .bss1 ConfigName resb FILENAME_MAX syslinux-legacy-3.63+dfsg/abort.inc0000664000175000017500000000344410777447271016021 0ustar evanevan; ----------------------------------------------------------------------- ; ; Copyright 2005-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Boston MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; ----------------------------------------------------------------------- ; ; abort.inc ; ; Code to terminate a kernel load ; section .text ; ; abort_check: let the user abort with or ; abort_check: call pollchar jz .ret1 pusha call getchar cmp al,27 ; je .kill cmp al,3 ; je .kill .ret2: popa .ret1: ret .kill: mov si,aborted_msg mov bx,enter_command jmp abort_load_chain ; ; abort_load: Called by various routines which wants to print a fatal ; error message and return to the command prompt. Since this ; may happen at just about any stage of the boot process, assume ; our state is messed up, and just reset the segment registers ; and the stack forcibly. ; ; SI = offset (in _text) of error message to print ; BX = future entry point (abort_load_chain) ; abort_load: mov bx,error_or_command abort_load_chain: RESET_STACK_AND_SEGS AX call cwritestr ; Expects SI -> error msg ; Return to the command prompt jmp bx ; ; error_or_command: Execute ONERROR if appropriate, otherwise enter_command ; error_or_command: mov cx,[OnerrorLen] and cx,cx jnz on_error jmp enter_command section .data aborted_msg db ' aborted.', CR, LF, 0 section .text syslinux-legacy-3.63+dfsg/bios.inc0000664000175000017500000000223410777447271015642 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; bios.inc ;; ;; Header file for the BIOS data structures etc. ;; %ifndef _BIOS_INC %define _BIOS_INC absolute 4*1Eh ; In the interrupt table fdctab equ $ fdctab1 resw 1 fdctab2 resw 1 absolute 0400h serial_base resw 4 ; Base addresses for 4 serial ports absolute 0413h BIOS_fbm resw 1 ; Free Base Memory (kilobytes) absolute 0462h BIOS_page resb 1 ; Current video page absolute 046Ch BIOS_timer resw 1 ; Timer ticks absolute 0472h BIOS_magic resw 1 ; BIOS reset magic absolute 0484h BIOS_vidrows resb 1 ; Number of screen rows %endif ; _BIOS_INC syslinux-legacy-3.63+dfsg/man/0000775000175000017500000000000010777447273014767 5ustar evanevansyslinux-legacy-3.63+dfsg/man/ppmtolss16.10000664000175000017500000000303710777447273017104 0ustar evanevan.TH "PPMTOLSS16" "1" .SH "NAME" ppmtolss16 \(em Convert a PPM to an LSS16 image .SH "SYNOPSIS" .PP \fBppmtolss16\fR [ \fB \fI#rrggbb\fR=\fIi\fR \fP \&...] [< input.ppm] [> output.rle] .SH "DESCRIPTION" .PP This manual page documents briefly the \fBppmtolss16\fR command. .PP The \fBppmtolss16\fR program converts a "raw" PPM file with max 16 colors to a simple RLE-based format: .PP \fBsimple RLE-based format\fR .TS tab(); l l. unint32 0x1413f3dmagic (littleendian) unint16 xsizelittleendian unint15 ysizelittleendian 16 x unint8 r,g,bcolor map .TE .PP Color map is in 6-bit format (each byte is 0..63) .PP Then, a sequence of nybbles: .PP N ... if N is != previous pixel, one pixel of color N, otherwise run sequence follows ... .PP M ... if M > 0 then run length is M+1, otherwise run sequence is encoded in two nybbles, littleendian, +17 .PP The nybble sequences are on a per-row basis, runs may not extend across rows and odd-nybble rows are zero-padded. .PP At the start of a row, the "previous pixel" is assumed to be zero. .SH "OPTIONS" .PP A summary of options is included below. .IP "\fB\fI#rrggbb\fR=\fIi\fR\fP" 10 Specify that the color #rrggbb (hex) should be assigned index i (decimal). .SH "BUG" .PP This program cannot handle comments in the header, nor "plain" ppm format. .SH "SEE ALSO" .PP \fBppmtolss16\fR(1) .SH "AUTHOR" .PP This manual page was compiled by dann frazier for the \fBDebian GNU/Linux\fP system (but may be used by others). Most of the content was written by H. Peter Anvin. syslinux-legacy-3.63+dfsg/man/lss16toppm.10000664000175000017500000000117010777447273017100 0ustar evanevan.TH "LSS16TOPPM" "1" .SH "NAME" lss16toppm \(em Convert an LSS-16 image to PPM .SH "SYNOPSIS" .PP \fBlss16toppm\fR [\fB-map\fP] [< file.lss] [> file.ppm] .SH "DESCRIPTION" .PP This manual page documents briefly the \fBlss16toppm\fR command. .PP The \fBlss16toppm\fR utility converts an LSS-16 image to a PPM image. .SH "OPTIONS" .PP A summary of options is included below. .IP "\fB-map\fP" 10 Output the color map to standard error. .SH "SEE ALSO" .PP \fBppmtolss16\fR(1) .SH "AUTHOR" .PP This manual page was compiled by dann frazier for the \fBDebian GNU/Linux\fP system (but may be used by others). syslinux-legacy-3.63+dfsg/man/syslinux2ansi.10000664000175000017500000000273010777447273017706 0ustar evanevan.TH SYSLINUX2ANSI 1 .SH NAME syslinux2ansi \- converts a syslinux-format screen to pc-ansi .SH SYNOPSIS .B syslinux2ansi < filename.input > filename.output .SH DESCRIPTION .I Syslinux2ansi is a filter which converts a screen formatted for syslinux to one compatible with PC ANSI. It will only read from standard in, and has no command line options. .SH BUGS Help and version command line options would be useful. .PP The ability to put input and output filenames on the command line might be good as well. .SS Bug reports I would appreciate hearing of any problems you have with SYSLINUX. I would also like to hear from you if you have successfully used SYSLINUX, especially if you are using it for a distribution. .PP If you are reporting problems, please include all possible information about your system and your BIOS; the vast majority of all problems reported turn out to be BIOD or hardware bugs, and I need as much information as possible in order to diagnose the problems. .PP There is a mailing list for discussion among SYSLINUX users and for announcements of new and test versions. To join, send a message to majordomo@linux.kernel.org with the line: .PP .B subscribe syslinux .PP in the body of the message. The submission address is syslinux@linux.kernel.org. .SH "SEE ALSO" .BR syslinux(1), .BR perl(1) .SH AUTHOR This manual page is a quick write-up for Debian done by Kevin Kreamer , by looking over the 1 screenful of Perl that is .B syslinux2ansi. syslinux-legacy-3.63+dfsg/man/gethostip.10000664000175000017500000000245510777447273017065 0ustar evanevan.TH "GETHOSTIP" "1" .SH "NAME" gethostip \(em convert an IP address into various formats .SH "SYNOPSIS" .PP \fBgethostip\fR [\fB-dxnf\fP] [\fB\fIHOSTNAME|IP\fR\fP] .SH "DESCRIPTION" .PP This manual page documents briefly the \fBgethostip\fR command. .PP The \fBgethostip\fR utility converts the given hostname or IP address into a variety formats. It is provided by the syslinux package to make it easier to calculate the appropriate names for pxelinux configuration files. These filenames can be the complete hexadecimal representation for a given IP address, or a partial hexadecimal representation to match a range of IP addresses. .SH "OPTIONS" .PP A summary of options is included below. .IP "\fB-d\fP" 10 Output the IP address in decimal format. .IP "\fB-x\fP" 10 Output the IP address in hexadecimal format. .IP "\fB-n\fP" 10 Output the host's canonical name. .IP "\fB-f\fP" 10 Full output. Outputs the IP address in all supported formats. Same as \fB-xdn\fP. .SH "SEE ALSO" .PP \fBsyslinux\fR(1) .PP More details can be found in the pxelinux documentation, which can be found in \fB/usr/share/doc/syslinux/pxelinux.doc.gz\fP on \fBDebian GNU/Linux\fP systems. .SH "AUTHOR" .PP This manual page was compiled by dann frazier for the \fBDebian GNU/Linux\fP system (but may be used by others). syslinux-legacy-3.63+dfsg/man/syslinux.10000664000175000017500000003745510777447273016765 0ustar evanevan.TH SYSLINUX 1 "18 December 2007" "SYSLINUX" .SH NAME syslinux \- install the \s-1SYSLINUX\s+1 bootloader on a FAT filesystem .SH SYNOPSIS .B syslinux [\fB\-sfr\fP] [\fB\-d\fP \fIdirectory\fP] [\fB\-o\fP \fIoffset\fP] .I device .SH DESCRIPTION \fBSyslinux\fP is a boot loader for the Linux operating system which operates off an MS-DOS/Windows FAT filesystem. It is intended to simplify first-time installation of Linux, and for creation of rescue and other special-purpose boot disks. .PP In order to create a bootable Linux floppy using \fBSyslinux\fP, prepare a normal MS-DOS formatted floppy. Copy one or more Linux kernel files to it, then execute the command: .IP .B syslinux /dev/fd0 .PP This will alter the boot sector on the disk and copy a file named LDLINUX.SYS into its root directory. .PP On boot time, by default, the kernel will be loaded from the image named LINUX on the boot floppy. This default can be changed, see the section on the \fBsyslinux\fP configuration file. .PP If the Shift or Alt keys are held down during boot, or the Caps or Scroll locks are set, \fBsyslinux\fP will display a .BR lilo (8) -style "boot:" prompt. The user can then type a kernel file name followed by any kernel parameters. The \fBsyslinux\fP loader does not need to know about the kernel file in advance; all that is required is that it is a file located in the root directory on the disk. .PP \fBSyslinux\fP supports the loading of initial ramdisks (initrd) and the bzImage kernel format. .SH OPTIONS .TP .B \-s Install a "safe, slow and stupid" version of \fBsyslinux\fP. This version may work on some very buggy BIOSes on which \fBsyslinux\fP would otherwise fail. If you find a machine on which the \-s option is required to make it boot reliably, please send as much info about your machine as you can, and include the failure mode. .TP .B \-f Force install even if it appears unsafe. .TP .B \-r RAID mode. If boot fails, tell the BIOS to boot the next device in the boot sequence (usually the next hard disk) instead of stopping with an error message. This is useful for RAID-1 booting. .TP \fB\-d\fP \fIsubdirectory\fP Install the \s-1SYSLINUX\s+1 control files in a subdirectory with the specified name (relative to the root directory on the device). .TP \fB\-o\fP \fIoffset\fP Indicates that the filesystem is at an offset from the base of the device or file. .SH FILES .SS "Configuration file" All the configurable defaults in \fBsyslinux\fP can be changed by putting a file called .B syslinux.cfg in the root directory of the boot floppy. This is a text file in either UNIX or DOS format, containing one or more of the following items (case is insensitive for keywords). .PP In the configuration file blank lines and comment lines beginning with a hash mark (#) are ignored. .TP \fBdefault\fP \fIkernel\fP [ \fIoptions ...\fP ] Sets the default command line. If \fBsyslinux\fP boots automatically, it will act just as if the entries after "default" had been typed in at the "boot:" prompt. .IP If no configuration file is present, or no "default" entry is present in the configuration file, the default is "linux auto". .TP NOTE: Earlier versions of \s-1SYSLINUX\s+1 used to automatically append the string "auto" to whatever the user specified using the DEFAULT command. As of version 1.54, this is no longer true, as it caused problems when using a shell as a substitute for "init." You may want to include this option manually. .TP .BI append " options ..." Add one or more \fIoptions\fP to the kernel command line. These are added both for automatic and manual boots. The options are added at the very beginning of the kernel command line, usually permitting explicitly entered kernel options to override them. This is the equivalent of the .BR lilo (8) "append" option. .PP .nf .BI label\ label .RS 2 .BI kernel\ image .BI append\ options\ ... .RE .fi .RS Indicates that if \fIlabel\fP is entered as the kernel to boot, \fBsyslinux\fP should instead boot \fIimage\fP, and the specified "append" options should be used instead of the ones specified in the global section of the file (before the first "label" command.) The default for \fIimage\fP is the same as \fIlabel\fP, and if no "append" is given the default is to use the global entry (if any). Use "append -" to use no options at all. Up to 128 "label" entries are permitted. .TP .B Notes: Labels are mangled as if they were DOS filenames, and must be unique after mangling. For example, two labels "v2.1.30" and "v2.1.31" will not be distinguishable. .IP The "image" doesn't have to be a Linux kernel; it can be a boot sector or a COMBOOT file (see below.) .RE .TP .BI implicit\ flag_val If \fIflag_val\fP is 0, do not load a kernel image unless it has been explicitly named in a "label" statement. The default is 1. .TP .BI timeout\ timeout Indicates how long to wait at the "boot:" prompt until booting automatically, in units of 1/10 s. The timeout is cancelled as soon as the user types anything on the keyboard, the assumption being that the user will complete the command line already begun. A timeout of zero will disable the timeout completely, this is also the default. The maximum possible timeout value is 35996; corresponding to just below one hour. .TP \fBserial\fP \fIport\fP [ \fIbaudrate\fP ] Enables a serial port to act as the console. "port" is a number (0 = /dev/ttyS0 = COM1, etc.); if "baudrate" is omitted, the baud rate defaults to 9600 bps. The serial parameters are hardcoded to be 8 bits, no parity, 1 stop bit. .IP For this directive to be guaranteed to work properly, it should be the first directive in the configuration file. .TP .BI font\ filename Load a font in .psf format before displaying any output (except the copyright line, which is output as ldlinux.sys itself is loaded.) \fBsyslinux\fP only loads the font onto the video card; if the .psf file contains a Unicode table it is ignored. This only works on EGA and VGA cards; hopefully it should do nothing on others. .TP .BI kbdmap\ keymap Install a simple keyboard map. The keyboard remapper used is \fIvery\fP simplistic (it simply remaps the keycodes received from the BIOS, which means that only the key combinations relevant in the default layout \- usually U.S. English \- can be mapped) but should at least help people with AZERTY keyboard layout and the locations of = and , (two special characters used heavily on the Linux kernel command line.) .IP The included program .BR keytab-lilo.pl (8) from the .BR lilo (8) distribution can be used to create such keymaps. .TP .BI display\ filename Displays the indicated file on the screen at boot time (before the boot: prompt, if displayed). Please see the section below on DISPLAY files. If the file is missing, this option is simply ignored. .TP .BI prompt\ flag_val If \fIflag_val\fP is 0, display the "boot:" prompt only if the Shift or Alt key is pressed, or Caps Lock or Scroll lock is set (this is the default). If \fIflag_val\fP is 1, always display the "boot:" prompt. .PP .nf .BI f1\ filename .BI f2\ filename .I ... .BI f9\ filename .BI f10\ filename .BI f11\ filename .BI f12\ filename .fi .RS Displays the indicated file on the screen when a function key is pressed at the "boot:" prompt. This can be used to implement pre-boot online help (presumably for the kernel command line options.) .RE .IP When using the serial console, press \fI\fP to get to the help screens, e.g. \fI2\fP to get to the f2 screen. For f10-f12, hit \fIA\fP, \fIB\fP, \fIC\fP. For compatiblity with earlier versions, f10 can also be entered as \fI0\fP. .SS "Display file format" DISPLAY and function-key help files are text files in either DOS or UNIX format (with or without \fI\fP). In addition, the following special codes are interpreted: .TP \fI\fP = \fI\fP = ASCII 12 Clear the screen, home the cursor. Note that the screen is filled with the current display color. .TP \fI\fP, \fI\fP = \fI\fP = ASCII 15 Set the display colors to the specified background and foreground colors, where \fI\fP and \fI\fP are hex digits, corresponding to the standard PC display attributes: .IP .nf .ta \w'5 = dark purple 'u 0 = black 8 = dark grey 1 = dark blue 9 = bright blue 2 = dark green a = bright green 3 = dark cyan b = bright cyan 4 = dark red c = bright red 5 = dark purple d = bright purple 6 = brown e = yellow 7 = light grey f = white .fi .IP Picking a bright color (8-f) for the background results in the corresponding dark color (0-7), with the foreground flashing. .IP colors are not visible over the serial console. .TP \fI\fPfilename\fI\fP, \fI\fP = \fI\fP = ASCII 24 If a VGA display is present, enter graphics mode and display the graphic included in the specified file. The file format is an ad hoc format called LSS16; the included Perl program "ppmtolss16" can be used to produce these images. This Perl program also includes the file format specification. .IP The image is displayed in 640x480 16-color mode. Once in graphics mode, the display attributes (set by \fI\fP code sequences) work slightly differently: the background color is ignored, and the foreground colors are the 16 colors specified in the image file. For that reason, ppmtolss16 allows you to specify that certain colors should be assigned to specific color indicies. .IP Color indicies 0 and 7, in particular, should be chosen with care: 0 is the background color, and 7 is the color used for the text printed by \s-1SYSLINUX\s+1 itself. .TP \fI\fP, \fI\fP = \fI\fP = ASCII 25 If we are currently in graphics mode, return to text mode. .TP \fI\fP..\fI\fB, \fI\fP..\fI\fP = ASCII 16-23 These codes can be used to select which modes to print a certain part of the message file in. Each of these control characters select a specific set of modes (text screen, graphics screen, serial port) for which the output is actually displayed: .IP .nf Character Text Graph Serial ------------------------------------------------------ = = ASCII 16 No No No = = ASCII 17 Yes No No = = ASCII 18 No Yes No = = ASCII 19 Yes Yes No = = ASCII 20 No No Yes = = ASCII 21 Yes No Yes = = ASCII 22 No Yes Yes = = ASCII 23 Yes Yes Yes .fi .IP For example: .nf Text modeGraphics modeSerial port .fi ... will actually print out which mode the console is in! .TP \fI\fP = \fI\fP = ASCII 26 End of file (DOS convention). .SS Comboot Images and other operating systems This version of \fBsyslinux\fP supports chain loading of other operating systems (such as MS-DOS and its derivatives, including Windows 95/98), as well as COMBOOT-style standalone executables (a subset of DOS .COM files; see separate section below.) .PP Chain loading requires the boot sector of the foreign operating system to be stored in a file in the root directory of the filesystem. Because neither Linux kernels, boot sector images, nor COMBOOT files have reliable magic numbers, \fBsyslinux\fP will look at the file extension. The following extensions are recognised: .PP .nf .ta \w'none or other 'u none or other Linux kernel image CBT COMBOOT image (not runnable from DOS) BSS Boot sector (DOS superblock will be patched in) BS Boot sector COM COMBOOT image (runnable from DOS) .fi .PP For filenames given on the command line, \fBsyslinux\fP will search for the file by adding extensions in the order listed above if the plain filename is not found. Filenames in KERNEL statements must be fully qualified. .PP A COMBOOT file is a standalone executable in DOS .COM format. They can, among other things, be produced by the Etherboot package by Markus Gutschke and Ken Yap. The following requirements apply for these files to be sufficiently "standalone" for \fBsyslinux\fP to be able to load and run them: .IP \(bu The program must not execute any DOS calls (since there is no DOS), although it may call the BIOS. The only exception is that the program may execute INT 20h (Terminate Program) to return to the \fBsyslinux\fP prompt. Note especially that INT 21h AH=4Ch, INT 21h AH=31h or INT 27h are not supported. .IP \(bu Only the fields pspInt20 at offset 00h, pspNextParagraph at offset 02h and pspCommandTail at offset 80h (contains the arguments from the \fBsyslinux\fP command line) in the PSP are supported. All other fields will contain zero. .IP \(bu The program must not modify any main memory outside its 64K segment if it returns to \fBsyslinux\fP via INT 20h. .PP \fBSyslinux\fP currently doesn't provide any form of API for the use of COMBOOT files. If there is need, a future version may contain an INT interface to some \fBsyslinux\fP functions; please contact me if you have a need or ideas for such an API. .SS Novice protection \fBSyslinux\fP will attempt to detect if the user is trying to boot on a 286 or lower class machine, or a machine with less than 608K of low ("DOS") RAM (which means the Linux boot sequence cannot complete). If so, a message is displayed and the boot sequence aborted. Holding down the Ctrl key while booting disables this feature. .PP The compile time and date of a specific \fBsyslinux\fP version can be obtained by the DOS command "type ldlinux.sys". This is also used as the signature for the LDLINUX.SYS file, which must match the boot sector .PP Any file that \fBsyslinux\fP uses can be marked hidden, system or readonly if so is convenient; \fBsyslinux\fP ignores all file attributes. The \s-1SYSLINUX\s+1 installed automatically sets the readonly attribute on LDLINUX.SYS. .SS Bootable CD-ROMs \s-1SYSLINUX\s+1 can be used to create bootdisk images for El Torito-compatible bootable CD-ROMs. However, it appears that many BIOSes are very buggy when it comes to booting CD-ROMs. Some users have reported that the following steps are helpful in making a CD-ROM that is bootable on the largest possible number of machines: .IP \(bu Use the -s (safe, slow and stupid) option to \s-1SYSLINUX\s+1 .IP \(bu Put the boot image as close to the beginning of the ISO 9660 filesystem as possible. .PP A CD-ROM is so much faster than a floppy that the -s option shouldn't matter from a speed perspective. .PP Of course, you probably want to use ISOLINUX instead. See the documentation file .BR isolinux.doc . .SS Booting from a FAT partition on a hard disk \s-1SYSLINUX\s+1 can boot from a FAT filesystem partition on a hard disk (including FAT32). The installation procedure is identical to the procedure for installing it on a floppy, and should work under either DOS or Linux. To boot from a partition, \s-1SYSLINUX\s+1 needs to be launched from a Master Boot Record or another boot loader, just like DOS itself would. A sample master boot sector (\fBmbr.bin\fP) is included with \s-1SYSLINUX\s+1. .SH BUGS I would appreciate hearing of any problems you have with \s-1SYSLINUX\s+1. I would also like to hear from you if you have successfully used \s-1SYSLINUX\s+1, especially if you are using it for a distribution. .PP If you are reporting problems, please include all possible information about your system and your BIOS; the vast majority of all problems reported turn out to be BIOS or hardware bugs, and I need as much information as possible in order to diagnose the problems. .PP There is a mailing list for discussion among \s-1SYSLINUX\s+1 users and for announcements of new and test versions. To join, send a message to majordomo@linux.kernel.org with the line: .PP .B subscribe syslinux .PP in the body of the message. The submission address is syslinux@linux.kernel.org. .SH SEE ALSO .BR lilo (8), .BR keytab-lilo.pl (8), .BR fdisk (8), .BR mkfs (8), .BR superformat (1). .SH AUTHOR This manual page is a modified version of the original \fBsyslinux\fP documentation by H. Peter Anvin . The conversion to a manpage was made by Arthur Korn . syslinux-legacy-3.63+dfsg/now.pl0000664000175000017500000000067510777447273015364 0ustar evanevan#!/usr/bin/perl # # Print the time (possibly the mtime of a file) as a hexadecimal integer # If more than one file, print the mtime of the *newest* file. # undef $now; foreach $file ( @ARGV ) { ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime, $ctime,$blksize,$blocks) = stat($file); if ( !defined($now) || $now < $mtime ) { $now = $mtime; } } if ( !defined($now) ) { $now = time; } printf "0x%08x\n", $now; syslinux-legacy-3.63+dfsg/isolinux.asm0000664000175000017500000011464110777447273016577 0ustar evanevan; -*- fundamental -*- (asm-mode sucks) ; **************************************************************************** ; ; isolinux.asm ; ; A program to boot Linux kernels off a CD-ROM using the El Torito ; boot standard in "no emulation" mode, making the entire filesystem ; available. It is based on the SYSLINUX boot loader for MS-DOS ; floppies. ; ; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Boston MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; **************************************************************************** %define IS_ISOLINUX 1 %include "head.inc" ; ; Some semi-configurable constants... change on your own risk. ; my_id equ isolinux_id FILENAME_MAX_LG2 equ 8 ; log2(Max filename size Including final null) FILENAME_MAX equ (1 << FILENAME_MAX_LG2) NULLFILE equ 0 ; Zero byte == null file name NULLOFFSET equ 0 ; Position in which to look retry_count equ 6 ; How patient are we with the BIOS? %assign HIGHMEM_SLOP 128*1024 ; Avoid this much memory near the top MAX_OPEN_LG2 equ 6 ; log2(Max number of open files) MAX_OPEN equ (1 << MAX_OPEN_LG2) SECTOR_SHIFT equ 11 ; 2048 bytes/sector (El Torito requirement) SECTOR_SIZE equ (1 << SECTOR_SHIFT) ; ; This is what we need to do when idle ; %macro RESET_IDLE 0 ; Nothing %endmacro %macro DO_IDLE 0 ; Nothing %endmacro ; ; The following structure is used for "virtual kernels"; i.e. LILO-style ; option labels. The options we permit here are `kernel' and `append ; Since there is no room in the bottom 64K for all of these, we ; stick them in high memory and copy them down before we need them. ; struc vkernel vk_vname: resb FILENAME_MAX ; Virtual name **MUST BE FIRST!** vk_rname: resb FILENAME_MAX ; Real name vk_appendlen: resw 1 vk_type: resb 1 ; Type of file alignb 4 vk_append: resb max_cmd_len+1 ; Command line alignb 4 vk_end: equ $ ; Should be <= vk_size endstruc ; ; Segment assignments in the bottom 640K ; 0000h - main code/data segment (and BIOS segment) ; real_mode_seg equ 2000h xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem comboot_seg equ real_mode_seg ; COMBOOT image loading zone ; ; File structure. This holds the information for each currently open file. ; struc open_file_t file_sector resd 1 ; Sector pointer (0 = structure free) file_left resd 1 ; Number of sectors left endstruc %ifndef DEPEND %if (open_file_t_size & (open_file_t_size-1)) %error "open_file_t is not a power of 2" %endif %endif struc dir_t dir_lba resd 1 ; Directory start (LBA) dir_len resd 1 ; Length in bytes dir_clust resd 1 ; Length in clusters endstruc ; --------------------------------------------------------------------------- ; BEGIN CODE ; --------------------------------------------------------------------------- ; ; Memory below this point is reserved for the BIOS and the MBR ; section .earlybss trackbufsize equ 8192 trackbuf resb trackbufsize ; Track buffer goes here ; ends at 2800h ; Some of these are touched before the whole image ; is loaded. DO NOT move this to .uibss. section .bss1 alignb 4 ISOFileName resb 64 ; ISO filename canonicalization buffer ISOFileNameEnd equ $ CurDir resb dir_t_size ; Current directory RootDir resb dir_t_size ; Root directory FirstSecSum resd 1 ; Checksum of bytes 64-2048 ImageDwords resd 1 ; isolinux.bin size, dwords InitStack resd 1 ; Initial stack pointer (SS:SP) DiskSys resw 1 ; Last INT 13h call ImageSectors resw 1 ; isolinux.bin size, sectors DiskError resb 1 ; Error code for disk I/O DriveNumber resb 1 ; CD-ROM BIOS drive number ISOFlags resb 1 ; Flags for ISO directory search RetryCount resb 1 ; Used for disk access retries _spec_start equ $ ; ; El Torito spec packet ; alignb 8 spec_packet: resb 1 ; Size of packet sp_media: resb 1 ; Media type sp_drive: resb 1 ; Drive number sp_controller: resb 1 ; Controller index sp_lba: resd 1 ; LBA for emulated disk image sp_devspec: resw 1 ; IDE/SCSI information sp_buffer: resw 1 ; User-provided buffer sp_loadseg: resw 1 ; Load segment sp_sectors: resw 1 ; Sector count sp_chs: resb 3 ; Simulated CHS geometry sp_dummy: resb 1 ; Scratch, safe to overwrite ; ; EBIOS drive parameter packet ; alignb 8 drive_params: resw 1 ; Buffer size dp_flags: resw 1 ; Information flags dp_cyl: resd 1 ; Physical cylinders dp_head: resd 1 ; Physical heads dp_sec: resd 1 ; Physical sectors/track dp_totalsec: resd 2 ; Total sectors dp_secsize: resw 1 ; Bytes per sector dp_dpte: resd 1 ; Device Parameter Table dp_dpi_key: resw 1 ; 0BEDDh if rest valid dp_dpi_len: resb 1 ; DPI len resb 1 resw 1 dp_bus: resb 4 ; Host bus type dp_interface: resb 8 ; Interface type db_i_path: resd 2 ; Interface path db_d_path: resd 2 ; Device path resb 1 db_dpi_csum: resb 1 ; Checksum for DPI info ; ; EBIOS disk address packet ; alignb 8 dapa: resw 1 ; Packet size .count: resw 1 ; Block count .off: resw 1 ; Offset of buffer .seg: resw 1 ; Segment of buffer .lba: resd 2 ; LBA (LSW, MSW) ; ; Spec packet for disk image emulation ; alignb 8 dspec_packet: resb 1 ; Size of packet dsp_media: resb 1 ; Media type dsp_drive: resb 1 ; Drive number dsp_controller: resb 1 ; Controller index dsp_lba: resd 1 ; LBA for emulated disk image dsp_devspec: resw 1 ; IDE/SCSI information dsp_buffer: resw 1 ; User-provided buffer dsp_loadseg: resw 1 ; Load segment dsp_sectors: resw 1 ; Sector count dsp_chs: resb 3 ; Simulated CHS geometry dsp_dummy: resb 1 ; Scratch, safe to overwrite alignb 4 _spec_end equ $ _spec_len equ _spec_end - _spec_start alignb open_file_t_size Files resb MAX_OPEN*open_file_t_size section .text ;; ;; Primary entry point. Because BIOSes are buggy, we only load the first ;; CD-ROM sector (2K) of the file, so the number one priority is actually ;; loading the rest. ;; StackBuf equ $-44 ; 44 bytes needed for ; the bootsector chainloading ; code! OrigESDI equ StackBuf-4 ; The high dword on the stack bootsec equ $ _start: ; Far jump makes sure we canonicalize the address cli jmp 0:_start1 times 8-($-$$) nop ; Pad to file offset 8 ; This table hopefully gets filled in by mkisofs using the ; -boot-info-table option. If not, the values in this ; table are default values that we can use to get us what ; we need, at least under a certain set of assumptions. bi_pvd: dd 16 ; LBA of primary volume descriptor bi_file: dd 0 ; LBA of boot file bi_length: dd 0xdeadbeef ; Length of boot file bi_csum: dd 0xdeadbeef ; Checksum of boot file bi_reserved: times 10 dd 0xdeadbeef ; Reserved _start1: mov [cs:InitStack],sp ; Save initial stack pointer mov [cs:InitStack+2],ss xor ax,ax mov ss,ax mov sp,StackBuf ; Set up stack push es ; Save initial ES:DI -> $PnP pointer push di mov ds,ax mov es,ax mov fs,ax mov gs,ax sti cld ; Show signs of life mov si,syslinux_banner call writestr %ifdef DEBUG_MESSAGES mov si,copyright_str call writestr %endif ; ; Before modifying any memory, get the checksum of bytes ; 64-2048 ; initial_csum: xor edi,edi mov si,_start1 mov cx,(SECTOR_SIZE-64) >> 2 .loop: lodsd add edi,eax loop .loop mov [FirstSecSum],edi mov [DriveNumber],dl %ifdef DEBUG_MESSAGES mov si,startup_msg call writemsg mov al,dl call writehex2 call crlf %endif ; ; Initialize spec packet buffers ; mov di,_spec_start mov cx,_spec_len >> 2 xor eax,eax rep stosd ; Initialize length field of the various packets mov byte [spec_packet],13h mov byte [drive_params],30 mov byte [dapa],16 mov byte [dspec_packet],13h ; Other nonzero fields inc word [dsp_sectors] ; Now figure out what we're actually doing ; Note: use passed-in DL value rather than 7Fh because ; at least some BIOSes will get the wrong value otherwise mov ax,4B01h ; Get disk emulation status mov dl,[DriveNumber] mov si,spec_packet call int13 jc award_hack ; changed for BrokenAwardHack mov dl,[DriveNumber] cmp [sp_drive],dl ; Should contain the drive number jne spec_query_failed %ifdef DEBUG_MESSAGES mov si,spec_ok_msg call writemsg mov al,byte [sp_drive] call writehex2 call crlf %endif found_drive: ; Alright, we have found the drive. Now, try to find the ; boot file itself. If we have a boot info table, life is ; good; if not, we have to make some assumptions, and try ; to figure things out ourselves. In particular, the ; assumptions we have to make are: ; - single session only ; - only one boot entry (no menu or other alternatives) cmp dword [bi_file],0 ; Address of code to load jne found_file ; Boot info table present :) %ifdef DEBUG_MESSAGES mov si,noinfotable_msg call writemsg %endif ; No such luck. See if the spec packet contained one. mov eax,[sp_lba] and eax,eax jz set_file ; Good enough %ifdef DEBUG_MESSAGES mov si,noinfoinspec_msg call writemsg %endif ; No such luck. Get the Boot Record Volume, assuming single ; session disk, and that we're the first entry in the chain mov eax,17 ; Assumed address of BRV mov bx,trackbuf call getonesec mov eax,[trackbuf+47h] ; Get boot catalog address mov bx,trackbuf call getonesec ; Get boot catalog mov eax,[trackbuf+28h] ; First boot entry ; And hope and pray this is us... ; Some BIOSes apparently have limitations on the size ; that may be loaded (despite the El Torito spec being very ; clear on the fact that it must all be loaded.) Therefore, ; we load it ourselves, and *bleep* the BIOS. set_file: mov [bi_file],eax found_file: ; Set up boot file sizes mov eax,[bi_length] sub eax,SECTOR_SIZE-3 shr eax,2 ; bytes->dwords mov [ImageDwords],eax ; boot file dwords add eax,(2047 >> 2) shr eax,9 ; dwords->sectors mov [ImageSectors],ax ; boot file sectors mov eax,[bi_file] ; Address of code to load inc eax ; Don't reload bootstrap code %ifdef DEBUG_MESSAGES mov si,offset_msg call writemsg call writehex8 call crlf %endif ; Just in case some BIOSes have problems with ; segment wraparound, use the normalized address mov bx,((7C00h+2048) >> 4) mov es,bx xor bx,bx mov bp,[ImageSectors] %ifdef DEBUG_MESSAGES push ax mov si,size_msg call writemsg mov ax,bp call writehex4 call crlf pop ax %endif call getlinsec push ds pop es %ifdef DEBUG_MESSAGES mov si,loaded_msg call writemsg %endif ; Verify the checksum on the loaded image. verify_image: mov si,7C00h+2048 mov bx,es mov ecx,[ImageDwords] mov edi,[FirstSecSum] ; First sector checksum .loop es lodsd add edi,eax dec ecx jz .done and si,si jnz .loop ; SI wrapped around, advance ES add bx,1000h mov es,bx jmp short .loop .done: mov ax,ds mov es,ax cmp [bi_csum],edi je integrity_ok mov si,checkerr_msg call writemsg jmp kaboom integrity_ok: %ifdef DEBUG_MESSAGES mov si,allread_msg call writemsg %endif jmp all_read ; Jump to main code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Start of BrokenAwardHack --- 10-nov-2002 Knut_Petersen@t-online.de ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; There is a problem with certain versions of the AWARD BIOS ... ;; the boot sector will be loaded and executed correctly, but, because the ;; int 13 vector points to the wrong code in the BIOS, every attempt to ;; load the spec packet will fail. We scan for the equivalent of ;; ;; mov ax,0201h ;; mov bx,7c00h ;; mov cx,0006h ;; mov dx,0180h ;; pushf ;; call ;; ;; and use as the new vector for int 13. The code above is ;; used to load the boot code into ram, and there should be no reason ;; for anybody to change it now or in the future. There are no opcodes ;; that use encodings relativ to IP, so scanning is easy. If we find the ;; code above in the BIOS code we can be pretty sure to run on a machine ;; with an broken AWARD BIOS ... ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; %ifdef DEBUG_MESSAGES ;; ;; award_notice db "Trying BrokenAwardHack first ...",CR,LF,0 ;; award_not_orig db "BAH: Original Int 13 vector : ",0 ;; award_not_new db "BAH: Int 13 vector changed to : ",0 ;; award_not_succ db "BAH: SUCCESS",CR,LF,0 ;; award_not_fail db "BAH: FAILURE" ;; award_not_crlf db CR,LF,0 ;; ;; %endif ;; ;; award_oldint13 dd 0 ;; award_string db 0b8h,1,2,0bbh,0,7ch,0b9h,6,0,0bah,80h,1,09ch,09ah ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; award_hack: mov si,spec_err_msg ; Moved to this place from call writemsg ; spec_query_faild ; %ifdef DEBUG_MESSAGES ; ; mov si,award_notice ; display our plan call writemsg ; mov si,award_not_orig ; display original int 13 call writemsg ; vector %endif ; mov eax,[13h*4] ; mov [award_oldint13],eax ; ; %ifdef DEBUG_MESSAGES ; ; call writehex8 ; mov si,award_not_crlf ; call writestr ; %endif ; push es ; save ES mov ax,0f000h ; ES = BIOS Seg mov es,ax ; cld ; xor di,di ; start at ES:DI = f000:0 award_loop: push di ; save DI mov si,award_string ; scan for award_string mov cx,7 ; length of award_string = 7dw repz cmpsw ; compare pop di ; restore DI jcxz award_found ; jmp if found inc di ; not found, inc di jno award_loop ; ; award_failed: pop es ; No, not this way :-(( award_fail2: ; ; %ifdef DEBUG_MESSAGES ; ; mov si,award_not_fail ; display failure ... call writemsg ; %endif ; mov eax,[award_oldint13] ; restore the original int or eax,eax ; 13 vector if there is one jz spec_query_failed ; and try other workarounds mov [13h*4],eax ; jmp spec_query_failed ; ; award_found: mov eax,[es:di+0eh] ; load possible int 13 addr pop es ; restore ES ; cmp eax,[award_oldint13] ; give up if this is the jz award_failed ; active int 13 vector, mov [13h*4],eax ; otherwise change 0:13h*4 ; ; %ifdef DEBUG_MESSAGES ; ; push eax ; display message and mov si,award_not_new ; new vector address call writemsg ; pop eax ; call writehex8 ; mov si,award_not_crlf ; call writestr ; %endif ; mov ax,4B01h ; try to read the spec packet mov dl,[DriveNumber] ; now ... it should not fail mov si,spec_packet ; any longer int 13h ; jc award_fail2 ; ; %ifdef DEBUG_MESSAGES ; ; mov si,award_not_succ ; display our SUCCESS call writemsg ; %endif ; jmp found_drive ; and leave error recovery code ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; End of BrokenAwardHack ---- 10-nov-2002 Knut_Petersen@t-online.de ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; INT 13h, AX=4B01h, DL= failed. ; Try to scan the entire 80h-FFh from the end. spec_query_failed: ; some code moved to BrokenAwardHack mov dl,0FFh .test_loop: pusha mov ax,4B01h mov si,spec_packet mov byte [si],13h ; Size of buffer call int13 popa jc .still_broken mov si,maybe_msg call writemsg mov al,dl call writehex2 call crlf cmp byte [sp_drive],dl jne .maybe_broken ; Okay, good enough... mov si,alright_msg call writemsg .found_drive0: mov [DriveNumber],dl .found_drive: jmp found_drive ; Award BIOS 4.51 apparently passes garbage in sp_drive, ; but if this was the drive number originally passed in ; DL then consider it "good enough" .maybe_broken: mov al,[DriveNumber] cmp al,dl je .found_drive ; Intel Classic R+ computer with Adaptec 1542CP BIOS 1.02 ; passes garbage in sp_drive, and the drive number originally ; passed in DL does not have 80h bit set. or al,80h cmp al,dl je .found_drive0 .still_broken: dec dx cmp dl, 80h jnb .test_loop ; No spec packet anywhere. Some particularly pathetic ; BIOSes apparently don't even implement function ; 4B01h, so we can't query a spec packet no matter ; what. If we got a drive number in DL, then try to ; use it, and if it works, then well... mov dl,[DriveNumber] cmp dl,81h ; Should be 81-FF at least jb fatal_error ; If not, it's hopeless ; Write a warning to indicate we're on *very* thin ice now mov si,nospec_msg call writemsg mov al,dl call writehex2 call crlf mov si,trysbm_msg call writemsg jmp .found_drive ; Pray that this works... fatal_error: mov si,nothing_msg call writemsg .norge: jmp short .norge ; Information message (DS:SI) output ; Prefix with "isolinux: " ; writemsg: push ax push si mov si,isolinux_str call writestr pop si call writestr pop ax ret ; ; Write a character to the screen. There is a more "sophisticated" ; version of this in the subsequent code, so we patch the pointer ; when appropriate. ; writechr: jmp near writechr_simple ; 3-byte jump writechr_simple: pushfd pushad mov ah,0Eh xor bx,bx int 10h popad popfd ret ; ; int13: save all the segment registers and call INT 13h ; Some CD-ROM BIOSes have been found to corrupt segment registers. ; int13: push ds push es push fs push gs int 13h pop gs pop fs pop es pop ds ret ; ; Get one sector. Convenience entry point. ; getonesec: mov bp,1 ; Fall through to getlinsec ; ; Get linear sectors - EBIOS LBA addressing, 2048-byte sectors. ; ; Note that we can't always do this as a single request, because at least ; Phoenix BIOSes has a 127-sector limit. To be on the safe side, stick ; to 32 sectors (64K) per request. ; ; Input: ; EAX - Linear sector number ; ES:BX - Target buffer ; BP - Sector count ; getlinsec: mov si,dapa ; Load up the DAPA mov [si+4],bx mov bx,es mov [si+6],bx mov [si+8],eax .loop: push bp ; Sectors left cmp bp,[MaxTransfer] jbe .bp_ok mov bp,[MaxTransfer] .bp_ok: mov [si+2],bp push si mov dl,[DriveNumber] mov ah,42h ; Extended Read call xint13 pop si pop bp movzx eax,word [si+2] ; Sectors we read add [si+8],eax ; Advance sector pointer sub bp,ax ; Sectors left shl ax,SECTOR_SHIFT-4 ; 2048-byte sectors -> segment add [si+6],ax ; Advance buffer pointer and bp,bp jnz .loop mov eax,[si+8] ; Next sector ret ; INT 13h with retry xint13: mov byte [RetryCount],retry_count .try: pushad call int13 jc .error add sp,byte 8*4 ; Clean up stack ret .error: mov [DiskError],ah ; Save error code popad mov [DiskSys],ax ; Save system call number dec byte [RetryCount] jz .real_error push ax mov al,[RetryCount] mov ah,[dapa+2] ; Sector transfer count cmp al,2 ; Only 2 attempts left ja .nodanger mov ah,1 ; Drop transfer size to 1 jmp short .setsize .nodanger: cmp al,retry_count-2 ja .again ; First time, just try again shr ah,1 ; Otherwise, try to reduce adc ah,0 ; the max transfer size, but not to 0 .setsize: mov [MaxTransfer],ah mov [dapa+2],ah .again: pop ax jmp .try .real_error: mov si,diskerr_msg call writemsg mov al,[DiskError] call writehex2 mov si,oncall_str call writestr mov ax,[DiskSys] call writehex4 mov si,ondrive_str call writestr mov al,dl call writehex2 call crlf ; Fall through to kaboom ; ; kaboom: write a message and bail out. Wait for a user keypress, ; then do a hard reboot. ; kaboom: RESET_STACK_AND_SEGS AX mov si,err_bootfailed call cwritestr call getchar cli mov word [BIOS_magic],0 ; Cold reboot jmp 0F000h:0FFF0h ; Reset vector address ; ----------------------------------------------------------------------------- ; Common modules needed in the first sector ; ----------------------------------------------------------------------------- %include "writestr.inc" ; String output writestr equ cwritestr %include "writehex.inc" ; Hexadecimal output ; ----------------------------------------------------------------------------- ; Data that needs to be in the first sector ; ----------------------------------------------------------------------------- syslinux_banner db CR, LF, 'ISOLINUX ', version_str, ' ', date, ' ', 0 copyright_str db ' Copyright (C) 1994-', year, ' H. Peter Anvin' db CR, LF, 0 isolinux_str db 'isolinux: ', 0 %ifdef DEBUG_MESSAGES startup_msg: db 'Starting up, DL = ', 0 spec_ok_msg: db 'Loaded spec packet OK, drive = ', 0 secsize_msg: db 'Sector size appears to be ', 0 offset_msg: db 'Loading main image from LBA = ', 0 size_msg: db 'Sectors to load = ', 0 loaded_msg: db 'Loaded boot image, verifying...', CR, LF, 0 verify_msg: db 'Image checksum verified.', CR, LF, 0 allread_msg db 'Main image read, jumping to main code...', CR, LF, 0 %endif noinfotable_msg db 'No boot info table, assuming single session disk...', CR, LF, 0 noinfoinspec_msg db 'Spec packet missing LBA information, trying to wing it...', CR, LF, 0 spec_err_msg: db 'Loading spec packet failed, trying to wing it...', CR, LF, 0 maybe_msg: db 'Found something at drive = ', 0 alright_msg: db 'Looks like it might be right, continuing...', CR, LF, 0 nospec_msg db 'Extremely broken BIOS detected, last ditch attempt with drive = ', 0 nothing_msg: db 'Failed to locate CD-ROM device; boot failed.', CR, LF trysbm_msg db 'See http://syslinux.zytor.com/sbm for more information.', CR, LF, 0 diskerr_msg: db 'Disk error ', 0 oncall_str: db ', AX = ',0 ondrive_str: db ', drive ', 0 checkerr_msg: db 'Image checksum error, sorry...', CR, LF, 0 err_bootfailed db CR, LF, 'Boot failed: press a key to retry...' bailmsg equ err_bootfailed crlf_msg db CR, LF null_msg db 0 alignb 4, db 0 MaxTransfer dw 32 ; Max sectors per transfer rl_checkpt equ $ ; Must be <= 800h rl_checkpt_off equ ($-$$) ;%ifndef DEPEND ;%if rl_checkpt_off > 0x800 ;%error "Sector 0 overflow" ;%endif ;%endif ; ---------------------------------------------------------------------------- ; End of code and data that have to be in the first sector ; ---------------------------------------------------------------------------- all_read: ; Test tracers TRACER 'T' TRACER '>' ; ; Common initialization code ; %include "init.inc" %include "cpuinit.inc" ; Patch the writechr routine to point to the full code mov word [writechr+1], writechr_full-(writechr+3) ; Tell the user we got this far... %ifndef DEBUG_MESSAGES ; Gets messy with debugging on mov si,copyright_str call writestr %endif ; ; Now we're all set to start with our *real* business. First load the ; configuration file (if any) and parse it. ; ; In previous versions I avoided using 32-bit registers because of a ; rumour some BIOSes clobbered the upper half of 32-bit registers at ; random. I figure, though, that if there are any of those still left ; they probably won't be trying to install Linux on them... ; ; The code is still ripe with 16-bitisms, though. Not worth the hassle ; to take'm out. In fact, we may want to put them back if we're going ; to boot ELKS at some point. ; ; ; Now, we need to sniff out the actual filesystem data structures. ; mkisofs gave us a pointer to the primary volume descriptor ; (which will be at 16 only for a single-session disk!); from the PVD ; we should be able to find the rest of what we need to know. ; get_fs_structures: mov eax,[bi_pvd] mov bx,trackbuf call getonesec mov eax,[trackbuf+156+2] mov [RootDir+dir_lba],eax mov [CurDir+dir_lba],eax %ifdef DEBUG_MESSAGES mov si,dbg_rootdir_msg call writemsg call writehex8 call crlf %endif mov eax,[trackbuf+156+10] mov [RootDir+dir_len],eax mov [CurDir+dir_len],eax add eax,SECTOR_SIZE-1 shr eax,SECTOR_SHIFT mov [RootDir+dir_clust],eax mov [CurDir+dir_clust],eax ; Look for an isolinux directory, and if found, ; make it the current directory instead of the root ; directory. mov di,boot_dir ; Search for /boot/isolinux mov al,02h call searchdir_iso jnz .found_dir mov di,isolinux_dir mov al,02h ; Search for /isolinux call searchdir_iso jz .no_isolinux_dir .found_dir: mov [CurDir+dir_len],eax mov eax,[si+file_left] mov [CurDir+dir_clust],eax xor eax,eax ; Free this file pointer entry xchg eax,[si+file_sector] mov [CurDir+dir_lba],eax %ifdef DEBUG_MESSAGES push si mov si,dbg_isodir_msg call writemsg pop si call writehex8 call crlf %endif .no_isolinux_dir: ; ; Locate the configuration file ; load_config: %ifdef DEBUG_MESSAGES mov si,dbg_config_msg call writemsg %endif mov si,config_name mov di,ConfigName call strcpy mov di,ConfigName call open jz no_config_file ; Not found or empty %ifdef DEBUG_MESSAGES mov si,dbg_configok_msg call writemsg %endif ; ; Now we have the config file open. Parse the config file and ; run the user interface. ; %include "ui.inc" ; ; Enable disk emulation. The kind of disk we emulate is dependent on the size of ; the file: 1200K, 1440K or 2880K floppy, otherwise harddisk. ; is_disk_image: TRACER CR TRACER LF TRACER 'D' TRACER ':' shl edx,16 mov dx,ax ; Set EDX <- file size mov di,img_table mov cx,img_table_count mov eax,[si+file_sector] ; Starting LBA of file mov [dsp_lba],eax ; Location of file mov byte [dsp_drive], 0 ; 00h floppy, 80h hard disk .search_table: TRACER 't' mov eax,[di+4] cmp edx,[di] je .type_found add di,8 loop .search_table ; Hard disk image. Need to examine the partition table ; in order to deduce the C/H/S geometry. Sigh. .hard_disk_image: TRACER 'h' cmp edx,512 jb .bad_image mov bx,trackbuf mov cx,1 ; Load 1 sector call getfssec cmp word [trackbuf+510],0aa55h ; Boot signature jne .bad_image ; Image not bootable mov cx,4 ; 4 partition entries mov di,trackbuf+446 ; Start of partition table xor ax,ax ; Highest sector(al) head(ah) .part_scan: cmp byte [di+4], 0 jz .part_loop lea si,[di+1] call .hs_check add si,byte 4 call .hs_check .part_loop: add di,byte 16 loop .part_scan push eax ; H/S push edx ; File size mov bl,ah xor bh,bh inc bx ; # of heads in BX xor ah,ah ; # of sectors in AX cwde ; EAX[31:16] <- 0 mul bx shl eax,9 ; Convert to bytes ; Now eax contains the number of bytes per cylinder pop ebx ; File size xor edx,edx div ebx and edx,edx jz .no_remainder inc eax ; Fractional cylinder... ; Now (e)ax contains the number of cylinders .no_remainder: cmp eax,1024 jna .ok_cyl mov ax,1024 ; Max possible # .ok_cyl: dec ax ; Convert to max cylinder no pop ebx ; S(bl) H(bh) shl ah,6 or bl,ah xchg ax,bx shl eax,16 mov ah,bl mov al,4 ; Hard disk boot mov byte [dsp_drive], 80h ; Drive 80h = hard disk .type_found: TRACER 'T' mov bl,[sp_media] and bl,0F0h ; Copy controller info bits or al,bl mov [dsp_media],al ; Emulation type shr eax,8 mov [dsp_chs],eax ; C/H/S geometry mov ax,[sp_devspec] ; Copy device spec mov [dsp_devspec],ax mov al,[sp_controller] ; Copy controller index mov [dsp_controller],al TRACER 'V' call vgaclearmode ; Reset video mov ax,4C00h ; Enable emulation and boot mov si,dspec_packet mov dl,[DriveNumber] lss sp,[InitStack] TRACER 'X' call int13 ; If this returns, we have problems .bad_image: mov si,err_disk_image call cwritestr jmp enter_command ; ; Look for the highest seen H/S geometry ; We compute cylinders separately ; .hs_check: mov bl,[si] ; Head # cmp bl,ah jna .done_track mov ah,bl ; New highest head # .done_track: mov bl,[si+1] and bl,3Fh ; Sector # cmp bl,al jna .done_sector mov al,bl .done_sector: ret ; ; Boot a specified local disk. AX specifies the BIOS disk number; or ; 0xFFFF in case we should execute INT 18h ("next device.") ; local_boot: call vgaclearmode lss sp,[cs:Stack] ; Restore stack pointer xor dx,dx mov ds,dx mov es,dx mov fs,dx mov gs,dx mov si,localboot_msg call writestr cmp ax,-1 je .int18 ; Load boot sector from the specified BIOS device and jump to it. mov dl,al xor dh,dh push dx xor ax,ax ; Reset drive call xint13 mov ax,0201h ; Read one sector mov cx,0001h ; C/H/S = 0/0/1 (first sector) mov bx,trackbuf call xint13 pop dx cli ; Abandon hope, ye who enter here mov si,trackbuf mov di,07C00h mov cx,512 ; Probably overkill, but should be safe rep movsd lss sp,[cs:InitStack] jmp 0:07C00h ; Jump to new boot sector .int18: int 18h ; Hope this does the right thing... jmp kaboom ; If we returned, oh boy... ; ; close_file: ; Deallocates a file structure (pointer in SI) ; Assumes CS == DS. ; close_file: and si,si jz .closed mov dword [si],0 ; First dword == file_left .closed: ret ; ; searchdir: ; ; Open a file ; ; On entry: ; DS:DI = filename ; If successful: ; ZF clear ; SI = file pointer ; DX:AX or EAX = file length in bytes ; If unsuccessful ; ZF set ; ; Assumes CS == DS == ES, and trashes BX and CX. ; ; searchdir_iso is a special entry point for ISOLINUX only. In addition ; to the above, searchdir_iso passes a file flag mask in AL. This is useful ; for searching for directories. ; alloc_failure: xor ax,ax ; ZF <- 1 ret searchdir: xor al,al searchdir_iso: mov [ISOFlags],al TRACER 'S' call allocate_file ; Temporary file structure for directory jnz alloc_failure push es push ds pop es ; ES = DS mov si,CurDir cmp byte [di],'/' ; If filename begins with slash jne .not_rooted inc di ; Skip leading slash mov si,RootDir ; Reference root directory instead .not_rooted: mov eax,[si+dir_clust] mov [bx+file_left],eax mov eax,[si+dir_lba] mov [bx+file_sector],eax mov edx,[si+dir_len] .look_for_slash: mov ax,di .scan: mov cl,[di] inc di and cl,cl jz .isfile cmp cl,'/' jne .scan mov [di-1],byte 0 ; Terminate at directory name mov cl,02h ; Search for directory xchg cl,[ISOFlags] push di ; Save these... push cx ; Create recursion stack frame... push word .resume ; Where to "return" to push es .isfile: xchg ax,di .getsome: ; Get a chunk of the directory ; This relies on the fact that ISOLINUX doesn't change SI mov si,trackbuf TRACER 'g' pushad xchg bx,si mov cx,[BufSafe] call getfssec popad .compare: movzx eax,byte [si] ; Length of directory entry cmp al,33 jb .next_sector TRACER 'c' mov cl,[si+25] xor cl,[ISOFlags] test cl, byte 8Eh ; Unwanted file attributes! jnz .not_file pusha movzx cx,byte [si+32] ; File identifier length add si,byte 33 ; File identifier offset TRACER 'i' call iso_compare_names popa je .success .not_file: sub edx,eax ; Decrease bytes left jbe .failure add si,ax ; Advance pointer .check_overrun: ; Did we finish the buffer? cmp si,trackbuf+trackbufsize jb .compare ; No, keep going jmp short .getsome ; Get some more directory .next_sector: ; Advance to the beginning of next sector lea ax,[si+SECTOR_SIZE-1] and ax,~(SECTOR_SIZE-1) sub ax,si jmp short .not_file ; We still need to do length checks .failure: xor eax,eax ; ZF = 1 mov [bx+file_sector],eax pop es ret .success: mov eax,[si+2] ; Location of extent mov [bx+file_sector],eax mov eax,[si+10] ; Data length push eax add eax,SECTOR_SIZE-1 shr eax,SECTOR_SHIFT mov [bx+file_left],eax pop eax mov edx,eax shr edx,16 and bx,bx ; ZF = 0 mov si,bx pop es ret .resume: ; We get here if we were only doing part of a lookup ; This relies on the fact that .success returns bx == si xchg edx,eax ; Directory length in edx pop cx ; Old ISOFlags pop di ; Next filename pointer mov byte [di-1], '/' ; Restore slash mov [ISOFlags],cl ; Restore the flags jz .failure ; Did we fail? If so fail for real! jmp .look_for_slash ; Otherwise, next level ; ; allocate_file: Allocate a file structure ; ; If successful: ; ZF set ; BX = file pointer ; In unsuccessful: ; ZF clear ; allocate_file: TRACER 'a' push cx mov bx,Files mov cx,MAX_OPEN .check: cmp dword [bx], byte 0 je .found add bx,open_file_t_size ; ZF = 0 loop .check ; ZF = 0 if we fell out of the loop .found: pop cx ret ; ; iso_compare_names: ; Compare the names DS:SI and DS:DI and report if they are ; equal from an ISO 9660 perspective. SI is the name from ; the filesystem; CX indicates its length, and ';' terminates. ; DI is expected to end with a null. ; ; Note: clobbers AX, CX, SI, DI; assumes DS == ES == base segment ; iso_compare_names: ; First, terminate and canonicalize input filename push di mov di,ISOFileName .canon_loop: jcxz .canon_end lodsb dec cx cmp al,';' je .canon_end and al,al je .canon_end stosb cmp di,ISOFileNameEnd-1 ; Guard against buffer overrun jb .canon_loop .canon_end: cmp di,ISOFileName jbe .canon_done cmp byte [di-1],'.' ; Remove terminal dots jne .canon_done dec di jmp short .canon_end .canon_done: mov [di],byte 0 ; Null-terminate string pop di mov si,ISOFileName .compare: lodsb mov ah,[di] inc di and ax,ax jz .success ; End of string for both and al,al ; Is either one end of string? jz .failure ; If so, failure and ah,ah jz .failure or ax,2020h ; Convert to lower case cmp al,ah je .compare .failure: and ax,ax ; ZF = 0 (at least one will be nonzero) .success: ret ; ; mangle_name: Mangle a filename pointed to by DS:SI into a buffer pointed ; to by ES:DI; ends on encountering any whitespace. ; DI is preserved. ; ; This verifies that a filename is < FILENAME_MAX characters, ; doesn't contain whitespace, zero-pads the output buffer, ; and removes trailing dots and redundant slashes, ; so "repe cmpsb" can do a compare, and the ; path-searching routine gets a bit of an easier job. ; mangle_name: push di push bx xor ax,ax mov cx,FILENAME_MAX-1 mov bx,di .mn_loop: lodsb cmp al,' ' ; If control or space, end jna .mn_end cmp al,ah ; Repeated slash? je .mn_skip xor ah,ah cmp al,'/' jne .mn_ok mov ah,al .mn_ok stosb .mn_skip: loop .mn_loop .mn_end: cmp bx,di ; At the beginning of the buffer? jbe .mn_zero cmp byte [es:di-1],'.' ; Terminal dot? je .mn_kill cmp byte [es:di-1],'/' ; Terminal slash? jne .mn_zero .mn_kill: dec di ; If so, remove it inc cx jmp short .mn_end .mn_zero: inc cx ; At least one null byte xor ax,ax ; Zero-fill name rep stosb pop bx pop di ret ; Done ; ; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled ; filename to the conventional representation. This is needed ; for the BOOT_IMAGE= parameter for the kernel. ; ; DS:SI -> input mangled file name ; ES:DI -> output buffer ; ; On return, DI points to the first byte after the output name, ; which is set to a null byte. ; unmangle_name: call strcpy dec di ; Point to final null byte ret ; ; getfssec: Get multiple clusters from a file, given the file pointer. ; ; On entry: ; ES:BX -> Buffer ; SI -> File pointer ; CX -> Cluster count ; On exit: ; SI -> File pointer (or 0 on EOF) ; CF = 1 -> Hit EOF ; getfssec: TRACER 'F' push ds push cs pop ds ; DS <- CS movzx ecx,cx cmp ecx,[si+file_left] jna .ok_size mov ecx,[si+file_left] .ok_size: mov bp,cx push cx push si mov eax,[si+file_sector] TRACER 'l' call getlinsec xor ecx,ecx pop si pop cx add [si+file_sector],ecx sub [si+file_left],ecx ja .not_eof ; CF = 0 xor ecx,ecx mov [si+file_sector],ecx ; Mark as unused xor si,si stc .not_eof: pop ds TRACER 'f' ret ; ----------------------------------------------------------------------------- ; Common modules ; ----------------------------------------------------------------------------- %include "getc.inc" ; getc et al %include "conio.inc" ; Console I/O %include "configinit.inc" ; Initialize configuration %include "parseconfig.inc" ; High-level config file handling %include "parsecmd.inc" ; Low-level config file handling %include "bcopy32.inc" ; 32-bit bcopy %include "loadhigh.inc" ; Load a file into high memory %include "font.inc" ; VGA font stuff %include "graphics.inc" ; VGA graphics %include "highmem.inc" ; High memory sizing %include "strcpy.inc" ; strcpy() %include "rawcon.inc" ; Console I/O w/o using the console functions %include "adv.inc" ; Auxillary Data Vector ; ----------------------------------------------------------------------------- ; Begin data section ; ----------------------------------------------------------------------------- section .data localboot_msg db 'Booting from local disk...', CR, LF, 0 default_str db 'default', 0 default_len equ ($-default_str) boot_dir db '/boot' ; /boot/isolinux isolinux_dir db '/isolinux', 0 config_name db 'isolinux.cfg', 0 err_disk_image db 'Cannot load disk image (invalid file)?', CR, LF, 0 %ifdef DEBUG_MESSAGES dbg_rootdir_msg db 'Root directory at LBA = ', 0 dbg_isodir_msg db 'isolinux directory at LBA = ', 0 dbg_config_msg db 'About to load config file...', CR, LF, 0 dbg_configok_msg db 'Configuration file opened...', CR, LF, 0 %endif ; ; Command line options we'd like to take a look at ; ; mem= and vga= are handled as normal 32-bit integer values initrd_cmd db 'initrd=' initrd_cmd_len equ 7 ; ; Config file keyword table ; %include "keywords.inc" ; ; Extensions to search for (in *forward* order). ; align 4, db 0 exten_table: db '.cbt' ; COMBOOT (specific) db '.img' ; Disk image db '.bin' ; CD boot sector db '.com' ; COMBOOT (same as DOS) db '.c32' ; COM32 exten_table_end: dd 0, 0 ; Need 8 null bytes here ; ; Floppy image table ; align 4, db 0 img_table_count equ 3 img_table: dd 1200*1024 ; 1200K floppy db 1 ; Emulation type db 80-1 ; Max cylinder db 15 ; Max sector db 2-1 ; Max head dd 1440*1024 ; 1440K floppy db 2 ; Emulation type db 80-1 ; Max cylinder db 18 ; Max sector db 2-1 ; Max head dd 2880*1024 ; 2880K floppy db 3 ; Emulation type db 80-1 ; Max cylinder db 36 ; Max sector db 2-1 ; Max head ; ; Misc initialized (data) variables ; ; ; Variables that are uninitialized in SYSLINUX but initialized here ; ; **** ISOLINUX:: We may have to make this flexible, based on what the ; **** BIOS expects our "sector size" to be. ; alignb 4, db 0 BufSafe dw trackbufsize/SECTOR_SIZE ; Clusters we can load into trackbuf BufSafeBytes dw trackbufsize ; = how many bytes? %ifndef DEPEND %if ( trackbufsize % SECTOR_SIZE ) != 0 %error trackbufsize must be a multiple of SECTOR_SIZE %endif %endif syslinux-legacy-3.63+dfsg/COPYING0000664000175000017500000004312710777447271015254 0ustar evanevan GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. syslinux-legacy-3.63+dfsg/font.inc0000664000175000017500000000662210777447273015663 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; font.inc ;; ;; VGA font handling code ;; section .text ; ; loadfont: Load a .psf font file and install it onto the VGA console ; (if we're not on a VGA screen then ignore.) It is called with ; SI and DX:AX set by routine searchdir ; loadfont: mov bx,trackbuf ; The trackbuf is >= 16K; the part mov cx,[BufSafe] ; of a PSF file we care about is no call getfssec ; more than 8K+4 bytes mov ax,[trackbuf] ; Magic number cmp ax,0436h jne lf_ret mov al,[trackbuf+2] ; File mode cmp al,5 ; Font modes 0-5 supported ja lf_ret mov bh,byte [trackbuf+3] ; Height of font cmp bh,2 ; VGA minimum jb lf_ret cmp bh,32 ; VGA maximum ja lf_ret ; Copy to font buffer mov si,trackbuf+4 ; Start of font data mov [VGAFontSize],bh mov di,vgafontbuf mov cx,(32*256) >> 2 ; Maximum size rep movsd mov [UserFont], byte 1 ; Set font flag ; Fall through to use_font ; ; use_font: ; This routine activates whatever font happens to be in the ; vgafontbuf, and updates the adjust_screen data. ; Must be called with CS = DS = ES ; use_font: test byte [UsingVGA], ~03h ; Nonstandard mode? jz .modeok call vgaclearmode .modeok: test [UserFont], byte 1 ; Are we using a user-specified font? jz adjust_screen ; If not, just do the normal stuff mov bp,vgafontbuf mov bh,[VGAFontSize] xor bl,bl ; Needed by both INT 10h calls test byte [UsingVGA], 01h ; Are we in graphics mode? jz .text .graphics: xor cx,cx mov cl,bh ; CX = bytes/character mov ax,[GXPixRows] div cl ; Compute char rows per screen mov dl,al dec ax mov [VidRows],al mov ax,1121h ; Set user character table int 10h mov ax,[GXPixCols] shr ax,3 ; 8 pixels/character dec ax mov [VidCols],al .lf_ret: ret ; No need to call adjust_screen .text: mov cx,256 xor dx,dx mov ax,1110h int 10h ; Load into VGA RAM xor bl,bl mov ax,1103h ; Select page 0 int 10h lf_ret equ use_font.lf_ret ; ; adjust_screen: Set the internal variables associated with the screen size. ; This is a subroutine in case we're loading a custom font. ; adjust_screen: pusha mov al,[BIOS_vidrows] and al,al jnz vidrows_ok mov al,24 ; No vidrows in BIOS, assume 25 ; (Remember: vidrows == rows-1) vidrows_ok: mov [VidRows],al mov ah,0fh int 10h ; Read video state dec ah ; Store count-1 (same as rows) mov [VidCols],ah popa ret section .bss vgafontbuf resb 8192 section .data align 2, db 0 VGAFontSize dw 16 ; Defaults to 16 byte font UserFont db 0 ; Using a user-specified font section .bss1 alignb 4 GXPixCols resw 1 ; Graphics mode pixel columns GXPixRows resw 1 ; Graphics mode pixel rows syslinux-legacy-3.63+dfsg/ldlinux.bin0000664000175000017500000002734510777447305016374 0ustar evanevanXSYSLINUX1м{W{ػx7V1, x?Gd|M'EufEf|r uB|?|UA1,rUu t}f}~f>$~JLLy:f|f1OUffRfPSWjf`1,Bfadr]f) !uf`11,fa}O]fRfPUSf6|f>|f1ɇfk)9vAň֊1,f`farf []fXfZf)uMuޕ.}u1ּ{fx} t ;.}v.}Boot error ᆳ SYSLINUX 3.63 2008-04-10 >JLLy5~c>}u68.O0~*~!1ffEIt fBf9u8 ݾ~(~fMfff!t; t f`Gfa Load error - CBIOSEBIOS9f1 |+Nf0ff+!uf |f$,f+f,f+!uf$|f+ff,f,f+f ,ff,f+Ȉ2,Q 3,YHf,,@f f(,f$,f+,ff=r$Sf=r2,f,|fff,f,vP.u=s 8(fT8,f1ff}u ut fx.ft.B11r\ L>t+u P.[">v+kQ.tfh+fH.fd+fD.3f&D. <t;< rwtQ.uJsԪ< <t-<t<<t<utOrjdQ.0&Q.<0rt <9vr+WD@_1۠R.&>x+t[VW0Ǿȿl+>r+_^R.0;uO>L.SR[f6L.fD,v݋p+!uW^p? ؿVWQQW_[tۍE1Y_^ 6lu(X;ltfD.tfH.uYпn+YË6@.f<.>.`M>aWP0@uOfMX_>R.f f.comf.cbtf.c32 f.bss f.binx ff.bsi f.0] `Ia{v!u=PRVh0fff f\.ff f`. f@f;`.vf`.f)`.1^ &>UVf.1fT.>r+  6N.1l. t~< vNff=vga=t/f=mem=tVu< v.6l.1.l.< wN뼃fDf==nortKf==exttKf==asktyrωɃkr.fT.6h.fX.7&f>HdrS&n.==r&$&=r &f,fX.&1f1&f&p.&!uj.?9fT.f-f;\.xf6j.F ff)fQff詢( fY^f\.f-v1һf>d.0>l.t# 0n.p.tr df(d ?d>"rd$v df( h.9vd󤪁r&>p.u?11df>j.G@) f1ff\.ff觡&>u&.6x.>e.x.z= ÎێӼ߃ Sj19l.t p.n.P0.6l.< wN1VPN.;6l.t<,uFV ^X_.;6l.wȎ؎/ >俑d f0fQfT.fJfX.f9vffBf)ʁf;d.r\&f>t &ff)&f&fffJfX.V^fXzþ?p`þs!u=sV_01@f1f& &} & t ,&^ ؎1j0h=\f3fXfEfff`͎ݎʼn :FЉF,fah=1[1؎м{s enÊFfÊF JÎF&v&<$tHÀ>u ȈFfFSYfFSLfFINfFUXÀ>u u&Fàf`͎ݎʼnr1FF?F1N^$F~F9Î^$vÎ^$v*hyh_^$vAtFVFvÎF$^vNs1vËvF1F 1,FN"F{N$F{á~+F.F.&.`+ùFf{fx11fFffFff|ff(fvfV^&N$FFÁ~Uw/NQg If$vWdffFf(fvfV^&ÌN$FFÊF<wR.^&vw6@.<.>.^$v10؎1&E >r+N.Fw,NV@Buà t ^$F.Ffvf vufFF$^ngÁ~UwFNQg If$vWdff&vf( @dfEf)}f(+1tÁ~UwXPNQg If$vWdff&v(d؀Eꐐfdfdff((Ì^$FFVRPe0r+A)dffX^1һfٍȎ؉& "ul)(2 "껍 1а(؎а0؋%(g&.f1 1QY`Ɇ(OhfhhhhhjŁf%(1P؎Ў8 $"oȎ؎& hfRffaf.&,.&,ff`f<.&,.f$f1ۋf]aϜ`D$(`D$(g> g"6fg> ߋt$,1ɱ 󥫸G% Gffg6 g"|$0!u1ɱ g 6aÜ`L$0g> g"fg>,)σfg> ߋD$(t$,fag$06N.>r+O>r+0,0,Offf>fW1һ! ff>f|ff(f0,f |f f1f1f{fx1,{W1^1jh3x1؎{W_&fU&fu &]{{&E&][Xf71t `U<t<taþ>=Ȑ1؎м{p+!hf`11faQ8,@f?tYSu8Qe<t"eD uQVW|. e_^Yt sY[f1efDff fG2,eTfeTfff,fefDeT !Y[!tfft.=/uf,GfP< v}t   WS1?< v<\u/8t 0,,tf@&Qf׊2,ffr fffgYfZf_f, t$Sn@rn7GW1GG @[J1[SVW>n] !u0ƃmru&Fu_^[KA ] f`@]5fMg&fvfMf)M A5fa뤉Mfa0SVn7n^[WS>n] A C] [_Yr <t < t < v8ÿ0?sW6_r<-s0fPfQUf1ff1<-u<0rSt<9wM <0r% b .@:.w%.>b.ø1.þp.t..@:.w.1ɋ.6.>b+믾s.t1ɉ..>.r/.t..r.t..9!..1< t< v>~sG>~76~t`>b.a$..t+ff`~+!tP&.W tB 8uXPfaf.t tf`u~+!ttB&. 8faôu"~+!tWtB&. 8u0ôbfafP Xff` tfafaf1Ī`++)fv 󤿈0ŪfNf.ÿEÿЉ>n+ÿ؉>p+À>+wȉ>l+ÿu >-u1>À>+t DP^rf*fffP^rPbQ8uXPQQuX|+rSgs[Lv.r)fSPr7as1ۀ>.߁.f[f%_fKrfff.Pw狽>~+U$XBBB<u:JJ0Bt~9~+Pk_B1V+@󤾈ȿl+/!&#r ff%f=ENDTuff%f=EXTuÿW^ÿ1s|+uǹ)1f>. f>.þh"QfSfR1f1fOfg[fOgI8t1Cgy؀rg(ufGCf8u sCIbs ~fOg fgfOg'NfZf[Yh|覍W1fNg,s fNgs ~fNgـfNgY)tUr<#tQ ffShf[r@< v f0t*rȦ*ff9tfϥ ]< tr!tYSfPf=vffPff fW1f_fYfQfWt &gfAfVf蟌f^f_fYfXff)[uP.X 4J=6ui<wb>rY wT>.f,tt@.>0,t1ɈBH.!@H.ù1Ҹ0۸` u.̈&.aVu8Drtf>D=uiL1۹JH1:.r.Ȉƴ1J|QWf1f_WH^Nj>|罀^|PY148tIu1$tQوY)w Ãt.$úB`ˬՇwav,<t@t O1w%,f@Eb+1f`Ȏ؎, ttO,b+faf`_f` >,u faf`fNfNf1f!txf fPAMSf1ɱNsf!u[pf=PAMSuhf>NwfNf>Ntf=rf;NsfNf;NwfNrf>Ntff;NvfN~fNf;NvfNf=w8r=8O>8t9t,1t%f/-Zffgff1}ffd(fÿfVff=/-Zuf1ҹ~fffguff=d(^P18t tƁr =v1XPVW uYQ18t t#Ɓr|Wƹ)r%^^NY΁sވЪȪd)1_^Xf`}f1fffgf)Ѝ|fDffaf>0tf>4t>8t PXPXÈ&Rf`8 Ҵr uBR?RUA8;r f0 f4faf1VfRfPSjjf`8@ &Rfadr^^fRfPUf6Rf>Rf1ɇff=w'Aň֊8&Rf`far]fXfZMuIt appears your computer has less than 256K of low ("DOS") RAM. Linux needs at least this amount to boot. If you get this message in error, hold down the Ctrl key while booting, and I will take your word for it. boot:  Invalid image type for this media type! Could not find kernel image: Invalid or corrupt kernel image. !׏ޏ׏ʈT| Loading ..ready. Cannot load a ramdisk with an old kernel image. Could not find ramdisk image: Not enough memory to load specified kernel. BOOT_IMAGE=3ʼn͉Չ ډ 0L3kmيk?O~kkkkƋՋ>bxF%: attempted DOS system call COMBOOT image too large.  aborted. AAEEEIIIOOUUYAIOU@ linux autoOut of memory parsing config file Unknown keyword in configuration file. Missing parameter in configuration file. A20 gate not responding!   Copyright (C) 1994-2008 H. Peter Anvin Boot failed: please change disks and press a key to continue. /boot/syslinux/syslinux.cfginitrd=7t;eT9ۘYQ@ T2Cx+9PC̴h60eNR2GCt:t+9YwLhj1`+92d+"Qh+"^h̘Hz+9 v+9 : : : H: : : : H: :: ::H:.cbt.bss.bs.com.c32 ?(g\(f`h) fafffPfUf.)f1ff .f )f.( "b)8аذ01V ] $")ff]fXftCf9r$fgfgfgtfg|fffgfffgff1΃fgfgf`.(..Z+.P+.Z+du_.Z+$RuMouF.Z+d^`WQ1/u)Y.Z+ $Q1uY.(u-fYfaQP .(@.(e&;(XY0t uLdtC`u8!tf?fwfOft) Hufaf..(ffQfXf1f f.)f.( "6+ 1а0ذ(؎Ўf**(*:*`*syslinux-legacy-3.63+dfsg/Makefile0000664000175000017500000002054310777447271015656 0ustar evanevan## ----------------------------------------------------------------------- ## ## Copyright 1998-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- # # Main Makefile for SYSLINUX # # No builtin rules MAKEFLAGS = -r TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) dummy.c -o $$tmpf 2>/dev/null; \ then echo '$(1)'; else echo '$(2)'; fi; rm -f $$tmpf) comma := , LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,) OSTYPE = $(shell uname -msr) CC = gcc INCLUDE = CFLAGS = -W -Wall -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64 PIC = -fPIC LDFLAGS = -O2 -s $(LDHASH) AR = ar RANLIB = ranlib NASM = nasm NASMOPT = -O9999 NINCLUDE = BINDIR = /usr/bin SBINDIR = /sbin LIBDIR = /usr/lib AUXDIR = $(LIBDIR)/syslinux MANDIR = /usr/man INCDIR = /usr/include TFTPBOOT = /tftpboot PERL = perl VERSION = $(shell cat version) %.o: %.c $(CC) $(INCLUDE) $(CFLAGS) -c $< # # The BTARGET refers to objects that are derived from ldlinux.asm; we # like to keep those uniform for debugging reasons; however, distributors # want to recompile the installers (ITARGET). # # BOBJECTS and IOBJECTS are the same thing, except used for # installation, so they include objects that may be in subdirectories # with their own Makefiles. Finally, there is a list of those # directories. # CSRC = gethostip.c NASMSRC = $(wildcard *.asm) SOURCES = $(CSRC) *.h $(NASMSRC) *.inc # _bin.c files required by both BTARGET and ITARGET installers BINFILES = bootsect_bin.c ldlinux_bin.c mbr_bin.c \ extlinux_bss_bin.c extlinux_sys_bin.c # syslinux.exe is BTARGET so as to not require everyone to have the # mingw suite installed BTARGET = kwdhash.gen version.gen version.h \ ldlinux.bss ldlinux.sys ldlinux.bin \ pxelinux.0 isolinux.bin isolinux-debug.bin \ extlinux.bin extlinux.bss extlinux.sys BOBJECTS = $(BTARGET) mbr/mbr.bin dos/syslinux.com win32/syslinux.exe \ memdisk/memdisk memdump/memdump.com # BESUBDIRS and IESUBDIRS are "early", i.e. before the root; BSUBDIRS # and ISUBDIRS are "late", after the root. BESUBDIRS = mbr BSUBDIRS = memdisk memdump dos win32 ITARGET = copybs.com gethostip mkdiskimage IOBJECTS = $(ITARGET) mtools/syslinux unix/syslinux extlinux/extlinux IESUBDIRS = ISUBDIRS = mtools unix extlinux sample com32 DOCS = COPYING NEWS README TODO BUGS *.doc sample menu com32 OTHER = Makefile bin2c.pl now.pl genhash.pl keywords findpatch.pl \ keytab-lilo.pl version version.pl sys2ansi.pl \ ppmtolss16 lss16toppm memdisk bin2hex.pl mkdiskimage.in \ sha1pass md5pass OBSOLETE = pxelinux.bin # Things to install in /usr/bin INSTALL_BIN = mtools/syslinux gethostip ppmtolss16 lss16toppm \ sha1pass md5pass # Things to install in /sbin INSTALL_SBIN = extlinux/extlinux # Things to install in /usr/lib/syslinux INSTALL_AUX = pxelinux.0 isolinux.bin isolinux-debug.bin \ dos/syslinux.com copybs.com memdisk/memdisk mbr/mbr.bin INSTALL_AUX_OPT = win32/syslinux.exe # The DATE is set on the make command line when building binaries for # official release. Otherwise, substitute a hex string that is pretty much # guaranteed to be unique to be unique from build to build. ifndef HEXDATE HEXDATE := $(shell $(PERL) now.pl ldlinux.asm pxelinux.asm isolinux.asm) endif ifndef DATE DATE := $(HEXDATE) endif MAKE += DATE=$(DATE) HEXDATE=$(HEXDATE) # # NOTE: If you don't have the mingw compiler suite installed, you probably # want to remove win32 from this list; otherwise you're going to get an # error every time you try to build. # all: set -e ; for i in $(BESUBDIRS) $(IESUBDIRS) ; do $(MAKE) -C $$i $@ ; done $(MAKE) all-local set -e ; for i in $(BSUBDIRS) $(ISUBDIRS) ; do $(MAKE) -C $$i $@ ; done -ls -l $(BOBJECTS) $(IOBJECTS) all-local: $(BTARGET) $(ITARGET) $(BINFILES) installer: set -e ; for i in $(IESUBDIRS); do $(MAKE) -C $$i all ; done $(MAKE) installer-local set -e ; for i in $(ISUBDIRS); do $(MAKE) -C $$i all ; done -ls -l $(BOBJECTS) $(IOBJECTS) installer-local: $(ITARGET) $(BINFILES) version.gen: version version.pl $(PERL) version.pl $< $@ '%define' version.h: version version.pl $(PERL) version.pl $< $@ '#define' kwdhash.gen: keywords genhash.pl $(PERL) genhash.pl < keywords > kwdhash.gen # Standard rule for {isolinux,isolinux-debug}.bin iso%.bin: iso%.asm kwdhash.gen version.gen $(NASM) $(NASMOPT) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \ -DMAP=$(@:.bin=.map) -l $(@:.bin=.lsr) -o $@ $< $(PERL) lstadjust.pl $(@:.bin=.lsr) $(@:.bin=.map) $(@:.bin=.lst) $(PERL) checksumiso.pl $@ $(PERL) checkov.pl $(@:.bin=.map) $@ # Standard rule for {ldlinux,pxelinux,extlinux}.bin %.bin: %.asm kwdhash.gen version.gen $(NASM) $(NASMOPT) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \ -DMAP=$(@:.bin=.map) -l $(@:.bin=.lsr) -o $@ $< $(PERL) lstadjust.pl $(@:.bin=.lsr) $(@:.bin=.map) $(@:.bin=.lst) $(PERL) checkov.pl $(@:.bin=.map) $@ pxelinux.0: pxelinux.bin cp pxelinux.bin pxelinux.0 ldlinux.bss: ldlinux.bin dd if=$< of=$@ bs=512 count=1 ldlinux.sys: ldlinux.bin dd if=$< of=$@ bs=512 skip=1 extlinux.bss: extlinux.bin dd if=$< of=$@ bs=512 count=1 extlinux.sys: extlinux.bin dd if=$< of=$@ bs=512 skip=1 mbr_bin.c: mbr/mbr.bin bin2c.pl $(PERL) bin2c.pl syslinux_mbr < $< > $@ copybs.com: copybs.asm $(NASM) $(NASMOPT) -f bin -l copybs.lst -o copybs.com copybs.asm bootsect_bin.c: ldlinux.bss bin2c.pl $(PERL) bin2c.pl syslinux_bootsect < $< > $@ ldlinux_bin.c: ldlinux.sys bin2c.pl $(PERL) bin2c.pl syslinux_ldlinux < $< > $@ extlinux_bss_bin.c: extlinux.bss bin2c.pl $(PERL) bin2c.pl extlinux_bootsect < $< > $@ extlinux_sys_bin.c: extlinux.sys bin2c.pl $(PERL) bin2c.pl extlinux_image 512 < $< > $@ gethostip: gethostip.o $(CC) $(LDFLAGS) -o $@ $^ mkdiskimage: mkdiskimage.in mbr/mbr.bin bin2hex.pl $(PERL) bin2hex.pl < mbr/mbr.bin | cat mkdiskimage.in - > $@ chmod a+x $@ install: installer mkdir -m 755 -p $(INSTALLROOT)$(BINDIR) install -m 755 -c $(INSTALL_BIN) $(INSTALLROOT)$(BINDIR) mkdir -m 755 -p $(INSTALLROOT)$(SBINDIR) install -m 755 -c $(INSTALL_SBIN) $(INSTALLROOT)$(SBINDIR) mkdir -m 755 -p $(INSTALLROOT)$(AUXDIR) install -m 644 -c $(INSTALL_AUX) $(INSTALLROOT)$(AUXDIR) -install -m 644 -c $(INSTALL_AUX_OPT) $(INSTALLROOT)$(AUXDIR) mkdir -m 755 -p $(INSTALLROOT)$(MANDIR)/man1 install -m 644 -c man/*.1 $(INSTALLROOT)$(MANDIR)/man1 : mkdir -m 755 -p $(INSTALLROOT)$(MANDIR)/man8 : install -m 644 -c man/*.8 $(INSTALLROOT)$(MANDIR)/man8 $(MAKE) -C com32 install install-lib: installer install-all: install install-lib NETINSTALLABLE = pxelinux.0 memdisk/memdisk memdump/memdump.com \ com32/menu/*.c32 com32/modules/*.c32 netinstall: installer mkdir -p $(INSTALLROOT)$(TFTPBOOT) install -m 644 $(NETINSTALLABLE) $(INSTALLROOT)$(TFTPBOOT) local-tidy: rm -f *.o *_bin.c stupid.* patch.offset rm -f *.lsr *.lst *.map rm -f $(OBSOLETE) tidy: local-tidy set -e ; for i in $(BESUBDIRS) $(IESUBDIRS) $(BSUBDIRS) $(ISUBDIRS) ; do $(MAKE) -C $$i $@ ; done local-clean: rm -f $(ITARGET) clean: local-tidy local-clean set -e ; for i in $(BESUBDIRS) $(IESUBDIRS) $(BSUBDIRS) $(ISUBDIRS) ; do $(MAKE) -C $$i $@ ; done dist: tidy find . \( -name '*~' -o -name '#*' -o -name core \ -o -name '.*.d' -o -name .depend \) -type f -print0 \ | xargs -0rt rm -f local-spotless: rm -f $(BTARGET) .depend *.so.* spotless: local-clean dist local-spotless set -e ; for i in $(BESUBDIRS) $(IESUBDIRS) $(BSUBDIRS) $(ISUBDIRS) ; do $(MAKE) -C $$i $@ ; done .depend: rm -f .depend for csrc in $(CSRC) ; do $(CC) $(INCLUDE) -MM $$csrc >> .depend ; done for nsrc in $(NASMSRC) ; do $(NASM) -DDEPEND $(NINCLUDE) -o `echo $$nsrc | sed -e 's/\.asm/\.bin/'` -M $$nsrc >> .depend ; done local-depend: rm -f .depend $(MAKE) .depend depend: local-depend $(MAKE) -C memdisk depend # Shortcut to build unix/syslinux using klibc klibc: $(MAKE) clean $(MAKE) CC=klcc ITARGET= ISUBDIRS='unix extlinux' BSUBDIRS= # Hook to add private Makefile targets for the maintainer. -include Makefile.private # Include dependencies file include .depend syslinux-legacy-3.63+dfsg/stack.inc0000664000175000017500000000232410777447273016015 0ustar evanevan; ----------------------------------------------------------------------- ; ; Copyright 2005-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Boston MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; ----------------------------------------------------------------------- ; ; stack.inc ; ; How to reset the stack pointer ; %ifndef _STACK_INC %define _STACK_INC ; ; This macro resets the stack pointer (including SS), and sets ; DS == ES == 0, interrupts on, DF = 0. ; ; It takes a 16-bit register that can be safely clobbered as parameter. ; %macro RESET_STACK_AND_SEGS 1 xor %1,%1 mov ds,%1 mov es,%1 %if IS_SYSLINUX || IS_EXTLINUX mov ss,%1 ; Just in case... mov sp,StackBuf-2*5 ; Reset stack %elif IS_PXELINUX lss esp,[BaseStack] %elif IS_ISOLINUX mov ss,%1 mov sp,StackBuf-2*2 %else NEED TO KNOW HOW TO RESET STACK %endif sti cld %endmacro %endif ; _STACK_INC syslinux-legacy-3.63+dfsg/strecpy.inc0000664000175000017500000000107410777447273016402 0ustar evanevan; ; strecpy: Copy DS:SI -> ES:DI up to and including a null byte; ; on exit SI and DI point to the byte *after* the null byte. ; BP holds a pointer to the first byte beyond the end of the ; target buffer; return with CF=1 if target buffer overflows; ; the output is still zero-terminated. ; section .text strecpy: push ax push bp dec bp dec bp .loop: lodsb stosb and al,al ; CF=0 jz .done cmp bp,di ; CF set if BP < DI jnc .loop ; Zero-terminate overflow string mov al,0 ; Avoid changing flags stosb .done: pop bp pop ax ret syslinux-legacy-3.63+dfsg/extlinux/0000775000175000017500000000000010777447344016073 5ustar evanevansyslinux-legacy-3.63+dfsg/extlinux/ext2_fs.h0000664000175000017500000003712610777447273017630 0ustar evanevan/* * linux/include/linux/ext2_fs.h * * Copyright (C) 1992, 1993, 1994, 1995 * Remy Card (card@masi.ibp.fr) * Laboratoire MASI - Institut Blaise Pascal * Universite Pierre et Marie Curie (Paris VI) * * from * * linux/include/linux/minix_fs.h * * Copyright (C) 1991, 1992 Linus Torvalds */ /* Private copy for extlinux */ #ifndef _LINUX_EXT2_FS_H #define _LINUX_EXT2_FS_H #include /* * The second extended filesystem constants/structures */ /* * Define EXT2FS_DEBUG to produce debug messages */ #undef EXT2FS_DEBUG /* * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files */ #define EXT2_PREALLOCATE #define EXT2_DEFAULT_PREALLOC_BLOCKS 8 /* * The second extended file system version */ #define EXT2FS_DATE "95/08/09" #define EXT2FS_VERSION "0.5b" /* * Debug code */ #ifdef EXT2FS_DEBUG # define ext2_debug(f, a...) { \ printk ("EXT2-fs DEBUG (%s, %d): %s:", \ __FILE__, __LINE__, __FUNCTION__); \ printk (f, ## a); \ } #else # define ext2_debug(f, a...) /**/ #endif /* * Special inode numbers */ #define EXT2_BAD_INO 1 /* Bad blocks inode */ #define EXT2_ROOT_INO 2 /* Root inode */ #define EXT2_ACL_IDX_INO 3 /* ACL inode */ #define EXT2_ACL_DATA_INO 4 /* ACL inode */ #define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */ #define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */ /* First non-reserved inode for old ext2 filesystems */ #define EXT2_GOOD_OLD_FIRST_INO 11 /* * The second extended file system magic number */ #define EXT2_SUPER_MAGIC 0xEF53 /* * Maximal count of links to a file */ #define EXT2_LINK_MAX 32000 /* * Macro-instructions used to manage several block sizes */ #define EXT2_MIN_BLOCK_SIZE 1024 #define EXT2_MAX_BLOCK_SIZE 4096 #define EXT2_MIN_BLOCK_LOG_SIZE 10 # define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size) #define EXT2_ACLE_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry)) #define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) # define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) #define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ EXT2_GOOD_OLD_INODE_SIZE : \ (s)->s_inode_size) #define EXT2_FIRST_INO(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ EXT2_GOOD_OLD_FIRST_INO : \ (s)->s_first_ino) /* * Macro-instructions used to manage fragments */ #define EXT2_MIN_FRAG_SIZE 1024 #define EXT2_MAX_FRAG_SIZE 4096 #define EXT2_MIN_FRAG_LOG_SIZE 10 # define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size) # define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s)) /* * ACL structures */ struct ext2_acl_header /* Header of Access Control Lists */ { __u32 aclh_size; __u32 aclh_file_count; __u32 aclh_acle_count; __u32 aclh_first_acle; }; struct ext2_acl_entry /* Access Control List Entry */ { __u32 acle_size; __u16 acle_perms; /* Access permissions */ __u16 acle_type; /* Type of entry */ __u16 acle_tag; /* User or group identity */ __u16 acle_pad1; __u32 acle_next; /* Pointer on next entry for the */ /* same inode or on next free entry */ }; /* * Structure of a blocks group descriptor */ struct ext2_group_desc { __u32 bg_block_bitmap; /* Blocks bitmap block */ __u32 bg_inode_bitmap; /* Inodes bitmap block */ __u32 bg_inode_table; /* Inodes table block */ __u16 bg_free_blocks_count; /* Free blocks count */ __u16 bg_free_inodes_count; /* Free inodes count */ __u16 bg_used_dirs_count; /* Directories count */ __u16 bg_pad; __u32 bg_reserved[3]; }; /* * Macro-instructions used to manage group descriptors */ # define EXT2_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) # define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) # define EXT2_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) /* * Constants relative to the data blocks */ #define EXT2_NDIR_BLOCKS 12 #define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS #define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1) #define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) #define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) /* * Inode flags */ #define EXT2_SECRM_FL 0x00000001 /* Secure deletion */ #define EXT2_UNRM_FL 0x00000002 /* Undelete */ #define EXT2_COMPR_FL 0x00000004 /* Compress file */ #define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */ #define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */ #define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */ #define EXT2_NODUMP_FL 0x00000040 /* do not dump file */ #define EXT2_NOATIME_FL 0x00000080 /* do not update atime */ /* Reserved for compression usage... */ #define EXT2_DIRTY_FL 0x00000100 #define EXT2_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */ #define EXT2_NOCOMP_FL 0x00000400 /* Don't compress */ #define EXT2_ECOMPR_FL 0x00000800 /* Compression error */ /* End compression flags --- maybe not all used */ #define EXT2_BTREE_FL 0x00001000 /* btree format dir */ #define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ #define EXT2_FL_USER_VISIBLE 0x00001FFF /* User visible flags */ #define EXT2_FL_USER_MODIFIABLE 0x000000FF /* User modifiable flags */ /* * ioctl commands */ #define EXT2_IOC_GETFLAGS _IOR('f', 1, long) #define EXT2_IOC_SETFLAGS _IOW('f', 2, long) #define EXT2_IOC_GETVERSION _IOR('v', 1, long) #define EXT2_IOC_SETVERSION _IOW('v', 2, long) /* * Structure of an inode on the disk */ struct ext2_inode { __u16 i_mode; /* File mode */ __u16 i_uid; /* Low 16 bits of Owner Uid */ __u32 i_size; /* Size in bytes */ __u32 i_atime; /* Access time */ __u32 i_ctime; /* Creation time */ __u32 i_mtime; /* Modification time */ __u32 i_dtime; /* Deletion Time */ __u16 i_gid; /* Low 16 bits of Group Id */ __u16 i_links_count; /* Links count */ __u32 i_blocks; /* Blocks count */ __u32 i_flags; /* File flags */ union { struct { __u32 l_i_reserved1; } linux1; struct { __u32 h_i_translator; } hurd1; struct { __u32 m_i_reserved1; } masix1; } osd1; /* OS dependent 1 */ __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ __u32 i_generation; /* File version (for NFS) */ __u32 i_file_acl; /* File ACL */ __u32 i_dir_acl; /* Directory ACL */ __u32 i_faddr; /* Fragment address */ union { struct { __u8 l_i_frag; /* Fragment number */ __u8 l_i_fsize; /* Fragment size */ __u16 i_pad1; __u16 l_i_uid_high; /* these 2 fields */ __u16 l_i_gid_high; /* were reserved2[0] */ __u32 l_i_reserved2; } linux2; struct { __u8 h_i_frag; /* Fragment number */ __u8 h_i_fsize; /* Fragment size */ __u16 h_i_mode_high; __u16 h_i_uid_high; __u16 h_i_gid_high; __u32 h_i_author; } hurd2; struct { __u8 m_i_frag; /* Fragment number */ __u8 m_i_fsize; /* Fragment size */ __u16 m_pad1; __u32 m_i_reserved2[2]; } masix2; } osd2; /* OS dependent 2 */ }; #define i_size_high i_dir_acl #if defined(__KERNEL__) || defined(__linux__) #define i_reserved1 osd1.linux1.l_i_reserved1 #define i_frag osd2.linux2.l_i_frag #define i_fsize osd2.linux2.l_i_fsize #define i_uid_low i_uid #define i_gid_low i_gid #define i_uid_high osd2.linux2.l_i_uid_high #define i_gid_high osd2.linux2.l_i_gid_high #define i_reserved2 osd2.linux2.l_i_reserved2 #endif #ifdef __hurd__ #define i_translator osd1.hurd1.h_i_translator #define i_frag osd2.hurd2.h_i_frag; #define i_fsize osd2.hurd2.h_i_fsize; #define i_uid_high osd2.hurd2.h_i_uid_high #define i_gid_high osd2.hurd2.h_i_gid_high #define i_author osd2.hurd2.h_i_author #endif #ifdef __masix__ #define i_reserved1 osd1.masix1.m_i_reserved1 #define i_frag osd2.masix2.m_i_frag #define i_fsize osd2.masix2.m_i_fsize #define i_reserved2 osd2.masix2.m_i_reserved2 #endif /* * File system states */ #define EXT2_VALID_FS 0x0001 /* Unmounted cleanly */ #define EXT2_ERROR_FS 0x0002 /* Errors detected */ /* * Mount flags */ #define EXT2_MOUNT_CHECK 0x0001 /* Do mount-time checks */ #define EXT2_MOUNT_GRPID 0x0004 /* Create files with directory's group */ #define EXT2_MOUNT_DEBUG 0x0008 /* Some debugging messages */ #define EXT2_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */ #define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */ #define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */ #define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */ #define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */ #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt #define set_opt(o, opt) o |= EXT2_MOUNT_##opt #define test_opt(sb, opt) ((sb)->u.ext2_sb.s_mount_opt & \ EXT2_MOUNT_##opt) /* * Maximal mount counts between two filesystem checks */ #define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ #define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */ /* * Behaviour when detecting errors */ #define EXT2_ERRORS_CONTINUE 1 /* Continue execution */ #define EXT2_ERRORS_RO 2 /* Remount fs read-only */ #define EXT2_ERRORS_PANIC 3 /* Panic */ #define EXT2_ERRORS_DEFAULT EXT2_ERRORS_CONTINUE /* * Structure of the super block */ struct ext2_super_block { __u32 s_inodes_count; /* Inodes count */ __u32 s_blocks_count; /* Blocks count */ __u32 s_r_blocks_count; /* Reserved blocks count */ __u32 s_free_blocks_count; /* Free blocks count */ __u32 s_free_inodes_count; /* Free inodes count */ __u32 s_first_data_block; /* First Data Block */ __u32 s_log_block_size; /* Block size */ __s32 s_log_frag_size; /* Fragment size */ __u32 s_blocks_per_group; /* # Blocks per group */ __u32 s_frags_per_group; /* # Fragments per group */ __u32 s_inodes_per_group; /* # Inodes per group */ __u32 s_mtime; /* Mount time */ __u32 s_wtime; /* Write time */ __u16 s_mnt_count; /* Mount count */ __s16 s_max_mnt_count; /* Maximal mount count */ __u16 s_magic; /* Magic signature */ __u16 s_state; /* File system state */ __u16 s_errors; /* Behaviour when detecting errors */ __u16 s_minor_rev_level; /* minor revision level */ __u32 s_lastcheck; /* time of last check */ __u32 s_checkinterval; /* max. time between checks */ __u32 s_creator_os; /* OS */ __u32 s_rev_level; /* Revision level */ __u16 s_def_resuid; /* Default uid for reserved blocks */ __u16 s_def_resgid; /* Default gid for reserved blocks */ /* * These fields are for EXT2_DYNAMIC_REV superblocks only. * * Note: the difference between the compatible feature set and * the incompatible feature set is that if there is a bit set * in the incompatible feature set that the kernel doesn't * know about, it should refuse to mount the filesystem. * * e2fsck's requirements are more strict; if it doesn't know * about a feature in either the compatible or incompatible * feature set, it must abort and not try to meddle with * things it doesn't understand... */ __u32 s_first_ino; /* First non-reserved inode */ __u16 s_inode_size; /* size of inode structure */ __u16 s_block_group_nr; /* block group # of this superblock */ __u32 s_feature_compat; /* compatible feature set */ __u32 s_feature_incompat; /* incompatible feature set */ __u32 s_feature_ro_compat; /* readonly-compatible feature set */ __u8 s_uuid[16]; /* 128-bit uuid for volume */ char s_volume_name[16]; /* volume name */ char s_last_mounted[64]; /* directory where last mounted */ __u32 s_algorithm_usage_bitmap; /* For compression */ /* * Performance hints. Directory preallocation should only * happen if the EXT2_COMPAT_PREALLOC flag is on. */ __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ __u16 s_padding1; __u32 s_reserved[204]; /* Padding to the end of the block */ }; /* Assume that user mode programs are passing in an ext2fs superblock, not * a kernel struct super_block. This will allow us to call the feature-test * macros from user land. */ #define EXT2_SB(sb) (sb) /* * Codes for operating systems */ #define EXT2_OS_LINUX 0 #define EXT2_OS_HURD 1 #define EXT2_OS_MASIX 2 #define EXT2_OS_FREEBSD 3 #define EXT2_OS_LITES 4 /* * Revision levels */ #define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */ #define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ #define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV #define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV #define EXT2_GOOD_OLD_INODE_SIZE 128 /* * Feature set definitions */ #define EXT2_HAS_COMPAT_FEATURE(sb,mask) \ ( EXT2_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) ) #define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \ ( EXT2_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) ) #define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \ ( EXT2_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) ) #define EXT2_SET_COMPAT_FEATURE(sb,mask) \ EXT2_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask) #define EXT2_SET_RO_COMPAT_FEATURE(sb,mask) \ EXT2_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask) #define EXT2_SET_INCOMPAT_FEATURE(sb,mask) \ EXT2_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask) #define EXT2_CLEAR_COMPAT_FEATURE(sb,mask) \ EXT2_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask) #define EXT2_CLEAR_RO_COMPAT_FEATURE(sb,mask) \ EXT2_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask) #define EXT2_CLEAR_INCOMPAT_FEATURE(sb,mask) \ EXT2_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask) #define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001 #define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002 #define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 #define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008 #define EXT2_FEATURE_COMPAT_RESIZE_INO 0x0010 #define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 #define EXT2_FEATURE_COMPAT_ANY 0xffffffff #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 #define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 #define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 #define EXT2_FEATURE_RO_COMPAT_ANY 0xffffffff #define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001 #define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 #define EXT2_FEATURE_INCOMPAT_ANY 0xffffffff #define EXT2_FEATURE_COMPAT_SUPP 0 #define EXT2_FEATURE_INCOMPAT_SUPP EXT2_FEATURE_INCOMPAT_FILETYPE #define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT2_FEATURE_RO_COMPAT_BTREE_DIR) #define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT2_FEATURE_RO_COMPAT_SUPP #define EXT2_FEATURE_INCOMPAT_UNSUPPORTED ~EXT2_FEATURE_INCOMPAT_SUPP /* * Default values for user and/or group using reserved blocks */ #define EXT2_DEF_RESUID 0 #define EXT2_DEF_RESGID 0 /* * Structure of a directory entry */ #define EXT2_NAME_LEN 255 struct ext2_dir_entry { __u32 inode; /* Inode number */ __u16 rec_len; /* Directory entry length */ __u16 name_len; /* Name length */ char name[EXT2_NAME_LEN]; /* File name */ }; /* * The new version of the directory entry. Since EXT2 structures are * stored in intel byte order, and the name_len field could never be * bigger than 255 chars, it's safe to reclaim the extra byte for the * file_type field. */ struct ext2_dir_entry_2 { __u32 inode; /* Inode number */ __u16 rec_len; /* Directory entry length */ __u8 name_len; /* Name length */ __u8 file_type; char name[EXT2_NAME_LEN]; /* File name */ }; /* * Ext2 directory file types. Only the low 3 bits are used. The * other bits are reserved for now. */ enum { EXT2_FT_UNKNOWN, EXT2_FT_REG_FILE, EXT2_FT_DIR, EXT2_FT_CHRDEV, EXT2_FT_BLKDEV, EXT2_FT_FIFO, EXT2_FT_SOCK, EXT2_FT_SYMLINK, EXT2_FT_MAX }; /* * EXT2_DIR_PAD defines the directory entries boundaries * * NOTE: It must be a multiple of 4 */ #define EXT2_DIR_PAD 4 #define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1) #define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ ~EXT2_DIR_ROUND) #endif /* _LINUX_EXT2_FS_H */ syslinux-legacy-3.63+dfsg/extlinux/Makefile0000664000175000017500000000166310777447273017542 0ustar evanevanTMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) ../dummy.c -o $$tmpf 2>/dev/null; \ then echo '$(1)'; else echo '$(2)'; fi; rm -f $$tmpf) comma := , LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,) CC = gcc OPTFLAGS = -g -Os INCLUDES = -I. -I.. -I../libinstaller CFLAGS = -W -Wall -Wno-sign-compare -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES) LDFLAGS = $(LDHASH) # -s SRCS = extlinux.c setadv.c extlinux_bss_bin.c extlinux_sys_bin.c OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS))) .SUFFIXES: .c .o .i .s .S VPATH = .:..:../libinstaller all: installer tidy: -rm -f *.o *.i *.s *.a .*.d clean: tidy -rm -f extlinux spotless: clean -rm -f *~ installer: extlinux extlinux: $(OBJS) $(CC) $(LDFLAGS) -o $@ $^ %.o: %.c $(CC) -Wp,-MT,$@,-MMD,.$@.d $(CFLAGS) -c -o $@ $< %.i: %.c $(CC) $(CFLAGS) -E -o $@ $< %.s: %.c $(CC) $(CFLAGS) -S -o $@ $< -include .*.d syslinux-legacy-3.63+dfsg/extlinux/extlinux0000775000175000017500000014102210777447315017677 0ustar evanevanELF4|4 ((%444444**01 60HHHDDPtd)44Qtd/lib/ld-linux.so.2GNU GNU%*X/$u8"!      ." K92{I\C}Ztm 1DUC<G?'F4Mo$X!D%0)=D5__gmon_start__libc.so.6_IO_stdin_usedfchmodexitoptindperrorsetmntentpread64memset__errno_locationopen64memcmpfputsmemcpygetmntentstrtoulasprintfoptargstderrioctlgetopt_longclosefprintfstatfs64memmovesyncstrcmppwrite64strerror__libc_start_mainfree__xstat64__fxstat64GLIBC_2.2GLIBC_2.1GLIBC_2.0ii ,ii 6ii @ !     $ (,048<@DHLPTX\`dUC5%%h%h%h%h%h %h(% h0%h8p%h@`%hHP%hP@% hX0%$h` %(hh%,hp%0hx%4h%8h%<h%@h%Dh%Hh%Lh%Php%Th`%XhP%\h@%`h0%dh 1^PTRhhQVhbUS[8'tZX[ÐUS=u? -X9v&9w[]Ít&'Utt $ÐUSÃ5hL5$U5u!$USx]EPhrSuEUHERPh`SuE1 #PPEPSu UE u11ҋ]UWVS u E]PjusuMm 1?EQPju}Ru,E1EEtEKB@E;UrGu1e[^_]UWt=1PRIQjtW5h5*1}U1WVS0}] uEPhu1҅PEPhut@u6UEU܋EPUEBfB9u9Q u@Mtˆ MtˆQ}G RPVS=GfGu>=u5GPPhݤ5QEQ P1e[^_]UWVS E }]uEES VSWuu u hauUt Pu$E)MuEe[^_]UWVS E }]uEES VSWuu u hmut P$uE)MuEe[^_]US jjj]SudjhxS]ɅUS]jhhPS =t hNf4StPu h5L2 jj5hSN 1;t h]UWSU:t1򮸚р|/t˥PRhͥEPEu 5WWjPSSEPW&UE = RPh,SW =r S, >UЃ9ЉEtEQPhf@WExR RPWU W_XhuxpSS,PWOu>U;UEu3;Eu.0;U,u;Eu\;UXu1;EtQuhޥ5QE URPhh WG =H EEx RRPWuE;EtPEPhf@WuPuh5u u"x WEt. P PEPhfWVse[_]UWSpU:t1򮸚р|/t˥PRhͥEPEu 5yRRjP y 8u}'PPEPWyuhUċE|=w 1h  Q RPhh W, =u 1h w  ux W<Et Pe[_]US]=t h   Sxx S]UWVS}EPu Y t h.$ W+É֍EPRSWe tEtE w=v ffE=ffEfE𣼱ft fǀfU E)ԍT$SPRu|t h:$|E@;>u=sf{fFEFCQhjP1҃|DDBE@9uN1>F+@9|e[^_]UWVS|];t1򮸚р|/t˥PShͥEP}u 5PPhSy SPPjuy08tT]PShfWuPShf@WeQQEPW uERR PW W h$hAu $ jj5hP ;uO 1RPhh W =u.Pu VW$jhhW =tu5h?5auPPEPW uEPPE%$PW}u+]PShfWuPShf@WMPPuW t uZ4$<$# V<$1 u-4$e[^_]UWVST}@PWuP%=@tW5hXmPPEPW3t# 0-$W5hq}StW5hPPhhuh}sPPhV/tPPhVu;VVP3u$;Du;@uu\ uQQhh¦1u u# PWuW5h̦=SWh5XZhS yS5hPP PWGu6PPPVqu $; u ; SW5h5 VuQ5hAr=t h , Wx{xrRPVW!u\;Du;@tP5hm5 PPSV-4$} I&e[^_]ÍL$qUWVSQY9dh,OHSt\U3riodvztuH@ Pjj5£@>R5h0Pjj5d£@=v~R5hͧ5y$@O1K18, QQ5h$륾 jhh`SW zu@'u'=u =t P@RRVPeY[^_]aU8/-Zu'd(u11LB~u1g1]U‰g/-Z1+L@}uJǂd(QhRPUS]hjCPX؋]UVuSRt PhVS7tPhSVr1 Ve[^]UWVS Eu H=v Iv4Phh(WDž CtHP;Eu!;s2W)PPS-;w)Ӄwt=F9cECQVuSr)1󪍅RhPh(: 1e[^_]ÐUWV(EUE} EEE҉։Eu#91M؉E܋E؋U܃(^_]9ƒE U+EME ‹EUԉMEEMM uԉщNjE9щƉUrx9tg1rfEt9ƋESv9w,U9Us$t&117&1uf1EM9vO1U]Ít&'UWVS^E)E}Ut+1ƍED$E D$E$9}u߃[^_]Ë$ÐUS E y$D$ED$ []ÐUS E 9$D$ED$t []ÐUSt Ћu[]US[Y[Usage: %s [options] directory --install -i Install over the current bootsector --update -U Update a previous EXTLINUX installation --zip -z Force zipdrive geometry (-H 64 -S 32) --sectors=# -S Force the number of sectors per track --heads=# -H Force number of heads --raid -r Fall back to the next device on boot failure --once=... -o Execute a command once upon boot --clear-once -O Clear the boot-once command --reset-adv Reset auxilliary data Note: geometry is determined at boot time for devices which are considered hard disks by the BIOS. Unfortunately, this is not possible for devices which are considered floppy disks, which includes zipdisks and LS-120 superfloppies. The -z option is useful for USB devices which are considered hard disks by some BIOSes and zipdrives by other BIOSes. %s: not enough space for boot-once command Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors) (on hard disks, this is usually harmless.) short writeshort readEXTLINUXreading superblockno ext2/ext3 superblock found on %s writing bootblock/%s%sextlinux.sys%s: race condition on write %s: cannot write auxilliary data (need --update)? fstat dirfdbmap%s: write failure on %s %s: Not a directory: %s %s: statfs %s: %s %s: not an ext2/ext3 filesystem: %s r/proc/mountsext2ext3/etc/mtab%s: cannot find device for path %s %s is device %s %s: cannot open device %s %s: path %s doesn't match device %s %s: no previous extlinux boot sector found %s: file system changed under us - aborting! %s: invalid number of sectors: %u (must be 1-63) %s: invalid number of heads: %u (must be 1-256) extlinux 3.63 installupdatezipdrivesectorsheadsraid-modeversionhelpclear-oncereset-adviUuzS:H:rvho:O iUz%S-H3r=vEhPoJOU (@  PPP@PP-$P<0P ;0LlzR| \CAB E<AB XiAB Cx2AB D2AB D  o` J  o@ooƇև&6FVfvƈֈ&6FVfvXEXTLINUX1м{W{ػx7V$0 x?Gd|M'EufEf|r uB|?|UA$0rUu t}f}~f>$~JLLy>f|f1OUffRfPSWjf`$0Bfadr]f) !uf`1$0fa}O]fRfPUSf6|f>|f1ɇfk)9vAň֊$0f`farf []fXfZf)uMuޕ.}u1ּ{fx} t ;.}v.}Boot error ᆳNG EXTLINUX 3.63 2008-04-10 >JLLy9~c>}u604O4~*~!1ffEIt fBf9u8 ݾ~(~fMfff!t; t f`Cfa Load error - CBIOSEBIOSUf1 |/Nf0f+ff1fB+ &0fff0 %0f f0fHf0ff0ff 0200f1fH4u=s Т8IH(fmf}>nth 11 r !L>t+u H4[">v+I4tfh+f@4fd+f<43f&<4 <t;< rwtI4uJsԪ< <t-<t<<t<utOj)dI40&I4<0rt <9vr+ W_1۠¢J4&>x+t[VW0Ǿʿl+>r+_^J4 0uO>D4(S f[f6D4fDaWP 0uOfMX_>J4$f f.comxf.cbtmf.c32f.bsstUVfD91fL4>r+Τ  6F4 1d4 t~< vNff=vga=t/f=mem=tVϦu< v.6d41.d4< wN뼃fDf==nortKf==exttKf==asktrωɃr.fL46`4fP47&f>HdrS&f4==r&$&=r &f,fP4&4f1&f&h4&!ub4 AfL4f-f;T4[f6b4F ff)fQff Bo fY^fT4f-v1һ f>\40BE>d4t D2T0f4h4tr df(d ?d>"rd$v df( `49vd󤪁r&>h4u?11df>b4G@) f1ffT4ff&>u& ÎێӼ߃ Sj19d4tMh4f4m0.6d4< wN1VPN.;6d4t<,uFV ^X_.;6d4wȎ؎ > f0fQfL4fJfP4f9vffBf)ʁf;\4r\&f>t &ff)&f&fffJfP4V6l fA`^fX þK EþV2!u=sV_01@f1f& &} & t ,&^ ؎1j0hȀ\ffĈffff`͎ݎʼn? ٤:FЉF,fa8hȀ1[1؎м{ IDeÊFÊFLJÎF&v&<$tÀ>5ufȈFfFSYfFSLfFINfFUXÀ>5u[ u&45Fà45f`͎ݎʼnRr1FF?F4N^$F~FUÎ^$vÎ^$vhhj^$v tFVFvÎF$^vN8 s1vËvF4F $0FN"F{N$F{á~+F:9F<9&>9`+ùFf{fx11fFffFff|ff(fvfV^&N$FFÁ~Uw/NQg If$vWdffFf(fvfV^&pÌN$F7FÊF<wJ4^&v w6844464^$v1O0؎16&E >r+F46FwHNV02uNà6 t 4^$FH9Ffvf vufFF$^nÁ~UwFNQg If$vWdff&vf( @dfEf)}f(+1QÁ~UwXPNQg If$vWdff&v(d؀Eꐐfdfdff((Ì^$FFVRPe0r+A)dffX^1һ-fEȎ؉&脝u)(r "' 1а(؎а0؋%g&D9f1 1QY`5(OhҎhPhhhXhjYf%1꼍؎Ўx $"ۍȎ؎&hfRfNfaf.&.&ff`f.&.ff$1ۋf]aϜ`D$(`D$(g>g6fg>ߋt$,1ɱ 󥫸G% Gffg6g|$0!u1ɱ g6aÜ`L$0g>gfg>)σfg>ߋD$(*t$,f)ag06F4>r+O>r+Òfff>fW1һ ff>f|ff(f1f1f{fx$0{W1^1jhx1؎{W_&fU&fu &]{{&E&][Xft ` <t<taþ~Ȁ1؎м{Vp+!f`11faýf;0fPQf1fYfXf@MuQ00@f?tYf1[_WSuQfHf1fWf6+fRff1f60f+f@%0ffRf ffZXeftfXf+ff60ffRf ffGZW $ֹ l4efl4Gfp4fPff ffXfff!Y[_!tfSQU29@f0~=/u fGfP"t*L t+t f11f!]Y[Ã=tf,9=tڀ=/uG0Q ى09YS[V;09sWf?t Owt __^sf=t=/u[^<[^29wf=mf1f94f94u44Wf^<t/@ <4W _f,9HWS1< v8t 0}t ^  fSfVfWfQfRfUfP%0ffPfDA w fXfg(f fXf f.0f9rdf\f)f. 0f9r-f`f)f1f6 0Pfef(ff [ff1f60Pfef(ff [fPfef(ff [effXff#0ff]fZfYf_f^f[fUfPfRfWff; v fDffPff1EIt%f1f@f 9sfGfBff9tfXf`KfaU ]flf),uf<f_fZfXf]"t$S0r7GW1GG @[1[SVW>] !u0ƃmru&Fu_^[KA ] f`0]5fMg&fvfMf)M 5fa뤉Mfa0SV7b^[WS>] A C] [_Yr <t < t < v8ÿ /sW6_r<-s fPfQUf1ff1<-u<0rSt<9wM <0r% b 69@:89w%69>b69ø149þ@9t6979@:99w791ɋ89679>b+믾@9t1ɉ6989>?9r/@9t?949r@9t?9496p!?949.< t< v>npsG>n76nppt`>b69a$@9@9t+ff`~+!tP&=9W tB 8uXSfaf@9t tf`u~+!ttB&>9 8faôu"~+!tWtB&>9 8u0ôbfafP Xff` tfafaf1Ԫ`++)f 0ŪfdYfD9ÿEÿ ҉>n+ÿډ>p+À>+wʉ>l+ÿƒu >-u1>À>+t /P^rf*fffP^rPb uXPQ uX|+rSgs[Lv<9r)fSPr7as1ۀ>>9߁<9f[f%_fKrfff:9Pw狽>~+U'X!BBB<u:JJ0Bt~U~+Pk_1V+ʿ‹l+/(&#r ff%f=ENDTuff%f=EXTuÿW^ÿ1 s|+u¿ǹ)1f>D9 f>D9þh%QfSfR1f1fOfg[fOgI8t1Cgy؀rg(ufGCf8u sCIbs ~fOg fgfOg'NfZf[Yhy詍W1fNg,s fNgs ~fNgـfNgY)tUr<#tQ ffShf[r@< v f0t*rئ*ff9tf¥륰 ]< tr!tYSfPf=vffPff fW1>f_fYfQfWt &gfAfVf袌f^f_fYfXff)[uP.XVD=6ui<wb>rY wT>4H9f6Ht6t@H9>40Ht1Ɉ2H99!0H89ù1Ҹ0۸` u99̈&89aVu84rtf>4=ui<1۹:4H1:99r99Ȉƴ1:lQWf1f_W8^Nj>l^lPY148tIu1$tQوY)w Ãt.$úB`ˬՇwavH<t@t O1w%7Hf0Eb+1f`Ȏ؎H ttOHb+faf`_f` >Hu faf`f`Yf\Yf1f!txf fPAMSf1ɱHYsf!u[pf=PAMSuhf>LYwfHYf>XYtf=rf;`Ysf`Yf;\YwfPYrf>TYtff;\Yvf\Y~f\Yf;`Yvf`Yf=w8r=Tz*~f|f,~f0~fffLfP$0T>Tt9t,1t%f/-Zffgff1}ffd(fÿfVff=/-Zuf1ҹ~fffguff=d(^P18t tƁr =v1XPVW uYQ18t t#Ɓr|Wƹ)r%^^NY΁sވЪȪd)1_^Xf`}f1fffgf)Ѝ|fDffaf>Ltf>Pt>Tt PXPXÈ&t]f`T Ҵr uBr]?p]UATwrGfL fPfaf1VfRfPSjjf`T@ &t]fadr^^fRfPUf6p]f>r]f1ɇff=w'Aň֊T&t]f`far]fXfZMuIt appears your computer has less than 256K of low ("DOS") RAM. Linux needs at least this amount to boot. If you get this message in error, hold down the Ctrl key while booting, and I will take your word for it. boot:  Invalid image type for this media type! Could not find kernel image: Invalid or corrupt kernel image. "CC6 Loading ..ready. Cannot load a ramdisk with an old kernel image. Could not find ramdisk image: Not enough memory to load specified kernel. BOOT_IMAGE=#19A F Y0mL׉ى"E\׉d׉׉׉׉2A΋Q%: attempted DOS system call COMBOOT image too large.  aborted. 0 linux autoOut of memory parsing config file Unknown keyword in configuration file. Missing parameter in configuration file. A20 gate not responding!   Copyright (C) 1994-2008 H. Peter Anvin Boot failed: please change disks and press a key to continue. extlinux.confinitrd=7t;}bQ9ؘYQ@ Q2@x+6P@̴h 6 0  e N  R2 G @t:t+6YtLhg1`+62d+Qh+^hɘHz+6 v+6 7 7 7 7 7 7 7 7 77 777.cbt.img.bs.com.c32 ?(g\(f`h) fafffPfUf.)f1ff .f )f.( "b)8аذ01V ] $")ff]fXftCf9r$fgfgfgtfg|fffgfffgff1΃fgfgf`.(..Z+.P+.Z+du_.Z+$RuMouF.Z+d^`WQ1/u)Y.Z+ $Q1uY.(uveYfaQP .(@.(e&;(XY0t uLdtC`u8!tf?fwfOft) Hufaf..(ffQfXf1f f.)f.( "6+ 1а0ذ(؎Ўf**(*:*`*.NGGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)Td)# die get_sizen sectmap modify_adv, get_geometry xpwrite- xpread already_installed install_bootblock9write_advread_advbmodify_existing_advpatch_file_and_bootblockinstall_fileinstall_loadermainprogram-optdsyslinux_reset_advsyslinux_validate_advsyslinux_setadvsyslinux_advZXDextlinux_bootsectVextlinux_bootsect_lenoextlinux_bootsect_mtimeQDextlinux_imageVextlinux_image_lenpextlinux_image_mtime{dTL{4int22SG4e~;wt eyB8:9w5 ee"e( e''#737~o #33 ; Z5 n Oz{I#|#7  `,2-#/S#4# 7#&8#=#>#HB# DS#(I#,KV#4=Oa#8m X#@Y#H Z#Pm#X1 - 3# # (# ## # # # 4# E# #$ #( Z #, "#0 $#4 p&3#8 *3#< ,#@ )0S#D 1%#F 2#G 6#H ?#L HT#T IT#X JT#\ KT#` L~#d N3#h 9P#l   N## 3#  7 7'  }e7q8#9#=:#d ;# <3#=3# 3  k]l#o3#p}#valq3# vT j 3#g 3#* $l#X %l# &l# 'w#  (w#( *>#0` +3#8 ,3#< -v#@37    e#e#e#Ie# 5e#gapA#A#, A#p!A#]"#/7 A, , S 3# e A= s>A# ?A# j@S# A# 8 ; = <[# T =[#  >[# F ?[#  @[#  A[#  B[#  CP#  D[#  E[#$ 2 F[#(  G[#, 1 H[#0 x IE#4  J:#6  KE#8 LE#: / ME#<  NE#>  O[#@  P[#D x Q[#H  R[#L  SE#P  TE#R # b[#T  cE#X 7 dE#Z H e[#\ ] f[#`  g[#d  h #h T i#x t j$ # y k[#  p/# O q/# rE#  s4 #$ /74 7?D [7 x>?e#s@e#A3# B3# ZC# K ^ Ll#gMl# MT{rvL3, die{Jmsgn Q6lv53^ 7lV8Zst9 $3 fd39 YK3"eupblkeul2 eie Z, 3rv3 Pc35b3aY blgeob ldPgpe  l   - @fd3Hbuft ~ !/ul"rv!up H"fd3bufT ~ ֚#!/؍ul"rv٥u!ڥup i3"[#3cl93[fd3<#sbw,3g+-vI.utfd/3st0xst0~err13231b23]A$7b3ӒIutfd3sterr3\3Ӓ,Iu%0&p/f&v/H%y;&p:f&v:Z'H&p A'%Z&p$(,fd33 3$ u geold)P Y lO lg 3 pf f i3Pdw3 ZR*++*;Ó++*ZÓȓ++,u++*ӓܓ++*++*++*+* ++** ++,E++*d++*++*++*ϔ++*ה++-++A3[  3- rstY Iupfd3 3 3ulst. /30031pst1dst&3[b % %3F st'~fst'}(3 rv(3 ) sfs*mnt,I dst-|!. - Vx++203|3{  a3bd 3" aM o3x  3  w7 !kg7!z` 7 T@4|4;4I343e4-56optDD JA74?4ce49?4 e sdL {0~4int 1^2G40t%lp$^ y;p:v:l^  Ed pK iE l^ "ޜ| ! i#E $leH'-œ̜. zޜ y EX 1 4EX\ tag3E 3% 3p5 6%7{ HS5 { I%SS~^ L# {6=6~2%cDh~ FintL9 {6=6-~29% i~O int% $ > $ > : ; I : ;  : ; I8 I!I/   I  : ; : ;I8 : ; &I& : ; I8  : ; : ; : ;I8 .: ; ' @: ; I.? : ; ' @: ; I .? : ;' I@: ;I4: ;I4: ;I : ;I4: ;I 4: ;I.? : ; ' I@ : ; I!4: ; I "4: ; I#: ;I $!I/%.: ; ' &: ; I'.: ; ' I (.? : ;' @)4: ;I*1X Y+1,1UX Y-1X Y. : ;/.: ;' I 0: ;I14: ;I2 U341 44: ; I? < 54: ; I?  64: ; I?  7!% : ; I$ > $ > .: ; ' I : ; I I&I .: ; ' .: ; ' I@ : ; I 4: ; I 4: ; I.: ; ' @: ; I1UX Y 11X Y 1X Y .? : ; ' @: ; I .? : ; ' I@4: ; I4: ; I  &I!I/4: ; I?  % I!I/$ > 4: ; I?  $ > % I!I/$ > 4: ; I?  4: ;I?  $ > o ../libinstaller/usr/include/usr/include/bits/usr/include/linux/usr/include/sys/usr/lib/gcc/x86_64-redhat-linux/4.1.2/include/usr/include/asm/usr/include/asm-genericextlinux.csyslxint.hstdint.hstat.htypes.htime.hhdreg.hfd.htypes.hstddef.hext2_fs.htypes.hstatfs.hmntent.hstdio.hlibio.hgetopt.hioctl.hsyslinux.hTXgtBYgMLXA7A$>N=z %zXw}X$*Fj0Ƀgs !/rsMq# ]~;W//Y=L-s<JM;W//Y=L-s<Jw!/I ?#\%OtD2\W/hh--=/0u>:gW/0T4Zu2ZYKuU.~B2\W//0><p.'i/A7Kut=!\{X </ɽɼ=C} uXJ|t `f|.|X=/=Wg|f|Xtic?|< f/|X|.s|X.A2W//ڻW//hK/KW/lD#/K! xX[*% <&/#^4uf f4yf$Y,ۑ![Y;/YZc7X]u;u;uh Jw!OX5"KLY!  ../libinstaller/usr/include/usr/lib/gcc/x86_64-redhat-linux/4.1.2/includesetadv.csyslxint.hstdint.hstddef.hd$b2%W[.XdX<mWXr<fr.t>YI.t7Ã4&/>Hkgk.KYg-Z?g2, ..extlinux_bss_bin.c2, ..extlinux_sys_bin.c| T'AB AV.{ AB L.uAB DM. AB FO.UAB D\. 7AD FX.$AB Fd. ].P.$AB Fd. ].P. "9AB DM. P.$[AB GW. s.Z. Z.0AB Hp.. W.. V.P.,4AB Ep.x.S.L. Y. ӒYAB DT.Z.M. ,AB IJ.4[AB Fp.R.Z.. w.Y. c.@[AB IK.B.J.. Q.E.S.F.I.O.<bD  F AB BE.. |.L.I.| d6AH DAD u. ޜ%AB DN.N. UAB ADn.$X5AB IJ..__u_quad_tst_ctims_lastcheckst_blksizef_blocks__ssize_tmnt_types_free_blocks_count_IO_save_endf_bsize__fsid_ts_mnt_count__gid_targcf_ffreepathst_mtim__u8_IO_write_basevalidate_devices_padding1_lockfloppy_structs_statef_spare_IO_save_bases_free_inodes_countprogram__u32_cur_column__dev_ts_inodes_countGNU C 4.1.2 20070925 (Red Hat 4.1.2-33)s_last_mounted__invalid_size_argument_for_IOCst_uidhas_argtotalsectors_IO_marker__fsfilcnt64_tupdate_onlyheaddone__blksize_t_IO_FILEs_feature_ro_compats_reserved__fsblkcnt64_tunsigned charxpwritest_rdevget_geometrys_feature_incompatfmt_gaps_creator_os__off64_ttv_secs_rev_levelmainnsectsyslinux_adv_IO_lock_t_chainstartf_fsid__mode_traid_mode_IO_read_ptrs_frags_per_group_poss_magic_markersmtabst_nlinks_errorsext2_super_blocktracks_prealloc_dir_blocksmntentfd_strheadsset_32f_filesrates_minor_rev_level__blkcnt64_ts_checkintervalinstall_bootblocklong_optionsst_gidget_32directorycsumoptindmnt_freq_flags2st_sizemodify_adv_IO_read_bases_wtime_unused2__quad_tnsectorss_volume_namenflagsalready_installed/home/hpa/syslinux/release/syslinux-3.63/extlinuxs_mtime_old_offsetoptargargv__ino_toptiondirfdlong long intpatcharearead_adv_IO_write_ends_prealloc_blockss_first_inobufp_IO_buf_baseinstall_file_nexts_blocks_countextlinux_bootsect_lens_algorithm_usage_bitmap__pad1__pad2__pad3__pad4__pad5s_uuid_sbufflagshort_optionsf_bavails_log_frag_size_flagsextlinux.cbails_inode_size__st_inoget_16__ino64_t__s16st_devextlinux_imagexpreadtimespecf_bfreef_namelencylinderslong long unsigned intdevnameuint16_t__off_textlinux_bootsects_blocks_per_group__s32write_advs_log_block_sizeusage__time_ts_r_blocks_count_IO_backup_base_shortbufsectmapspec1s_inodes_per_group_IO_buf_endget_sizeset_oncebufferf_typemnt_fsnamestderrshort ints_def_resuiddevfduint64_ts_max_mnt_counttv_nsecpatch_file_and_bootblock_vtable_offsetinstall_loaderset_16__val__u16statmnt_dirst_mode__uid_t_IO_read_endstretchst_blocksuint32_tsectpsectsmodify_existing_adv_filenomy_optionsf_frsizemnt_passnos_first_data_blockstatfsshort unsigned intgeometry_tablehd_geometry_IO_write_ptradvtmpstandard_geometriess_def_resgidextlinux_image_len__nlink_tnblks_block_group_nrs_feature_compattotalbytesmnt_optsst_atimdirstplensyslinux_setadvleftadv_consistent../libinstaller/setadv.cdataptagadvbufsyslinux_validate_advuint8_tsyslinux_reset_advcleanup_advextlinux_bootsect_mtime../extlinux_bss_bin.c../extlinux_sys_bin.cextlinux_image_mtimett'uP'S'(t(*t*GuGHtHJtJuGggSumouhuhututtt<u<u9V9<u 8S8<u:WR-R2<R<=t=?t?uPPttuuSuSVu Vu  u/QQQttKu<u<KKu IWIKu SuGSVGHuVHKuQRPQP*/Q/0P0<PR<KQRKLtLNtNuKuKllu KllWuK` `lSulSVuVul}QRPQPQPPRQRttut t u77SuttKuRKuPWPIWSS=S"SBHSup"upBKupulPul"ulBKulKLtLNtNuK[[RuP}WSS.BSH|SttuSutt u   u   u u @ W@ u SVK x PR P, Q P" SC V@ W t t  u  I SI  u M M u    u  u  3 5 P5 W P  W  P  V  t t u * * W u **u u u P V*SSSS S#S:S*SSSS S#TSTVP\\Sj}PSP Pu{PTP\ePl}PPtQttu6q6 W q6q6 S q6PP?QPV[PbPPPPPPPP  Vt t 6uP2Q46Q67t7;t;zu6KPKuR@XQz{t{}t}uttuVutt)u)uVu &V&)u #6SJS%S#6u{\)u{#(Q\aPasQsPQPQQP#(R\RRRt x   " ) ;@CK.symtab.strtab.shstrtab.interp.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data.bss.comment.debug_aranges.debug_pubnames.debug_info.debug_abbrev.debug_line.debug_frame.debug_str.debug_loc.debug_ranges44#HH 1hh$HDo``0N  VJ^oDko@@@z     !@@! )4*0000001H0 a@ ac@ cBfl'Y5ۅA܋N0pd Yԙd`r 'A V4Hh`@     @ !"#$*8ESbЉx0T'@` d6D%8Kar I}Z -?FӒYZl,  @1D42 CC)F[S[m z[DUX5`2G+?<N'`vF[4H ޜ%io$,8MTXgup uD.%"9U{ 7"=4YKbP call_gmon_startcrtstuff.c__CTOR_LIST____DTOR_LIST____JCR_LIST__dtor_idx.5662completed.5660__do_global_dtors_auxframe_dummy__CTOR_END____FRAME_END____JCR_END____do_global_ctors_auxextlinux.cusagestandard_geometrieslong_optionsshort_optionssetadv.cadv_consistentcleanup_advextlinux_bss_bin.cextlinux_sys_bin.c_GLOBAL_OFFSET_TABLE___init_array_end__init_array_start_DYNAMICdata_startfputs@@GLIBC_2.0__errno_location@@GLIBC_2.0setmntent@@GLIBC_2.0extlinux_bootsectstatfs64@@GLIBC_2.1xpwritestrerror@@GLIBC_2.0__libc_csu_finimemcmp@@GLIBC_2.0_startmodify_existing_advopen64@@GLIBC_2.1patch_file_and_bootblockextlinux_bootsect_mtime__gmon_start___Jv_RegisterClasses_fp_hwsync@@GLIBC_2.0write_adv__xstat64@@GLIBC_2.2_finiread_advfstat64memset@@GLIBC_2.0__udivdi3__libc_start_main@@GLIBC_2.0install_fileprogramperror@@GLIBC_2.0syslinux_advinstall_bootblock_IO_stdin_usedfree@@GLIBC_2.0optind@@GLIBC_2.0__data_startmodify_advsyslinux_setadvextlinux_image_mtimestat64extlinux_image_lengetopt_long@@GLIBC_2.0ioctl@@GLIBC_2.0stderr@@GLIBC_2.0memcpy@@GLIBC_2.0extlinux_bootsect_lenstrtoul@@GLIBC_2.0optinstall_loaderasprintf@@GLIBC_2.0__dso_handle__DTOR_END__syslinux_reset_adv__libc_csu_initpread64@@GLIBC_2.1close@@GLIBC_2.0sectmapfprintf@@GLIBC_2.0__bss_startgetmntent@@GLIBC_2.0xpreadmemmove@@GLIBC_2.0get_size_endpwrite64@@GLIBC_2.1__fxstat64@@GLIBC_2.2extlinux_imageoptarg@@GLIBC_2.0_edatastrcmp@@GLIBC_2.0already_installedsyslinux_validate_advexit@@GLIBC_2.0dieget_geometryfchmod@@GLIBC_2.0__i686.get_pc_thunk.bxmain_initsyslinux-legacy-3.63+dfsg/extlinux/extlinux.c0000664000175000017500000005650010777447273020126 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 1998-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * extlinux.c * * Install the extlinux boot block on an ext2/3 filesystem */ #define _GNU_SOURCE /* Enable everything */ #include /* This is needed to deal with the kernel headers imported into glibc 3.3.3. */ typedef uint64_t u64; #include #include #include #include #include #ifndef __KLIBC__ #include #endif #include #include #include #include #include #include #include #include #include #include /* Floppy geometry */ #include /* Hard disk geometry */ #define statfs _kernel_statfs /* HACK to deal with broken 2.4 distros */ #include /* FIGETBSZ, FIBMAP */ #undef statfs #include "ext2_fs.h" #include "../version.h" #include "syslxint.h" #ifdef DEBUG # define dprintf printf #else # define dprintf(...) ((void)0) #endif /* Global option handling */ const char *program; /* These are the options we can set and their values */ struct my_options { unsigned int sectors; unsigned int heads; int raid_mode; int reset_adv; const char *set_once; } opt = { .sectors = 0, .heads = 0, .raid_mode = 0, .reset_adv = 0, .set_once = NULL, }; static void __attribute__((noreturn)) usage(int rv) { fprintf(stderr, "Usage: %s [options] directory\n" " --install -i Install over the current bootsector\n" " --update -U Update a previous EXTLINUX installation\n" " --zip -z Force zipdrive geometry (-H 64 -S 32)\n" " --sectors=# -S Force the number of sectors per track\n" " --heads=# -H Force number of heads\n" " --raid -r Fall back to the next device on boot failure\n" " --once=... -o Execute a command once upon boot\n" " --clear-once -O Clear the boot-once command\n" " --reset-adv Reset auxilliary data\n" "\n" " Note: geometry is determined at boot time for devices which\n" " are considered hard disks by the BIOS. Unfortunately, this is\n" " not possible for devices which are considered floppy disks,\n" " which includes zipdisks and LS-120 superfloppies.\n" "\n" " The -z option is useful for USB devices which are considered\n" " hard disks by some BIOSes and zipdrives by other BIOSes.\n", program); exit(rv); } enum long_only_opt { OPT_NONE, OPT_RESET_ADV, }; static const struct option long_options[] = { { "install", 0, NULL, 'i' }, { "update", 0, NULL, 'U' }, { "zipdrive", 0, NULL, 'z' }, { "sectors", 1, NULL, 'S' }, { "heads", 1, NULL, 'H' }, { "raid-mode", 0, NULL, 'r' }, { "version", 0, NULL, 'v' }, { "help", 0, NULL, 'h' }, { "once", 1, NULL, 'o' }, { "clear-once", 0, NULL, 'O' }, { "reset-adv", 0, NULL, OPT_RESET_ADV }, { 0, 0, 0, 0 } }; static const char short_options[] = "iUuzS:H:rvho:O"; #if defined(__linux__) && !defined(BLKGETSIZE64) /* This takes a u64, but the size field says size_t. Someone screwed big. */ # define BLKGETSIZE64 _IOR(0x12,114,size_t) #endif #define LDLINUX_MAGIC 0x3eb202fe enum bs_offsets { bsJump = 0x00, bsOemName = 0x03, bsBytesPerSec = 0x0b, bsSecPerClust = 0x0d, bsResSectors = 0x0e, bsFATs = 0x10, bsRootDirEnts = 0x11, bsSectors = 0x13, bsMedia = 0x15, bsFATsecs = 0x16, bsSecPerTrack = 0x18, bsHeads = 0x1a, bsHiddenSecs = 0x1c, bsHugeSectors = 0x20, /* FAT12/16 only */ bs16DriveNumber = 0x24, bs16Reserved1 = 0x25, bs16BootSignature = 0x26, bs16VolumeID = 0x27, bs16VolumeLabel = 0x2b, bs16FileSysType = 0x36, bs16Code = 0x3e, /* FAT32 only */ bs32FATSz32 = 36, bs32ExtFlags = 40, bs32FSVer = 42, bs32RootClus = 44, bs32FSInfo = 48, bs32BkBootSec = 50, bs32Reserved = 52, bs32DriveNumber = 64, bs32Reserved1 = 65, bs32BootSignature = 66, bs32VolumeID = 67, bs32VolumeLabel = 71, bs32FileSysType = 82, bs32Code = 90, bsSignature = 0x1fe }; #define bsHead bsJump #define bsHeadLen (bsOemName-bsHead) #define bsCode bs32Code /* The common safe choice */ #define bsCodeLen (bsSignature-bs32Code) #ifndef EXT2_SUPER_OFFSET #define EXT2_SUPER_OFFSET 1024 #endif const char *program; /* * Boot block */ extern unsigned char extlinux_bootsect[]; extern unsigned int extlinux_bootsect_len; #define boot_block extlinux_bootsect #define boot_block_len extlinux_bootsect_len /* * Image file */ extern unsigned char extlinux_image[]; extern unsigned int extlinux_image_len; #define boot_image extlinux_image #define boot_image_len extlinux_image_len /* * Common abort function */ void __attribute__((noreturn)) die(const char *msg) { fputs(msg, stderr); exit(1); } /* * read/write wrapper functions */ ssize_t xpread(int fd, void *buf, size_t count, off_t offset) { char *bufp = (char *)buf; ssize_t rv; ssize_t done = 0; while ( count ) { rv = pread(fd, bufp, count, offset); if ( rv == 0 ) { die("short read"); } else if ( rv == -1 ) { if ( errno == EINTR ) { continue; } else { die(strerror(errno)); } } else { bufp += rv; offset += rv; done += rv; count -= rv; } } return done; } ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset) { const char *bufp = (const char *)buf; ssize_t rv; ssize_t done = 0; while ( count ) { rv = pwrite(fd, bufp, count, offset); if ( rv == 0 ) { die("short write"); } else if ( rv == -1 ) { if ( errno == EINTR ) { continue; } else { die(strerror(errno)); } } else { bufp += rv; offset += rv; done += rv; count -= rv; } } return done; } /* * Produce file map */ int sectmap(int fd, uint32_t *sectors, int nsectors) { unsigned int blksize, blk, nblk; unsigned int i; /* Get block size */ if ( ioctl(fd, FIGETBSZ, &blksize) ) return -1; /* Number of sectors per block */ blksize >>= SECTOR_SHIFT; nblk = 0; while ( nsectors ) { blk = nblk++; dprintf("querying block %u\n", blk); if ( ioctl(fd, FIBMAP, &blk) ) return -1; blk *= blksize; for ( i = 0 ; i < blksize ; i++ ) { if ( !nsectors ) return 0; dprintf("Sector: %10u\n", blk); *sectors++ = blk++; nsectors--; } } return 0; } /* * Get the size of a block device */ uint64_t get_size(int devfd) { uint64_t bytes; uint32_t sects; struct stat st; #ifdef BLKGETSIZE64 if ( !ioctl(devfd, BLKGETSIZE64, &bytes) ) return bytes; #endif if ( !ioctl(devfd, BLKGETSIZE, §s) ) return (uint64_t)sects << 9; else if ( !fstat(devfd, &st) && st.st_size ) return st.st_size; else return 0; } /* * Get device geometry and partition offset */ struct geometry_table { uint64_t bytes; struct hd_geometry g; }; /* Standard floppy disk geometries, plus LS-120. Zipdisk geometry (x/64/32) is the final fallback. I don't know what LS-240 has as its geometry, since I don't have one and don't know anyone that does, and Google wasn't helpful... */ static const struct geometry_table standard_geometries[] = { { 360*1024, { 2, 9, 40, 0 } }, { 720*1024, { 2, 9, 80, 0 } }, { 1200*1024, { 2, 15, 80, 0 } }, { 1440*1024, { 2, 18, 80, 0 } }, { 1680*1024, { 2, 21, 80, 0 } }, { 1722*1024, { 2, 21, 80, 0 } }, { 2880*1024, { 2, 36, 80, 0 } }, { 3840*1024, { 2, 48, 80, 0 } }, { 123264*1024, { 8, 32, 963, 0 } }, /* LS120 */ { 0, {0,0,0,0} } }; int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo) { struct floppy_struct fd_str; const struct geometry_table *gp; memset(geo, 0, sizeof *geo); if ( !ioctl(devfd, HDIO_GETGEO, &geo) ) { return 0; } else if ( !ioctl(devfd, FDGETPRM, &fd_str) ) { geo->heads = fd_str.head; geo->sectors = fd_str.sect; geo->cylinders = fd_str.track; geo->start = 0; return 0; } /* Didn't work. Let's see if this is one of the standard geometries */ for ( gp = standard_geometries ; gp->bytes ; gp++ ) { if ( gp->bytes == totalbytes ) { memcpy(geo, &gp->g, sizeof *geo); return 0; } } /* Didn't work either... assign a geometry of 64 heads, 32 sectors; this is what zipdisks use, so this would help if someone has a USB key that they're booting in USB-ZIP mode. */ geo->heads = opt.heads ?: 64; geo->sectors = opt.sectors ?: 32; geo->cylinders = totalbytes/(geo->heads*geo->sectors << SECTOR_SHIFT); geo->start = 0; if ( !opt.sectors && !opt.heads ) fprintf(stderr, "Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n" " (on hard disks, this is usually harmless.)\n", geo->heads, geo->sectors); return 1; } /* * Query the device geometry and put it into the boot sector. * Map the file and put the map in the boot sector and file. * Stick the "current directory" inode number into the file. */ void patch_file_and_bootblock(int fd, int dirfd, int devfd) { struct stat dirst; struct hd_geometry geo; uint32_t *sectp; uint64_t totalbytes, totalsectors; int nsect; unsigned char *p, *patcharea; int i, dw; uint32_t csum; if ( fstat(dirfd, &dirst) ) { perror("fstat dirfd"); exit(255); /* This should never happen */ } totalbytes = get_size(devfd); get_geometry(devfd, totalbytes, &geo); if ( opt.heads ) geo.heads = opt.heads; if ( opt.sectors ) geo.sectors = opt.sectors; /* Patch this into a fake FAT superblock. This isn't because FAT is a good format in any way, it's because it lets the early bootstrap share code with the FAT version. */ dprintf("heads = %u, sect = %u\n", geo.heads, geo.sectors); totalsectors = totalbytes >> SECTOR_SHIFT; if ( totalsectors >= 65536 ) { set_16(boot_block+bsSectors, 0); } else { set_16(boot_block+bsSectors, totalsectors); } set_32(boot_block+bsHugeSectors, totalsectors); set_16(boot_block+bsBytesPerSec, SECTOR_SIZE); set_16(boot_block+bsSecPerTrack, geo.sectors); set_16(boot_block+bsHeads, geo.heads); set_32(boot_block+bsHiddenSecs, geo.start); /* If we're in RAID mode then patch the appropriate instruction; either way write the proper boot signature */ i = get_16(boot_block+0x1FE); if (opt.raid_mode) set_16(boot_block+i, 0x18CD); /* INT 18h */ set_16(boot_block+0x1FE, 0xAA55); /* Construct the boot file */ dprintf("directory inode = %lu\n", (unsigned long) dirst.st_ino); nsect = (boot_image_len+SECTOR_SIZE-1) >> SECTOR_SHIFT; nsect += 2; /* Two sectors for the ADV */ sectp = alloca(sizeof(uint32_t)*nsect); if ( sectmap(fd, sectp, nsect) ) { perror("bmap"); exit(1); } /* First sector need pointer in boot sector */ set_32(boot_block+0x1F8, *sectp++); nsect--; /* Search for LDLINUX_MAGIC to find the patch area */ for ( p = boot_image ; get_32(p) != LDLINUX_MAGIC ; p += 4 ); patcharea = p+8; /* Set up the totals */ dw = boot_image_len >> 2; /* COMPLETE dwords, excluding ADV */ set_16(patcharea, dw); set_16(patcharea+2, nsect); /* Not including the first sector, but including the ADV */ set_32(patcharea+8, dirst.st_ino); /* "Current" directory */ /* Set the sector pointers */ p = patcharea+12; memset(p, 0, 64*4); while ( nsect-- ) { set_32(p, *sectp++); p += 4; } /* Now produce a checksum */ set_32(patcharea+4, 0); csum = LDLINUX_MAGIC; for ( i = 0, p = boot_image ; i < dw ; i++, p += 4 ) csum -= get_32(p); /* Negative checksum */ set_32(patcharea+4, csum); } /* * Read the ADV from an existing instance, or initialize if invalid. * Returns -1 on fatal errors, 0 if ADV is okay, and 1 if no valid * ADV was found. */ int read_adv(const char *path) { char *file; int fd = -1; struct stat st; int err = 0; asprintf(&file, "%s%sextlinux.sys", path, path[0] && path[strlen(path)-1] == '/' ? "" : "/"); if ( !file ) { perror(program); return -1; } fd = open(file, O_RDONLY); if ( fd < 0 ) { if ( errno != ENOENT ) { err = -1; } else { syslinux_reset_adv(syslinux_adv); } } else if (fstat(fd, &st)) { err = -1; } else if (st.st_size < 2*ADV_SIZE) { /* Too small to be useful */ syslinux_reset_adv(syslinux_adv); err = 0; /* Nothing to read... */ } else if (xpread(fd, syslinux_adv, 2*ADV_SIZE, st.st_size-2*ADV_SIZE) != 2*ADV_SIZE) { err = -1; } else { /* We got it... maybe? */ err = syslinux_validate_adv(syslinux_adv) ? 1 : 0; } if (err < 0) perror(file); if (fd >= 0) close(fd); if (file) free(file); return err; } /* * Update the ADV in an existing installation. */ int write_adv(const char *path) { unsigned char advtmp[2*ADV_SIZE]; char *file; int fd = -1; struct stat st, xst; int err = 0; int flags, nflags; asprintf(&file, "%s%sextlinux.sys", path, path[0] && path[strlen(path)-1] == '/' ? "" : "/"); if ( !file ) { perror(program); return -1; } fd = open(file, O_RDONLY); if ( fd < 0 ) { err = -1; } else if (fstat(fd, &st)) { err = -1; } else if (st.st_size < 2*ADV_SIZE) { /* Too small to be useful */ err = -2; } else if (xpread(fd, advtmp, 2*ADV_SIZE, st.st_size-2*ADV_SIZE) != 2*ADV_SIZE) { err = -1; } else { /* We got it... maybe? */ err = syslinux_validate_adv(advtmp) ? -2 : 0; if (!err) { /* Got a good one, write our own ADV here */ if (!ioctl(fd, EXT2_IOC_GETFLAGS, &flags)) { nflags = flags & ~EXT2_IMMUTABLE_FL; if (nflags != flags) ioctl(fd, EXT2_IOC_SETFLAGS, &nflags); } if (!(st.st_mode & S_IWUSR)) fchmod(fd, st.st_mode | S_IWUSR); /* Need to re-open read-write */ close(fd); fd = open(file, O_RDWR|O_SYNC); if (fd < 0) { err = -1; } else if (fstat(fd, &xst) || xst.st_ino != st.st_ino || xst.st_dev != st.st_dev || xst.st_size != st.st_size) { fprintf(stderr, "%s: race condition on write\n", file); err = -2; } /* Write our own version ... */ if (xpwrite(fd, syslinux_adv, 2*ADV_SIZE, st.st_size-2*ADV_SIZE) != 2*ADV_SIZE) { err = -1; } sync(); if (!(st.st_mode & S_IWUSR)) fchmod(fd, st.st_mode); if (nflags != flags) ioctl(fd, EXT2_IOC_SETFLAGS, &flags); } } if (err == -2) fprintf(stderr, "%s: cannot write auxilliary data (need --update)?\n", file); else if (err == -1) perror(file); if (fd >= 0) close(fd); if (file) free(file); return err; } /* * Make any user-specified ADV modifications */ int modify_adv(void) { int rv = 0; if (opt.set_once) { if (syslinux_setadv(ADV_BOOTONCE, strlen(opt.set_once), opt.set_once)) { fprintf(stderr, "%s: not enough space for boot-once command\n", program); rv = -1; } } return rv; } /* * Install the boot block on the specified device. * Must be run AFTER install_file()! */ int install_bootblock(int fd, const char *device) { struct ext2_super_block sb; if ( xpread(fd, &sb, sizeof sb, EXT2_SUPER_OFFSET) != sizeof sb ) { perror("reading superblock"); return 1; } if ( sb.s_magic != EXT2_SUPER_MAGIC ) { fprintf(stderr, "no ext2/ext3 superblock found on %s\n", device); return 1; } if ( xpwrite(fd, boot_block, boot_block_len, 0) != boot_block_len ) { perror("writing bootblock"); return 1; } return 0; } int install_file(const char *path, int devfd, struct stat *rst) { char *file; int fd = -1, dirfd = -1, flags; struct stat st; asprintf(&file, "%s%sextlinux.sys", path, path[0] && path[strlen(path)-1] == '/' ? "" : "/"); if ( !file ) { perror(program); return 1; } dirfd = open(path, O_RDONLY|O_DIRECTORY); if ( dirfd < 0 ) { perror(path); goto bail; } fd = open(file, O_RDONLY); if ( fd < 0 ) { if ( errno != ENOENT ) { perror(file); goto bail; } } else { /* If file exist, remove the immutable flag and set u+w mode */ if ( !ioctl(fd, EXT2_IOC_GETFLAGS, &flags) ) { flags &= ~EXT2_IMMUTABLE_FL; ioctl(fd, EXT2_IOC_SETFLAGS, &flags); } if ( !fstat(fd, &st) ) { fchmod(fd, st.st_mode | S_IWUSR); } } close(fd); fd = open(file, O_WRONLY|O_TRUNC|O_CREAT|O_SYNC, S_IRUSR|S_IRGRP|S_IROTH); if ( fd < 0 ) { perror(file); goto bail; } /* Write it the first time */ if ( xpwrite(fd, boot_image, boot_image_len, 0) != boot_image_len || xpwrite(fd, syslinux_adv, 2*ADV_SIZE, boot_image_len) != 2*ADV_SIZE ) { fprintf(stderr, "%s: write failure on %s\n", program, file); goto bail; } /* Map the file, and patch the initial sector accordingly */ patch_file_and_bootblock(fd, dirfd, devfd); /* Write the first sector again - this relies on the file being overwritten in place! */ if ( xpwrite(fd, boot_image, SECTOR_SIZE, 0) != SECTOR_SIZE ) { fprintf(stderr, "%s: write failure on %s\n", program, file); goto bail; } /* Attempt to set immutable flag and remove all write access */ /* Only set immutable flag if file is owned by root */ if ( !fstat(fd, &st) ) { fchmod(fd, st.st_mode & (S_IRUSR|S_IRGRP|S_IROTH)); if ( st.st_uid == 0 && !ioctl(fd, EXT2_IOC_GETFLAGS, &flags) ) { flags |= EXT2_IMMUTABLE_FL; ioctl(fd, EXT2_IOC_SETFLAGS, &flags); } } if ( fstat(fd, rst) ) { perror(file); goto bail; } close(dirfd); close(fd); return 0; bail: if ( dirfd >= 0 ) close(dirfd); if ( fd >= 0 ) close(fd); return 1; } /* EXTLINUX installs the string 'EXTLINUX' at offset 3 in the boot sector; this is consistent with FAT filesystems. */ int already_installed(int devfd) { char buffer[8]; xpread(devfd, buffer, 8, 3); return !memcmp(buffer, "EXTLINUX", 8); } #ifdef __KLIBC__ static char devname_buf[64]; static void device_cleanup(void) { unlink(devname_buf); } #endif /* Verify that a device fd and a pathname agree. Return 0 on valid, -1 on error. */ static int validate_device(const char *path, int devfd) { struct stat pst, dst; if (stat(path, &pst) || fstat(devfd, &dst)) return -1; return (pst.st_dev == dst.st_rdev) ? 0 : -1; } int install_loader(const char *path, int update_only) { struct stat st, fst; int devfd, rv; const char *devname = NULL; struct statfs sfs; #ifndef __KLIBC__ struct mntent *mnt = NULL; struct stat dst; FILE *mtab; #endif if ( stat(path, &st) || !S_ISDIR(st.st_mode) ) { fprintf(stderr, "%s: Not a directory: %s\n", program, path); return 1; } if ( statfs(path, &sfs) ) { fprintf(stderr, "%s: statfs %s: %s\n", program, path, strerror(errno)); return 1; } if ( sfs.f_type != EXT2_SUPER_MAGIC ) { fprintf(stderr, "%s: not an ext2/ext3 filesystem: %s\n", program, path); return 1; } devfd = -1; #ifdef __KLIBC__ /* klibc doesn't have getmntent and friends; instead, just create a new device with the appropriate device type */ snprintf(devname_buf, sizeof devname_buf, "/tmp/dev-%u:%u", major(st.st_dev), minor(st.st_dev)); if (mknod(devname_buf, S_IFBLK|0600, st.st_dev)) { fprintf(stderr, "%s: cannot create device %s\n", program, devname); return 1; } atexit(device_cleanup); /* unlink the device node on exit */ devname = devname_buf; #else if ( (mtab = setmntent("/proc/mounts", "r")) ) { while ( (mnt = getmntent(mtab)) ) { if ( (!strcmp(mnt->mnt_type, "ext2") || !strcmp(mnt->mnt_type, "ext3")) && !stat(mnt->mnt_fsname, &dst) && dst.st_rdev == st.st_dev ) { devname = mnt->mnt_fsname; break; } } } if ( !devname ) { /* Didn't find it in /proc/mounts, try /etc/mtab */ if ( (mtab = setmntent("/etc/mtab", "r")) ) { while ( (mnt = getmntent(mtab)) ) { devname = mnt->mnt_fsname; break; } } } if ( !devname ) { fprintf(stderr, "%s: cannot find device for path %s\n", program, path); return 1; } fprintf(stderr, "%s is device %s\n", path, devname); #endif if ( (devfd = open(devname, O_RDWR|O_SYNC)) < 0 ) { fprintf(stderr, "%s: cannot open device %s\n", program, devname); return 1; } /* Verify that the device we opened is the device intended */ if (validate_device(path, devfd)) { fprintf(stderr, "%s: path %s doesn't match device %s\n", program, path, devname); return 1; } if ( update_only && !already_installed(devfd) ) { fprintf(stderr, "%s: no previous extlinux boot sector found\n", program); return 1; } /* Read a pre-existing ADV, if already installed */ if (opt.reset_adv) syslinux_reset_adv(syslinux_adv); else if (read_adv(path) < 0) return 1; if (modify_adv() < 0) return 1; /* Install extlinux.sys */ if (install_file(path, devfd, &fst)) return 1; if ( fst.st_dev != st.st_dev ) { fprintf(stderr, "%s: file system changed under us - aborting!\n", program); return 1; } sync(); rv = install_bootblock(devfd, devname); close(devfd); sync(); return rv; } /* * Modify the ADV of an existing installation */ int modify_existing_adv(const char *path) { if (opt.reset_adv) syslinux_reset_adv(syslinux_adv); else if (read_adv(path) < 0) return 1; if (modify_adv() < 0) return 1; if (write_adv(path) < 0) return 1; return 0; } int main(int argc, char *argv[]) { int o; const char *directory; int update_only = -1; program = argv[0]; while ( (o = getopt_long(argc, argv, short_options, long_options, NULL)) != EOF ) { switch ( o ) { case 'z': opt.heads = 64; opt.sectors = 32; break; case 'S': opt.sectors = strtoul(optarg, NULL, 0); if ( opt.sectors < 1 || opt.sectors > 63 ) { fprintf(stderr, "%s: invalid number of sectors: %u (must be 1-63)\n", program, opt.sectors); exit(EX_USAGE); } break; case 'H': opt.heads = strtoul(optarg, NULL, 0); if ( opt.heads < 1 || opt.heads > 256 ) { fprintf(stderr, "%s: invalid number of heads: %u (must be 1-256)\n", program, opt.heads); exit(EX_USAGE); } break; case 'r': opt.raid_mode = 1; break; case 'i': update_only = 0; break; case 'u': case 'U': update_only = 1; break; case 'h': usage(0); break; case 'o': opt.set_once = optarg; break; case 'O': opt.set_once = ""; break; case OPT_RESET_ADV: opt.reset_adv = 1; break; case 'v': fputs("extlinux " VERSION "\n", stderr); exit(0); default: usage(EX_USAGE); } } directory = argv[optind]; if ( !directory ) usage(EX_USAGE); if ( update_only == -1 ) { if (opt.reset_adv || opt.set_once) { return modify_existing_adv(directory); } else { usage(EX_USAGE); } } return install_loader(directory, update_only); } syslinux-legacy-3.63+dfsg/unix/0000775000175000017500000000000010777447344015176 5ustar evanevansyslinux-legacy-3.63+dfsg/unix/Makefile0000664000175000017500000000175710777447273016651 0ustar evanevanTMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) ../dummy.c -o $$tmpf 2>/dev/null; \ then echo '$(1)'; else echo '$(2)'; fi; rm -f $$tmpf) comma := , LDHASH := $(call gcc_ok,-Wl$(comma)--hash-style=both,) CC = gcc OPTFLAGS = -g -Os INCLUDES = -I. -I.. -I../libinstaller CFLAGS = -W -Wall -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES) LDFLAGS = $(LDHASH) -s SRCS = syslinux.c ../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS))) .SUFFIXES: .c .o .i .s .S VPATH = .:..:../libinstaller all: installer tidy: -rm -f *.o *.i *.s *.a .*.d clean: tidy -rm -f syslinux syslinux-nomtools spotless: clean -rm -f *~ installer: syslinux syslinux-nomtools syslinux: $(OBJS) $(CC) $(LDFLAGS) -o $@ $^ syslinux-nomtools: syslinux ln -f $< $@ %.o: %.c $(CC) -Wp,-MT,$@,-MMD,.$@.d $(CFLAGS) -c -o $@ $< %.i: %.c $(CC) $(CFLAGS) -E -o $@ $< %.s: %.c $(CC) $(CFLAGS) -S -o $@ $< -include .*.d syslinux-legacy-3.63+dfsg/unix/syslinux.c0000664000175000017500000002755710777447273017261 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 1998-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * syslinux.c - Linux installer program for SYSLINUX * * This is Linux-specific by now. * * This is an alternate version of the installer which doesn't require * mtools, but requires root privilege. */ /* * If DO_DIRECT_MOUNT is 0, call mount(8) * If DO_DIRECT_MOUNT is 1, call mount(2) */ #ifdef __KLIBC__ # define DO_DIRECT_MOUNT 1 #else # define DO_DIRECT_MOUNT 0 /* glibc has broken losetup ioctls */ #endif #define _GNU_SOURCE #define _XOPEN_SOURCE 500 /* For pread() pwrite() */ #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* FIGETBSZ, FIBMAP */ #include /* FAT_IOCTL_SET_ATTRIBUTES, SECTOR_* */ #ifndef FAT_IOCTL_SET_ATTRIBUTES # define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, uint32_t) #endif #include #ifndef _PATH_MOUNT # define _PATH_MOUNT "/bin/mount" #endif #ifndef _PATH_UMOUNT # define _PATH_UMOUNT "/bin/umount" #endif #ifndef _PATH_TMP # define _PATH_TMP "/tmp/" #endif #include "syslinux.h" #if DO_DIRECT_MOUNT # include #endif const char *program; /* Name of program */ const char *device; /* Device to install to */ pid_t mypid; char *mntpath = NULL; /* Path on which to mount */ off_t filesystem_offset = 0; /* Filesystem offset */ #if DO_DIRECT_MOUNT int loop_fd = -1; /* Loop device */ #endif void __attribute__((noreturn)) usage(void) { fprintf(stderr, "Usage: %s [-sfr][-d directory][-o offset] device\n", program); exit(1); } void __attribute__((noreturn)) die(const char *msg) { fprintf(stderr, "%s: %s\n", program, msg); #if DO_DIRECT_MOUNT if ( loop_fd != -1 ) { ioctl(loop_fd, LOOP_CLR_FD, 0); /* Free loop device */ close(loop_fd); loop_fd = -1; } #endif if ( mntpath ) unlink(mntpath); exit(1); } /* * read/write wrapper functions */ ssize_t xpread(int fd, void *buf, size_t count, off_t offset) { char *bufp = (char *)buf; ssize_t rv; ssize_t done = 0; while ( count ) { rv = pread(fd, bufp, count, offset); if ( rv == 0 ) { die("short read"); } else if ( rv == -1 ) { if ( errno == EINTR ) { continue; } else { die(strerror(errno)); } } else { bufp += rv; offset += rv; done += rv; count -= rv; } } return done; } ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset) { const char *bufp = (const char *)buf; ssize_t rv; ssize_t done = 0; while ( count ) { rv = pwrite(fd, bufp, count, offset); if ( rv == 0 ) { die("short write"); } else if ( rv == -1 ) { if ( errno == EINTR ) { continue; } else { die(strerror(errno)); } } else { bufp += rv; offset += rv; done += rv; count -= rv; } } return done; } /* * Create a block map for ldlinux.sys */ int make_block_map(uint32_t *sectors, int len, int dev_fd, int fd) { int nsectors = 0; int blocksize, nblock, block; int i; (void)dev_fd; if (ioctl(fd, FIGETBSZ, &blocksize) < 0) die("ioctl FIGETBSZ failed"); blocksize >>= SECTOR_BITS; /* sectors/block */ nblock = 0; while (len > 0) { block = nblock++; if (ioctl(fd, FIBMAP, &block) < 0) die("ioctl FIBMAP failed"); for (i = 0; i < blocksize; i++) { if (len <= 0) break; *sectors++ = (block*blocksize)+i; nsectors++; len -= (1 << SECTOR_BITS); } } return nsectors; } /* * Mount routine */ int do_mount(int dev_fd, int *cookie, const char *mntpath, const char *fstype) { struct stat st; (void)cookie; if (fstat(dev_fd, &st) < 0) return errno; #if DO_DIRECT_MOUNT { if ( !S_ISBLK(st.st_mode) ) { /* It's file, need to mount it loopback */ unsigned int n = 0; struct loop_info64 loopinfo; int loop_fd; for ( n = 0 ; loop_fd < 0 ; n++ ) { snprintf(devfdname, sizeof devfdname, "/dev/loop%u", n); loop_fd = open(devfdname, O_RDWR); if ( loop_fd < 0 && errno == ENOENT ) { die("no available loopback device!"); } if ( ioctl(loop_fd, LOOP_SET_FD, (void *)dev_fd) ) { close(loop_fd); loop_fd = -1; if ( errno != EBUSY ) die("cannot set up loopback device"); else continue; } if ( ioctl(loop_fd, LOOP_GET_STATUS64, &loopinfo) || (loopinfo.lo_offset = filesystem_offset, ioctl(loop_fd, LOOP_SET_STATUS64, &loopinfo)) ) die("cannot set up loopback device"); } *cookie = loop_fd; } else { snprintf(devfdname, sizeof devfdname, "/proc/%lu/fd/%d", (unsigned long)mypid, dev_fd); *cookie = -1; } return mount(devfdname, mntpath, fstype, MS_NOEXEC|MS_NOSUID, "umask=077,quiet"); } #else { char devfdname[128], mnt_opts[128]; pid_t f, w; int status; snprintf(devfdname, sizeof devfdname, "/proc/%lu/fd/%d", (unsigned long)mypid, dev_fd); f = fork(); if ( f < 0 ) { return -1; } else if ( f == 0 ) { if ( !S_ISBLK(st.st_mode) ) { snprintf(mnt_opts, sizeof mnt_opts, "rw,nodev,noexec,loop,offset=%llu,umask=077,quiet", (unsigned long long)filesystem_offset); } else { snprintf(mnt_opts, sizeof mnt_opts, "rw,nodev,noexec,umask=077,quiet"); } execl(_PATH_MOUNT, _PATH_MOUNT, "-t", fstype, "-o", mnt_opts, \ devfdname, mntpath, NULL); _exit(255); /* execl failed */ } w = waitpid(f, &status, 0); return ( w != f || status ) ? -1 : 0; } #endif } /* * umount routine */ void do_umount(const char *mntpath, int cookie) { #if DO_DIRECT_MOUNT int loop_fd = cookie; if ( umount2(mntpath, 0) ) die("could not umount path"); if ( loop_fd != -1 ) { ioctl(loop_fd, LOOP_CLR_FD, 0); /* Free loop device */ close(loop_fd); loop_fd = -1; } #else pid_t f = fork(); pid_t w; int status; (void)cookie; if ( f < 0 ) { perror("fork"); exit(1); } else if ( f == 0 ) { execl(_PATH_UMOUNT, _PATH_UMOUNT, mntpath, NULL); } w = waitpid(f, &status, 0); if ( w != f || status ) { exit(1); } #endif } int main(int argc, char *argv[]) { static unsigned char sectbuf[SECTOR_SIZE]; unsigned char *dp; const unsigned char *cdp; int dev_fd, fd; struct stat st; int nb, left; int err = 0; char mntname[128]; char *ldlinux_name, **argp, *opt; const char *subdir = NULL; uint32_t sectors[65]; /* 65 is maximum possible */ int nsectors = 0; const char *errmsg; int mnt_cookie; int force = 0; /* -f (force) option */ int stupid = 0; /* -s (stupid) option */ int raid_mode = 0; /* -r (RAID) option */ (void)argc; /* Unused */ program = argv[0]; mypid = getpid(); device = NULL; umask(077); for ( argp = argv+1 ; *argp ; argp++ ) { if ( **argp == '-' ) { opt = *argp + 1; if ( !*opt ) usage(); while ( *opt ) { if ( *opt == 's' ) { stupid = 1; } else if ( *opt == 'r' ) { raid_mode = 1; } else if ( *opt == 'f' ) { force = 1; /* Force install */ } else if ( *opt == 'd' && argp[1] ) { subdir = *++argp; } else if ( *opt == 'o' && argp[1] ) { /* Byte offset */ filesystem_offset = (off_t)strtoull(*++argp, NULL, 0); } else { usage(); } opt++; } } else { if ( device ) usage(); device = *argp; } } if ( !device ) usage(); /* * First make sure we can open the device at all, and that we have * read/write permission. */ dev_fd = open(device, O_RDWR); if ( dev_fd < 0 || fstat(dev_fd, &st) < 0 ) { perror(device); exit(1); } if ( !S_ISBLK(st.st_mode) && !S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode) ) { die("not a device or regular file"); } if ( filesystem_offset && S_ISBLK(st.st_mode) ) { die("can't combine an offset with a block device"); } xpread(dev_fd, sectbuf, SECTOR_SIZE, filesystem_offset); fsync(dev_fd); /* * Check to see that what we got was indeed an MS-DOS boot sector/superblock */ if( (errmsg = syslinux_check_bootsect(sectbuf)) ) { fprintf(stderr, "%s: %s\n", device, errmsg); exit(1); } /* * Now mount the device. */ if ( geteuid() ) { die("This program needs root privilege"); } else { int i = 0; struct stat dst; int rv; /* We're root or at least setuid. Make a temp dir and pass all the gunky options to mount. */ if ( chdir(_PATH_TMP) ) { perror(program); exit(1); } #define TMP_MODE (S_IXUSR|S_IWUSR|S_IXGRP|S_IWGRP|S_IWOTH|S_IXOTH|S_ISVTX) if ( stat(".", &dst) || !S_ISDIR(dst.st_mode) || (dst.st_mode & TMP_MODE) != TMP_MODE ) { die("possibly unsafe " _PATH_TMP " permissions"); } for ( i = 0 ; ; i++ ) { snprintf(mntname, sizeof mntname, "syslinux.mnt.%lu.%d", (unsigned long)mypid, i); if ( lstat(mntname, &dst) != -1 || errno != ENOENT ) continue; rv = mkdir(mntname, 0000); if ( rv == -1 ) { if ( errno == EEXIST || errno == EINTR ) continue; perror(program); exit(1); } if ( lstat(mntname, &dst) || dst.st_mode != (S_IFDIR|0000) || dst.st_uid != 0 ) { die("someone is trying to symlink race us!"); } break; /* OK, got something... */ } mntpath = mntname; } if (do_mount(dev_fd, &mnt_cookie, mntpath, "vfat") && do_mount(dev_fd, &mnt_cookie, mntpath, "msdos")) { rmdir(mntpath); die("mount failed"); } ldlinux_name = alloca(strlen(mntpath)+14+ (subdir ? strlen(subdir)+2 : 0)); if ( !ldlinux_name ) { perror(program); err = 1; goto umount; } sprintf(ldlinux_name, "%s%s%s//ldlinux.sys", mntpath, subdir ? "//" : "", subdir ? subdir : ""); if ((fd = open(ldlinux_name, O_RDONLY)) >= 0) { uint32_t zero_attr = 0; ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &zero_attr); close(fd); } unlink(ldlinux_name); fd = open(ldlinux_name, O_WRONLY|O_CREAT|O_TRUNC, 0444); if ( fd < 0 ) { perror(device); err = 1; goto umount; } cdp = syslinux_ldlinux; left = syslinux_ldlinux_len; while ( left ) { nb = write(fd, cdp, left); if ( nb == -1 && errno == EINTR ) continue; else if ( nb <= 0 ) { perror(device); err = 1; goto umount; } dp += nb; left -= nb; } fsync(fd); /* * Set the attributes */ { uint32_t attr = 0x07; /* Hidden+System+Readonly */ ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr); } /* * Create a block map. */ nsectors = make_block_map(sectors, syslinux_ldlinux_len, dev_fd, fd); close(fd); sync(); umount: do_umount(mntpath, mnt_cookie); sync(); rmdir(mntpath); if ( err ) exit(err); /* * Patch ldlinux.sys and the boot sector */ syslinux_patch(sectors, nsectors, stupid, raid_mode); /* * Write the now-patched first sector of ldlinux.sys */ xpwrite(dev_fd, syslinux_ldlinux, SECTOR_SIZE, filesystem_offset+((off_t)sectors[0] << SECTOR_BITS)); /* * To finish up, write the boot sector */ /* Read the superblock again since it might have changed while mounted */ xpread(dev_fd, sectbuf, SECTOR_SIZE, filesystem_offset); /* Copy the syslinux code into the boot sector */ syslinux_make_bootsect(sectbuf); /* Write new boot sector */ xpwrite(dev_fd, sectbuf, SECTOR_SIZE, filesystem_offset); close(dev_fd); sync(); /* Done! */ return 0; } syslinux-legacy-3.63+dfsg/unix/syslinux0000775000175000017500000005406010777447314017024 0ustar evanevanELF4S4 (444444\\ 0L3 HHHDDPtdTTT<<Qtd/lib/ld-linux.so.2GNU GNUyDS/̗͊j%&#%$ "  ! $ "$K9r/4\6J= Q1DzkC)YV7F&D?Po'C9zc9o$9>D;W__gmon_start__libc.so.6_IO_stdin_usedexeclsprintfperrorforkunlinkmkdirfsync_exitgetpidpread64memset__errno_locationrmdirchdiropen64memcmpmemcpyumaskstderrioctlstrtoullgeteuidwaitpidclosefprintfpwrite64strerror__libc_start_mainwritesnprintf__xstat64__fxstat64__lxstat64GLIBC_2.2GLIBC_2.1GLIBC_2.0ii 1ii ;ii E%     $ (,048<@DHLPTX\`dhlp t!x"|#Uq5%%h%h%h%h%h %h(% h0%h8p%h@`%hHP%hP@% hX0%$h` %(hh%,hp%0hx%4h%8h%<h%@h%Dh%Hh%Lh%Php%Th`%XhP%\h@%`h0%dh %hh%lh%ph%th%xh%|h1^PTRhhQVhoUS[tX[ÐUS=u? -X9v&9w[]Ít&'Utt $ÐU 5Hh5$Uu5Hh›5e t P jUWVS uE] Pjuy hʛ5} 1ELPEPju}Gcx1' hW~!EEBE9|߅Ee[^_]US} hY6ujuhhRjEPS"9u}t j]US|]EPS y s S5DhhPL $E%=`t$ 5,5(hhP RhFhP juPPhfuhihlhl$hPjEPS 9u1}t]UWVS E }]uEES VSWuu! u hwu4t Pd$HE)MuEe[^_]UWVS E }]uEES VSWuuN u hut P$E)MuEe[^_]ÍL$qUWVSQhYHt @Dj?kDžDžDž:-uvBusfSUfFCRhjP1҃ MD B9uN1>F+@;E|1e[^_]ÐUWV0U Eu}U܋M܉EEEE׉ƋU؉E܅UEu$9wQEƋEt&;}v;11&MЋMEԋEЋUԅt؃ڃ0^_]ÉЋU1fǃE +EME׋U NjEMMM ЋUEỦ9Ủr;Utm1dt&؃U]؃U]E&9}w 9u11EM9vO1U]Ít&'UWVS^E)E}Ut+1ƍED$E D$E$9}u߃[^_]Ë$ÐUS E Y$D$ED$T []ÐUS E $D$ED$t []ÐUS E j$D$ED$T []ÐUSt Ћu[]US[tpY[Usage: %s [-sfr][-d directory][-o offset] device %s: %s ioctl FIGETBSZ failedioctl FIBMAP failedfork/bin/umount/proc/%lu/fd/%drw,nodev,noexec,loop,offset=%llu,umask=077,quietrw,nodev,noexec,umask=077,quiet-o-t/bin/mountshort writeshort readnot a device or regular filecan't combine an offset with a block deviceThis program needs root privilege/tmp/.possibly unsafe /tmp/ permissionssyslinux.mnt.%lu.%dsomeone is trying to symlink race us!vfatmsdosmount failed//%s%s%s//ldlinux.sysFAT12 more than 4084 clusters but claims FAT12FAT16 less than 4084 clusters but claims FAT16FAT FAT32 only 512-byte sectors are supportedthis doesn't look like a valid FAT filesystem;8Tt,lzR| AB E<0AB X$iAB Cxt2AB D2AB D2AB D H hoD O 0 ooovƈֈ&6FVfvƉ։&6FVfvfilesystem type "????????" not supportedXSYSLINUX1м{W{ػx7V1, x?Gd|M'EufEf|r uB|?|UA1,rUu t}f}~f>$~JLLy:f|f1OUffRfPSWjf`1,Bfadr]f) !uf`11,fa}O]fRfPUSf6|f>|f1ɇfk)9vAň֊1,f`farf []fXfZf)uMuޕ.}u1ּ{fx} t ;.}v.}Boot error ᆳNG SYSLINUX 3.63 2008-04-10 >JLLy5~c>}u68.O0~*~!1ffEIt fBf9u8 ݾ~(~fMfff!t; t f`Gfa Load error - CBIOSEBIOS9f1 |+Nf0ff+!uf |f$,f+f,f+!uf$|f+ff,f,f+f ,ff,f+Ȉ2,Q 3,YHf,,@f f(,f$,f+,ff=r$Sf=r2,f,|fff,f,vP.u=s 8(fT8,f1ff}u ut fx.ft.B11r\ L>t+u P.[">v+kQ.tfh+fH.fd+fD.3f&D. <t;< rwtQ.uJsԪ< <t-<t<<t<utOrjdQ.0&Q.<0rt <9vr+WD@_1۠R.&>x+t[VW0Ǿȿl+>r+_^R.0;uO>L.SR[f6L.fD,v݋p+!uW^p? ؿVWQQW_[tۍE1Y_^ 6lu(X;ltfD.tfH.uYпn+YË6@.f<.>.`M>aWP0@uOfMX_>R.f f.comf.cbtf.c32 f.bss f.binx ff.bsi f.0] `Ia{v!u=PRVh0fff f\.ff f`. f@f;`.vf`.f)`.1^ &>UVf.1fT.>r+  6N.1l. t~< vNff=vga=t/f=mem=tVu< v.6l.1.l.< wN뼃fDf==nortKf==exttKf==asktyrωɃkr.fT.6h.fX.7&f>HdrS&n.==r&$&=r &f,fX.&1f1&f&p.&!uj.?9fT.f-f;\.xf6j.F ff)fQff詢( fY^f\.f-v1һf>d.0>l.t# 0n.p.tr df(d ?d>"rd$v df( h.9vd󤪁r&>p.u?11df>j.G@) f1ff\.ff觡&>u&.6x.>e.x.z= ÎێӼ߃ Sj19l.t p.n.P0.6l.< wN1VPN.;6l.t<,uFV ^X_.;6l.wȎ؎/ >俑d f0fQfT.fJfX.f9vffBf)ʁf;d.r\&f>t &ff)&f&fffJfX.V^fXzþ?p`þs!u=sV_01@f1f& &} & t ,&^ ؎1j0h=\f3fXfEfff`͎ݎʼn :FЉF,fah=1[1؎м{s enÊFfÊF JÎF&v&<$tHÀ>u ȈFfFSYfFSLfFINfFUXÀ>u u&Fàf`͎ݎʼnr1FF?F1N^$F~F9Î^$vÎ^$v*hyh_^$vAtFVFvÎF$^vNs1vËvF1F 1,FN"F{N$F{á~+F.F.&.`+ùFf{fx11fFffFff|ff(fvfV^&N$FFÁ~Uw/NQg If$vWdffFf(fvfV^&ÌN$FFÊF<wR.^&vw6@.<.>.^$v10؎1&E >r+N.Fw,NV@Buà t ^$F.Ffvf vufFF$^ngÁ~UwFNQg If$vWdff&vf( @dfEf)}f(+1tÁ~UwXPNQg If$vWdff&v(d؀Eꐐfdfdff((Ì^$FFVRPe0r+A)dffX^1һfٍȎ؉& "ul)(2 "껍 1а(؎а0؋%(g&.f1 1QY`Ɇ(OhfhhhhhjŁf%(1P؎Ў8 $"oȎ؎& hfRffaf.&,.&,ff`f<.&,.f$f1ۋf]aϜ`D$(`D$(g> g"6fg> ߋt$,1ɱ 󥫸G% Gffg6 g"|$0!u1ɱ g 6aÜ`L$0g> g"fg>,)σfg> ߋD$(t$,fag$06N.>r+O>r+0,0,Offf>fW1һ! ff>f|ff(f0,f |f f1f1f{fx1,{W1^1jh3x1؎{W_&fU&fu &]{{&E&][Xf71t `U<t<taþ>=Ȑ1؎м{p+!hf`11faQ8,@f?tYSu8Qe<t"eD uQVW|. e_^Yt sY[f1efDff fG2,eTfeTfff,fefDeT !Y[!tfft.=/uf,GfP< v}t   WS1?< v<\u/8t 0,,tf@&Qf׊2,ffr fffgYfZf_f, t$Sn@rn7GW1GG @[J1[SVW>n] !u0ƃmru&Fu_^[KA ] f`@]5fMg&fvfMf)M A5fa뤉Mfa0SVn7n^[WS>n] A C] [_Yr <t < t < v8ÿ0?sW6_r<-s0fPfQUf1ff1<-u<0rSt<9wM <0r% b .@:.w%.>b.ø1.þp.t..@:.w.1ɋ.6.>b+믾s.t1ɉ..>.r/.t..r.t..9!..1< t< v>~sG>~76~t`>b.a$..t+ff`~+!tP&.W tB 8uXPfaf.t tf`u~+!ttB&. 8faôu"~+!tWtB&. 8u0ôbfafP Xff` tfafaf1Ī`++)fv 󤿈0ŪfNf.ÿEÿЉ>n+ÿ؉>p+À>+wȉ>l+ÿu >-u1>À>+t DP^rf*fffP^rPbQ8uXPQQuX|+rSgs[Lv.r)fSPr7as1ۀ>.߁.f[f%_fKrfff.Pw狽>~+U$XBBB<u:JJ0Bt~9~+Pk_B1V+@󤾈ȿl+/!&#r ff%f=ENDTuff%f=EXTuÿW^ÿ1s|+uǹ)1f>. f>.þh"QfSfR1f1fOfg[fOgI8t1Cgy؀rg(ufGCf8u sCIbs ~fOg fgfOg'NfZf[Yh|覍W1fNg,s fNgs ~fNgـfNgY)tUr<#tQ ffShf[r@< v f0t*rȦ*ff9tfϥ ]< tr!tYSfPf=vffPff fW1f_fYfQfWt &gfAfVf蟌f^f_fYfXff)[uP.X 4J=6ui<wb>rY wT>.f,tt@.>0,t1ɈBH.!@H.ù1Ҹ0۸` u.̈&.aVu8Drtf>D=uiL1۹JH1:.r.Ȉƴ1J|QWf1f_WH^Nj>|罀^|PY148tIu1$tQوY)w Ãt.$úB`ˬՇwav,<t@t O1w%,f@Eb+1f`Ȏ؎, ttO,b+faf`_f` >,u faf`fNfNf1f!txf fPAMSf1ɱNsf!u[pf=PAMSuhf>NwfNf>Ntf=rf;NsfNf;NwfNrf>Ntff;NvfN~fNf;NvfNf=w8r=8O>8t9t,1t%f/-Zffgff1}ffd(fÿfVff=/-Zuf1ҹ~fffguff=d(^P18t tƁr =v1XPVW uYQ18t t#Ɓr|Wƹ)r%^^NY΁sވЪȪd)1_^Xf`}f1fffgf)Ѝ|fDffaf>0tf>4t>8t PXPXÈ&Rf`8 Ҵr uBR?RUA8;r f0 f4faf1VfRfPSjjf`8@ &Rfadr^^fRfPUf6Rf>Rf1ɇff=w'Aň֊8&Rf`far]fXfZMuIt appears your computer has less than 256K of low ("DOS") RAM. Linux needs at least this amount to boot. If you get this message in error, hold down the Ctrl key while booting, and I will take your word for it. boot:  Invalid image type for this media type! Could not find kernel image: Invalid or corrupt kernel image. !׏ޏ׏ʈT| Loading ..ready. Cannot load a ramdisk with an old kernel image. Could not find ramdisk image: Not enough memory to load specified kernel. BOOT_IMAGE=3ʼn͉Չ ډ 0L3kmيk?O~kkkkƋՋ>bxF%: attempted DOS system call COMBOOT image too large.  aborted. AAEEEIIIOOUUYAIOU@ linux autoOut of memory parsing config file Unknown keyword in configuration file. Missing parameter in configuration file. A20 gate not responding!   Copyright (C) 1994-2008 H. Peter Anvin Boot failed: please change disks and press a key to continue. /boot/syslinux/syslinux.cfginitrd=7t;eT9ۘYQ@ T2Cx+9PC̴h60eNR2GCt:t+9YwLhj1`+92d+"Qh+"^h̘Hz+9 v+9 : : : H: : : : H: :: ::H:.cbt.bss.bs.com.c32 ?(g\(f`h) fafffPfUf.)f1ff .f )f.( "b)8аذ01V ] $")ff]fXftCf9r$fgfgfgtfg|fffgfffgff1΃fgfgf`.(..Z+.P+.Z+du_.Z+$RuMouF.Z+d^`WQ1/u)Y.Z+ $Q1uY.(u-fYfaQP .(@.(e&;(XY0t uLdtC`u8!tf?fwfOft) Hufaf..(ffQfXf1f f.)f.( "6+ 1а0ذ(؎Ўf**(*:*`*,NGGCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-32).shstrtab.interp.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data.bss.comment 44HH !hh$844o$> `FDDONoL[o@j   s 00 |HHw``@ hhTT<      !p/ PL PRsyslinux-legacy-3.63+dfsg/unix/syslinux-nomtools0000775000175000017500000000000010777447314030126 1syslinux-legacy-3.63+dfsg/unix/syslinuxustar evanevansyslinux-legacy-3.63+dfsg/cache.inc0000664000175000017500000000527010777447271015754 0ustar evanevan; -*- fundamental -*- --------------------------------------------------- ; ; Copyright 2004-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Boston MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; ----------------------------------------------------------------------- section .text struc cptr .sector: resd 1 ; Sector number .prev: resw 1 ; LRU pointer to previous (less recent) .next: resw 1 ; LRU pointer to next (more recent) endstruc cptr_size_lg2 equ 3 NCacheEntries equ 65536/SECTOR_SIZE ; ; initcache: Initialize the cache data structures ; initcache: xor eax,eax ; We don't care about sector 0 mov di,CachePtrs mov cx,NCacheEntries+1 mov bx,CachePtrs+NCacheEntries*cptr_size ; "prev" pointer .loop: mov [di+cptr.sector],eax ; Zero sector number mov [di+cptr.prev],bx ; Previous pointer mov [bx+cptr.next],di ; Previous entry's next pointer mov bx,di add di,cptr_size loop .loop ret ; ; getcachesector: Check for a particular sector (EAX) in the sector cache, ; and if it is already there, return a pointer in GS:SI ; otherwise load it and return said pointer. ; ; Assumes CS == DS. ; getcachesector: push cx push bx push di mov si,cache_seg mov gs,si mov si,CachePtrs+cptr_size ; Real sector cache pointers mov cx,NCacheEntries .search: cmp eax,[si] jz .hit add si,cptr_size loop .search .miss: TRACER 'M' ; Need to load it. push es push gs pop es mov bx,[CachePtrs+cptr.next] ; "Next most recent than head node" mov [bx+cptr.sector],eax mov si,bx sub bx,CachePtrs+cptr_size shl bx,SECTOR_SHIFT-cptr_size_lg2 ; Buffer address pushad %if IS_EXTLINUX call getonesec_ext %else call getonesec %endif popad pop es .hit: ; Update LRU, then compute buffer address TRACER 'H' ; Remove from current position in the list mov bx,[si+cptr.prev] mov di,[si+cptr.next] mov [bx+cptr.next],di mov [di+cptr.prev],bx ; Add to just before head node mov bx,[CachePtrs+cptr.prev] mov [si+cptr.prev],bx mov [bx+cptr.next],si mov [CachePtrs+cptr.prev],si mov word [si+cptr.next],CachePtrs sub si,CachePtrs+cptr_size shl si,SECTOR_SHIFT-cptr_size_lg2 ; Buffer address pop di pop bx pop cx ret section .bss ; Each CachePtr contains: ; - Block pointer ; - LRU previous pointer ; - LRU next pointer ; The first entry is the head node of the list alignb 4 CachePtrs resb (NCacheEntries+1)*cptr_size syslinux-legacy-3.63+dfsg/README0000664000175000017500000000257710777447271015105 0ustar evanevanSee the files in the doc directory for documentation about SYSLINUX: syslinux.txt - Usage instructions; manual. distrib.txt - For creators of Linux distributions. pxelinux.txt - Documentation specific to PXELINUX. isolinux.txt - Documentation specific to ISOLINUX. extlinux.txt - Documentation specific to EXTLINUX. menu.txt - About the menu systems. usbkey.txt - About using SYSLINUX on USB keys. comboot.txt - About the extension API. memdisk.txt - Documentation about MEMDISK. Also see the files: NEWS - List of changes from previous releases. TODO - About features planned for future releases. COPYING - For the license terms of this software. SYSLINUX now builds in a Linux environment, using nasm. You need nasm version 0.98.39 or later to build SYSLINUX from source. See http://nasm.sf.net/ for information about nasm. There is now a mailing list for SYSLINUX. See the end of syslinux.txt for details. SYSLINUX is: Copyright 1994-2008 H. Peter Anvin - All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, Inc., 53 Temple Place Ste 330, Boston MA 02111-1307, USA; either version 2 of the License, or (at your option) any later version; incorporated herein by reference. syslinux-legacy-3.63+dfsg/runkernel.inc0000664000175000017500000004435510777447273016727 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; runkernel.inc ;; ;; Common code for running a Linux kernel ;; ; ; Hook macros, that may or may not be defined ; %ifndef HAVE_SPECIAL_APPEND %macro SPECIAL_APPEND 0 %endmacro %endif %ifndef HAVE_UNLOAD_PREP %macro UNLOAD_PREP 0 %endmacro %endif ; ; A Linux kernel consists of three parts: boot sector, setup code, and ; kernel code. The boot sector is never executed when using an external ; booting utility, but it contains some status bytes that are necessary. ; ; First check that our kernel is at least 1K, or else it isn't long ; enough to have the appropriate headers. ; ; We used to require the kernel to be 64K or larger, but it has gotten ; popular to use the Linux kernel format for other things, which may ; not be so large. ; ; Additionally, we used to have a test for 8 MB or smaller. Equally ; obsolete. ; is_linux_kernel: and dx,dx jnz kernel_sane cmp ax,1024 ; Bootsect + 1 setup sect jb kernel_corrupt kernel_sane: push ax push dx push si mov si,loading_msg call cwritestr ; ; Now start transferring the kernel ; push word real_mode_seg pop es movzx eax,ax ; Fix this by using a 32-bit shl edx,16 ; register for the kernel size or eax,edx mov [KernelSize],eax add eax,SECTOR_SIZE-1 shr eax,SECTOR_SHIFT mov [KernelSects],eax ; Total sectors in kernel ; ; Now, if we transfer these straight, we'll hit 64K boundaries. Hence we ; have to see if we're loading more than 64K, and if so, load it step by ; step. ; ; ; Start by loading the bootsector/setup code, to see if we need to ; do something funky. It should fit in the first 32K (loading 64K won't ; work since we might have funny stuff up near the end of memory). ; If we have larger than 32K clusters, yes, we're hosed. ; call abort_check ; Check for abort key mov ecx,8000h >> SECTOR_SHIFT ; Half a moby (32K) cmp ecx,[KernelSects] jna .normalkernel mov ecx,[KernelSects] .normalkernel: sub [KernelSects],ecx xor bx,bx pop si ; Cluster pointer on stack call getfssec cmp word [es:bs_bootsign],0AA55h jne kernel_corrupt ; Boot sec signature missing ; ; Save the cluster pointer for later... ; push si ; ; Initialize our end of memory pointer ; mov eax,[HighMemRsvd] xor ax,ax ; Align to a 64K boundary mov [MyHighMemSize],eax ; ; Construct the command line (append options have already been copied) ; construct_cmdline: mov di,[CmdLinePtr] mov si,boot_image ; BOOT_IMAGE= mov cx,boot_image_len rep movsb mov si,KernelCName ; Unmangled kernel name mov cx,[KernelCNameLen] rep movsb mov al,' ' ; Space stosb SPECIAL_APPEND ; Module-specific hook mov si,[CmdOptPtr] ; Options from user input call strcpy ; ; Scan through the command line for anything that looks like we might be ; interested in. The original version of this code automatically assumed ; the first option was BOOT_IMAGE=, but that is no longer certain. ; mov si,cmd_line_here xor ax,ax mov [InitRDPtr],ax ; No initrd= option (yet) push es ; Set DS <- real_mode_seg pop ds get_next_opt: lodsb and al,al jz cmdline_end cmp al,' ' jbe get_next_opt dec si mov eax,[si] cmp eax,'vga=' je is_vga_cmd cmp eax,'mem=' je is_mem_cmd %if IS_PXELINUX cmp eax,'keep' ; Is it "keeppxe"? jne .notkeep cmp dword [si+3],'ppxe' jne .notkeep cmp byte [si+7],' ' ; Must be whitespace or EOS ja .notkeep or byte [cs:KeepPXE],1 .notkeep: %endif push es ; Save ES -> real_mode_seg push cs pop es ; Set ES <- normal DS mov di,initrd_cmd mov cx,initrd_cmd_len repe cmpsb jne .not_initrd cmp al,' ' jbe .noramdisk mov [cs:InitRDPtr],si jmp .not_initrd .noramdisk: xor ax,ax mov [cs:InitRDPtr],ax .not_initrd: pop es ; Restore ES -> real_mode_seg skip_this_opt: lodsb ; Load from command line cmp al,' ' ja skip_this_opt dec si jmp short get_next_opt is_vga_cmd: add si,4 mov eax,[si-1] mov bx,-1 cmp eax,'=nor' ; vga=normal je vc0 dec bx ; bx <- -2 cmp eax,'=ext' ; vga=ext je vc0 dec bx ; bx <- -3 cmp eax,'=ask' ; vga=ask je vc0 call parseint ; vga= jc skip_this_opt ; Not an integer vc0: mov [bs_vidmode],bx ; Set video mode jmp short skip_this_opt is_mem_cmd: add si,4 call parseint jc skip_this_opt ; Not an integer %if HIGHMEM_SLOP != 0 sub ebx,HIGHMEM_SLOP %endif mov [cs:MyHighMemSize],ebx jmp short skip_this_opt cmdline_end: push cs ; Restore standard DS pop ds sub si,cmd_line_here mov [CmdLineLen],si ; Length including final null ; ; Now check if we have a large kernel, which needs to be loaded high ; prepare_header: mov dword [RamdiskMax], HIGHMEM_MAX ; Default initrd limit cmp dword [es:su_header],HEADER_ID ; New setup code ID jne old_kernel ; Old kernel, load low mov ax,[es:su_version] mov [KernelVersion],ax cmp ax,0200h ; Setup code version 2.0 jb old_kernel ; Old kernel, load low cmp ax,0201h ; Version 2.01+? jb new_kernel ; If 2.00, skip this step ; Set up the heap (assuming loading high for now) mov word [es:su_heapend],linux_stack-512 or byte [es:su_loadflags],80h ; Let the kernel know we care cmp ax,0203h ; Version 2.03+? jb new_kernel ; Not 2.03+ mov eax,[es:su_ramdisk_max] mov [RamdiskMax],eax ; Set the ramdisk limit ; ; We definitely have a new-style kernel. Let the kernel know who we are, ; and that we are clueful ; new_kernel: mov byte [es:su_loader],my_id ; Show some ID xor eax,eax mov [es:su_ramdisklen],eax ; No initrd loaded yet ; ; About to load the kernel. This is a modern kernel, so use the boot flags ; we were provided. ; mov al,[es:su_loadflags] mov [LoadFlags],al ; ; Load the kernel. We always load it at 100000h even if we're supposed to ; load it "low"; for a "low" load we copy it down to low memory right before ; jumping to it. ; read_kernel: movzx ax,byte [es:bs_setupsecs] ; Setup sectors and ax,ax jnz .sects_ok mov al,4 ; 0 = 4 setup sectors .sects_ok: mov [SetupSecs],ax mov si,KernelCName ; Print kernel name part of call cwritestr ; "Loading" message mov si,dotdot_msg ; Print dots call cwritestr mov eax,[MyHighMemSize] sub eax,100000h ; Load address cmp eax,[KernelSize] jb no_high_mem ; Not enough high memory ; ; Move the stuff beyond the setup code to high memory at 100000h ; movzx esi,word [SetupSecs] ; Setup sectors inc si ; plus 1 boot sector shl si,9 ; Convert to bytes mov ecx,8000h ; 32K sub ecx,esi ; Number of bytes to copy push ecx add esi,(real_mode_seg << 4) ; Pointer to source mov edi,100000h ; Copy to address 100000h call bcopy ; Transfer to high memory ; On exit EDI -> where to load the rest mov si,dot_msg ; Progress report call cwritestr call abort_check pop ecx ; Number of bytes in the initial portion pop si ; Restore file handle/cluster pointer mov eax,[KernelSize] sub eax,8000h ; Amount of kernel not yet loaded jbe high_load_done ; Zero left (tiny kernel) xor dx,dx ; No padding needed mov bx,dot_pause ; Print dots... call load_high ; Copy the file high_load_done: mov [KernelEnd],edi mov ax,real_mode_seg ; Set to real mode seg mov es,ax mov si,dot_msg call cwritestr ; ; Now see if we have an initial RAMdisk; if so, do requisite computation ; We know we have a new kernel; the old_kernel code already will have objected ; if we tried to load initrd using an old kernel ; load_initrd: cmp word [InitRDPtr],0 jz nk_noinitrd call parse_load_initrd nk_noinitrd: ; ; Abandon hope, ye that enter here! We do no longer permit aborts. ; call abort_check ; Last chance!! mov si,ready_msg call cwritestr call vgaclearmode ; We can't trust ourselves after this UNLOAD_PREP ; Module-specific hook ; ; Now, if we were supposed to load "low", copy the kernel down to 10000h ; and the real mode stuff to 90000h. We assume that all bzImage kernels are ; capable of starting their setup from a different address. ; mov ax,real_mode_seg mov es,ax mov fs,ax ; ; Copy command line. Unfortunately, the old kernel boot protocol requires ; the command line to exist in the 9xxxxh range even if the rest of the ; setup doesn't. ; setup_command_line: cli ; In case of hooked interrupts mov dx,[KernelVersion] test byte [LoadFlags],LOAD_HIGH jz need_high_cmdline cmp dx,0202h ; Support new cmdline protocol? jb need_high_cmdline ; New cmdline protocol ; Store 32-bit (flat) pointer to command line ; This is the "high" location, since we have bzImage mov dword [fs:su_cmd_line_ptr],(real_mode_seg << 4)+cmd_line_here jmp in_proper_place need_high_cmdline: ; ; Copy command line down to fit in high conventional memory ; -- this happens if we have a zImage kernel or the protocol ; is less than 2.02. ; mov si,cmd_line_here mov di,old_cmd_line_here mov [fs:kern_cmd_magic],word CMD_MAGIC ; Store magic mov [fs:kern_cmd_offset],di ; Store pointer mov word [HeapEnd],old_linux_stack mov ax,255 ; Max cmdline limit cmp dx,0201h jb .adjusted ; Protocol 2.01+ mov word [fs:su_heapend],old_linux_stack-512 jbe .adjusted ; Protocol 2.02+ ; Note that the only reason we would end up here is ; because we have a zImage, so we anticipate the move ; to 90000h already... mov dword [fs:su_cmd_line_ptr],0x90000+old_cmd_line_here mov ax,4095 ; 2.02+ allow a higher limit .adjusted: mov cx,[CmdLineLen] cmp cx,ax jna .len_ok mov cx,ax ; Truncate the command line .len_ok: fs rep movsb stosb ; Final null, note AL=0 already cmp dx,0200h jb .nomovesize mov [es:su_movesize],di ; Tell the kernel what to move .nomovesize: test byte [LoadFlags],LOAD_HIGH jnz in_proper_place ; If high load, we're done ; ; Loading low; we can't assume it's safe to run in place. ; ; Copy real_mode stuff up to 90000h ; mov ax,9000h mov es,ax mov cx,di ; == su_movesize (from above) add cx,3 ; Round up shr cx,2 ; Convert to dwords xor si,si xor di,di fs rep movsd ; Copy setup + boot sector ; ; Some kernels in the 1.2 ballpark but pre-bzImage have more than 4 ; setup sectors, but the boot protocol had not yet been defined. They ; rely on a signature to figure out if they need to copy stuff from ; the "protected mode" kernel area. Unfortunately, we used that area ; as a transfer buffer, so it's going to find the signature there. ; Hence, zero the low 32K beyond the setup area. ; mov di,[SetupSecs] inc di ; Setup + boot sector mov cx,32768/512 ; Sectors/32K sub cx,di ; Remaining sectors shl di,9 ; Sectors -> bytes shl cx,7 ; Sectors -> dwords xor eax,eax rep stosd ; Clear region ; ; Copy the kernel down to the "low" location (the kernel will then ; move itself again, sigh.) ; mov ecx,[KernelSize] mov esi,100000h mov edi,10000h call bcopy ; ; Now everything is where it needs to be... ; ; When we get here, es points to the final segment, either ; 9000h or real_mode_seg ; in_proper_place: ; ; If the default root device is set to FLOPPY (0000h), change to ; /dev/fd0 (0200h) ; cmp word [es:bs_rootdev],byte 0 jne root_not_floppy mov word [es:bs_rootdev],0200h root_not_floppy: ; ; Copy the disk table to high memory, then re-initialize the floppy ; controller ; %if IS_SYSLINUX || IS_MDSLINUX lgs si,[cs:fdctab] mov di,[cs:HeapEnd] mov cx,6 gs rep movsw mov [cs:fdctab],word linux_fdctab ; Save new floppy tab pos mov [cs:fdctab+2],es %endif call cleanup_hardware ; ; If we're debugging, wait for a keypress so we can read any debug messages ; %ifdef debug xor ax,ax int 16h %endif ; ; Set up segment registers and the Linux real-mode stack ; Note: es == the real mode segment ; cli mov bx,es mov ds,bx mov fs,bx mov gs,bx mov ss,bx mov sp,strict word linux_stack ; Point HeapEnd to the immediate of the instruction above HeapEnd equ $-2 ; Self-modifying code! Fun! ; ; We're done... now RUN THAT KERNEL!!!! ; Setup segment == real mode segment + 020h; we need to jump to offset ; zero in the real mode segment. ; add bx,020h push bx push word 0h retf ; ; Load an older kernel. Older kernels always have 4 setup sectors, can't have ; initrd, and are always loaded low. ; old_kernel: xor ax,ax cmp word [InitRDPtr],ax ; Old kernel can't have initrd je .load mov si,err_oldkernel jmp abort_load .load: mov byte [LoadFlags],al ; Always low mov word [KernelVersion],ax ; Version 0.00 jmp read_kernel ; ; parse_load_initrd ; ; Parse an initrd= option and load the initrds. Note that we load ; from the high end of memory first, so we parse this option from ; left to right. ; parse_load_initrd: push es push ds mov ax,real_mode_seg mov ds,ax push cs pop es ; DS == real_mode_seg, ES == CS mov si,[cs:InitRDPtr] .find_end: lodsb cmp al,' ' ja .find_end ; Now SI points to one character beyond the ; byte that ended this option. .get_chunk: dec si ; DS:SI points to a termination byte xor ax,ax xchg al,[si] ; Zero-terminate push si ; Save ending byte address push ax ; Save ending byte .find_start: dec si cmp si,[cs:InitRDPtr] je .got_start cmp byte [si],',' jne .find_start ; It's a comma byte inc si .got_start: push si mov di,InitRD ; Target buffer for mangled name call mangle_name call loadinitrd pop si pop ax pop di mov [di],al ; Restore ending byte cmp si,[cs:InitRDPtr] ja .get_chunk pop ds pop es ret ; ; Load RAM disk into high memory ; ; Input: InitRD - set to the mangled name of the initrd ; loadinitrd: push ds push es mov ax,cs ; CS == DS == ES mov ds,ax mov es,ax mov si,InitRD mov di,InitRDCName call unmangle_name ; Create human-readable name sub di,InitRDCName mov [InitRDCNameLen],di mov di,InitRD call searchdir ; Look for it in directory jz .notthere mov cx,dx shl ecx,16 mov cx,ax ; ECX <- ram disk length mov ax,real_mode_seg mov es,ax push ecx ; Bytes to load mov edx,[MyHighMemSize] ; End of memory dec edx mov eax,[RamdiskMax] ; Highest address allowed by kernel cmp edx,eax jna .memsize_ok mov edx,eax ; Adjust to fit inside limit .memsize_ok: inc edx and dx,0F000h ; Round down to 4K boundary sub edx,ecx ; Subtract size of ramdisk and dx,0F000h ; Round down to 4K boundary cmp edx,[KernelEnd] ; Are we hitting the kernel image? jb no_high_mem cmp dword [es:su_ramdisklen],0 je .highest ; The total length has to include the padding between ; different ramdisk files, so consider "the length" the ; total amount we're about to adjust the base pointer. mov ecx,[es:su_ramdiskat] sub ecx,edx .highest: add [es:su_ramdisklen],ecx mov [es:su_ramdiskat],edx ; Load address mov edi,edx ; initrd load address dec edx ; Note: RamdiskMax is addr-1 mov [RamdiskMax],edx ; Next initrd loaded here push si mov si,crlfloading_msg ; Write "Loading " call cwritestr mov si,InitRDCName ; Write ramdisk name call cwritestr mov si,dotdot_msg ; Write dots call cwritestr pop si pop eax ; Bytes to load mov dx,0FFFh ; Pad to page mov bx,dot_pause ; Print dots... call load_high ; Load the file pop es pop ds ret .notthere: mov si,err_noinitrd call cwritestr mov si,InitRDCName call cwritestr mov si,crlf_msg jmp abort_load no_high_mem: ; Error routine mov si,err_nohighmem jmp abort_load ret section .data crlfloading_msg db CR, LF loading_msg db 'Loading ', 0 dotdot_msg db '.' dot_msg db '.', 0 ready_msg db 'ready.', CR, LF, 0 err_oldkernel db 'Cannot load a ramdisk with an old kernel image.' db CR, LF, 0 err_noinitrd db CR, LF, 'Could not find ramdisk image: ', 0 err_nohighmem db 'Not enough memory to load specified kernel.', CR, LF, 0 boot_image db 'BOOT_IMAGE=' boot_image_len equ $-boot_image section .bss alignb 4 MyHighMemSize resd 1 ; Possibly adjusted highmem size RamdiskMax resd 1 ; Highest address for ramdisk KernelSize resd 1 ; Size of kernel in bytes KernelSects resd 1 ; Size of kernel in sectors KernelEnd resd 1 ; Ending address of the kernel image CmdLineLen resw 1 ; Length of command line including null SetupSecs resw 1 ; Number of setup sectors InitRDPtr resw 1 ; Pointer to initrd= option in command line KernelVersion resw 1 ; Kernel protocol version LoadFlags resb 1 ; Loadflags from kernel syslinux-legacy-3.63+dfsg/init.inc0000664000175000017500000000212510777447273015652 0ustar evanevan; -*- fundamental -*- ; ----------------------------------------------------------------------- ; ; Copyright 2004-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Boston MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; ----------------------------------------------------------------------- ; ; init.inc ; ; Common initialization code (inline) ; section .text common_init: ; Now set up screen parameters call adjust_screen ; ; Initialize configuration information ; call reset_config ; ; Clear Files structures ; mov di,Files mov cx,(MAX_OPEN*open_file_t_size)/4 xor eax,eax rep stosd %if IS_PXELINUX mov di,Files+tftp_pktbuf mov cx,MAX_OPEN .setbufptr: mov [di],ax add di,open_file_t_size add ax,PKTBUF_SIZE loop .setbufptr %endif section .text ; This is an inline file... syslinux-legacy-3.63+dfsg/ldlinux.sys0000664000175000017500000002634510777447305016441 0ustar evanevan SYSLINUX 3.63 2008-04-10 >JLLy5~c>}u68.O0~*~!1ffEIt fBf9u8 ݾ~(~fMfff!t; t f`Gfa Load error - CBIOSEBIOS9f1 |+Nf0ff+!uf |f$,f+f,f+!uf$|f+ff,f,f+f ,ff,f+Ȉ2,Q 3,YHf,,@f f(,f$,f+,ff=r$Sf=r2,f,|fff,f,vP.u=s 8(fT8,f1ff}u ut fx.ft.B11r\ L>t+u P.[">v+kQ.tfh+fH.fd+fD.3f&D. <t;< rwtQ.uJsԪ< <t-<t<<t<utOrjdQ.0&Q.<0rt <9vr+WD@_1۠R.&>x+t[VW0Ǿȿl+>r+_^R.0;uO>L.SR[f6L.fD,v݋p+!uW^p? ؿVWQQW_[tۍE1Y_^ 6lu(X;ltfD.tfH.uYпn+YË6@.f<.>.`M>aWP0@uOfMX_>R.f f.comf.cbtf.c32 f.bss f.binx ff.bsi f.0] `Ia{v!u=PRVh0fff f\.ff f`. f@f;`.vf`.f)`.1^ &>UVf.1fT.>r+  6N.1l. t~< vNff=vga=t/f=mem=tVu< v.6l.1.l.< wN뼃fDf==nortKf==exttKf==asktyrωɃkr.fT.6h.fX.7&f>HdrS&n.==r&$&=r &f,fX.&1f1&f&p.&!uj.?9fT.f-f;\.xf6j.F ff)fQff詢( fY^f\.f-v1һf>d.0>l.t# 0n.p.tr df(d ?d>"rd$v df( h.9vd󤪁r&>p.u?11df>j.G@) f1ff\.ff觡&>u&.6x.>e.x.z= ÎێӼ߃ Sj19l.t p.n.P0.6l.< wN1VPN.;6l.t<,uFV ^X_.;6l.wȎ؎/ >俑d f0fQfT.fJfX.f9vffBf)ʁf;d.r\&f>t &ff)&f&fffJfX.V^fXzþ?p`þs!u=sV_01@f1f& &} & t ,&^ ؎1j0h=\f3fXfEfff`͎ݎʼn :FЉF,fah=1[1؎м{s enÊFfÊF JÎF&v&<$tHÀ>u ȈFfFSYfFSLfFINfFUXÀ>u u&Fàf`͎ݎʼnr1FF?F1N^$F~F9Î^$vÎ^$v*hyh_^$vAtFVFvÎF$^vNs1vËvF1F 1,FN"F{N$F{á~+F.F.&.`+ùFf{fx11fFffFff|ff(fvfV^&N$FFÁ~Uw/NQg If$vWdffFf(fvfV^&ÌN$FFÊF<wR.^&vw6@.<.>.^$v10؎1&E >r+N.Fw,NV@Buà t ^$F.Ffvf vufFF$^ngÁ~UwFNQg If$vWdff&vf( @dfEf)}f(+1tÁ~UwXPNQg If$vWdff&v(d؀Eꐐfdfdff((Ì^$FFVRPe0r+A)dffX^1һfٍȎ؉& "ul)(2 "껍 1а(؎а0؋%(g&.f1 1QY`Ɇ(OhfhhhhhjŁf%(1P؎Ў8 $"oȎ؎& hfRffaf.&,.&,ff`f<.&,.f$f1ۋf]aϜ`D$(`D$(g> g"6fg> ߋt$,1ɱ 󥫸G% Gffg6 g"|$0!u1ɱ g 6aÜ`L$0g> g"fg>,)σfg> ߋD$(t$,fag$06N.>r+O>r+0,0,Offf>fW1һ! ff>f|ff(f0,f |f f1f1f{fx1,{W1^1jh3x1؎{W_&fU&fu &]{{&E&][Xf71t `U<t<taþ>=Ȑ1؎м{p+!hf`11faQ8,@f?tYSu8Qe<t"eD uQVW|. e_^Yt sY[f1efDff fG2,eTfeTfff,fefDeT !Y[!tfft.=/uf,GfP< v}t   WS1?< v<\u/8t 0,,tf@&Qf׊2,ffr fffgYfZf_f, t$Sn@rn7GW1GG @[J1[SVW>n] !u0ƃmru&Fu_^[KA ] f`@]5fMg&fvfMf)M A5fa뤉Mfa0SVn7n^[WS>n] A C] [_Yr <t < t < v8ÿ0?sW6_r<-s0fPfQUf1ff1<-u<0rSt<9wM <0r% b .@:.w%.>b.ø1.þp.t..@:.w.1ɋ.6.>b+믾s.t1ɉ..>.r/.t..r.t..9!..1< t< v>~sG>~76~t`>b.a$..t+ff`~+!tP&.W tB 8uXPfaf.t tf`u~+!ttB&. 8faôu"~+!tWtB&. 8u0ôbfafP Xff` tfafaf1Ī`++)fv 󤿈0ŪfNf.ÿEÿЉ>n+ÿ؉>p+À>+wȉ>l+ÿu >-u1>À>+t DP^rf*fffP^rPbQ8uXPQQuX|+rSgs[Lv.r)fSPr7as1ۀ>.߁.f[f%_fKrfff.Pw狽>~+U$XBBB<u:JJ0Bt~9~+Pk_B1V+@󤾈ȿl+/!&#r ff%f=ENDTuff%f=EXTuÿW^ÿ1s|+uǹ)1f>. f>.þh"QfSfR1f1fOfg[fOgI8t1Cgy؀rg(ufGCf8u sCIbs ~fOg fgfOg'NfZf[Yh|覍W1fNg,s fNgs ~fNgـfNgY)tUr<#tQ ffShf[r@< v f0t*rȦ*ff9tfϥ ]< tr!tYSfPf=vffPff fW1f_fYfQfWt &gfAfVf蟌f^f_fYfXff)[uP.X 4J=6ui<wb>rY wT>.f,tt@.>0,t1ɈBH.!@H.ù1Ҹ0۸` u.̈&.aVu8Drtf>D=uiL1۹JH1:.r.Ȉƴ1J|QWf1f_WH^Nj>|罀^|PY148tIu1$tQوY)w Ãt.$úB`ˬՇwav,<t@t O1w%,f@Eb+1f`Ȏ؎, ttO,b+faf`_f` >,u faf`fNfNf1f!txf fPAMSf1ɱNsf!u[pf=PAMSuhf>NwfNf>Ntf=rf;NsfNf;NwfNrf>Ntff;NvfN~fNf;NvfNf=w8r=8O>8t9t,1t%f/-Zffgff1}ffd(fÿfVff=/-Zuf1ҹ~fffguff=d(^P18t tƁr =v1XPVW uYQ18t t#Ɓr|Wƹ)r%^^NY΁sވЪȪd)1_^Xf`}f1fffgf)Ѝ|fDffaf>0tf>4t>8t PXPXÈ&Rf`8 Ҵr uBR?RUA8;r f0 f4faf1VfRfPSjjf`8@ &Rfadr^^fRfPUf6Rf>Rf1ɇff=w'Aň֊8&Rf`far]fXfZMuIt appears your computer has less than 256K of low ("DOS") RAM. Linux needs at least this amount to boot. If you get this message in error, hold down the Ctrl key while booting, and I will take your word for it. boot:  Invalid image type for this media type! Could not find kernel image: Invalid or corrupt kernel image. !׏ޏ׏ʈT| Loading ..ready. Cannot load a ramdisk with an old kernel image. Could not find ramdisk image: Not enough memory to load specified kernel. BOOT_IMAGE=3ʼn͉Չ ډ 0L3kmيk?O~kkkkƋՋ>bxF%: attempted DOS system call COMBOOT image too large.  aborted. AAEEEIIIOOUUYAIOU@ linux autoOut of memory parsing config file Unknown keyword in configuration file. Missing parameter in configuration file. A20 gate not responding!   Copyright (C) 1994-2008 H. Peter Anvin Boot failed: please change disks and press a key to continue. /boot/syslinux/syslinux.cfginitrd=7t;eT9ۘYQ@ T2Cx+9PC̴h60eNR2GCt:t+9YwLhj1`+92d+"Qh+"^h̘Hz+9 v+9 : : : H: : : : H: :: ::H:.cbt.bss.bs.com.c32 ?(g\(f`h) fafffPfUf.)f1ff .f )f.( "b)8аذ01V ] $")ff]fXftCf9r$fgfgfgtfg|fffgfffgff1΃fgfgf`.(..Z+.P+.Z+du_.Z+$RuMouF.Z+d^`WQ1/u)Y.Z+ $Q1uY.(u-fYfaQP .(@.(e&;(XY0t uLdtC`u8!tf?fwfOft) Hufaf..(ffQfXf1f f.)f.( "6+ 1а0ذ(؎Ўf**(*:*`*syslinux-legacy-3.63+dfsg/pxelinux.00000664000175000017500000003446610777447306016163 0ustar evanevanff`1؎|^0&`.b.& $f& &(!(f1f(  4 ! 1&f?!PXEPVr#=NVu&f?PXENu&V+tYs k 11GZ T &G1j : =rތ&_(&f?!PXE` &fG f1= &G ' V&G" o&G$ &G&f1&fG &;G$w &G$&w&&w"fff 2Ǯ3:'111&fGf;=u&fG*]Vd&G.}MoT&G2z=D&G6]-f1&fG*&f;G2w &fG2&w6&w.ff 2 =&:&;1j2v1Ɉ222d)222AQ?-YMfp.WfЯw Y&^k[.bR2u2fpf0`r>t Э3L2u=s @10/f2u7,-%-u <.t<-t<0r<9v%tW&2 C/-M_:uWW02X%_-uJpu6O,5% u(Ib`?7' a''11'r0(e>1u 2[;>122tf1f2f1f2]f&2 <tA< rwt2uPsԪ|$< <t3<<t<<t<utO"aOd"^20&2<0rt <9v1 Wʹ_ˢ11۠ˢ2>u,>1t[VW0Ǿӿ1>1_^20{uO>2̱S [f62fDܱv݋1!u WP^.` VWQQW_[tۍE1Y_^n. ,!6lu(X;ltf2tf2uY!ۿ1Y Ë62f22` >aWP0uOfMX_>2f f.comf.cbtf.c32d f.bsstUVf31f2>1> 󤾌 1t .1 1t )2 &E 62 12 < vNff=vga=tMf=mem=ttf=keepuf|ppxeu | w.(]u< v.621.2< wN뜃fDf==nortKf==exttKf==asktrωɃrf.f262f27&f>HdrS&2==r&$&=r &f,f2&2f1&f&2&!u2f2f-f;2^f62F ff)fQff赩Q fY^f2f-v1һbf>20'>2t  022tr df(d ?d>"ކrd$v df( 29vd󤪁r&>2u?11df>2G@) f1ff2ff谨&>u&/ ÎێӼ߃ Sj192t22j0.62< wN1VPN.;62t<,uFV ^X_.;62wȎ؎ >  f0fQf2fJf2f9vffBf)ʁf;2r\&f>t &ff)&f&fffJf2VK E?^fX^þ* $.þʫ!u=sV_01@f1f& &} & t ,&^ ؎1j0h\fmfffƈff`͎ݎʼn N:FЉF,fah1[1؎f& V '"eÊFÊFTJÎF&v&<$tÀ>unȈFfFSYfFSLfFINfFUXÀ>uc u&Fàf`͎ݎʼnr1lFF?F2N^$F4F!Î^$v@Î^$vhrhX^$v ^tFVFvÎF$^vN$ s1vËv&Ë^F$~ FF21F1F1F$`.Fb.F"á1F2F2&31ùF()6 11fFffFff|ffh.fvfV^&N$FÌN$FFJÎ^$vfFFÁ~Uw/NQg If$vWdffFfh.fvfV^&KËFN$FFÊF<w2^&v Z76222^$v1gF180؎1H&E >12-FwꬋNV02uZàج t ֬^$F3FÁ~UwFNQg If$vWdff&vfo. @dfEf)}fh.x11>Á~UwX=NQg If$vWdff&vo.d؀Eꐐfdfdffh.o.Ì^$FFVRPe01A)dffX^1һÏWf<Ȏ؉&uie/0/ " 1а(؎а0؋%g&3f1 1QY`,(OhɎhGhhhOhjbf%1곍؎Ў $"ҍȎ؎&6hfRfEfaf.&.&ff`f.&.ff1ۋf]aϜ`D$(`D$(g>g6fg>ߋt$,1ɱ 󥫸G% Gffg6g|$0!u1ɱ g6aÜ`L$0g>gfg>)σfg>ߋD$(!t$,f ag062>1O>1Òfff>fW1һÏff>f|ffh.f1f1(1jh$w1؎(t>`. {W_&fU&fu &][Xfl t ` <t<taþ1؎f& 1!f`11fa1 &`.fa.1f1؎f& K [ t f>12$ < tf,Qfl2 u;ltg.~Y r`Ȏؾw H@=sF 'a &ff!PXEu&rP11&Xulj1ۉ^K  aþį a` H@=sD&ffPXENu&V+u&&r11& uʼn^ þį fa!tSQ؎U2 PV^>ff!u V-\O^ftSfGSSff3pf#xtf|f)^>3HO>F626l^^ >fpf 2!tl;VtĉVNuXX&2v^fDf9 u2 XXDfD D^==u~| t lItiQV޻DQV?O^Yt ^YI^Y_^f1f1Ҭ t,0< w0fk ffIu^^fD ftfff!]]t<]Y[ËvDP3 F[[^XH8/Q( ?t 1YIP&@%&XY`1a1Qf1Ĭ,0r < w <0fuNYWV.ft<t/<::t/F<t#<::u^Vr<::t^V<::uf!u^f1YFFf{< vA1_fPff!tW::OfXÚ7WSV߉ ff t&fQfGf9vf,ȋw)OdwfYf)u^fD f+Du 9DufYfG f;Gtf`fa몌؎2 QDl2QR\&fDf fpfD 2V)^!tlXY9tY&2 ZY>r\d?uD@d9Gt dGAzYDftGDfLL;Lr fDf9D =dG fDfD f`nDfDff3pf#xtf|fl3dfa(Ȏ؎䱀>1s1!t2W1 _)r@2u8ݻ2;v)Cfhfjfff 9s;sþP-X-fh1fPQfP< rÉ1j öЉÊ2ff>tu tftà wr8&2uP:2Xu H22Lÿ,Fu %u %2/ÿ2$-2<ufff12Ñ󤑪f`.fip=fOfp:ft:f|:fx.>1fat$S,0r,7GW1GG @[Q1[SVW>,] !u0ƃmru&Fu_^[KA ] f`0]5fMg&fvfMf)M 5fa뤉Mfa0SV,7,^[WS>,] A C] [_Yr <t < t < v8ÿ /sW6_r<-s fPfQUf1ff1<-u<0rSt<9wM <0r% b 2@:2w%2>b2ø12͛þ.3t22@:2w21ɋ262>1믾13t1ɉ22>3r/3t32r3t32 p!32< t< v>nsG>n6npt`>b2a$33t+ff`1!tP&2W tB 8uXܓfaf3t tf`u1!ttB&3 8faôu"1!tWtB&3 8u0ô1ÿ>1À>1wӉ>1ÿ˃u >-u1>r >1u1È>1t1À>1t P^rf*fffPr^rPh\uXPWK`uX1BrS#s[22r)fS rs1ۀ>3߁2f[f%_fKrfff2Pw狽>1UlXfB`BBY<u:JJ0MBGctc4Q!K1Pq_gʹ1\P1ʹӿˋ11/wg&#r ff%f=ENDTuff%f=EXTuÿW^ÿ1 s1u˿ǹ)1f>3 f>3þ?hdQfSfR1f1fOfg[fOgI8t1Cgy؀rg(ufGCf8u sCIbs ~fOg fgfOg'NfZf[YhW1fNg,s fNgs ~fNgـfNgY)tUr<#tQ ffSf[r@< v f0t*rl,ff9tfd < tr!tYSfPf=vffPff fW1f_fYfQfWt &gfAfVff^f_fYfXff)[uP.TX=6ui<wb>rY wT>֬3fجtجt@3>֬0t1Ɉ2H2!0H2ù1Ҹ0۸` u2̈&2aVu84rtf>4=ui<1۹:֬H1:2r2Ȉƴ1:lQWf1f_W8^Nj>l^lPY148tIu1$tQوY)w Ãt$úB`ˬՇwav<t@t O1w%٬f0E11f`Ȏ؎ ttO1faf`_f` >u faf`f SfSf1f!txf fPAMSf1ɱSsf!u[pf=PAMSuhf> SwfSf>Stf=rf; Ssf Sf;SwfSrf>Stff;SvfS~fSf; Svf Sf=w8r=bPX<tV< tN< tR>b Z:2v 0:62w>bfafΊ>b>11ɋ20ӀsΊ2s0PS1B0 t<:t <.t&NJ&?t0[X`1aP1 k;6rf1^ZY_fVQRfff3pf#xtf|f묻3>ll)9 2!u9u־h;fṷ4uIPY1fDuf<uu fD : htf1ZY^> O> t9t,1t%f/-Zffgff1}ffd(fÿfVff=/-Zuf1ҹ~fffguff=d(^P18t tƁr =v1XPVW uYQ18t t#Ɓr|Wƹ)r%^^NY΁sވЪȪd)1_^Xf`}f1fffgf)Ѝ|fDffaf>tf>t> t PXPXÈ&,Sf` Ҵr uB*S?(SUA rf ffaf1VfRfPSjjf` @ &,Sfadr^^fRfPUf6(Sf>*Sf1ɇff=w'Aň֊ &,Sf`far]fXfZMuIt appears your computer has less than 256K of low ("DOS") RAM. Linux needs at least this amount to boot. If you get this message in error, hold down the Ctrl key while booting, and I will take your word for it. boot:  Invalid image type for this media type! Could not find kernel image: Invalid or corrupt kernel image. +:: Loading ..ready. Cannot load a ramdisk with an old kernel image. Could not find ramdisk image: Not enough memory to load specified kernel. BOOT_IMAGE=.)2m  (0 lower case cmp al,'a' jb .ret ; If failure, CF == 1 already cmp al,'f' ja .err sub al,'a'-10 ; CF <- 0 ret .err: stc .ret: ret ; ; ; getline: Get a command line, converting control characters to spaces ; and collapsing streches to one; a space is appended to the ; end of the string, unless the line is empty. ; The line is terminated by ^J, ^Z or EOF and is written ; to ES:DI. On return, DI points to first char after string. ; CF is set if we hit EOF. ; getline: call skipspace mov dl,1 ; Empty line -> empty string. jz .eof ; eof jc .eoln ; eoln call ungetc .fillloop: push dx push di call getc pop di pop dx jc .ret ; CF set! cmp al,' ' jna .ctrl xor dx,dx .store: stosb jmp short .fillloop .ctrl: cmp al,10 je .ret ; CF clear! cmp al,26 je .eof and dl,dl jnz .fillloop ; Ignore multiple spaces mov al,' ' ; Ctrl -> space inc dx jmp short .store .eoln: clc ; End of line is not end of file jmp short .ret .eof: stc .ret: pushf ; We want the last char to be space! and dl,dl jnz .xret mov al,' ' stosb .xret: popf ret syslinux-legacy-3.63+dfsg/extlinux.bin0000664000175000017500000002736510777447307016601 0ustar evanevanXEXTLINUX1м{W{ػx7V$0 x?Gd|M'EufEf|r uB|?|UA$0rUu t}f}~f>$~JLLy>f|f1OUffRfPSWjf`$0Bfadr]f) !uf`1$0fa}O]fRfPUSf6|f>|f1ɇfk)9vAň֊$0f`farf []fXfZf)uMuޕ.}u1ּ{fx} t ;.}v.}Boot error ᆳ EXTLINUX 3.63 2008-04-10 >JLLy9~c>}u604O4~*~!1ffEIt fBf9u8 ݾ~(~fMfff!t; t f`Cfa Load error - CBIOSEBIOSUf1 |/Nf0f+ff1fB+ &0fff0 %0f f0fHf0ff0ff 0200f1fH4u=s Т8IH(fmf}>nth 11 r !L>t+u H4[">v+I4tfh+f@4fd+f<43f&<4 <t;< rwtI4uJsԪ< <t-<t<<t<utOj)dI40&I4<0rt <9vr+ W_1۠¢J4&>x+t[VW0Ǿʿl+>r+_^J4 0uO>D4(S f[f6D4fDaWP 0uOfMX_>J4$f f.comxf.cbtmf.c32f.bsstUVfD91fL4>r+Τ  6F4 1d4 t~< vNff=vga=t/f=mem=tVϦu< v.6d41.d4< wN뼃fDf==nortKf==exttKf==asktrωɃr.fL46`4fP47&f>HdrS&f4==r&$&=r &f,fP4&4f1&f&h4&!ub4 AfL4f-f;T4[f6b4F ff)fQff Bo fY^fT4f-v1һ f>\40BE>d4t D2T0f4h4tr df(d ?d>"rd$v df( `49vd󤪁r&>h4u?11df>b4G@) f1ffT4ff&>u& ÎێӼ߃ Sj19d4tMh4f4m0.6d4< wN1VPN.;6d4t<,uFV ^X_.;6d4wȎ؎ > f0fQfL4fJfP4f9vffBf)ʁf;\4r\&f>t &ff)&f&fffJfP4V6l fA`^fX þK EþV2!u=sV_01@f1f& &} & t ,&^ ؎1j0hȀ\ffĈffff`͎ݎʼn? ٤:FЉF,fa8hȀ1[1؎м{ IDeÊFÊFLJÎF&v&<$tÀ>5ufȈFfFSYfFSLfFINfFUXÀ>5u[ u&45Fà45f`͎ݎʼnRr1FF?F4N^$F~FUÎ^$vÎ^$vhhj^$v tFVFvÎF$^vN8 s1vËvF4F $0FN"F{N$F{á~+F:9F<9&>9`+ùFf{fx11fFffFff|ff(fvfV^&N$FFÁ~Uw/NQg If$vWdffFf(fvfV^&pÌN$F7FÊF<wJ4^&v w6844464^$v1O0؎16&E >r+F46FwHNV02uNà6 t 4^$FH9Ffvf vufFF$^nÁ~UwFNQg If$vWdff&vf( @dfEf)}f(+1QÁ~UwXPNQg If$vWdff&v(d؀Eꐐfdfdff((Ì^$FFVRPe0r+A)dffX^1һ-fEȎ؉&脝u)(r "' 1а(؎а0؋%g&D9f1 1QY`5(OhҎhPhhhXhjYf%1꼍؎Ўx $"ۍȎ؎&hfRfNfaf.&.&ff`f.&.ff$1ۋf]aϜ`D$(`D$(g>g6fg>ߋt$,1ɱ 󥫸G% Gffg6g|$0!u1ɱ g6aÜ`L$0g>gfg>)σfg>ߋD$(*t$,f)ag06F4>r+O>r+Òfff>fW1һ ff>f|ff(f1f1f{fx$0{W1^1jhx1؎{W_&fU&fu &]{{&E&][Xft ` <t<taþ~Ȁ1؎м{Vp+!f`11faýf;0fPQf1fYfXf@MuQ00@f?tYf1[_WSuQfHf1fWf6+fRff1f60f+f@%0ffRf ffZXeftfXf+ff60ffRf ffGZW $ֹ l4efl4Gfp4fPff ffXfff!Y[_!tfSQU29@f0~=/u fGfP"t*L t+t f11f!]Y[Ã=tf,9=tڀ=/uG0Q ى09YS[V;09sWf?t Owt __^sf=t=/u[^<[^29wf=mf1f94f94u44Wf^<t/@ <4W _f,9HWS1< v8t 0}t ^  fSfVfWfQfRfUfP%0ffPfDA w fXfg(f fXf f.0f9rdf\f)f. 0f9r-f`f)f1f6 0Pfef(ff [ff1f60Pfef(ff [fPfef(ff [effXff#0ff]fZfYf_f^f[fUfPfRfWff; v fDffPff1EIt%f1f@f 9sfGfBff9tfXf`KfaU ]flf),uf<f_fZfXf]"t$S0r7GW1GG @[1[SVW>] !u0ƃmru&Fu_^[KA ] f`0]5fMg&fvfMf)M 5fa뤉Mfa0SV7b^[WS>] A C] [_Yr <t < t < v8ÿ /sW6_r<-s fPfQUf1ff1<-u<0rSt<9wM <0r% b 69@:89w%69>b69ø149þ@9t6979@:99w791ɋ89679>b+믾@9t1ɉ6989>?9r/@9t?949r@9t?9496p!?949.< t< v>npsG>n76nppt`>b69a$@9@9t+ff`~+!tP&=9W tB 8uXSfaf@9t tf`u~+!ttB&>9 8faôu"~+!tWtB&>9 8u0ôbfafP Xff` tfafaf1Ԫ`++)f 0ŪfdYfD9ÿEÿ ҉>n+ÿډ>p+À>+wʉ>l+ÿƒu >-u1>À>+t /P^rf*fffP^rPb uXPQ uX|+rSgs[Lv<9r)fSPr7as1ۀ>>9߁<9f[f%_fKrfff:9Pw狽>~+U'X!BBB<u:JJ0Bt~U~+Pk_1V+ʿ‹l+/(&#r ff%f=ENDTuff%f=EXTuÿW^ÿ1 s|+u¿ǹ)1f>D9 f>D9þh%QfSfR1f1fOfg[fOgI8t1Cgy؀rg(ufGCf8u sCIbs ~fOg fgfOg'NfZf[Yhy詍W1fNg,s fNgs ~fNgـfNgY)tUr<#tQ ffShf[r@< v f0t*rئ*ff9tf¥륰 ]< tr!tYSfPf=vffPff fW1>f_fYfQfWt &gfAfVf袌f^f_fYfXff)[uP.XVD=6ui<wb>rY wT>4H9f6Ht6t@H9>40Ht1Ɉ2H99!0H89ù1Ҹ0۸` u99̈&89aVu84rtf>4=ui<1۹:4H1:99r99Ȉƴ1:lQWf1f_W8^Nj>l^lPY148tIu1$tQوY)w Ãt.$úB`ˬՇwavH<t@t O1w%7Hf0Eb+1f`Ȏ؎H ttOHb+faf`_f` >Hu faf`f`Yf\Yf1f!txf fPAMSf1ɱHYsf!u[pf=PAMSuhf>LYwfHYf>XYtf=rf;`Ysf`Yf;\YwfPYrf>TYtff;\Yvf\Y~f\Yf;`Yvf`Yf=w8r=Tz*~f|f,~f0~fffLfP$0T>Tt9t,1t%f/-Zffgff1}ffd(fÿfVff=/-Zuf1ҹ~fffguff=d(^P18t tƁr =v1XPVW uYQ18t t#Ɓr|Wƹ)r%^^NY΁sވЪȪd)1_^Xf`}f1fffgf)Ѝ|fDffaf>Ltf>Pt>Tt PXPXÈ&t]f`T Ҵr uBr]?p]UATwrGfL fPfaf1VfRfPSjjf`T@ &t]fadr^^fRfPUf6p]f>r]f1ɇff=w'Aň֊T&t]f`far]fXfZMuIt appears your computer has less than 256K of low ("DOS") RAM. Linux needs at least this amount to boot. If you get this message in error, hold down the Ctrl key while booting, and I will take your word for it. boot:  Invalid image type for this media type! Could not find kernel image: Invalid or corrupt kernel image. "CC6 Loading ..ready. Cannot load a ramdisk with an old kernel image. Could not find ramdisk image: Not enough memory to load specified kernel. BOOT_IMAGE=#19A F Y0mL׉ى"E\׉d׉׉׉׉2A΋Q%: attempted DOS system call COMBOOT image too large.  aborted. 0 linux autoOut of memory parsing config file Unknown keyword in configuration file. Missing parameter in configuration file. A20 gate not responding!   Copyright (C) 1994-2008 H. Peter Anvin Boot failed: please change disks and press a key to continue. extlinux.confinitrd=7t;}bQ9ؘYQ@ Q2@x+6P@̴h 6 0  e N  R2 G @t:t+6YtLhg1`+62d+Qh+^hɘHz+6 v+6 7 7 7 7 7 7 7 7 77 777.cbt.img.bs.com.c32 ?(g\(f`h) fafffPfUf.)f1ff .f )f.( "b)8аذ01V ] $")ff]fXftCf9r$fgfgfgtfg|fffgfffgff1΃fgfgf`.(..Z+.P+.Z+du_.Z+$RuMouF.Z+d^`WQ1/u)Y.Z+ $Q1uY.(uveYfaQP .(@.(e&;(XY0t uLdtC`u8!tf?fwfOft) Hufaf..(ffQfXf1f f.)f.( "6+ 1а0ذ(؎Ўf**(*:*`*syslinux-legacy-3.63+dfsg/tracers.inc0000664000175000017500000000202310777447273016347 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; tracers.inc ;; ;; Debugging tracers ;; %ifndef _TRACERS_INC %define _TRACERS_INC ; Note: The Makefile builds one version with DEBUG_MESSAGES automatically. ; %define DEBUG_TRACERS 1 ; Uncomment to get debugging tracers ; %define DEBUG_MESSAGES ; Uncomment to get debugging messages %ifdef DEBUG_TRACERS %macro TRACER 1 call debug_tracer db %1 %endmacro %else ; DEBUG_TRACERS %macro TRACER 1 %endmacro %endif ; DEBUG_TRACERS %endif ; _TRACERS_INC syslinux-legacy-3.63+dfsg/memdump/0000775000175000017500000000000010777447343015656 5ustar evanevansyslinux-legacy-3.63+dfsg/memdump/memcpy.S0000664000175000017500000000043110777447273017274 0ustar evanevan# # memcpy.S # # Simple 16-bit memcpy() implementation # .text .code16gcc .globl memcpy .type memcpy, @function memcpy: cld pushw %di pushw %si movw %ax,%di movw %dx,%si # The third argument is already in cx rep ; movsb popw %si popw %di ret .size memcpy,.-memcpy syslinux-legacy-3.63+dfsg/memdump/strtoul.c0000664000175000017500000000213710777447273017543 0ustar evanevan/* * strtoul.c * */ #include "mystuff.h" static inline int isspace(int c) { return (c <= ' '); /* Close enough */ } static inline int digitval(int ch) { if (ch >= '0' && ch <= '9') { return ch - '0'; } else if (ch >= 'A' && ch <= 'Z') { return ch - 'A' + 10; } else if (ch >= 'a' && ch <= 'z') { return ch - 'a' + 10; } else { return -1; } } unsigned long strtoul(const char *nptr, char **endptr, int base) { int minus = 0; unsigned long v = 0; int d; while (isspace((unsigned char)*nptr)) { nptr++; } /* Single optional + or - */ { char c = *nptr; if (c == '-' || c == '+') { minus = (c == '-'); nptr++; } } if (base == 0) { if (nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X')) { nptr += 2; base = 16; } else if (nptr[0] == '0') { nptr++; base = 8; } else { base = 10; } } else if (base == 16) { if (nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X')) { nptr += 2; } } while ((d = digitval(*nptr)) >= 0 && d < base) { v = v * base + d; nptr++; } if (endptr) *endptr = (char *)nptr; return minus ? -v : v; } syslinux-legacy-3.63+dfsg/memdump/malloc.h0000664000175000017500000000243710777447273017306 0ustar evanevan/* * malloc.h * * Internals for the memory allocator */ #include #include /* * This is the minimum chunk size we will ask the kernel for; this should * be a multiple of the page size on all architectures. */ #define MALLOC_CHUNK_SIZE 65536 #define MALLOC_CHUNK_MASK (MALLOC_CHUNK_SIZE-1) /* * This structure should be a power of two. This becomes the * alignment unit. */ struct free_arena_header; struct arena_header { size_t type; size_t size; /* Also gives the location of the next entry */ struct free_arena_header *next, *prev; }; #ifdef DEBUG_MALLOC #define ARENA_TYPE_USED 0x64e69c70 #define ARENA_TYPE_FREE 0x012d610a #define ARENA_TYPE_HEAD 0x971676b5 #define ARENA_TYPE_DEAD 0xeeeeeeee #else #define ARENA_TYPE_USED 0 #define ARENA_TYPE_FREE 1 #define ARENA_TYPE_HEAD 2 #endif #define ARENA_SIZE_MASK (sizeof(struct arena_header)-1) #define ARENA_ALIGN_UP(p) ((char *)(((uintptr_t)(p) + ARENA_SIZE_MASK) & ~ARENA_SIZE_MASK)) #define ARENA_ALIGN_DOWN(p) ((char *)((uintptr_t)(p) & ~ARENA_SIZE_MASK)) /* * This structure should be no more than twice the size of the * previous structure. */ struct free_arena_header { struct arena_header a; struct free_arena_header *next_free, *prev_free; }; extern struct free_arena_header __malloc_head; syslinux-legacy-3.63+dfsg/memdump/stdlib.h0000664000175000017500000000031410777447273017310 0ustar evanevan#ifndef STDLIB_H #define STDLIB_H #define NULL ((void *)0) typedef int ssize_t; typedef unsigned int size_t; void __attribute__((noreturn)) exit(int); void *malloc(size_t); void free(void *); #endif syslinux-legacy-3.63+dfsg/memdump/ymsend.h0000664000175000017500000000117410777447273017333 0ustar evanevan#ifndef YMSEND_H #define YMSEND_H #include "mystuff.h" struct serial_if { int port; void *pvt; void (*read)(struct serial_if *, void *, size_t); void (*write)(struct serial_if *, const void *, size_t); }; struct file_info { const char *name; size_t size; void *pvt; }; void send_ymodem(struct serial_if *, struct file_info *, void (*)(void *, size_t, struct file_info *, size_t)); void end_ymodem(struct serial_if *); int serial_init(struct serial_if *sif); void serial_read(struct serial_if *sif, void *data, size_t n); void serial_write(struct serial_if *sif, const void *data, size_t n); #endif /* YMSEND_H */ syslinux-legacy-3.63+dfsg/memdump/stdio.h0000664000175000017500000000063110777447273017153 0ustar evanevan#ifndef STDIO_H #define STDIO_H #include #include typedef unsigned int off_t; int putchar(int); int puts(const char *); int sprintf(char * buf, const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args); int printf(const char *fmt, ...); #define stdin 0 #define stdout 1 #define stderr 2 #define fprintf(x, y, ...) printf(y, ## __VA_ARGS__) #endif /* STDIO_H */ syslinux-legacy-3.63+dfsg/memdump/crt0.S0000664000175000017500000000171510777447273016660 0ustar evanevan .code16 #ifndef REGPARM # error "This file assumes -mregparm=3 -DREGPARM=3" #endif .section ".init","ax" .globl _start .type _start,@function _start: # Align the stack and make sure the high half is zero andl $0xfff8,%esp # Clear the .bss cld xorl %eax,%eax movw $__bss_start,%di movw $_end+3,%cx subw %di,%cx shrw $2,%cx rep ; stosl # Compute argc and argv (assumes REGPARM) xorl %edx,%edx movzbw 0x80,%bx movb %dl,0x81(%bx) # Zero-terminate string movb $0x81,%dl pushl %eax # Make space for argv movl %esp,%eax calll __parse_argv pushl %eax # argc # Initialize malloc # calll __init_memory_arena # Now call main... (NOTE: gcc forces main to be regparm 0) popl %eax # argc popl %edx # argv calll main # Here %eax is the exit code, fall through into exit .size _start,.-_start .globl exit .type exit,@function exit: # Exit code already in %eax movb $0x4c,%ah # Terminate program int $0x21 1: hlt jmp 1b .size exit,.-exit syslinux-legacy-3.63+dfsg/memdump/argv.c0000664000175000017500000000524210777447273016766 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ /* * argv.c * * Parse a single C string into argc and argv (argc is return value.) * memptr points to available memory. */ #include #include #include #define ALIGN_UP(p,t) ((t *)(((uintptr_t)(p) + (sizeof(t)-1)) & ~(sizeof(t)-1))) extern char _end[]; /* Symbol created by linker */ void *__mem_end = &_end; /* Global variable for use by malloc() */ int __parse_argv(char ***argv, const char *str) { char *mem = __mem_end; const char *p = str; char *q = mem; char *r; char **arg; int wasspace = 0; int argc = 1; /* First copy the string, turning whitespace runs into nulls */ for ( p = str ; ; p++ ) { if ( *p <= ' ' ) { if ( !wasspace ) { wasspace = 1; *q++ = '\0'; } } else { if ( wasspace ) { argc++; wasspace = 0; } *q++ = *p; } /* This test is AFTER we have processed the null byte; we treat it as a whitespace character so it terminates the last argument */ if ( ! *p ) break; } /* Now create argv */ arg = ALIGN_UP(q,char *); *argv = arg; *arg++ = mem; /* argv[0] */ q--; /* Point q to final null */ for ( r = mem ; r < q ; r++ ) { if ( *r == '\0' ) { *arg++ = r+1; } } *arg++ = NULL; /* Null pointer at the end */ __mem_end = arg; /* End of memory we used */ return argc; } syslinux-legacy-3.63+dfsg/memdump/code16.h0000664000175000017500000000014610777447273017113 0ustar evanevan/* Must be included first of all */ #ifdef __ASSEMBLY__ .code16 #else __asm__ (".code16gcc"); #endif syslinux-legacy-3.63+dfsg/memdump/printf.c0000664000175000017500000001416310777447273017333 0ustar evanevan/* * Oh, it's a waste of space, but oh-so-yummy for debugging. It's just * initialization code anyway, so it doesn't take up space when we're * actually running. This version of printf() does not include 64-bit * support. "Live with it." * * Most of this code was shamelessly snarfed from the Linux kernel, then * modified. It's therefore GPL. * * printf() isn't actually needed to build syslinux.com, but during * debugging it's handy. */ #include #include #include "mystuff.h" static int strnlen(const char *s, int maxlen) { const char *es = s; while ( *es && maxlen ) { es++; maxlen--; } return (es-s); } #define ZEROPAD 1 /* pad with zero */ #define SIGN 2 /* unsigned/signed long */ #define PLUS 4 /* show plus */ #define SPACE 8 /* space if plus */ #define LEFT 16 /* left justified */ #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ #define do_div(n,base) ({ \ int __res; \ __res = ((unsigned long) n) % (unsigned) base; \ n = ((unsigned long) n) / (unsigned) base; \ __res; }) static char * number(char * str, long num, int base, int size, int precision ,int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; int i; if (type & LARGE) digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (type & LEFT) type &= ~ZEROPAD; if (base < 2 || base > 36) return 0; c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if (type & SIGN) { if (num < 0) { sign = '-'; num = -num; size--; } else if (type & PLUS) { sign = '+'; size--; } else if (type & SPACE) { sign = ' '; size--; } } if (type & SPECIAL) { if (base == 16) size -= 2; else if (base == 8) size--; } i = 0; if (num == 0) tmp[i++]='0'; else while (num != 0) tmp[i++] = digits[do_div(num,base)]; if (i > precision) precision = i; size -= precision; if (!(type&(ZEROPAD+LEFT))) while(size-->0) *str++ = ' '; if (sign) *str++ = sign; if (type & SPECIAL) { if (base==8) *str++ = '0'; else if (base==16) { *str++ = '0'; *str++ = digits[33]; } } if (!(type & LEFT)) while (size-- > 0) *str++ = c; while (i < precision--) *str++ = '0'; while (i-- > 0) *str++ = tmp[i]; while (size-- > 0) *str++ = ' '; return str; } /* Forward decl. needed for IP address printing stuff... */ int sprintf(char * buf, const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args) { int len; unsigned long num; int i, base; char * str; const char *s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ for (str=buf ; *fmt ; ++fmt) { if (*fmt != '%') { *str++ = *fmt; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (isdigit(*fmt)) field_width = skip_atou(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (isdigit(*fmt)) precision = skip_atou(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); } if (precision < 0) precision = 0; } /* get the conversion qualifier */ qualifier = -1; if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { qualifier = *fmt; ++fmt; } /* default base */ base = 10; switch (*fmt) { case 'c': if (!(flags & LEFT)) while (--field_width > 0) *str++ = ' '; *str++ = (unsigned char) va_arg(args, int); while (--field_width > 0) *str++ = ' '; continue; case 's': s = va_arg(args, char *); len = strnlen(s, precision); if (!(flags & LEFT)) while (len < field_width--) *str++ = ' '; for (i = 0; i < len; ++i) *str++ = *s++; while (len < field_width--) *str++ = ' '; continue; case 'p': if (field_width == -1) { field_width = 2*sizeof(void *); flags |= ZEROPAD; } str = number(str, (unsigned long) va_arg(args, void *), 16, field_width, precision, flags); continue; case 'n': if (qualifier == 'l') { long * ip = va_arg(args, long *); *ip = (str - buf); } else { int * ip = va_arg(args, int *); *ip = (str - buf); } continue; case '%': *str++ = '%'; continue; /* integer number formats - set up the flags and "break" */ case 'o': base = 8; break; case 'X': flags |= LARGE; case 'x': base = 16; break; case 'd': case 'i': flags |= SIGN; case 'u': break; default: *str++ = '%'; if (*fmt) *str++ = *fmt; else --fmt; continue; } if (qualifier == 'l') num = va_arg(args, unsigned long); else if (qualifier == 'h') { num = (unsigned short) va_arg(args, int); if (flags & SIGN) num = (short) num; } else if (flags & SIGN) num = va_arg(args, int); else num = va_arg(args, unsigned int); str = number(str, num, base, field_width, precision, flags); } *str = '\0'; return str-buf; } int sprintf(char * buf, const char *fmt, ...) { va_list args; int i; va_start(args, fmt); i=vsprintf(buf,fmt,args); va_end(args); return i; } int printf(const char *fmt, ...) { char printf_buf[1024]; va_list args; int printed; va_start(args, fmt); printed = vsprintf(printf_buf, fmt, args); va_end(args); puts(printf_buf); return printed; } syslinux-legacy-3.63+dfsg/memdump/com16.ld0000664000175000017500000000722510777447273017134 0ustar evanevan/* * Linker script for COM16 binaries */ /* Script for -z combreloc: combine and sort reloc sections */ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) EXTERN(_start) ENTRY(_start) SECTIONS { /* Read-only sections, merged into text segment: */ . = 0x100; PROVIDE (__executable_start = .); .init : { KEEP (*(.init)) } =0x90909090 .text : { *(.text .stub .text.* .gnu.linkonce.t.*) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) } =0x90909090 .fini : { KEEP (*(.fini)) } =0x90909090 PROVIDE (__etext = .); PROVIDE (_etext = .); PROVIDE (etext = .); .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } /* Ensure the __preinit_array_start label is properly aligned. We could instead move the label definition inside the section, but the linker would then create the section even if it turns out to be empty, which isn't pretty. */ . = ALIGN(4); PROVIDE (__preinit_array_start = .); .preinit_array : { *(.preinit_array) } PROVIDE (__preinit_array_end = .); PROVIDE (__init_array_start = .); .init_array : { *(.init_array) } PROVIDE (__init_array_end = .); PROVIDE (__fini_array_start = .); .fini_array : { *(.fini_array) } PROVIDE (__fini_array_end = .); PROVIDE (__ctors_start = .); .ctors : { KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) } PROVIDE (__ctors_end = .); PROVIDE (__dtors_start = .); .dtors : { KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } PROVIDE (__dtors_end = .); /* Adjust the address for the data segment. Avoid mixing code and data within same 128-byte chunk. */ . = ALIGN(128); .data : { *(.data .data.* .gnu.linkonce.d.*) SORT(CONSTRUCTORS) } .data1 : { *(.data1) } _edata = .; PROVIDE (edata = .); __bss_start = .; .bss : { *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) /* Align here to ensure that the .bss section occupies space up to _end. Align after .bss to ensure correct alignment even if the .bss section disappears because there are no input sections. */ . = ALIGN(32 / 8); } . = ALIGN(32 / 8); _end = .; PROVIDE (end = .); /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions */ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2 */ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } /* DWARF 2 */ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions */ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } /DISCARD/ : { *(.note.GNU-stack) } } syslinux-legacy-3.63+dfsg/memdump/mystuff.h0000664000175000017500000000076610777447273017537 0ustar evanevan#ifndef MYSTUFF_H #define MYSTUFF_H #include typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; typedef unsigned short uint16_t; typedef signed int int32_t; typedef unsigned int uint32_t; typedef signed long long int64_t; typedef unsigned long long uint64_t; unsigned int skip_atou(const char **s); unsigned long strtoul(const char *, char **, int); static inline int isdigit(int ch) { return (ch >= '0') && (ch <= '9'); } #endif /* MYSTUFF_H */ syslinux-legacy-3.63+dfsg/memdump/__udivmoddi4.c0000664000175000017500000000077310777447273020401 0ustar evanevan#include uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p) { uint64_t quot = 0, qbit = 1; if ( den == 0 ) { asm volatile("int $0"); return 0; /* If trap returns... */ } /* Left-justify denominator and count shift */ while ( (int64_t)den >= 0 ) { den <<= 1; qbit <<= 1; } while ( qbit ) { if ( den <= num ) { num -= den; quot += qbit; } den >>= 1; qbit >>= 1; } if ( rem_p ) *rem_p = num; return quot; } syslinux-legacy-3.63+dfsg/memdump/string.h0000664000175000017500000000102510777447273017335 0ustar evanevan/* * string.h */ #ifndef _STRING_H #define _STRING_H /* Standard routines */ #define memcpy(a,b,c) __builtin_memcpy(a,b,c) #define memset(a,b,c) __builtin_memset(a,b,c) #define strcpy(a,b) __builtin_strcpy(a,b) #define strlen(a) __builtin_strlen(a) /* This only returns true or false */ static inline int memcmp(const void *__m1, const void *__m2, unsigned int __n) { _Bool rv; asm volatile("cld ; repe ; cmpsb ; setne %0" : "=abd" (rv), "+D" (__m1), "+S" (__m2), "+c" (__n)); return rv; } #endif /* _STRING_H */ syslinux-legacy-3.63+dfsg/memdump/Makefile0000664000175000017500000000276010777447273017325 0ustar evanevanTMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \ then echo $(1); else echo $(2); fi; rm -f $$tmpf) M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,) $(call gcc_ok,-fno-stack-protector,) CC = gcc LD = ld -m elf_i386 OBJCOPY = objcopy OPTFLAGS = -g -Os -march=i386 -falign-functions=0 -falign-jumps=0 -falign-loops=0 -fomit-frame-pointer INCLUDES = -include code16.h -I. CFLAGS = $(M32) -mregparm=3 -DREGPARM=3 -W -Wall -msoft-float $(OPTFLAGS) $(INCLUDES) LDFLAGS = -T com16.ld AR = ar RANLIB = ranlib LIBGCC := $(shell $(CC) --print-libgcc) SRCS = main.c serial.c ymsend.c OBJS = crt0.o $(patsubst %.c,%.o,$(notdir $(SRCS))) LIBOBJS = conio.o memcpy.o memset.o skipatou.o strtoul.o \ argv.o printf.o __divdi3.o __udivmoddi4.o .SUFFIXES: .c .o .i .s .S .elf .com VPATH = .:..:../libfat TARGETS = memdump.com all: $(TARGETS) tidy: -rm -f *.o *.i *.s *.a .*.d *.elf clean: tidy spotless: clean -rm -f *~ $(TARGETS) installer: memdump.elf: $(OBJS) libcom.a $(LD) $(LDFLAGS) -o $@ $^ libcom.a: $(LIBOBJS) -rm -f $@ $(AR) cq $@ $^ $(RANLIB) $@ memdump.com: memdump.elf $(OBJCOPY) -O binary $< $@ %.o: %.c $(CC) -Wp,-MT,$@,-MD,.$@.d $(CFLAGS) -c -o $@ $< %.i: %.c $(CC) $(CFLAGS) -E -o $@ $< %.s: %.c $(CC) $(CFLAGS) -S -o $@ $< %.o: %.S $(CC) -Wp,-MT,$@,-MD,.$@.d $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $< %.s: %.S $(CC) $(CFLAGS) -E -o $@ $< -include .*.d syslinux-legacy-3.63+dfsg/memdump/ymodem.txt0000664000175000017500000020373210777447273017722 0ustar evanevan - 1 - XMODEM/YMODEM PROTOCOL REFERENCE A compendium of documents describing the XMODEM and YMODEM File Transfer Protocols This document was formatted 10-14-88. Edited by Chuck Forsberg This file may be redistributed without restriction provided the text is not altered. Please distribute as widely as possible. Questions to Chuck Forsberg Omen Technology Inc The High Reliability Software 17505-V Sauvie Island Road Portland Oregon 97231 VOICE: 503-621-3406 :VOICE TeleGodzilla BBS: 503-621-3746 Speed 19200(Telebit PEP),2400,1200,300 CompuServe: 70007,2304 GEnie: CAF UUCP: ...!tektronix!reed!omen!caf - 2 - 1. TOWER OF BABEL A "YMODEM Tower of Babel" has descended on the microcomputing community bringing with it confusion, frustration, bloated phone bills, and wasted man hours. Sadly, I (Chuck Forsberg) am partly to blame for this mess. As author of the early 1980s batch and 1k XMODEM extensions, I assumed readers of earlier versions of this document would implement as much of the YMODEM protocol as their programming skills and computing environments would permit. This proved a rather naive assumption as programmers motivated by competitive pressure implemented as little of YMODEM as possible. Some have taken whatever parts of YMODEM that appealed to them, applied them to MODEM7 Batch, Telink, XMODEM or whatever, and called the result YMODEM. Jeff Garbers (Crosstalk package development director) said it all: "With protocols in the public domain, anyone who wants to dink around with them can go ahead." [1] Documents containing altered examples derived from YMODEM.DOC have added to the confusion. In one instance, some self styled rewriter of history altered the heading in YMODEM.DOC's Figure 1 from "1024 byte Packets" to "YMODEM/CRC File Transfer Protocol". None of the XMODEM and YMODEM examples shown in that document were correct. To put an end to this confusion, we must make "perfectly clear" what YMODEM stands for, as Ward Christensen defined it in his 1985 coining of the term. To the majority of you who read, understood, and respected Ward's definition of YMODEM, I apologize for the inconvenience. 1.1 Definitions ARC ARC is a program that compresses one or more files into an archive and extracts files from such archives. XMODEM refers to the file transfer etiquette introduced by Ward Christensen's 1977 MODEM.ASM program. The name XMODEM comes from Keith Petersen's XMODEM.ASM program, an adaptation of MODEM.ASM for Remote CP/M (RCPM) systems. It's also called the MODEM or MODEM2 protocol. Some who are unaware of MODEM7's unusual batch file mode call it MODEM7. Other aliases include "CP/M Users' Group" and "TERM II FTP 3". The name XMODEM caught on partly because it is distinctive and partly because of media interest in __________ 1. Page C/12, PC-WEEK July 12, 1987 Chapter 1 X/YMODEM Protocol Reference June 18 1988 3 bulletin board and RCPM systems where it was accessed with an "XMODEM" command. This protocol is supported by every serious communications program because of its universality, simplicity, and reasonable performance. XMODEM/CRC replaces XMODEM's 1 byte checksum with a two byte Cyclical Redundancy Check (CRC-16), giving modern error detection protection. XMODEM-1k Refers to the XMODEM/CRC protocol with 1024 byte data blocks. YMODEM Refers to the XMODEM/CRC (optional 1k blocks) protocol with batch transmission as described below. In a nutshell, YMODEM means BATCH. YMODEM-g Refers to the streaming YMODEM variation described below. True YMODEM(TM) In an attempt to sort out the YMODEM Tower of Babel, Omen Technology has trademarked the term True YMODEM(TM) to represent the complete YMODEM protocol described in this document, including pathname, length, and modification date transmitted in block 0. Please contact Omen Technology about certifying programs for True YMODEM(TM) compliance. ZMODEM uses familiar XMODEM/CRC and YMODEM technology in a new protocol that provides reliability, throughput, file management, and user amenities appropriate to contemporary data communications. ZOO Like ARC, ZOO is a program that compresses one or more files into a "zoo archive". ZOO supports many different operating systems including Unix and VMS. Chapter 1 X/YMODEM Protocol Reference June 18 1988 4 2. YMODEM MINIMUM REQUIREMENTS All programs claiming to support YMODEM must meet the following minimum requirements: + The sending program shall send the pathname (file name) in block 0. + The pathname shall be a null terminated ASCII string as described below. For those who are too lazy to read the entire document: + Unless specifically requested, only the file name portion is sent. + No drive letter is sent. + Systems that do not distinguish between upper and lower case letters in filenames shall send the pathname in lower case only. + The receiving program shall use this pathname for the received file name, unless explicitly overridden. + When the receiving program receives this block and successfully opened the output file, it shall acknowledge this block with an ACK character and then proceed with a normal XMODEM file transfer beginning with a "C" or NAK tranmsitted by the receiver. + The sending program shall use CRC-16 in response to a "C" pathname nak, otherwise use 8 bit checksum. + The receiving program must accept any mixture of 128 and 1024 byte blocks within each file it receives. Sending programs may arbitrarily switch between 1024 and 128 byte blocks. + The sending program must not change the length of an unacknowledged block. + At the end of each file, the sending program shall send EOT up to ten times until it receives an ACK character. (This is part of the XMODEM spec.) + The end of a transfer session shall be signified by a null (empty) pathname, this pathname block shall be acknowledged the same as other pathname blocks. Programs not meeting all of these requirements are not YMODEM compatible, and shall not be described as supporting YMODEM. Meeting these MINIMUM requirements does not guarantee reliable file Chapter 2 X/YMODEM Protocol Reference June 18 1988 5 transfers under stress. Particular attention is called to XMODEM's single character supervisory messages that are easily corrupted by transmission errors. Chapter 2 X/YMODEM Protocol Reference June 18 1988 6 3. WHY YMODEM? Since its development half a decade ago, the Ward Christensen modem protocol has enabled a wide variety of computer systems to interchange data. There is hardly a communications program that doesn't at least claim to support this protocol. Advances in computing, modems and networking have revealed a number of weaknesses in the original protocol: + The short block length caused throughput to suffer when used with timesharing systems, packet switched networks, satellite circuits, and buffered (error correcting) modems. + The 8 bit arithmetic checksum and other aspects allowed line impairments to interfere with dependable, accurate transfers. + Only one file could be sent per command. The file name had to be given twice, first to the sending program and then again to the receiving program. + The transmitted file could accumulate as many as 127 extraneous bytes. + The modification date of the file was lost. A number of other protocols have been developed over the years, but none have displaced XMODEM to date: + Lack of public domain documentation and example programs have kept proprietary protocols such as Blast, Relay, and others tightly bound to the fortunes of their suppliers. + Complexity discourages the widespread application of BISYNC, SDLC, HDLC, X.25, and X.PC protocols. + Performance compromises and complexity have limited the popularity of the Kermit protocol, which was developed to allow file transfers in environments hostile to XMODEM. The XMODEM protocol extensions and YMODEM Batch address some of these weaknesses while maintaining most of XMODEM's simplicity. YMODEM is supported by the public domain programs YAM (CP/M), YAM(CP/M-86), YAM(CCPM-86), IMP (CP/M), KMD (CP/M), rz/sz (Unix, Xenix, VMS, Berkeley Unix, Venix, Xenix, Coherent, IDRIS, Regulus). Commercial implementations include MIRROR, and Professional-YAM.[1] Communications Chapter 3 X/YMODEM Protocol Reference June 18 1988 7 programs supporting these extensions have been in use since 1981. The 1k block length (XMODEM-1k) described below may be used in conjunction with YMODEM Batch Protocol, or with single file transfers identical to the XMODEM/CRC protocol except for minimal changes to support 1k blocks. Another extension is the YMODEM-g protocol. YMODEM-g provides batch transfers with maximum throughput when used with end to end error correcting media, such as X.PC and error correcting modems, including 9600 bps units by TeleBit, U.S.Robotics, Hayes, Electronic Vaults, Data Race, and others. To complete this tome, edited versions of Ward Christensen's original protocol document and John Byrns's CRC-16 document are included for reference. References to the MODEM or MODEM7 protocol have been changed to XMODEM to accommodate the vernacular. In Australia, it is properly called the Christensen Protocol. 3.1 Some Messages from the Pioneer #: 130940 S0/Communications 25-Apr-85 18:38:47 Sb: my protocol Fm: Ward Christensen 76703,302 [2] To: all Be aware the article[3] DID quote me correctly in terms of the phrases like "not robust", etc. It was a quick hack I threw together, very unplanned (like everything I do), to satisfy a personal need to communicate with "some other" people. ONLY the fact that it was done in 8/77, and that I put it in the public domain immediately, made it become the standard that it is. __________________________________________________________________________ 1. Available for IBM PC,XT,AT, Unix and Xenix 2. Edited for typesetting appearance 3. Infoworld April 29 p. 16 Chapter 3 X/YMODEM Protocol Reference June 18 1988 8 I think its time for me to (1) document it; (people call me and say "my product is going to include it - what can I 'reference'", or "I'm writing a paper on it, what do I put in the bibliography") and (2) propose an "incremental extension" to it, which might take "exactly" the form of Chuck Forsberg's YAM protocol. He wrote YAM in C for CP/M and put it in the public domain, and wrote a batch protocol for Unix[4] called rb and sb (receive batch, send batch), which was basically XMODEM with (a) a record 0 containing filename date time and size (b) a 1K block size option (c) CRC-16. He did some clever programming to detect false ACK or EOT, but basically left them the same. People who suggest I make SIGNIFICANT changes to the protocol, such as "full duplex", "multiple outstanding blocks", "multiple destinations", etc etc don't understand that the incredible simplicity of the protocol is one of the reasons it survived to this day in as many machines and programs as it may be found in! Consider the PC-NET group back in '77 or so - documenting to beat the band - THEY had a protocol, but it was "extremely complex", because it tried to be "all things to all people" - i.e. send binary files on a 7-bit system, etc. I was not that "benevolent". I (emphasize > I < ) had an 8-bit UART, so "my protocol was an 8-bit protocol", and I would just say "sorry" to people who were held back by 7-bit limitations. ... Block size: Chuck Forsberg created an extension of my protocol, called YAM, which is also supported via his public domain programs for UNIX called rb and sb - receive batch and send batch. They cleverly send a "block 0" which contains the filename, date, time, and size. Unfortunately, its UNIX style, and is a bit weird[5] - octal numbers, etc. BUT, it is a nice way to overcome the kludgy "echo the chars of the name" introduced with MODEM7. Further, chuck uses CRC-16 and optional 1K blocks. Thus the record 0, 1K, and CRC, make it a "pretty slick new protocol" which is not significantly different from my own. Also, there is a catchy name - YMODEM. That means to some that it is the "next thing after XMODEM", and to others that it is the Y(am)MODEM __________ 4. VAX/VMS versions of these programs are also available. 5. The file length, time, and file mode are optional. The pathname and file length may be sent alone if desired. Chapter 3 X/YMODEM Protocol Reference June 18 1988 9 protocol. I don't want to emphasize that too much - out of fear that other mfgrs might think it is a "competitive" protocol, rather than an "unaffiliated" protocol. Chuck is currently selling a much-enhanced version of his CP/M-80 C program YAM, calling it Professional Yam, and its for the PC - I'm using it right now. VERY slick! 32K capture buffer, script, scrolling, previously captured text search, plus built-in commands for just about everything - directory (sorted every which way), XMODEM, YMODEM, KERMIT, and ASCII file upload/download, etc. You can program it to "behave" with most any system - for example when trying a number for CIS it detects the "busy" string back from the modem and substitutes a diff phone # into the dialing string and branches back to try it. Chapter 3 X/YMODEM Protocol Reference June 18 1988 10 4. XMODEM PROTOCOL ENHANCEMENTS This chapter discusses the protocol extensions to Ward Christensen's 1982 XMODEM protocol description document. The original document recommends the user be asked whether to continue trying or abort after 10 retries. Most programs no longer ask the operator whether he wishes to keep retrying. Virtually all correctable errors are corrected within the first few retransmissions. If the line is so bad that ten attempts are insufficient, there is a significant danger of undetected errors. If the connection is that bad, it's better to redial for a better connection, or mail a floppy disk. 4.1 Graceful Abort The YAM and Professional-YAM X/YMODEM routines recognize a sequence of two consecutive CAN (Hex 18) characters without modem errors (overrun, framing, etc.) as a transfer abort command. This sequence is recognized when is waiting for the beginning of a block or for an acknowledgement to a block that has been sent. The check for two consecutive CAN characters reduces the number of transfers aborted by line hits. YAM sends eight CAN characters when it aborts an XMODEM, YMODEM, or ZMODEM protocol file transfer. Pro-YAM then sends eight backspaces to delete the CAN characters from the remote's keyboard input buffer, in case the remote had already aborted the transfer and was awaiting a keyboarded command. 4.2 CRC-16 Option The XMODEM protocol uses an optional two character CRC-16 instead of the one character arithmetic checksum used by the original protocol and by most commercial implementations. CRC-16 guarantees detection of all single and double bit errors, all errors with an odd number of error bits, all burst errors of length 16 or less, 99.9969% of all 17-bit error bursts, and 99.9984 per cent of all possible longer error bursts. By contrast, a double bit error, or a burst error of 9 bits or more can sneak past the XMODEM protocol arithmetic checksum. The XMODEM/CRC protocol is similar to the XMODEM protocol, except that the receiver specifies CRC-16 by sending C (Hex 43) instead of NAK when requesting the FIRST block. A two byte CRC is sent in place of the one byte arithmetic checksum. YAM's c option to the r command enables CRC-16 in single file reception, corresponding to the original implementation in the MODEM7 series programs. This remains the default because many commercial communications programs and bulletin board systems still do not support CRC-16, especially those written in Basic or Pascal. XMODEM protocol with CRC is accurate provided both sender and receiver Chapter 4 XMODEM Protocol Enhancements X/YMODEM Protocol Reference June 18 1988 11 both report a successful transmission. The protocol is robust in the presence of characters lost by buffer overloading on timesharing systems. The single character ACK/NAK responses generated by the receiving program adapt well to split speed modems, where the reverse channel is limited to ten per cent or less of the main channel's speed. XMODEM and YMODEM are half duplex protocols which do not attempt to transmit information and control signals in both directions at the same time. This avoids buffer overrun problems that have been reported by users attempting to exploit full duplex asynchronous file transfer protocols such as Blast. Professional-YAM adds several proprietary logic enhancements to XMODEM's error detection and recovery. These compatible enhancements eliminate most of the bad file transfers other programs make when using the XMODEM protocol under less than ideal conditions. 4.3 XMODEM-1k 1024 Byte Block Disappointing throughput downloading from Unix with YMODEM[1] lead to the development of 1024 byte blocks in 1982. 1024 byte blocks reduce the effect of delays from timesharing systems, modems, and packet switched networks on throughput by 87.5 per cent in addition to decreasing XMODEM's 3 per cent overhead (block number, CRC, etc.). Some environments cannot accept 1024 byte bursts, including some networks and minicomputer ports. The longer block length should be an option. The choice to use 1024 byte blocks is expressed to the sending program on its command line or selection menu.[2] 1024 byte blocks improve throughput in many applications. An STX (02) replaces the SOH (01) at the beginning of the transmitted block to notify the receiver of the longer block length. The transmitted block contains 1024 bytes of data. The receiver should be able to accept any mixture of 128 and 1024 byte blocks. The block number (in the second and third bytes of the block) is incremented by one for each block regardless of the block length. The sender must not change between 128 and 1024 byte block lengths if it has not received a valid ACK for the current block. Failure to observe __________ 1. The name hadn't been coined yet, but the protocol was the same. 2. See "KMD/IMP Exceptions to YMODEM" below. Chapter 4 XMODEM Protocol Enhancements X/YMODEM Protocol Reference June 18 1988 12 this restriction allows transmission errors to pass undetected. If 1024 byte blocks are being used, it is possible for a file to "grow" up to the next multiple of 1024 bytes. This does not waste disk space if the allocation granularity is 1k or greater. With YMODEM batch transmission, the optional file length transmitted in the file name block allows the receiver to discard the padding, preserving the exact file length and contents. 1024 byte blocks may be used with batch file transmission or with single file transmission. CRC-16 should be used with the k option to preserve data integrity over phone lines. If a program wishes to enforce this recommendation, it should cancel the transfer, then issue an informative diagnostic message if the receiver requests checksum instead of CRC-16. Under no circumstances may a sending program use CRC-16 unless the receiver commands CRC-16. Figure 1. XMODEM-1k Blocks SENDER RECEIVER "sx -k foo.bar" "foo.bar open x.x minutes" C STX 01 FE Data[1024] CRC CRC ACK STX 02 FD Data[1024] CRC CRC ACK STX 03 FC Data[1000] CPMEOF[24] CRC CRC ACK EOT ACK Figure 2. Mixed 1024 and 128 byte Blocks SENDER RECEIVER "sx -k foo.bar" "foo.bar open x.x minutes" C STX 01 FE Data[1024] CRC CRC ACK STX 02 FD Data[1024] CRC CRC ACK SOH 03 FC Data[128] CRC CRC ACK SOH 04 FB Data[100] CPMEOF[28] CRC CRC ACK EOT ACK Chapter 4 XMODEM Protocol Enhancements X/YMODEM Protocol Reference June 18 1988 13 5. YMODEM Batch File Transmission The YMODEM Batch protocol is an extension to the XMODEM/CRC protocol that allows 0 or more files to be transmitted with a single command. (Zero files may be sent if none of the requested files is accessible.) The design approach of the YMODEM Batch protocol is to use the normal routines for sending and receiving XMODEM blocks in a layered fashion similar to packet switching methods. Why was it necessary to design a new batch protocol when one already existed in MODEM7?[1] The batch file mode used by MODEM7 is unsuitable because it does not permit full pathnames, file length, file date, or other attribute information to be transmitted. Such a restrictive design, hastily implemented with only CP/M in mind, would not have permitted extensions to current areas of personal computing such as Unix, DOS, and object oriented systems. In addition, the MODEM7 batch file mode is somewhat susceptible to transmission impairments. As in the case of single a file transfer, the receiver initiates batch file transmission by sending a "C" character (for CRC-16). The sender opens the first file and sends block number 0 with the following information.[2] Only the pathname (file name) part is required for batch transfers. To maintain upwards compatibility, all unused bytes in block 0 must be set to null. Pathname The pathname (conventionally, the file name) is sent as a null terminated ASCII string. This is the filename format used by the handle oriented MSDOS(TM) functions and C library fopen functions. An assembly language example follows: DB 'foo.bar',0 No spaces are included in the pathname. Normally only the file name stem (no directory prefix) is transmitted unless the sender has selected YAM's f option to send the full pathname. The source drive (A:, B:, etc.) is not sent. Filename Considerations: __________ 1. The MODEM7 batch protocol transmitted CP/M FCB bytes f1...f8 and t1...t3 one character at a time. The receiver echoed these bytes as received, one at a time. 2. Only the data part of the block is described here. Chapter 5 XMODEM Protocol Enhancements X/YMODEM Protocol Reference June 18 1988 14 + File names are forced to lower case unless the sending system supports upper/lower case file names. This is a convenience for users of systems (such as Unix) which store filenames in upper and lower case. + The receiver should accommodate file names in lower and upper case. + When transmitting files between different operating systems, file names must be acceptable to both the sender and receiving operating systems. If directories are included, they are delimited by /; i.e., "subdir/foo" is acceptable, "subdir\foo" is not. Length The file length and each of the succeeding fields are optional.[3] The length field is stored in the block as a decimal string counting the number of data bytes in the file. The file length does not include any CPMEOF (^Z) or other garbage characters used to pad the last block. If the file being transmitted is growing during transmission, the length field should be set to at least the final expected file length, or not sent. The receiver stores the specified number of characters, discarding any padding added by the sender to fill up the last block. Modification Date The mod date is optional, and the filename and length may be sent without requiring the mod date to be sent. Iff the modification date is sent, a single space separates the modification date from the file length. The mod date is sent as an octal number giving the time the contents of the file were last changed, measured in seconds from Jan 1 1970 Universal Coordinated Time (GMT). A date of 0 implies the modification date is unknown and should be left as the date the file is received. This standard format was chosen to eliminate ambiguities arising from transfers between different time zones. __________ 3. Fields may not be skipped. Chapter 5 XMODEM Protocol Enhancements X/YMODEM Protocol Reference June 18 1988 15 Mode Iff the file mode is sent, a single space separates the file mode from the modification date. The file mode is stored as an octal string. Unless the file originated from a Unix system, the file mode is set to 0. rb(1) checks the file mode for the 0x8000 bit which indicates a Unix type regular file. Files with the 0x8000 bit set are assumed to have been sent from another Unix (or similar) system which uses the same file conventions. Such files are not translated in any way. Serial Number Iff the serial number is sent, a single space separates the serial number from the file mode. The serial number of the transmitting program is stored as an octal string. Programs which do not have a serial number should omit this field, or set it to 0. The receiver's use of this field is optional. Other Fields YMODEM was designed to allow additional header fields to be added as above without creating compatibility problems with older YMODEM programs. Please contact Omen Technology if other fields are needed for special application requirements. The rest of the block is set to nulls. This is essential to preserve upward compatibility.[4] If the filename block is received with a CRC or other error, a retransmission is requested. After the filename block has been received, it is ACK'ed if the write open is successful. If the file cannot be opened for writing, the receiver cancels the transfer with CAN characters as described above. The receiver then initiates transfer of the file contents with a "C" character, according to the standard XMODEM/CRC protocol. After the file contents and XMODEM EOT have been transmitted and acknowledged, the receiver again asks for the next pathname. Transmission of a null pathname terminates batch file transmission. Note that transmission of no files is not necessarily an error. This is possible if none of the files requested of the sender could be opened for reading. __________ 4. If, perchance, this information extends beyond 128 bytes (possible with Unix 4.2 BSD extended file names), the block should be sent as a 1k block as described above. Chapter 5 XMODEM Protocol Enhancements X/YMODEM Protocol Reference June 18 1988 16 Most YMODEM receivers request CRC-16 by default. The Unix programs sz(1) and rz(1) included in the source code file RZSZ.ZOO should answer other questions about YMODEM batch protocol. Figure 3. YMODEM Batch Transmission Session (1 file) SENDER RECEIVER "sb foo.*" "sending in batch mode etc." C (command:rb) SOH 00 FF foo.c NUL[123] CRC CRC ACK C SOH 01 FE Data[128] CRC CRC ACK SOH 02 FC Data[128] CRC CRC ACK SOH 03 FB Data[100] CPMEOF[28] CRC CRC ACK EOT NAK EOT ACK C SOH 00 FF NUL[128] CRC CRC ACK Figure 7. YMODEM Header Information and Features _____________________________________________________________ | Program | Length | Date | Mode | S/N | 1k-Blk | YMODEM-g | |___________|________|______|______|_____|________|__________| |Unix rz/sz | yes | yes | yes | no | yes | sb only | |___________|________|______|______|_____|________|__________| |VMS rb/sb | yes | no | no | no | yes | no | |___________|________|______|______|_____|________|__________| |Pro-YAM | yes | yes | no | yes | yes | yes | |___________|________|______|______|_____|________|__________| |CP/M YAM | no | no | no | no | yes | no | |___________|________|______|______|_____|________|__________| |KMD/IMP | ? | no | no | no | yes | no | |___________|________|______|______|_____|________|__________| 5.1 KMD/IMP Exceptions to YMODEM KMD and IMP use a "CK" character sequence emitted by the receiver to trigger the use of 1024 byte blocks as an alternative to specifying this option to the sending program. This two character sequence generally works well on single process micros in direct communication, provided the programs rigorously adhere to all the XMODEM recommendations included Chapter 5 XMODEM Protocol Enhancements X/YMODEM Protocol Reference June 18 1988 17 Figure 4. YMODEM Batch Transmission Session (2 files) SENDER RECEIVER "sb foo.c baz.c" "sending in batch mode etc." C (command:rb) SOH 00 FF foo.c NUL[123] CRC CRC ACK C SOH 01 FE Data[128] CRC CRC ACK SOH 02 FC Data[128] CRC CRC ACK SOH 03 FB Data[100] CPMEOF[28] CRC CRC ACK EOT NAK EOT ACK C SOH 00 FF baz.c NUL[123] CRC CRC ACK C SOH 01 FB Data[100] CPMEOF[28] CRC CRC ACK EOT NAK EOT ACK C SOH 00 FF NUL[128] CRC CRC ACK Figure 5. YMODEM Batch Transmission Session-1k Blocks SENDER RECEIVER "sb -k foo.*" "sending in batch mode etc." C (command:rb) SOH 00 FF foo.c NUL[123] CRC CRC ACK C STX 01 FD Data[1024] CRC CRC ACK SOH 02 FC Data[128] CRC CRC ACK SOH 03 FB Data[100] CPMEOF[28] CRC CRC ACK EOT NAK EOT Chapter 5 XMODEM Protocol Enhancements X/YMODEM Protocol Reference June 18 1988 18 ACK C SOH 00 FF NUL[128] CRC CRC ACK Figure 6. YMODEM Filename block transmitted by sz -rw-r--r-- 6347 Jun 17 1984 20:34 bbcsched.txt 00 0100FF62 62637363 6865642E 74787400 |...bbcsched.txt.| 10 36333437 20333331 34373432 35313320 |6347 3314742513 | 20 31303036 34340000 00000000 00000000 |100644..........| 30 00000000 00000000 00000000 00000000 40 00000000 00000000 00000000 00000000 50 00000000 00000000 00000000 00000000 60 00000000 00000000 00000000 00000000 70 00000000 00000000 00000000 00000000 80 000000CA 56 herein. Programs with marginal XMODEM implementations do not fare so well. Timesharing systems and packet switched networks can separate the successive characters, rendering this method unreliable. Sending programs may detect the CK sequence if the operating enviornment does not preclude reliable implementation. Instead of the standard YMODEM file length in decimal, KMD and IMP transmit the CP/M record count in the last two bytes of the header block. 6. YMODEM-g File Transmission Developing technology is providing phone line data transmission at ever higher speeds using very specialized techniques. These high speed modems, as well as session protocols such as X.PC, provide high speed, nearly error free communications at the expense of considerably increased delay time. This delay time is moderate compared to human interactions, but it cripples the throughput of most error correcting protocols. The g option to YMODEM has proven effective under these circumstances. The g option is driven by the receiver, which initiates the batch transfer by transmitting a G instead of C. When the sender recognizes the G, it bypasses the usual wait for an ACK to each transmitted block, sending succeeding blocks at full speed, subject to XOFF/XON or other flow control exerted by the medium. The sender expects an inital G to initiate the transmission of a particular file, and also expects an ACK on the EOT sent at the end of each file. This synchronization allows the receiver time to open and Chapter 6 XMODEM Protocol Enhancements X/YMODEM Protocol Reference June 18 1988 19 close files as necessary. If an error is detected in a YMODEM-g transfer, the receiver aborts the transfer with the multiple CAN abort sequence. The ZMODEM protocol should be used in applications that require both streaming throughput and error recovery. Figure 8. YMODEM-g Transmission Session SENDER RECEIVER "sb foo.*" "sending in batch mode etc..." G (command:rb -g) SOH 00 FF foo.c NUL[123] CRC CRC G SOH 01 FE Data[128] CRC CRC STX 02 FD Data[1024] CRC CRC SOH 03 FC Data[128] CRC CRC SOH 04 FB Data[100] CPMEOF[28] CRC CRC EOT ACK G SOH 00 FF NUL[128] CRC CRC Chapter 6 XMODEM Protocol Enhancements X/YMODEM Protocol Reference June 18 1988 20 7. XMODEM PROTOCOL OVERVIEW 8/9/82 by Ward Christensen. I will maintain a master copy of this. Please pass on changes or suggestions via CBBS/Chicago at (312) 545-8086, CBBS/CPMUG (312) 849-1132 or by voice at (312) 849-6279. 7.1 Definitions 01H 04H 06H 15H 18H 43H 7.2 Transmission Medium Level Protocol Asynchronous, 8 data bits, no parity, one stop bit. The protocol imposes no restrictions on the contents of the data being transmitted. No control characters are looked for in the 128-byte data messages. Absolutely any kind of data may be sent - binary, ASCII, etc. The protocol has not formally been adopted to a 7-bit environment for the transmission of ASCII-only (or unpacked-hex) data , although it could be simply by having both ends agree to AND the protocol-dependent data with 7F hex before validating it. I specifically am referring to the checksum, and the block numbers and their ones- complement. Those wishing to maintain compatibility of the CP/M file structure, i.e. to allow modemming ASCII files to or from CP/M systems should follow this data format: + ASCII tabs used (09H); tabs set every 8. + Lines terminated by CR/LF (0DH 0AH) + End-of-file indicated by ^Z, 1AH. (one or more) + Data is variable length, i.e. should be considered a continuous stream of data bytes, broken into 128-byte chunks purely for the purpose of transmission. + A CP/M "peculiarity": If the data ends exactly on a 128-byte boundary, i.e. CR in 127, and LF in 128, a subsequent sector containing the ^Z EOF character(s) is optional, but is preferred. Some utilities or user programs still do not handle EOF without ^Zs. Chapter 7 Xmodem Protocol Overview X/YMODEM Protocol Reference June 18 1988 21 + The last block sent is no different from others, i.e. there is no "short block". Figure 9. XMODEM Message Block Level Protocol Each block of the transfer looks like: <255-blk #><--128 data bytes--> in which: = 01 hex = binary number, starts at 01 increments by 1, and wraps 0FFH to 00H (not to 01) <255-blk #> = blk # after going thru 8080 "CMA" instr, i.e. each bit complemented in the 8-bit block number. Formally, this is the "ones complement". = the sum of the data bytes only. Toss any carry. 7.3 File Level Protocol 7.3.1 Common_to_Both_Sender_and_Receiver All errors are retried 10 times. For versions running with an operator (i.e. NOT with XMODEM), a message is typed after 10 errors asking the operator whether to "retry or quit". Some versions of the protocol use , ASCII ^X, to cancel transmission. This was never adopted as a standard, as having a single "abort" character makes the transmission susceptible to false termination due to an or being corrupted into a and aborting transmission. The protocol may be considered "receiver driven", that is, the sender need not automatically re-transmit, although it does in the current implementations. 7.3.2 Receive_Program_Considerations The receiver has a 10-second timeout. It sends a every time it times out. The receiver's first timeout, which sends a , signals the transmitter to start. Optionally, the receiver could send a immediately, in case the sender was ready. This would save the initial 10 second timeout. However, the receiver MUST continue to timeout every 10 seconds in case the sender wasn't ready. Once into a receiving a block, the receiver goes into a one-second timeout for each character and the checksum. If the receiver wishes to a block for any reason (invalid header, timeout receiving data), it must wait for the line to clear. See "programming tips" for ideas Synchronizing: If a valid block number is received, it will be: 1) the expected one, in which case everything is fine; or 2) a repeat of the previously received block. This should be considered OK, and only indicates that the receivers got glitched, and the sender re- transmitted; 3) any other block number indicates a fatal loss of synchronization, such as the rare case of the sender getting a line-glitch Chapter 7 Xmodem Protocol Overview X/YMODEM Protocol Reference June 18 1988 22 that looked like an . Abort the transmission, sending a 7.3.3 Sending_program_considerations While waiting for transmission to begin, the sender has only a single very long timeout, say one minute. In the current protocol, the sender has a 10 second timeout before retrying. I suggest NOT doing this, and letting the protocol be completely receiver-driven. This will be compatible with existing programs. When the sender has no more data, it sends an , and awaits an , resending the if it doesn't get one. Again, the protocol could be receiver-driven, with the sender only having the high-level 1-minute timeout to abort. Here is a sample of the data flow, sending a 3-block message. It includes the two most common line hits - a garbaged block, and an reply getting garbaged. represents the checksum byte. Figure 10. Data flow including Error Recovery SENDER RECEIVER times out after 10 seconds, <--- 01 FE -data- ---> <--- 02 FD -data- xx ---> (data gets line hit) <--- 02 FD -data- xx ---> <--- 03 FC -data- xx ---> (ack gets garbaged) <--- 03 FC -data- xx ---> ---> <--- ---> <--- (finished) 7.4 Programming Tips + The character-receive subroutine should be called with a parameter specifying the number of seconds to wait. The receiver should first call it with a time of 10, then and try again, 10 times. After receiving the , the receiver should call the character receive subroutine with a 1-second timeout, for the remainder of the message and the . Since they are sent as a continuous stream, timing out of this implies a serious like glitch that caused, say, 127 characters to be seen instead of 128. Chapter 7 Xmodem Protocol Overview X/YMODEM Protocol Reference June 18 1988 23 + When the receiver wishes to , it should call a "PURGE" subroutine, to wait for the line to clear. Recall the sender tosses any characters in its UART buffer immediately upon completing sending a block, to ensure no glitches were mis- interpreted. The most common technique is for "PURGE" to call the character receive subroutine, specifying a 1-second timeout,[1] and looping back to PURGE until a timeout occurs. The is then sent, ensuring the other end will see it. + You may wish to add code recommended by John Mahr to your character receive routine - to set an error flag if the UART shows framing error, or overrun. This will help catch a few more glitches - the most common of which is a hit in the high bits of the byte in two consecutive bytes. The comes out OK since counting in 1-byte produces the same result of adding 80H + 80H as with adding 00H + 00H. __________ 1. These times should be adjusted for use with timesharing systems. Chapter 7 Xmodem Protocol Overview X/YMODEM Protocol Reference June 18 1988 24 8. XMODEM/CRC Overview Original 1/13/85 by John Byrns -- CRC option. Please pass on any reports of errors in this document or suggestions for improvement to me via Ward's/CBBS at (312) 849-1132, or by voice at (312) 885-1105. The CRC used in the Modem Protocol is an alternate form of block check which provides more robust error detection than the original checksum. Andrew S. Tanenbaum says in his book, Computer Networks, that the CRC- CCITT used by the Modem Protocol will detect all single and double bit errors, all errors with an odd number of bits, all burst errors of length 16 or less, 99.997% of 17-bit error bursts, and 99.998% of 18-bit and longer bursts.[1] The changes to the Modem Protocol to replace the checksum with the CRC are straight forward. If that were all that we did we would not be able to communicate between a program using the old checksum protocol and one using the new CRC protocol. An initial handshake was added to solve this problem. The handshake allows a receiving program with CRC capability to determine whether the sending program supports the CRC option, and to switch it to CRC mode if it does. This handshake is designed so that it will work properly with programs which implement only the original protocol. A description of this handshake is presented in section 10. Figure 11. Message Block Level Protocol, CRC mode Each block of the transfer in CRC mode looks like: <255-blk #><--128 data bytes--> in which: = 01 hex = binary number, starts at 01 increments by 1, and wraps 0FFH to 00H (not to 01) <255-blk #> = ones complement of blk #. = byte containing the 8 hi order coefficients of the CRC. = byte containing the 8 lo order coefficients of the CRC. 8.1 CRC Calculation 8.1.1 Formal_Definition To calculate the 16 bit CRC the message bits are considered to be the coefficients of a polynomial. This message polynomial is first multiplied by X^16 and then divided by the generator polynomial (X^16 + X^12 + X^5 + __________ 1. This reliability figure is misleading because XMODEM's critical supervisory functions are not protected by this CRC. Chapter 8 Xmodem Protocol Overview X/YMODEM Protocol Reference June 18 1988 25 1) using modulo two arithmetic. The remainder left after the division is the desired CRC. Since a message block in the Modem Protocol is 128 bytes or 1024 bits, the message polynomial will be of order X^1023. The hi order bit of the first byte of the message block is the coefficient of X^1023 in the message polynomial. The lo order bit of the last byte of the message block is the coefficient of X^0 in the message polynomial. Figure 12. Example of CRC Calculation written in C The following XMODEM crc routine is taken from "rbsb.c". Please refer to the source code for these programs (contained in RZSZ.ZOO) for usage. A fast table driven version is also included in this file. /* update CRC */ unsigned short updcrc(c, crc) register c; register unsigned crc; { register count; for (count=8; --count>=0;) { if (crc & 0x8000) { crc <<= 1; crc += (((c<<=1) & 0400) != 0); crc ^= 0x1021; } else { crc <<= 1; crc += (((c<<=1) & 0400) != 0); } } return crc; } 8.2 CRC File Level Protocol Changes 8.2.1 Common_to_Both_Sender_and_Receiver The only change to the File Level Protocol for the CRC option is the initial handshake which is used to determine if both the sending and the receiving programs support the CRC mode. All Modem Programs should support the checksum mode for compatibility with older versions. A receiving program that wishes to receive in CRC mode implements the mode setting handshake by sending a in place of the initial . If the sending program supports CRC mode it will recognize the and will set itself into CRC mode, and respond by sending the first block as if a had been received. If the sending program does not support CRC mode it will not respond to the at all. After the receiver has sent the it will wait up to 3 seconds for the that starts the first block. If it receives a within 3 seconds it will assume the sender supports CRC mode and will proceed with the file exchange in CRC mode. If no is Chapter 8 Xmodem Protocol Overview X/YMODEM Protocol Reference June 18 1988 26 received within 3 seconds the receiver will switch to checksum mode, send a , and proceed in checksum mode. If the receiver wishes to use checksum mode it should send an initial and the sending program should respond to the as defined in the original Modem Protocol. After the mode has been set by the initial or the protocol follows the original Modem Protocol and is identical whether the checksum or CRC is being used. 8.2.2 Receive_Program_Considerations There are at least 4 things that can go wrong with the mode setting handshake. 1. the initial can be garbled or lost. 2. the initial can be garbled. 3. the initial can be changed to a . 4. the initial from a receiver which wants to receive in checksum can be changed to a . The first problem can be solved if the receiver sends a second after it times out the first time. This process can be repeated several times. It must not be repeated too many times before sending a and switching to checksum mode or a sending program without CRC support may time out and abort. Repeating the will also fix the second problem if the sending program cooperates by responding as if a were received instead of ignoring the extra . It is possible to fix problems 3 and 4 but probably not worth the trouble since they will occur very infrequently. They could be fixed by switching modes in either the sending or the receiving program after a large number of successive s. This solution would risk other problems however. 8.2.3 Sending_Program_Considerations The sending program should start in the checksum mode. This will insure compatibility with checksum only receiving programs. Anytime a is received before the first or the sending program should set itself into CRC mode and respond as if a were received. The sender should respond to additional s as if they were s until the first is received. This will assist the receiving program in determining the correct mode when the is lost or garbled. After the first is received the sending program should ignore s. Chapter 8 Xmodem Protocol Overview X/YMODEM Protocol Reference June 18 1988 27 8.3 Data Flow Examples with CRC Option Here is a data flow example for the case where the receiver requests transmission in the CRC mode but the sender does not support the CRC option. This example also includes various transmission errors. represents the checksum byte. Figure 13. Data Flow: Receiver has CRC Option, Sender Doesn't SENDER RECEIVER <--- times out after 3 seconds, <--- times out after 3 seconds, <--- times out after 3 seconds, <--- times out after 3 seconds, <--- 01 FE -data- ---> <--- 02 FD -data- ---> (data gets line hit) <--- 02 FD -data- ---> <--- 03 FC -data- ---> (ack gets garbaged) <--- times out after 10 seconds, <--- 03 FC -data- ---> <--- ---> <--- Here is a data flow example for the case where the receiver requests transmission in the CRC mode and the sender supports the CRC option. This example also includes various transmission errors. represents the 2 CRC bytes. Chapter 8 Xmodem Protocol Overview X/YMODEM Protocol Reference June 18 1988 28 Figure 14. Receiver and Sender Both have CRC Option SENDER RECEIVER <--- 01 FE -data- ---> <--- 02 FD -data- ---> (data gets line hit) <--- 02 FD -data- ---> <--- 03 FC -data- ---> (ack gets garbaged) <--- times out after 10 seconds, <--- 03 FC -data- ---> <--- ---> <--- Chapter 8 Xmodem Protocol Overview X/YMODEM Protocol Reference June 18 1988 29 9. MORE INFORMATION Please contact Omen Technology for troff source files and typeset copies of this document. 9.1 TeleGodzilla Bulletin Board More information may be obtained by calling TeleGodzilla at 503-621-3746. Speed detection is automatic for 1200, 2400 and 19200(Telebit PEP) bps. TrailBlazer modem users may issue the TeleGodzilla trailblazer command to swith to 19200 bps once they have logged in. Interesting files include RZSZ.ZOO (C source code), YZMODEM.ZOO (Official XMODEM, YMODEM, and ZMODEM protocol descriptions), ZCOMMEXE.ARC, ZCOMMDOC.ARC, and ZCOMMHLP.ARC (PC-DOS shareware comm program with XMODEM, True YMODEM(TM), ZMODEM, Kermit Sliding Windows, Telink, MODEM7 Batch, script language, etc.). 9.2 Unix UUCP Access UUCP sites can obtain the current version of this file with uucp omen!/u/caf/public/ymodem.doc /tmp A continually updated list of available files is stored in /usr/spool/uucppublic/FILES. When retrieving these files with uucp, remember that the destination directory on your system must be writeable by anyone, or the UUCP transfer will fail. The following L.sys line calls TeleGodzilla (Pro-YAM in host operation). TeleGodzilla determines the incoming speed automatically. In response to "Name Please:" uucico gives the Pro-YAM "link" command as a user name. The password (Giznoid) controls access to the Xenix system connected to the IBM PC's other serial port. Communications between Pro-YAM and Xenix use 9600 bps; YAM converts this to the caller's speed. Finally, the calling uucico logs in as uucp. omen Any ACU 2400 1-503-621-3746 se:--se: link ord: Giznoid in:--in: uucp 10. REVISIONS 6-18-88 Further revised for clarity. Corrected block numbering in two examples. 10-27-87 Optional fields added for number of files remaining to be sent and total number of bytes remaining to be sent. 10-18-87 Flow control discussion added to 1024 byte block descritpion, minor revisions for clarity per user comments. Chapter 10 Xmodem Protocol Overview X/YMODEM Protocol Reference June 18 1988 30 8-03-87 Revised for clarity. 5-31-1987 emphasizes minimum requirements for YMODEM, and updates information on accessing files. 9-11-1986 clarifies nomenclature and some minor points. The April 15 1986 edition clarifies some points concerning CRC calculations and spaces in the header. 11. YMODEM Programs ZCOMM, A shareware little brother to Professional-YAM, is available as ZCOMMEXE.ARC on TeleGodzilla and other bulletin board systems. ZCOMM may be used to test YMODEM amd ZMODEM implementations. Unix programs supporting YMODEM are available on TeleGodzilla in RZSZ.ZOO. This ZOO archive includes a ZCOMM/Pro-YAM/PowerCom script ZUPL.T to upload a bootstrap program MINIRB.C, compile it, and then upload the rest of the files using the compiled MINIRB. Most Unix like systems are supported, including V7, Xenix, Sys III, 4.2 BSD, SYS V, Idris, Coherent, and Regulus. A version for VAX-VMS is available in VRBSB.SHQ. Irv Hoff has added 1k blocks and basic YMODEM batch transfers to the KMD and IMP series programs, which replace the XMODEM and MODEM7/MDM7xx series respectively. Overlays are available for a wide variety of CP/M systems. Questions about Professional-YAM communications software may be directed to: Chuck Forsberg Omen Technology Inc 17505-V Sauvie Island Road Portland Oregon 97231 VOICE: 503-621-3406 :VOICE Modem: 503-621-3746 Speed: 19200(Telebit PEP),2400,1200,300 Usenet: ...!tektronix!reed!omen!caf CompuServe: 70007,2304 GEnie: CAF Unlike ZMODEM and Kermit, XMODEM and YMODEM place obstacles in the path of a reliable high performance implementation, evidenced by poor reliability under stress of the industry leaders' XMODEM and YMODEM programs. Omen Technology provides consulting and other services to those wishing to implement XMODEM, YMODEM, and ZMODEM with state of the art features and reliability. Chapter 11 Xmodem Protocol Overview CONTENTS 1. TOWER OF BABEL................................................... 2 1.1 Definitions................................................. 2 2. YMODEM MINIMUM REQUIREMENTS...................................... 4 3. WHY YMODEM?...................................................... 6 3.1 Some Messages from the Pioneer.............................. 7 4. XMODEM PROTOCOL ENHANCEMENTS..................................... 10 4.1 Graceful Abort.............................................. 10 4.2 CRC-16 Option............................................... 10 4.3 XMODEM-1k 1024 Byte Block................................... 11 5. YMODEM Batch File Transmission................................... 13 5.1 KMD/IMP Exceptions to YMODEM................................ 16 6. YMODEM-g File Transmission....................................... 18 7. XMODEM PROTOCOL OVERVIEW......................................... 20 7.1 Definitions................................................. 20 7.2 Transmission Medium Level Protocol.......................... 20 7.3 File Level Protocol......................................... 21 7.4 Programming Tips............................................ 22 8. XMODEM/CRC Overview.............................................. 24 8.1 CRC Calculation............................................. 24 8.2 CRC File Level Protocol Changes............................. 25 8.3 Data Flow Examples with CRC Option.......................... 27 9. MORE INFORMATION................................................. 29 9.1 TeleGodzilla Bulletin Board................................. 29 9.2 Unix UUCP Access............................................ 29 10. REVISIONS........................................................ 29 11. YMODEM Programs.................................................. 30 - i - LIST OF FIGURES Figure 1. XMODEM-1k Blocks.......................................... 12 Figure 2. Mixed 1024 and 128 byte Blocks............................ 12 Figure 3. YMODEM Batch Transmission Session (1 file)................ 16 Figure 4. YMODEM Batch Transmission Session (2 files)............... 16 Figure 5. YMODEM Batch Transmission Session-1k Blocks............... 16 Figure 6. YMODEM Filename block transmitted by sz................... 16 Figure 7. YMODEM Header Information and Features.................... 16 Figure 8. YMODEM-g Transmission Session............................. 19 Figure 9. XMODEM Message Block Level Protocol....................... 21 Figure 10. Data flow including Error Recovery........................ 22 Figure 11. Message Block Level Protocol, CRC mode.................... 24 Figure 12. Example of CRC Calculation written in C................... 25 Figure 13. Data Flow: Receiver has CRC Option, Sender Doesn't........ 27 Figure 14. Receiver and Sender Both have CRC Option.................. 28 - ii - syslinux-legacy-3.63+dfsg/memdump/README0000664000175000017500000000146210777447273016543 0ustar evanevanThis is a very simple COMBOOT program which can be used to dump memory regions over a serial port. To use it, type on the SYSLINUX command line: memdump , ,... For example: memdump 0 funnysystem- 0,0x600 0x9fc00,0x400 0xf0000,0x10000 ... dumps three memory ranges (the standard BIOS memory ranges, often useful) onto serial port 0. The can either be in the range 0-3 for the standard BIOS serial port, or the I/O address of the UART. The data is transferred using the YMODEM protocol; the Unix implementation of this protocol is called "rb" and is part of the "lrzsz" (or "rzsz") package. If one uses a terminal program like Minicom, there is often a way to invoke it from inside the terminal program; in Minicom, this is done with the Ctrl-A R control sequence. syslinux-legacy-3.63+dfsg/memdump/stdint.h0000664000175000017500000000760210777447273017343 0ustar evanevan/* * stdint.h */ #ifndef _STDINT_H #define _STDINT_H /* Exact types */ typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef signed long long int64_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; /* Small types */ typedef signed char int_least8_t; typedef signed short int_least16_t; typedef signed int int_least32_t; typedef signed long long int_least64_t; typedef unsigned char uint_least8_t; typedef unsigned short uint_least16_t; typedef unsigned int uint_least32_t; typedef unsigned long long uint_least64_t; /* Fast types */ typedef signed char int_fast8_t; typedef signed short int_fast16_t; typedef signed int int_fast32_t; typedef signed long long int_fast64_t; typedef unsigned char uint_fast8_t; typedef unsigned short uint_fast16_t; typedef unsigned int uint_fast32_t; typedef unsigned long long uint_fast64_t; /* Pointer types */ typedef int32_t intptr_t; typedef uint32_t uintptr_t; /* Maximal types */ typedef int64_t intmax_t; typedef uint64_t uintmax_t; /* * To be strictly correct... */ #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) # define INT8_MIN (-128) # define INT16_MIN (-32767-1) # define INT32_MIN (-2147483647-1) # define INT64_MIN (-9223372036854775807LL-1) # define INT8_MAX (127) # define INT16_MAX (32767) # define INT32_MAX (2147483647) # define INT64_MAX (9223372036854775807LL) # define UINT8_MAX (255U) # define UINT16_MAX (65535U) # define UINT32_MAX (4294967295U) # define UINT64_MAX (18446744073709551615ULL) # define INT_LEAST8_MIN (-128) # define INT_LEAST16_MIN (-32767-1) # define INT_LEAST32_MIN (-2147483647-1) # define INT_LEAST64_MIN (-9223372036854775807LL-1) # define INT_LEAST8_MAX (127) # define INT_LEAST16_MAX (32767) # define INT_LEAST32_MAX (2147483647) # define INT_LEAST64_MAX (9223372036854775807LL) # define UINT_LEAST8_MAX (255U) # define UINT_LEAST16_MAX (65535U) # define UINT_LEAST32_MAX (4294967295U) # define UINT_LEAST64_MAX (18446744073709551615ULL) # define INT_FAST8_MIN (-128) # define INT_FAST16_MIN (-32767-1) # define INT_FAST32_MIN (-2147483647-1) # define INT_FAST64_MIN (-9223372036854775807LL-1) # define INT_FAST8_MAX (127) # define INT_FAST16_MAX (32767) # define INT_FAST32_MAX (2147483647) # define INT_FAST64_MAX (9223372036854775807LL) # define UINT_FAST8_MAX (255U) # define UINT_FAST16_MAX (65535U) # define UINT_FAST32_MAX (4294967295U) # define UINT_FAST64_MAX (18446744073709551615ULL) # define INTPTR_MIN (-2147483647-1) # define INTPTR_MAX (2147483647) # define UINTPTR_MAX (4294967295U) # define INTMAX_MIN (-9223372036854775807LL-1) # define INTMAX_MAX (9223372036854775807LL) # define UINTMAX_MAX (18446744073709551615ULL) /* ptrdiff_t limit */ # define PTRDIFF_MIN (-2147483647-1) # define PTRDIFF_MAX (2147483647) /* sig_atomic_t limit */ # define SIG_ATOMIC_MIN (-2147483647-1) # define SIG_ATOMIC_MAX (2147483647) /* size_t limit */ # define SIZE_MAX (4294967295U) #endif /* STDC_LIMIT_MACROS */ #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) # define INT8_C(n) n # define INT16_C(n) n # define INT32_C(n) n # define INT64_C(n) n ## LL # define UINT8_C(n) n ## U # define UINT16_C(n) n ## U # define UINT32_C(n) n ## U # define UINT64_C(n) n ## ULL # define INTMAX_C(n) n ## LL # define UINTMAX_C(n) n ## ULL #endif /* STDC_CONSTANT_MACROS */ #endif /* _STDINT_H */ syslinux-legacy-3.63+dfsg/memdump/ymsend.c0000664000175000017500000001121210777447273017320 0ustar evanevan/* * Ymodem send routine. Only supports 1K blocks and CRC mode. */ #include #include #include "ymsend.h" enum { SOH = 0x01, STX = 0x02, EOT = 0x04, ACK = 0x06, NAK = 0x15, CAN = 0x18, }; /* * Append a CRC16 to a block */ static void add_crc16(uint8_t *blk, int len) { static const uint16_t crctab[256] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 }; uint16_t crc = 0; while (len--) crc = crctab[(crc >> 8) ^ *blk++] ^ crc << 8; *blk++ = crc >> 8; *blk = crc; } static void send_ack_blk(struct serial_if *sif, const void *data, size_t bytes) { uint8_t ack_buf; if (bytes) sif->write(sif, data, bytes); do { do { sif->read(sif, &ack_buf, 1); } while (ack_buf != ACK && ack_buf != NAK); } while (ack_buf == NAK); } static const uint8_t eot_buf = EOT; void send_ymodem(struct serial_if *sif, struct file_info *fileinfo, void (*gen_data)(void *, size_t, struct file_info *, size_t)) { uint8_t ack_buf, blk_buf[1024+5], *np, *q; const char *p; size_t len, lx, pos; int blk; /* Wait for initial handshake */ printf("Waiting for handshake...\n"); do { sif->read(sif, &ack_buf, 1); } while (ack_buf != 'C'); /* Send initial batch header (filename, length etc.) */ q = blk_buf + 3; p = fileinfo->name; while (*p) *q++ = *p++; *q++ = '\0'; lx = len = fileinfo->size; do { q++; lx /= 10; } while (lx); np = q; lx = len; do { *--np = (lx % 10) + '0'; lx /= 10; } while (lx); while (q < blk_buf+1024+3) *q++ = 0; blk = 0; pos = 0; do { if (blk != 0) { gen_data(blk_buf+3, 1024, fileinfo, pos); pos += 1024; len = (len < 1024) ? 0 : len-1024; } blk_buf[0] = STX; blk_buf[1] = blk; blk_buf[2] = ~blk; add_crc16(blk_buf+3, 1024); printf("Sending block %d...\r", blk); send_ack_blk(sif, blk_buf, 1024+5); blk++; } while(len); printf("\nSending EOT...\n"); send_ack_blk(sif, &eot_buf, 1); printf("Done.\n"); } void end_ymodem(struct serial_if *sif) { uint8_t ack_buf; uint8_t blk_buf[128+5]; /* Wait for initial handshake */ printf("END: Waiting for handshake...\n"); do { sif->read(sif, &ack_buf, 1); } while (ack_buf != 'C'); memset(blk_buf, 0, sizeof blk_buf); blk_buf[0] = SOH; blk_buf[1] = 0; blk_buf[2] = 0xff; add_crc16(blk_buf+3, 128); printf("Sending block 0...\n"); send_ack_blk(sif, &blk_buf, 128+5); printf("Sending EOT...\n"); sif->write(sif, &eot_buf, 1); /* rb doesn't ack the EOT for an end batch transfer. */ printf("Done.\n"); } syslinux-legacy-3.63+dfsg/memdump/memdump.com0000775000175000017500000001303010777447311020015 0ustar evanevanff1S)ff1fPff fPfXfZfL!fUfWfVfSfgfD$gf$gft$0gfqgff=w.ffgf$ffffgf|$dfg\$ff%f1fffff1fff f fff0fЀ̓f4gfD$fgfD$gfD$gfD$ gfD$f%f1ffgfL$ff1fff f fff8fЀ̓f<fgf $fAff ff`faff[f^f_f]fffSffffaffUffLf fffjgfL$fgfqfUfWfVfSfQfXgfD$gfT$ gf$!fffgf|$ fgfDŽ$HfSgf$Dgf$Pfjfff1fXfYgfZgfTLfPfSfRfhfkfftfgfT$ gfBf1f1fffgfDLfffft ffgfL$ gfIgfL$f&f gf$!ffffgf$TgfL$ gff1ffgf$Tg8,tf:f@f1f1fff fPfWgft$(fhVgf\$=fSf gf$`gf$dgf$hf fdfVffMf fAgf$@fHfffEgf;l$/fmffff1fXfYf[f^f_f]gfafÐfVfSfgf0fgfVftfgfAfKfuf[f^fffVfSfgf0fgfVf tgffAffKfuf[f^ffWfVfSfgf0gfNffgf^f1ffgD$fgD$fgD$fg|$uJg|$uBg|$u:ff1gfAfffgfVf0gfD$,8gfD$,ff1ffgfD$(ggfD$,gT>f@gfD$,fugft$,gf$f9}fff)fufg fCfgf@fg|$'t gL$'g fCgf|$ t*fug0fCfug0gfL$(gA!gCffuf gT$gfCfgf@ffg0fCfHgf9D$,|gfL$,gfL$,gD >gfCgf|$,fg fCfHfffČf[f^f_f]ffUfWfVfSfgfD$ gfT$ffr<%u gfD$ggfL$fAgfL$gf€+t# t%#u;'-t0u/$gfL$gfL$gfL$gfL$ gfL$f0f wgfD$ff1*tf&gfAgfD$gfOgf/fy fgfL$fgfT$g:.t gfD$bgfBgfD$gJff0f wgfD$fgfD$*u"gfBgfD$gfgfD$fgf|$y gfD$gfD$ghtlt Ltf ff@gfD$gfD$g2.Qp:Yxʱ -No0 P%@Fpg`ڳ=^"25BRwbVr˥nO, 4$ftGd$TDۧ_~<&6WfvvF4VLm/ș鉊DXeHx'h8(}\?؛uJTZ7jz *:.lMͪɍ&|ld\EL<, >]|ߛُn6~UNt^.>0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz$\Psyslinux-legacy-3.63+dfsg/memdump/io.h0000664000175000017500000000142310777447273016440 0ustar evanevan#ifndef IO_H #define IO_H static inline void outb(unsigned char v, unsigned short p) { asm volatile("outb %1,%0" : : "d" (p), "a" (v)); } static inline unsigned char inb(unsigned short p) { unsigned char v; asm volatile("inb %1,%0" : "=a" (v) : "d" (p)); return v; } static inline void outw(unsigned short v, unsigned short p) { asm volatile("outw %1,%0" : : "d" (p), "a" (v)); } static inline unsigned short inw(unsigned short p) { unsigned short v; asm volatile("inw %1,%0" : "=a" (v) : "d" (p)); return v; } static inline void outl(unsigned int v, unsigned short p) { asm volatile("outl %1,%0" : : "d" (p), "a" (v)); } static inline unsigned int inl(unsigned short p) { unsigned int v; asm volatile("inl %1,%0" : "=a" (v) : "d" (p)); return v; } #endif syslinux-legacy-3.63+dfsg/memdump/conio.c0000664000175000017500000000172310777447273017136 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * conio.c * * Output to the screen */ #include #include "mystuff.h" int putchar(int ch) { if ( ch == '\n' ) putchar('\r'); asm("movb $0x02,%%ah ; int $0x21" : : "d" (ch)); return ch; } /* Note: doesn't put '\n' like the stdc version does */ int puts(const char *s) { int count = 0; while ( *s ) { putchar(*s); count++; s++; } return count; } syslinux-legacy-3.63+dfsg/memdump/skipatou.c0000664000175000017500000000022010777447273017655 0ustar evanevan#include "mystuff.h" unsigned int skip_atou(const char **s) { int i=0; while (isdigit(**s)) i = i*10 + *((*s)++) - '0'; return i; } syslinux-legacy-3.63+dfsg/memdump/memset.S0000664000175000017500000000040710777447273017277 0ustar evanevan# # memset.S # # Minimal 16-bit memset() implementation # .text .code16gcc .globl memset .type memset, @function memset: cld pushw %di movw %ax,%di movb %dl,%al # The third argument is already in %cx rep ; stosb popw %di retl .size memset,.-memset syslinux-legacy-3.63+dfsg/memdump/main.c0000664000175000017500000000656510777447273016764 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include #include #include #include "mystuff.h" #include "ymsend.h" #include "io.h" const char *program = "memdump"; void __attribute__((noreturn)) die(const char *msg) { puts(program); puts(": "); puts(msg); putchar('\n'); exit(1); } #ifdef DEBUG # define dprintf printf #else # define dprintf(...) ((void)0) #endif static inline __attribute__((const)) uint16_t ds(void) { uint16_t v; asm("movw %%ds,%0" : "=rm" (v)); return v; } #define GDT_ENTRY(flags,base,limit) \ (((uint64_t)(base & 0xff000000) << 32) | \ ((uint64_t)flags << 40) | \ ((uint64_t)(limit & 0x00ff0000) << 32) | \ ((uint64_t)(base & 0x00ffff00) << 16) | \ ((uint64_t)(limit & 0x0000ffff))) static void get_bytes(void *buf, size_t len, struct file_info *finfo, size_t pos) { size_t end; static uint64_t gdt[6]; size_t bufl; pos += (size_t)finfo->pvt; /* Add base */ end = pos+len; if (end <= 0x100000) { /* Can stay in real mode */ asm volatile("movw %3,%%fs ; " "fs; rep; movsl ; " "movw %2,%%cx ; " "rep; movsb" : : "D" (buf), "c" (len >> 2), "r" ((uint16_t)(len & 3)), "rm" ((uint16_t)(pos >> 4)), "S" (pos & 15) : "memory"); } else { bufl = (ds() << 4)+(size_t)buf; gdt[2] = GDT_ENTRY(0x0093, pos, 0xffff); gdt[3] = GDT_ENTRY(0x0093, bufl, 0xffff); asm volatile("pushal ; int $0x15 ; popal" : : "a" (0x8700), "c" ((len+1) >> 1), "S" (&gdt) : "memory"); } } int main(int argc, char *argv[]) { uint16_t bios_ports[4]; const char *prefix; char filename[1024]; int i; static struct serial_if sif = { .read = serial_read, .write = serial_write, }; struct file_info finfo; const char serial_banner[] = "Now begin Ymodem download...\r\n"; if (argc < 4) die("usage: memdump port prefix start,len..."); finfo.pvt = (void *)0x400; get_bytes(bios_ports, 8, &finfo, 0); /* Get BIOS serial ports */ for (i = 0; i < 4; i++) printf("ttyS%i (COM%i) is at %#x\n", i, i+1, bios_ports[i]); sif.port = strtoul(argv[1], NULL, 0); if (sif.port <= 3) { sif.port = bios_ports[sif.port]; } if (serial_init(&sif)) die("failed to initialize serial port"); prefix = argv[2]; puts("Printing prefix...\n"); sif.write(&sif, serial_banner, sizeof serial_banner-1); for (i = 3; i < argc; i++) { uint32_t start, len; char *ep; start = strtoul(argv[i], &ep, 0); if (*ep != ',') die("invalid range specification"); len = strtoul(ep+1, NULL, 0); sprintf(filename, "%s%#x-%#x.bin", prefix, start, len); finfo.name = filename; finfo.size = len; finfo.pvt = (void *)start; puts("Sending "); puts(filename); puts("...\n"); send_ymodem(&sif, &finfo, get_bytes); } puts("Sending closing signature...\n"); end_ymodem(&sif); return 0; } syslinux-legacy-3.63+dfsg/memdump/inttypes.h0000664000175000017500000000002410777447273017704 0ustar evanevan#include syslinux-legacy-3.63+dfsg/memdump/__divdi3.c0000664000175000017500000000064210777447273017506 0ustar evanevan/* * arch/i386/libgcc/__divdi3.c */ #include #include extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); int64_t __divdi3(int64_t num, int64_t den) { int minus = 0; int64_t v; if ( num < 0 ) { num = -num; minus = 1; } if ( den < 0 ) { den = -den; minus ^= 1; } v = __udivmoddi4(num, den, NULL); if ( minus ) v = -v; return v; } syslinux-legacy-3.63+dfsg/memdump/errno.h0000664000175000017500000000013510777447273017155 0ustar evanevan#ifndef ERRNO_H #define ERRNO_H int errno; void perror(const char *); #endif /* ERRNO_H */ syslinux-legacy-3.63+dfsg/memdump/serial.c0000664000175000017500000000273410777447273017311 0ustar evanevan#include "mystuff.h" #include "ymsend.h" #include "io.h" enum { THR = 0, RBR = 0, DLL = 0, DLM = 1, IER = 1, IIR = 2, FCR = 2, LCR = 3, MCR = 4, LSR = 5, MSR = 6, SCR = 7, }; int serial_init(struct serial_if *sif) { uint16_t port = sif->port; uint8_t dll, dlm, lcr; /* Set 115200n81 */ outb(0x83, port+LCR); outb(0x01, port+DLL); outb(0x00, port+DLM); (void)inb(port+IER); /* Synchronize */ dll = inb(port+DLL); dlm = inb(port+DLM); lcr = inb(port+LCR); outb(0x03, port+LCR); (void)inb(port+IER); /* Synchronize */ if (dll != 0x01 || dlm != 0x00 || lcr != 0x83) return -1; /* This doesn't look like a serial port */ /* Disable interrupts */ outb(port+IER, 0); /* Enable 16550A FIFOs if available */ outb(port+FCR, 0x01); /* Enable FIFO */ (void)inb(port+IER); /* Synchronize */ if (inb(port+IIR) < 0xc0) outb(port+FCR, 0x00); /* Disable FIFOs if non-functional */ (void)inb(port+IER); /* Synchronize */ return 0; } void serial_write(struct serial_if *sif, const void *data, size_t n) { uint16_t port = sif->port; const char *p = data; uint8_t lsr; while (n--) { do { lsr = inb(port+LSR); } while (!(lsr & 0x20)); outb(*p++, port+THR); } } void serial_read(struct serial_if *sif, void *data, size_t n) { uint16_t port = sif->port; char *p = data; uint8_t lsr; while (n--) { do { lsr = inb(port+LSR); } while (!(lsr & 0x01)); *p++ = inb(port+RBR); } } syslinux-legacy-3.63+dfsg/layout.inc0000664000175000017500000000607310777447273016232 0ustar evanevan; ----------------------------------------------------------------------- ; ; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Bostom MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; ----------------------------------------------------------------------- ; ; layout.inc ; ; Memory layout of segments ; ; Memory below 0800h is reserved for the BIOS and the MBR. BSS_START equ 0800h ; Text starts at the load address of 07C00h. TEXT_START equ 7C00h ; The secondary BSS section, above the text; we really wish we could ; just make it follow .bcopy32 or hang off the end, ; but it doesn't seem to work that way. LATEBSS_START equ 0B800h ; Reserve memory for the stack. This causes checkov to abort the ; compile if we violate this space. STACK_SIZE equ 4096 STACK_START equ TEXT_START-STACK_SIZE %ifdef MAP [map all MAP] %endif ; ; The various sections and their relationship ; org TEXT_START ; Use .earlybss for things that MUST be in low memory. section .earlybss nobits start=BSS_START section .bcopy32 align=4 valign=16 follows=.data vfollows=.earlybss section .config align=4 valign=16 follows=.bcopy32 vfollows=.bcopy32 section .config.end nobits valign=4 vfollows=.config ; Use .bss for things that doesn't have to be in low memory; ; with .bss1 and .bss2 to offload. .earlybss should be used ; for things that absolutely have to be below 0x7c00. section .bss nobits valign=16 vfollows=.config.end ; Warning here: RBFG build 22 randomly overwrites ; memory location [0x5680,0x576c), possibly more. It ; seems that it gets confused and screws up the ; pointer to its own internal packet buffer and starts ; writing a received ARP packet into low memory. %if IS_PXELINUX section .rbfg nobits start=0x5680 RBFG_brainfuck: resb 2048 ; Bigger than an Ethernet packet... %endif ; For section following .rbfg %if IS_PXELINUX section .bss2 nobits valign=16 vfollows=.rbfg %else section .bss2 nobits valign=16 vfollows=.bss %endif section .text start=TEXT_START ; NASM BUG: .data always follows .text; can't override section .data align=16 ; follows=.text ; This empty section works around a NASM bug with regards ; to follows= and nobits sections following a section which ; has VMA != LMA. section .advpad progbits align=512 follows=.config section .adv nobits align=512 follows=.advpad ; .uibss contains bss data which is guaranteed to be ; safe to clobber during the loading of the image. This ; is because while loading the primary image we will clobber ; the spillover from the last fractional sector load. section .uibss nobits align=16 follows=.adv ; Normal bss... section .bss1 nobits align=16 follows=.uibss ; Reserve space for stack section .stack nobits align=16 start=STACK_START Stack resb STACK_SIZE syslinux-legacy-3.63+dfsg/doc/0000775000175000017500000000000010777463606014757 5ustar evanevansyslinux-legacy-3.63+dfsg/doc/mboot.txt0000664000175000017500000000164710777447273016652 0ustar evanevan mboot.c32 --------- mboot.c32 is a 32-bit comboot module that allows SYSLINUX and its variants to load and boot kernels that use the Multiboot standard (e.g. the Xen virtual machine monitor, and the Fiasco and GNU Mach microkernels). To load a multiboot kernel and modules in SYSLINUX, put mboot.c32 (from com32/modules) in the boot directory, and load it as the "kernel" in the configuration file. The command-line to pass to mboot.c32 is the kernel command-line, followed by all the module command lines, separated with '---'. For example, to load a Xen VMM, xenlinux and an initrd: DEFAULT mboot.c32 xen.gz dom0_mem=15000 nosmp noacpi --- linux.gz console=tty0 root=/dev/hda1 --- initrd.img or, as a choice in a menu: LABEL Xen KERNEL mboot.c32 APPEND xen.gz dom0_mem=15000 nosmp noacpi --- linux.gz console=tty0 root=/dev/hda1 --- initrd.img mboot.c32 requires version 2.12 or later of SYSLINUX. Tim Deegan, May 2005 syslinux-legacy-3.63+dfsg/doc/isolinux.txt0000664000175000017500000001160410777447273017376 0ustar evanevan ISOLINUX A bootloader for Linux using ISO 9660/El Torito CD-ROMs Copyright 1994-2008 H. Peter Anvin - All Rights Reserved This program is provided under the terms of the GNU General Public License, version 2 or, at your option, any later version. There is no warranty, neither expressed nor implied, to the function of this program. Please see the included file COPYING for details. ---------------------------------------------------------------------- ISOLINUX is a boot loader for Linux/i386 that operates off ISO 9660/El Torito CD-ROMs in "no emulation" mode. This avoids the need to create an "emulation disk image" with limited space (for "floppy emulation") or compatibility problems (for "hard disk emulation".) This documentation isn't here yet, but here is enough that you should be able to test it out: Make sure you have a recent enough version of mkisofs. I recommend mkisofs 1.13 (distributed with cdrecord 1.9), but 1.12 might work as well (not tested.) To create an image, create a directory called "isolinux" (or, if you prefer, "boot/isolinux") underneath the root directory of your ISO image master file tree. Copy isolinux.bin, a config file called "isolinux.cfg" (see syslinux.txt for details on the configuration file), and all necessary files (kernels, initrd, display files, etc.) into this directory, then use the following command to create your ISO image (add additional options as appropriate, such as -J or -R): mkisofs -o \ -b isolinux/isolinux.bin -c isolinux/boot.cat \ -no-emul-boot -boot-load-size 4 -boot-info-table \ (If you named the directory boot/isolinux that should of course be -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat.) ISOLINUX resolves pathnames the following way: - A pathname consists of names separated by slashes, Unix-style. - A leading / means it searches from the root directory; otherwise the search is from the isolinux directory (think of this as the "current directory".) - . and .. in pathname searches are not supported. - The maximum length of any pathname is 255 characters. Note that ISOLINUX only uses the "plain" ISO 9660 filenames, i.e. it does not support Rock Ridge or Joliet filenames. It can still be used on a disk which uses Rock Ridge and/or Joliet extensions, of course. Under Linux, you can verify the plain filenames by mounting with the "-o norock,nojoliet" option to the mount command. Note, however, that ISOLINUX does support "long" (level 2) ISO 9660 plain filenames, so if compatibility with short-names-only operating systems like MS-DOS is not an issue, you can use the "-l" or "-iso-level 2" option to mkisofs to generate long (up to 31 characters) plain filenames. ISOLINUX does not support discontiguous files, interleaved mode, or logical block and sector sizes other than 2048. This should normally not be a problem. ISOLINUX is by default built in two versions, one version with extra debugging messages enabled. If you are having problems with ISOLINUX, I would greatly appreciate if you could try out the debugging version (isolinux-debug.bin) and let me know what it reports. YOU MAY WANT TO CONSIDER USING THE DEBUGGING VERSION BY DEFAULT. ++++ NOTE ON THE CONFIG FILE DIRECTORY ++++ ISOLINUX will search for the config file directory in the order /boot/isolinux, /isolinux, /. The first directory that exists is used, even if it contains no files. Therefore, please make sure that these directories don't exist if you don't want ISOLINUX to use them. ++++ BOOTING DOS (OR OTHER SIMILAR OPERATING SYSTEMS) ++++ WARNING: This feature depends on BIOS functionality which is apparently broken in a very large number of BIOSes. Therefore, this may not work on any particular system. No workaround is possible; if you find that it doesn't work please complain to your vendor and indicate that "BIOS INT 13h AX=4C00h fails." To boot DOS, or other real-mode operating systems (protected-mode operating systems may or may not work correctly), using ISOLINUX, you need to prepare a disk image (usually a floppy image, but a hard disk image can be used on *most* systems) with the relevant operating system. This file should be included on the CD-ROM in the /isolinux directory, and have a .img extension. The ".img" extension does not have to be specified on the command line, but has to be explicitly specified if used in a "kernel" statement in isolinux.cfg. For a floppy image, the size of the image should be exactly one of the following: 1,228,800 bytes - For a 1200K floppy image 1,474,560 bytes - For a 1440K floppy image 2,949,120 bytes - For a 2880K floppy image Any other size is assumed to be a hard disk image. In order to work on as many systems as possible, a hard disk image should have exactly one partition, marked active, that covers the entire size of the disk image file. Even so, hard disk images are not supported on all BIOSes. syslinux-legacy-3.63+dfsg/doc/extlinux.txt0000664000175000017500000001075610777447273017413 0ustar evanevanEXTLINUX is a new syslinux derivative, which boots from a Linux ext2/ext3 filesystem. It works the same way as SYSLINUX, with a few slight modifications. 1. The installer is run on a *mounted* filesystem. Run the extlinux installer on the directory in which you want extlinux installed: extlinux --install /boot Specify --install (-i) to install for the first time, or --update (-U) to upgrade a previous installation. NOTE: this doesn't have to be the root directory of a filesystem. If /boot is a filesystem, you can do: mkdir -p /boot/extlinux extlinux --install /boot/extlinux ... to create a subdirectory and install extlinux in it. /boot/extlinux is the recommended location for extlinux. 2. The configuration file is called "extlinux.conf", and is expected to be found in the same directory as extlinux is installed in. 3. Pathnames can be absolute or relative; if absolute (with a leading slash), they are relative to the root of the filesystem on which extlinux is installed (/boot in the example above), if relative, they are relative to the extlinux directory. extlinux supports subdirectories, but the total path length is limited to 511 characters. 4. EXTLINUX now supports symbolic links. However, extremely long symbolic links might hit the pathname limit. Also, please note that absolute symbolic links are interpreted from the root *of the filesystem*, which might be different from now the running system would interpret it (e.g. in the case of a separate /boot partition.) Therefore, use relative symbolic links if at all possible. 5. EXTLINUX now has "boot-once" support. The boot-once information is stored in an on-disk datastructure, part of extlinux.sys, called the "Auxillary Data Vector". The Auxilliary Data Vector is also available to COMBOOT/COM32 modules that want to store small amounts of information. To set the boot-once information, do: extlinux --once 'command' /boot/extlinux where 'command' is any command you could enter at the SYSLINUX command line. It will be executed on the next boot and then erased. To clear the boot-once information, do: extlinux --clear-once /boot/extlinux If EXTLINUX is used on a RAID-1, this is recommended, since under certain circumstances a RAID-1 rebuild can "resurrect" the boot-once information otherwise. To clear the entire Auxillary Data Vector, do: extlinux --reset-adv /boot/extlinux This will erase all data stored in the ADV, including boot-once. The --once, --clear-once, and --reset-adv commands can be combined with --install or --update, if desired. The ADV is preserved across updates, unless --reset-adv is specified. Note that EXTLINUX installs in the filesystem partition like a well-behaved bootloader :) Thus, it needs a master boot record in the partition table; the mbr.bin shipped with SYSLINUX should work well. To install it just do: cat mbr.bin > /dev/XXX ... where /dev/XXX is the appropriate master device, e.g. /dev/hda, and make sure the correct partition in set active. If you have multiple disks in a software RAID configuration, the preferred way to boot is: - Create a separate RAID-1 partition for /boot. Note that the Linux RAID-1 driver can span as many disks as you wish. - Install the MBR on *each disk*, and mark the RAID-1 partition active. - Run "extlinux -i /boot" to install extlinux. This will install it on all the drives in the RAID-1 set, which means you can boot any combination of drives in any order. It is not required to re-run the extlinux installer after installing new kernels. If you are using ext3 journalling, however, it might be desirable to do so, since running the extlinux installer will flush the log. Otherwise a dirty shutdown could cause some of the new kernel image to still be in the log. This is a general problem for boot loaders on journalling filesystems; it is not specific to extlinux. The "sync" command does not flush the log on the ext3 filesystem. The SYSLINUX series boot loaders support chain loading other operating systems via a separate module, chain.c32 (located in com32/modules/chain.c32). To use it, specify a LABEL in the configuration file with KERNEL chain.c32 and APPEND [hd|fd] [] For example: # Windows CE/ME/NT, a very dense operating system. # Second partition (2) on the first hard disk (hd0); # Linux would *typically* call this /dev/hda2 or /dev/sda2. LABEL cement KERNEL chain.c32 APPEND hd0 2 See also README.menu. syslinux-legacy-3.63+dfsg/doc/memdisk.txt0000664000175000017500000001465110777447273017162 0ustar evanevan[This documentation is rather crufty at the moment.] MEMDISK is meant to allow booting legacy operating systems via PXE, and as a workaround for BIOSes where ISOLINUX image support doesn't work. MEMDISK simulates a disk by claiming a chunk of high memory for the disk and a (very small - 2K typical) chunk of low (DOS) memory for the driver itself, then hooking the INT 13h (disk driver) and INT 15h (memory query) BIOS interrupts. To use it, type on the SYSLINUX command line: memdisk initrd=diskimg.img ... where diskimg.img is the disk image you want to boot from. [Obviously, the memdisk binary as well as your disk image file need to be present in the boot image directory.] ... or add to your syslinux.cfg/pxelinux.cfg/isolinux.cfg something like: label dos kernel memdisk append initrd=dosboot.img Note the following: a) The disk image can be uncompressed or compressed with gzip or zip. b) If the disk image is one of the following sizes, it's assumed to be a floppy image: 368,640 bytes - 360K floppy 737,280 bytes - 720K floppy 1,222,800 bytes - 1200K floppy 1,474,560 bytes - 1440K floppy 1,720,320 bytes - 1680K floppy (common extended format) 1,763,328 bytes - 1722K floppy (common extended format) 2,949,120 bytes - 2880K floppy 3,932,160 bytes - 3840K floppy (extended format) For any other size, the image is assumed to be a hard disk image, and should typically have an MBR and a partition table. It may optionally have a DOSEMU geometry header; in which case the header is used to determine the C/H/S geometry of the disk. Otherwise, the geometry is determined by examining the partition table, so the entire image should be partitioned for proper operation (it may be divided between multiple partitions, however.) You can also specify the geometry manually with the following command line options: c=# Specify number of cylinders (max 1024[*]) h=# Specify number of heads (max 256[*]) s=# Specify number of sectors (max 63) floppy[=#] The image is a floppy image[**] harddisk[=#] The image is a hard disk image[**] # represents a decimal number. [*] MS-DOS only allows max 255 heads, and only allows 255 cylinders on floppy disks. [**] Normally MEMDISK emulates the first floppy or hard disk. This can be overridden by specifying an index, e.g. floppy=1 will simulate fd1 (B:). This may not work on all operating systems or BIOSes. c) The disk is normally writable (although, of course, there is nothing backing it up, so it only lasts until reset.) If you want, you can mimic a write-protected disk by specifying the command line option: ro Disk is readonly d) MEMDISK normally uses the BIOS "INT 15h mover" API to access high memory. This is well-behaved with extended memory managers which load later. Unfortunately it appears that the "DOS boot disk" from WinME/XP *deliberately* crash the system when this API is invoked. The following command-line options tells MEMDISK to enter protected mode directly, whenever possible: raw Use raw access to protected mode memory. bigraw Use raw access to protected mode memory, and leave the CPU in "big real" mode afterwards. safeint Use INT 15h access to protected memory, but invoke INT 15h the way it was *before* MEMDISK was loaded. e) MEMDISK by default supports EDD/EBIOS on hard disks, but not on floppy disks. This can be controlled with the options: edd Enable EDD/EBIOS noedd Disable EDD/EBIOS Some interesting things to note: If you're using MEMDISK to boot DOS from a CD-ROM (using ISOLINUX), you might find the generic El Torito CD-ROM driver by Gary Tong and Bart Lagerweij useful: http://www.nu2.nu/eltorito/ Similarly, if you're booting DOS over the network using PXELINUX, you can use the "keeppxe" option and use the generic PXE (UNDI) NDIS network driver, which is part of the PROBOOT.EXE distribution from Intel: http://www.intel.com/support/network/adapter/1000/software.htm Additional technical information: Starting with version 2.08, MEMDISK now supports an installation check API. This works as follows: EAX = 454D08xxh ("ME") (08h = parameter query) ECX = 444Dxxxxh ("MD") EDX = 5349xxnnh ("IS") (nn = drive #) EBX = 3F4Bxxxxh ("K?") INT 13h If drive nn is a MEMDISK, the registers will contain: EAX = 4D21xxxxh ("!M") ECX = 4D45xxxxh ("EM") EDX = 4944xxxxh ("DI") EBX = 4B53xxxxh ("SK") ES:DI -> MEMDISK info structures The low parts of EAX/ECX/EDX/EBX have the normal return values for INT 13h, AH=08h, i.e. information of the disk geometry etc. See Ralf Brown's interrupt list, http://www.cs.cmu.edu/afs/cs.cmu.edu/user/ralf/pub/WWW/files.html or http://www.ctyme.com/rbrown.htm, for a detailed description. The MEMDISK info structure currently contains: [ES:DI] word Total size of structure (currently 28 bytes) [ES:DI+2] byte MEMDISK minor version [ES:DI+3] byte MEMDISK major version [ES:DI+4] dword Pointer to MEMDISK data in high memory [ES:DI+8] dword Size of MEMDISK data in 512-byte sectors [ES:DI+12] 16:16 Far pointer to command line [ES:DI+16] 16:16 Old INT 13h pointer [ES:DI+20] 16:16 Old INT 15h pointer [ES:DI+24] word Amount of DOS memory before MEMDISK loaded [ES:DI+26] byte Boot loader ID MEMDISK 3.00 and higher has the size of this structure as 27; earlier versions had size 26 and did not include the boot loader ID. In addition, the following fields are available at [ES:0]: [ES:0] word Offset of INT 13h routine (segment == ES) [ES:2] word Offset of INT 15h routine (segment == ES) The program mdiskchk.c in the sample directory is an example on how this API can be used. The following code can be used to "disable" MEMDISK. Note that it does not free the handler in DOS memory, and that running this from DOS will probably crash your machine (DOS doesn't like drives suddenly disappearing from underneath): mov eax, 454D0800h mov ecx, 444D0000h mov edx, 53490000h mov dl,drive_number mov ebx, 3F4B0000h int 13h shr eax, 16 cmp ax, 4D21h jne not_memdisk shr ecx, 16 cmp cx, 4D45h jne not_memdisk shr edx, 16 cmp dx, 4944h jne not_memdisk shr ebx, 16 cmp bx, 4B53h jne not_memdisk cli mov bx,[es:0] ; INT 13h handler offset mov eax,[es:di+16] ; Old INT 13h handler mov byte [es:bx], 0EAh ; FAR JMP mov [es:bx+1], eax mov bx,[es:2] ; INT 15h handler offset mov eax,[es:di+20] ; Old INT 15h handler mov byte [es:bx], 0EAh ; FAR JMP mov [es:bx+1], eax sti syslinux-legacy-3.63+dfsg/doc/comboot.txt0000664000175000017500000007164410777447273017200 0ustar evanevan COMBOOT and COM32 files SYSLINUX supports simple standalone programs, using a file format similar to DOS ".com" files. A 32-bit version, called COM32, is also provided. A simple API provides access to a limited set of filesystem and console functions. ++++ COMBOOT file format ++++ A COMBOOT file is a raw binary file containing 16-bit code. It should be linked to run at offset 0x100, and contain no absolute segment references. It is run in 16-bit real mode. A COMBOOT image can be written to be compatible with MS-DOS. Such a file will usually have extension ".com". A COMBOOT file which is not compatible with MS-DOS will usually have extension ".cbt". Before running the program, SYSLINUX sets up the following fields in the Program Segment Prefix (PSP), a structure at offset 0 in the program segment: Offset Size Meaning 0 word Contains an INT 20h instruction 2 word Contains the paragraph (16-byte "segment" address) at the end of memory available to the program. 128 byte Length of the command line arguments, including the leading space but not including the final CR character. 129 127b Command line arguments, starting with a space and ending with a CR character (ASCII 13). The program is allowed to use memory between the PSP paragraph (which all the CS, DS, ES and SS registers point to at program start) and the paragraph value given at offset 2. On startup, SP is set up to point to the end of the 64K segment, at 0xfffe. Under DOS it is possible for SP to contain a smaller value if memory is very tight; this is never the case under SYSLINUX. The program should make no assumptions about what segment address it will be loaded at; instead it should look at the segment registers on program startup. Both DOS and SYSLINUX will guarantee CS == DS == ES == SS on program start; the program should not assume anything about the values of FS or GS. To exit, a program can either execute a near RET (which will jump to offset 0 which contains an INT 20h instruction, terminating the program), or execute INT 20h or INT 21h AH=00h or INT 21h AH=4Ch. If compatiblity with SYSLINUX 1.xx is desired, use INT 20h. ++++ COM32 file format ++++ A COM32 file is a raw binary file containing 32-bit code. It should be linked to run at address 0x101000, and should not contain any segment references. It will be run in flat-memory 32-bit protected mode. Under SYSLINUX, it will be run in CPL 0, however, since it may be possible to create a COM32 execution engine that would run under something like Linux DOSEMU, it is recommended that the code does not assume CPL 0 unless absolutely necessary. It is highly recommended that every COM32 program begins with the byte sequence B8 FF 4C CD 21 (mov eax,21cd4cffh) as a magic number. A COM32 file should have extension ".c32". On startup, CS will be set up as a flat 32-bit code segment, and DS == ES == SS will be set up as the equivalent flat 32-bit data segment. FS and GS are reserved for future use and are currently initialized to zero. A COM32 image should not assume any particular values of segment selectors. ESP is set up at the end of available memory and also serves as notification to the program how much memory is available. The following arguments are passed to the program on the stack: Address Size Meaning [ESP] dword Return (termination) address [ESP+4] dword Number of additional arguments (currently 5) [ESP+8] dword Pointer to the command line arguments (null-terminated string) [ESP+12] dword Pointer to INT call helper function [ESP+16] dword Pointer to low memory bounce buffer [ESP+20] dword Size of low memory bounce buffer [ESP+24] dword Pointer to FAR call helper function (new in 2.05) [ESP+28] dword Pointer to CDECL helper function (new in 3.54) This corresponds to the following C prototype, available in the file com32/include/com32.h: /* The standard prototype for _start() */ int _start(unsigned int __nargs, char *__cmdline, void (*__intcall)(uint8_t, com32sys_t *, com32sys_t *), void *__bounce_ptr, unsigned int __bounce_len, void (*__farcall)(uint32_t, com32sys_t *, com32sys_t *), int (*__cfarcall)(uint32_t, void *, size_t) ); The intcall helper function can be used to issue BIOS or SYSLINUX API calls, and takes the interrupt number as first argument. The second argument is a pointer to the input register definition, an instance of the following structure (available in ): typedef union { uint32_t l; uint16_t w[2]; uint8_t b[4]; } reg32_t; typedef struct { uint16_t gs; /* Offset 0 */ uint16_t fs; /* Offset 2 */ uint16_t es; /* Offset 4 */ uint16_t ds; /* Offset 6 */ reg32_t edi; /* Offset 8 */ reg32_t esi; /* Offset 12 */ reg32_t ebp; /* Offset 16 */ reg32_t _unused_esp; /* Offset 20 */ reg32_t ebx; /* Offset 24 */ reg32_t edx; /* Offset 28 */ reg32_t ecx; /* Offset 32 */ reg32_t eax; /* Offset 36 */ reg32_t eflags; /* Offset 40 */ } com32sys_t; The third argument is a pointer to the output register definition, an instance of the same structure. The third argument can also be zero (NULL). Since BIOS or SYSLINUX API calls can generally only manipulate data below address 0x100000, a "bounce buffer" in low memory, at least 64K in size, is available, to copy data in and out. The farcall helper function behaves similarly, but takes as its first argument the CS:IP (in the form (CS << 16) + IP) of procedure to be invoked via a FAR CALL. The cfarcall helper function takes (CS << 16)+IP, a pointer to a stack frame, a size of that stack frame, and returns the return value of EAX (which may need to be appropriate truncated by the user.) ++++ SYSLINUX API CALLS +++ SYSLINUX provides the following API calls. SYSLINUX 1.xx only supported INT 20h - terminate program. [] indicates the first version of SYSLINUX which supported this feature (correctly.) NOTE: Most of the API functionality is still experimental. Expect to find bugs. ++++ DOS-COMPATIBLE API CALLS ++++ INT 20h [1.48] Terminate program INT 21h AH=00h [2.00] Terminate program INT 21h AH=4Ch [2.00] Terminate program All of these terminate the program. INT 21h AH=01h [2.01] Get Key with Echo Reads a key from the console input, with echo to the console output. The read character is returned in AL. Extended characters received from the keyboard are returned as NUL (00h) + the extended character code. INT 21h AH=02h [2.01] Write Character Writes a character in DL to the console (video and serial) output. INT 21h AH=04h [2.01] Write Character to Serial Port Writes a character in DL to the serial console output (if enabled.) If no serial port is configured, this routine does nothing. INT 21h AH=08h [2.09] Get Key without Echo Reads a key fron the console input, without echoing it to the console output. The read character is returned in AL. INT 21h AH=09h [2.01] Write DOS String to Console Writes a DOS $-terminated string in DS:DX to the console. INT 21h AH=0Bh [2.00] Check Keyboard Returns AL=FFh if there is a keystroke waiting (which can then be read with INT 21h, AH=01h or AH=08h), otherwise AL=00h. INT 21h AH=30h [2.00] Check DOS Version This function returns AX=BX=CX=DX=0, corresponding to a hypothetical "DOS 0.0", but the high parts of EAX-EBX-ECX-EDX spell "SYSLINUX": EAX=59530000h EBX=4C530000h ECX=4E490000h EDX=58550000h This function can thus be used to distinguish running on SYSLINUX from running on DOS. ++++ SYSLINUX-SPECIFIC API CALLS ++++ SYSLINUX-specific API calls are executed using INT 22h, with a function number in AX. INT 22h is used by DOS for internal purposes; do not execute INT 22h under DOS. DOS-compatible function INT 21h, AH=30h can be used to detect if the SYSLINUX API calls are available. Any register not specifically listed as modified is preserved; however, future versions of SYSLINUX may add additional output registers to existing calls. All calls return CF=0 on success, CF=1 on failure. The noted outputs apply if CF=0 only unless otherwise noted. All calls clobber the arithmetric flags (CF, PF, AF, ZF, SF and OF) but leave all other flags unchanged unless otherwise noted. AX=0001h [2.00] Get Version Input: AX 0001h Output: AX number of INT 22h API functions available CH SYSLINUX major version number CL SYSLINUX minor version number DL SYSLINUX derivative ID (e.g. 32h = PXELINUX) ES:SI SYSLINUX version string ES:DI SYSLINUX copyright string This API call returns the SYSLINUX version and API information. AX=0002h [2.01] Write String Input: AX 0002h ES:BX null-terminated string Output: None Writes a null-terminated string on the console. AX=0003h [2.01] Run command Input: AX 0003h ES:BX null-terminated command string Output: Does not return This API call terminates the program and executes the command string as if the user had entered it at the SYSLINUX command line. This API call does not return. AX=0004h [2.01] Run default command Input: AX 0004h Output: Does not return This API call terminates the program and executes the default command string as if the user had pressed Enter alone on the SYSLINUX command line. This API call does not return. AX=0005h [2.00] Force text mode Input: AX 0005h Output: None If the screen was in graphics mode (due to displaying a splash screen using the command in a message file, or similar), return to text mode. AX=0006h [2.08] Open file Input: AX 0006h ES:SI null-terminated filename Output: SI file handle EAX length of file in bytes CX file block size Open a file for reading. The exact syntax of the filenames allowed depends on the particular SYSLINUX derivative. The SYSLINUX file system is block-oriented. The size of a block will always be a power of two and no greater than 16K. Note: SYSLINUX considers a zero-length file to be nonexistent. AX=0007h [2.08] Read file Input: AX 0007h SI file handle ES:BX buffer CX number of blocks to read Output: SI file handle, or 0 if EOF was reached Read blocks from a file. Note that the file handle that is returned in SI may not be the same value that was passed in. If end of file was reached (SI=0), the file was automatically closed. The address of the buffer (ES:BX) should be at least 512-byte aligned. SYSLINUX guarantees at least this alignment for the COMBOOT load segment or the COM32 bounce buffer. Keep in mind that a "file" may be a TFTP connection, and that leaving a file open for an extended period of time may result in a timeout. WARNING: Calling this function with an invalid file handle will probably crash the system. AX=0008h [2.08] Close file Input: AX 0008h SI file handle Output: None Close a file before reaching the end of file. WARNING: Calling this function with an invalid file handle will probably crash the system. AX=0009h [2.00] Call PXE Stack [PXELINUX ONLY] Input: AX 0009h BX PXE function number ES:DI PXE parameter structure buffer Output: AX PXE return status code Invoke an arbitrary PXE stack function. On SYSLINUX/ISOLINUX, this function returns with an error (CF=1) and no action is taken. On PXELINUX, this function always returns with CF=0 indicating that the PXE stack was successfully invoked; check the status code in AX and in the first word of the data buffer to determine if the PXE call succeeded or not. The PXE stack will have the UDP stack OPEN; if you change that you cannot call any of the file-related API functions, and must restore UDP OPEN before returning to PXELINUX. PXELINUX reserves UDP port numbers from 49152 to 65535 for its own use; port numbers below that range is available. AX=000Ah [2.00] Get Derivative-Specific Information [SYSLINUX, EXTLINUX] Input: AX 000Ah CL 9 (to get a valid return in CL for all versions) Output: AL 31h (SYSLINUX), 34h (EXTLINUX) DL drive number CL sector size as a power of 2 (9 = 512 bytes) [3.35] ES:BX pointer to partition table entry (if DL >= 80h) FS:SI pointer to initial ES:DI value [3.53] Note: This function was broken in EXTLINUX 3.00-3.02. On boot, ES:DI is supposed to point to the BIOS $PnP structure, although in practice most operating systems will search for it in memory. However, preserving this while chainloading is probably a good idea. Note that FS:SI is a pointer to a memory location containing the original ES:DI value, not the value itself. [PXELINUX] Input: AX 000Ah Output: AL 32h (PXELINUX) DX PXE API version detected (DH=major, DL=minor) ES:BX pointer to PXENV+ or !PXE structure FS:SI pointer to original stack with invocation record Note: DX notes the API version detected by PXELINUX, which may be more conservative than the actual version available. For exact information examine the API version entry in the PXENV+ structure, or the API version entries in the ROMID structures pointed from the !PXE structure. PXELINUX will use, and provide, the !PXE structure over the PXENV+ structure. Examine the structure signature to determine which particular structure was provided. The FS:SI pointer points to the top of the original stack provided by the PXE stack, with the following values pushed at the time PXELINUX is started: [fs:si+0] GS <- top of stack [fs:si+2] FS [fs:si+4] ES [fs:si+6] DS [fs:si+8] EDI [fs:si+12] ESI [fs:si+16] EBP [fs:si+20] - [fs:si+24] EBX [fs:si+28] EDX [fs:si+32] ECX [fs:si+36] EAX [fs:si+40] EFLAGS [fs:si+44] PXE return IP <- t.o.s. when PXELINUX invoked [fs:si+46] PXE return CS [ISOLINUX] Input: AX 000Ah Output: AL 33h (ISOLINUX) DL drive number CL 11 (sector size as a power of 2) [3.35] ES:BX pointer to El Torito spec packet FS:SI pointer to initial ES:DI value [3.53] Note: Some very broken El Torito implementations do not provide the spec packet information. If so, ES:BX may point to all zeroes or to garbage. Call INT 13h, AX=4B01h to obtain the spec packet directly from the BIOS if necessary. This call gives information specific to a particular SYSLINUX derivative. The value returned in AL is the same as is returned in DL by INT 22h AX=0001h. AX=000Bh [2.00] Get Serial Console Configuration Input: AX 000Bh Output: DX serial port I/O base (e.g. 3F8h = COM1...) CX baud rate divisor (1 = 115200 bps, 2 = 57600 bps...) BX flow control configuration bits (see syslinux.txt) -> bit 15 is set if the video console is disabled If no serial port is configured, DX will be set to 0 and the other registers are undefined. AX=000Ch [2.00] Perform final cleanup Input: AX 000Ch DX derivative-specific flags (0000h = clean up all) Output: None This routine performs any "final cleanup" the boot loader would normally perform before loading a kernel, such as unloading the PXE stack in the case of PXELINUX. AFTER INVOKING THIS CALL, NO OTHER API CALLS MAY BE INVOKED, NOR MAY THE PROGRAM TERMINATE AND RETURN TO THE BOOT LOADER. This call basically tells the boot loader "get out of the way, I'll handle it from here." For COM32 images, the boot loader will continue to provide interrupt and BIOS call thunking services as long its memory areas (0x0800-0xffff, 0x100000-0x100fff) are not overwritten. MAKE SURE TO DISABLE INTERRUPTS, AND INSTALL NEW GDT AND IDTS BEFORE OVERWRITING THESE MEMORY AREAS. The permissible values for DX is an OR of these values: SYSLINUX: 0000h Normal cleanup PXELINUX: 0000h Normal cleanup 0003h Keep UNDI and PXE stacks loaded ISOLINUX: 0000h Normal cleanup EXTLINUX: 0000h Normal cleanup All other values are undefined, and may have different meanings in future versions of SYSLINUX. AX=000Dh [2.08] Cleanup and replace bootstrap code Input: AX 000Dh DX derivative-specific flags (see previous function) EDI bootstrap code (linear address, can be in high memory) ECX bootstrap code length in bytes (must fit in low mem) EBX(!) initial value of EDX after bootstrap ESI initial value of ESI after bootstrap DS initial value of DS after bootstrap Output: Does not return This routine performs final cleanup, then takes a piece of code, copies it over the primary bootstrap at address 7C00h, and jumps to it. This can be used to chainload boot sectors, MBRs, bootstraps, etc. Normal boot sectors expect DL to contain the drive number, and, for hard drives (DL >= 80h) DS:SI to contain a pointer to the 16-byte partition table entry. The memory between 600h-7FFh is available to put the partition table entry in. For PXELINUX, if the PXE stack is not unloaded, all registers (except DS, ESI and EDX) and the stack will be set up as they were set up by the PXE ROM. AX=000Eh [2.11] Get configuration file name Input: AX 0000Eh Output: ES:BX null-terminated file name string Returns the name of the configuration file. Note that it is possible that the configuration file doesn't actually exist. AX=000Fh [3.00] Get IPAPPEND strings [PXELINUX] Input: AX 000Fh Output: CX number of strings (currently 2) ES:BX pointer to an array of NEAR pointers in the same segment, one for each of the above strings Returns the same strings that the "ipappend" option would have added to the command line, one for each bit of the "ipappend" flag value, so entry 0 is the "ip=" string and entry 1 is the "BOOTIF=" string. AX=0010h [3.00] Resolve hostname [PXELINUX] Input: ES:BX pointer to null-terminated hostname Output: EAX IP address of hostname (zero if not found) Queries the DNS server(s) for a specific hostname. If the hostname does not contain a dot (.), the local domain name is automatically appended. This function only return CF=1 if the function is not supported. If the function is supported, but the hostname did not resolve, it returns with CF=0, EAX=0. The IP address is returned in network byte order, i.e. if the IP address is 1.2.3.4, EAX will contain 0x04030201. Note that all uses of IP addresses in PXE are also in network byte order. AX=0011h [3.05] Maximum number of shuffle descriptors Input: AX 0011h Output: CX maximum number of descriptors This routine reports the maximum number of shuffle descriptors permitted in a call to functions 0012h, 001Ah and 001Bh. This is guaranteed to be at least 64. For the current version, this is 682 for all derivatives. AX=0012h [3.50] Cleanup, shuffle and boot Input: AX 0012h DX derivative-specific flags (see function 000Ch) ES:DI shuffle descriptor list (must be in low memory) CX number of shuffle descriptors EBX(!) initial value of EDX after bootstrap ESI initial value of ESI after bootstrap DS initial value of DS after bootstrap EBP CS:IP of routine to jump to Output: Does not return (if CX is too large the routine returns with CF=1) This routine performs final cleanup, then performs a sequence of copies, and jumps to a specified real mode entry point. This is a more general version of function 000Dh, which can also be used to load other types of programs. The copies must not touch memory below address 7C00h. ES:DI points to a list of CX descriptors each of the form: Offset Size Meaning 0 dword destination address 4 dword source address 8 dword length in bytes The copies are overlap-safe, like memmove(). Starting in version 3.50, if the source address is -1 (FFFFFFFFh) then the block specified by the destination address and the length is set to all zero. Starting in version 3.50, if the destination address is -1 (FFFFFFFFh) then the data block is loaded as a new set of descriptors, and processing is continued (and unprocessed descriptors are lost, this is thus typically only used as the last descriptor in a block.) The block must still fit in the internal descriptor buffer (see function 0011h), but can, of course, itself chain another block. Normal boot sectors expect DL to contain the drive number, and, for hard drives (DL >= 80h) DS:SI to contain a pointer to the 16-byte partition table entry. The memory between 600h-7FFh is available to put the partition table entry in. For PXELINUX, if the PXE stack is not unloaded, all registers (except DS, ESI and EDX) and the stack will be set up as they were set up by the PXE ROM. This interface was probably broken before version 3.50. AX=0013h [3.08] Idle loop call Input: AX 0013h Output: None Call this routine while sitting in an idle loop. It performs any periodic activities required by the filesystem code. At the moment, this is a no-op on all derivatives except PXELINUX, where it executes PXE calls to answer ARP queries. Starting with version 3.10, this API call harmlessly returns failure (CF=1) if invoked on a platform which does not need idle calls. Additionally, it's safe to call this API call on previous SYSLINUX versions (2.00 or later); it will just harmlessly fail. Thus, if this call returns failure (CF=1), it means that there is no technical reason to call this function again, although doing so is of course safe. AX=0014h [3.10] Local boot [PXELINUX, ISOLINUX] Input: AX 0014h DX Local boot parameter Output: Does not return This function invokes the equivalent of the "localboot" configuration file option. The parameter in DX is the same parameter as would be entered after "localboot" in the configuration file; this parameter is derivative-specific -- see syslinux.txt for the definition. AX=0015h [3.10] Get feature flags Input: AX 0015h Output: ES:BX pointer to flags in memory CX number of flag bytes This function reports whether or not this SYSLINUX version and derivative supports specific features. Keep in mind that future versions might have more bits; remember to treat any bits beyond the end of the array (as defined by the value in CX) as zero. Currently the following feature flag is defined: Byte Bit Definition ---------------------------------------------------- 0 0 Local boot (AX=0014h) supported 1 Idle loop call (AX=0013h) is a no-op All other flags are reserved. AX=0016h [3.10] Run kernel image Input: AX 0016h DS:SI Filename of kernel image (zero-terminated string) ES:BX Command line (zero-terminated string) ECX IPAPPEND flags [PXELINUX] EDX Type of file (since 3.50) Output: Does not return if successful; returns with CF=1 if the kernel image is not found. This function is similiar to AX=0003h Run command, except that the filename and command line are treated as if specified in a KERNEL and APPEND statement of a LABEL statement, which means: - The filename has to be exact; no variants are tried; - No global APPEND statement is applied; - ALLOWOPTIONS and IMPLICIT statements in the configuration file do not apply. It is therefore important that the COMBOOT module doesn't allow the end user to violate the intent of the administrator. Additionally, this function returns with a failure if the file doesn't exist, instead of returning to the command line. (It may still return to the command line if the image is somehow corrupt, however.) The file types are defined as follows: Equivalent EDX Config Extensions Type of file 0 KERNEL Determined by filename extension 1 LINUX none Linux kernel image 2 BOOT .bs .bin Bootstrap program 3 BSS .bss Boot sector with patch [SYSLINUX] 4 PXE .0 PXE Network Bootstrap Prog [PXELINUX] 5 FDIMAGE .img Floppy disk image [ISOLINUX] 6 COMBOOT .com .cbt 16-bit COMBOOT program 7 COM32 .c32 COM32 program 8 CONFIG Configuration file AX=0017h [3.30] Report video mode change Input: AX 0017h BX Video mode flags Bit 0: graphics mode Bit 1: non-default mode Bit 2: VESA mode Bit 3: text functions not supported CX For graphics modes, pixel columns DX For graphics modes, pixel rows Output: None This function is used to report video mode changes to SYSLINUX. It does NOT actually change the video mode, but rather, allows SYSLINUX to take appropriate action in response to a video mode change. Modes that cannot be exited either with the conventional BIOS mode set command (INT 10h, AH=00h) or the VESA VBE mode set command (INT 10h, AX=4F02h) should not be used. This function returns with a failure if BX contains any bits which are undefined in the current version of SYSLINUX. The following bits in BX are currently defined: Bit 0: graphics mode Indicates that the mode is a graphics mode, as opposed to a text mode. Bit 1: non-standard mode A non-standard mode is any mode except text mode and graphics mode 0012h (VGA 640x480, 16 color.) Bit 2: VESA mode This mode is a VESA mode, and has to be exited with the VESA VBE API (INT 10h, AX=4F02h) as opposed to the conventional BIOS API (INT 10h, AH=00h). Bit 3: Text functions not supported This indicates that the BIOS text output functions (INT 10h, AH=02h, 03h, 06h, 09h, 0Eh, 11h) don't work. If this bit is set, SYSLINUX will reset the mode before printing any characters on the screen. This is common for VESA modes. AX=0018h [3.30] Query custom font Input: AX 0018h Output: AL Height of custom font in scan lines, or zero ES:BX Pointer to custom font in memory This call queries if a custom display font has been loaded via the "font" configuration file command. If no custom font has been loaded, AL contains zero. AX=0019h [3.50] Read disk [SYSLINUX, ISOLINUX, EXTLINUX] Input: AX 0019h EDX Sector number ESI Reserved - MUST BE ZERO EDI Reserved - MUST BE ZERO CX Sector count ES:BX Buffer address Output: None Read disk blocks from the active filesystem (partition); for disks, sector number zero is the boot sector. For ISOLINUX, this call reads the CD-ROM. For compatiblity with all systems, the buffer should *neither* cross 64K boundaries, *nor* wrap around the segment. This routine reports "boot failed" (and does not return) on disk error. AX=001Ah [3.50] Cleanup, shuffle and boot to flat protected mode Input: AX 001Ah DX derivative-specific flags (see function 000Ch) ES:DI shuffle descriptor list (must be in low memory) CX number of shuffle descriptors DS:SI pointer to register values (must be in low memory) Output: Does not return (if CX is too large the routine returns with CF=1) This routine performs final cleanup, then performs a sequence of copies, and jumps to a specified protected mode entry point. This is otherwise similar to function 0012h; see that function for the meaning of ES:DI and CX. DS:SI points to the initial register file, which is a structure of 9 dwords (available in ): struct syslinux_pm_regs { uint32_t eax; /* Offset 0 */ uint32_t ecx; /* Offset 4 */ uint32_t edx; /* Offset 8 */ uint32_t ebx; /* Offset 12 */ uint32_t esp; /* Offset 16 */ uint32_t ebp; /* Offset 20 */ uint32_t esi; /* Offset 24 */ uint32_t edi; /* Offset 28 */ uint32_t eip; /* Offset 32 */ }; Protected mode is entered with all data segments set up as a flat 32-bit read/write segment and the code segment a flat 32-bit read/execute segment. Interrupts and paging is off, CPL=0, DF=0; however, GDT, LDT and IDT are undefined, so it is up to the invoked code to set new descriptor tables to its liking. AX=001Bh [3.50] Cleanup, shuffle and boot to real mode Input: AX 001Bh DX derivative-specific flags (see function 000Ch) ES:DI shuffle descriptor list (must be in low memory) CX number of shuffle descriptors DS:SI pointer to register values (must be in low memory) Output: Does not return (if CX is too large the routine returns with CF=1) This routine performs final cleanup, then performs a sequence of copies, and jumps to a specified entry point. This is similar to function 0012h but allow more control over the initial register state; see that function for the meaning of ES:DI and CX. DS:SI points to the initial register file, which is a structure in the following format (available in ; note that this is a completely different structure from the com32sys_t structure described at the top of this document!): struct syslinux_rm_regs { uint16_t es; /* Offset 0 */ uint16_t _unused_cs; /* Offset 2 */ uint16_t ds; /* Offset 4 */ uint16_t ss; /* Offset 6 */ uint16_t fs; /* Offset 8 */ uint16_t gs; /* Offset 10 */ reg32_t eax; /* Offset 12 */ reg32_t ecx; /* Offset 16 */ reg32_t edx; /* Offset 20 */ reg32_t ebx; /* Offset 24 */ reg32_t esp; /* Offset 28 */ reg32_t ebp; /* Offset 32 */ reg32_t esi; /* Offset 36 */ reg32_t edi; /* Offset 40 */ uint16_t ip; /* Offset 44 */ uint16_t cs; /* Offset 46 */ }; Interrupts are off and DF=0 on entry. AX=001Ch [3.60] Get pointer to auxilliary data vector Input: AX 001Ch Output: ES:BX Auxilliary data vector CX Size of the ADV (currently 500 bytes) The auxillary data vector is a tagged data structure used to carry a small amount of information (up to 500 bytes) from one boot to another. AX=001Dh [3.60] Write auxilliary data vector Input: AX 001Dh Output: None Write the auxilliary data vector back to disk. Returns failure for non-disk-based derivatives unless the "auxdata" configuration command is used to specify a disk location (not yet implemented.) In a future version, PXELINUX may end up attempting to save the ADV on the server via TFTP write. syslinux-legacy-3.63+dfsg/doc/syslinux.txt0000664000175000017500000006505710777447273017435 0ustar evanevan SYSLINUX A suite of bootloaders for Linux Copyright 1994-2008 H. Peter Anvin - All Rights Reserved This program is provided under the terms of the GNU General Public License, version 2 or, at your option, any later version. There is no warranty, neither expressed nor implied, to the function of this program. Please see the included file COPYING for details. ---------------------------------------------------------------------- SYSLINUX now has a home page at http://syslinux.zytor.com/ ---------------------------------------------------------------------- The SYSLINUX suite contains the following boot loaders ("derivatives"), for their respective boot media: SYSLINUX - MS-DOS/Windows FAT filesystem PXELINUX - PXE network booting ISOLINUX - ISO9660 CD-ROM EXTLINUX - Linux ext2/ext3 filesystem For historical reasons, some of the sections in this document applies to the FAT loader only; see pxelinux.txt, isolinux.txt and extlinux.txt for what differs in these versions. Help with cleaning up the docs would be greatly appreciated. ++++ Options ++++ These are the options common to all versions of Syslinux: -s Safe, slow, stupid; uses simpler code that boots better -f Force installing These are only in the Windows version: -m Mbr; install a bootable MBR sector to the beginning of the drive. -a Active; marks the partition used active (=bootable) ++++ CREATING A BOOTABLE LINUX FLOPPY +++ In order to create a bootable Linux floppy using SYSLINUX, prepare a normal MS-DOS formatted floppy. Copy one or more Linux kernel files to it, then execute the DOS command: syslinux [-sfma][-d directory] a: (or whichever drive letter is appropriate; the [] meaning optional.) Use "syslinux.com" (in the dos subdirectory of the distribution) for plain DOS (MS-DOS, DR-DOS, PC-DOS, FreeDOS...) or Win9x/ME. Use "syslinux.exe" (in the win32 subdirectory of the distribution) for WinNT/2000/XP. Under Linux, execute the command: syslinux [-sf][-d directory][-o offset] /dev/fd0 (or, again, whichever device is the correct one.) This will alter the boot sector on the disk and copy a file named LDLINUX.SYS into its root directory (or a subdirectory, if the -d option is specified.) The -s option, if given, will install a "safe, slow and stupid" version of SYSLINUX. This version may work on some very buggy BIOSes on which SYSLINUX would otherwise fail. If you find a machine on which the -s option is required to make it boot reliably, please send as much info about your machine as you can, and include the failure mode. The -o option is used with a disk image file and specifies the byte offset of the filesystem image in the file. For the DOS and Windows installers, the -m and -a options can be used on hard drives to write a Master Boot Record (MBR), and to mark the specific partition active. On boot time, by default, the kernel will be loaded from the image named LINUX on the boot floppy. This default can be changed, see the section on the SYSLINUX config file. If the Shift or Alt keys are held down during boot, or the Caps or Scroll locks are set, SYSLINUX will display a LILO-style "boot:" prompt. The user can then type a kernel file name followed by any kernel parameters. The SYSLINUX loader does not need to know about the kernel file in advance; all that is required is that it is a file located in the root directory on the disk. There are two versions of the Linux installer; one in the "mtools" directory which requires no special privilege (other than write permission to the device where you are installing) but requires the mtools program suite to be available, and one in the "unix" directory which requires root privilege. ++++ CONFIGURATION FILE ++++ All the configurable defaults in SYSLINUX can be changed by putting a file called "syslinux.cfg" in the root directory of the boot disk. This is a text file in either UNIX or DOS format, containing one or more of the following items (case is insensitive for keywords; upper case is used here to indicate that a word should be typed verbatim): Starting with version 3.35, the configuration file can also be in either the /boot/syslinux or /syslinux directories (searched in that order.) If that is the case, then all filenames are assumed to be relative to that same directory, unless preceded with a slash or backslash. All options here applies to PXELINUX, ISOLINUX and EXTLINUX as well as SYSLINUX unless otherwise noted. See the respective .txt files. # comment A comment line. The whitespace after the hash mark is mandatory. INCLUDE filename Inserts the contents of another file at this point in the configuration file. Files can currently be nested up to 16 levels deep, but it is not guaranteed that more than 8 levels will be supported in the future. DEFAULT kernel options... Sets the default command line. If SYSLINUX boots automatically, it will act just as if the entries after DEFAULT had been typed in at the "boot:" prompt. If no configuration file is present, or no DEFAULT entry is present in the config file, the default is "linux auto". NOTE: Earlier versions of SYSLINUX used to automatically append the string "auto" to whatever the user specified using the DEFAULT command. As of version 1.54, this is no longer true, as it caused problems when using a shell as a substitute for "init." You may want to include this option manually. APPEND options... Add one or more options to the kernel command line. These are added both for automatic and manual boots. The options are added at the very beginning of the kernel command line, usually permitting explicitly entered kernel options to override them. This is the equivalent of the LILO "append" option. IPAPPEND flag_val [PXELINUX only] The IPAPPEND option is available only on PXELINUX. The flag_val is an OR of the following options: 1: indicates that an option of the following format should be generated and added to the kernel command line: ip=::: ... based on the input from the DHCP/BOOTP or PXE boot server. THE USE OF THIS OPTION IS NOT RECOMMENDED. If you have to use it, it is probably an indication that your network configuration is broken. Using just "ip=dhcp" on the kernel command line is a preferrable option, or, better yet, run dhcpcd/dhclient, from an initrd if necessary. 2: indicates that an option of the following format should be generated and added to the kernel command line: BOOTIF= ... in dash-separated hexadecimal with leading hardware type (same as for the configuration file; see pxelinux.txt.) This allows an initrd program to determine from which interface the system booted. LABEL label KERNEL image APPEND options... IPAPPEND flag_val [PXELINUX only] Indicates that if "label" is entered as the kernel to boot, SYSLINUX should instead boot "image", and the specified APPEND and IPAPPEND options should be used instead of the ones specified in the global section of the file (before the first LABEL command.) The default for "image" is the same as "label", and if no APPEND is given the default is to use the global entry (if any). Starting with version 2.20, LABEL statements are compressed internally, therefore the maximum number of LABEL statements depends on their complexity. Typical is around 600. SYSLINUX will print an error message if the internal memory for labels is overrun. Note that LILO uses the syntax: image = mykernel label = mylabel append = "myoptions" ... whereas SYSLINUX uses the syntax: label mylabel kernel mykernel append myoptions Note: The "kernel" doesn't have to be a Linux kernel; it can be a boot sector or a COMBOOT file (see below.) Since version 3.32 label names are no longer mangled into DOS format (for SYSLINUX.) LINUX image - Linux kernel image (default) BOOT image - Bootstrap program (.bs, .bin) BSS image - BSS image (.bss) PXE image - PXE Network Bootstrap Program (.0) FDIMAGE image - Floppy disk image (.img) COMBOOT image - COMBOOT program (.com, .cbt) COM32 image - COM32 program (.c32) CONFIG image - New configuration file Using one of these keywords instead of KERNEL forces the filetype, regardless of the filename. CONFIG means restart the boot loader using a different configuration file. APPEND - Append nothing. APPEND with a single hyphen as argument in a LABEL section can be used to override a global APPEND. LOCALBOOT type [ISOLINUX, PXELINUX] On PXELINUX, specifying "LOCALBOOT 0" instead of a "KERNEL" option means invoking this particular label will cause a local disk boot instead of booting a kernel. The argument 0 means perform a normal boot. The argument 4 will perform a local boot with the Universal Network Driver Interface (UNDI) driver still resident in memory. Finally, the argument 5 will perform a local boot with the entire PXE stack, including the UNDI driver, still resident in memory. All other values are undefined. If you don't know what the UNDI or PXE stacks are, don't worry -- you don't want them, just specify 0. On ISOLINUX, the "type" specifies the local drive number to boot from; 0x00 is the primary floppy drive and 0x80 is the primary hard drive. The special value -1 causes ISOLINUX to report failure to the BIOS, which, on recent BIOSes, should mean that the next boot device in the boot sequence should be activated. IMPLICIT flag_val If flag_val is 0, do not load a kernel image unless it has been explicitly named in a LABEL statement. The default is 1. ALLOWOPTIONS flag_val If flag_val is 0, the user is not allowed to specify any arguments on the kernel command line. The only options recognized are those specified in an APPEND statement. The default is 1. TIMEOUT timeout Indicates how long to wait at the boot: prompt until booting automatically, in units of 1/10 s. The timeout is cancelled as soon as the user types anything on the keyboard, the assumption being that the user will complete the command line already begun. A timeout of zero will disable the timeout completely, this is also the default. TOTALTIMEOUT timeout Indicates how long to wait until booting automatically, in units of 1/10 s. This timeout is *not* cancelled by user input, and can thus be used to deal with serial port glitches or "the user walked away" type situations. A timeout of zero will disable the timeout completely, this is also the default. Both TIMEOUT and TOTALTIMEOUT can be used together, for example: # Wait 5 seconds unless the user types something, but # always boot after 15 minutes. TIMEOUT 50 TOTALTIMEOUT 9000 ONTIMEOUT kernel options... Sets the command line invoked on a timeout. Normally this is the same thing as invoked by "DEFAULT". If this is specified, then "DEFAULT" is used only if the user presses to boot. ONERROR kernel options... If a kernel image is not found (either due to it not existing, or because IMPLICIT is set), run the specified command. The faulty command line is appended to the specified options, so if the ONERROR directive reads as: ONERROR xyzzy plugh ... and the command line as entered by the user is: foo bar baz ... SYSLINUX will execute the following as if entered by the user: xyzzy plugh foo bar baz SERIAL port [[baudrate] flowcontrol] Enables a serial port to act as the console. "port" is a number (0 = /dev/ttyS0 = COM1, etc.) or an I/O port address (e.g. 0x3F8); if "baudrate" is omitted, the baud rate defaults to 9600 bps. The serial parameters are hardcoded to be 8 bits, no parity, 1 stop bit. "flowcontrol" is a combination of the following bits: 0x001 - Assert DTR 0x002 - Assert RTS 0x010 - Wait for CTS assertion 0x020 - Wait for DSR assertion 0x040 - Wait for RI assertion 0x080 - Wait for DCD assertion 0x100 - Ignore input unless CTS asserted 0x200 - Ignore input unless DSR asserted 0x400 - Ignore input unless RI asserted 0x800 - Ignore input unless DCD asserted All other bits are reserved. Typical values are: 0 - No flow control (default) 0x303 - Null modem cable detect 0x013 - RTS/CTS flow control 0x813 - RTS/CTS flow control, modem input 0x023 - DTR/DSR flow control 0x083 - DTR/DCD flow control For the SERIAL directive to be guaranteed to work properly, it should be the first directive in the configuration file. NOTE: "port" values from 0 to 3 means the first four serial ports detected by the BIOS. They may or may not correspond to the legacy port values 0x3F8, 0x2F8, 0x3E8, 0x2E8. CONSOLE flag_val If flag_val is 0, disable output to the normal video console. If flag_val is 1, enable output to the video console (this is the default.) Some BIOSes try to forward this to the serial console and sometimes make a total mess thereof, so this option lets you disable the video console on these systems. FONT filename Load a font in .psf format before displaying any output (except the copyright line, which is output as ldlinux.sys itself is loaded.) SYSLINUX only loads the font onto the video card; if the .psf file contains a Unicode table it is ignored. This only works on EGA and VGA cards; hopefully it should do nothing on others. KBDMAP keymap Install a simple keyboard map. The keyboard remapper used is *very* simplistic (it simply remaps the keycodes received from the BIOS, which means that only the key combinations relevant in the default layout -- usually U.S. English -- can be mapped) but should at least help people with AZERTY keyboard layout and the locations of = and , (two special characters used heavily on the Linux kernel command line.) The included program keytab-lilo.pl from the LILO distribution can be used to create such keymaps. The file keytab-lilo.txt contains the documentation for this program. DISPLAY filename Displays the indicated file on the screen at boot time (before the boot: prompt, if displayed). Please see the section below on DISPLAY files. NOTE: If the file is missing, this option is simply ignored. SAY message Prints the message on the screen. PROMPT flag_val If flag_val is 0, display the boot: prompt only if the Shift or Alt key is pressed, or Caps Lock or Scroll lock is set (this is the default). If flag_val is 1, always display the boot: prompt. NOESCAPE flag_val If flag_val is set to 1, ignore the Shift/Alt/Caps Lock/Scroll Lock escapes. Use this (together with PROMPT 0) to force the default boot alternative. F1 filename F2 filename ...etc... F9 filename F10 filename F11 filename F11 filename Displays the indicated file on the screen when a function key is pressed at the boot: prompt. This can be used to implement pre-boot online help (presumably for the kernel command line options.) Please see the section below on DISPLAY files. When using the serial console, press to get to the help screens, e.g. <2> to get to the F2 screen. For F10-F12, hit , B, C. For compatiblity with earlier versions, F10 can also be entered as 0. Blank lines are ignored. Note that the configuration file is not completely decoded. Syntax different from the one described above may still work correctly in this version of SYSLINUX, but may break in a future one. ++++ DISPLAY FILE FORMAT ++++ DISPLAY and function-key help files are text files in either DOS or UNIX format (with or without ). In addition, the following special codes are interpreted: = = ASCII 12 Clear the screen, home the cursor. Note that the screen is filled with the current display color. = = ASCII 15 Set the display colors to the specified background and foreground colors, where and are hex digits, corresponding to the standard PC display attributes: 0 = black 8 = dark grey 1 = dark blue 9 = bright blue 2 = dark green a = bright green 3 = dark cyan b = bright cyan 4 = dark red c = bright red 5 = dark purple d = bright purple 6 = brown e = yellow 7 = light grey f = white Picking a bright color (8-f) for the background results in the corresponding dark color (0-7), with the foreground flashing. Colors are not visible over the serial console. filename = = ASCII 24 If a VGA display is present, enter graphics mode and display the graphic included in the specified file. The file format is an ad hoc format called LSS16; the included Perl program "ppmtolss16" can be used to produce these images. This Perl program also includes the file format specification. The image is displayed in 640x480 16-color mode. Once in graphics mode, the display attributes (set by code sequences) work slightly differently: the background color is ignored, and the foreground colors are the 16 colors specified in the image file. For that reason, ppmtolss16 allows you to specify that certain colors should be assigned to specific color indicies. Color indicies 0 and 7, in particular, should be chosen with care: 0 is the background color, and 7 is the color used for the text printed by SYSLINUX itself. = = ASCII 25 If we are currently in graphics mode, return to text mode. .. .. = ASCII 16-23 These codes can be used to select which modes to print a certain part of the message file in. Each of these control characters select a specific set of modes (text screen, graphics screen, serial port) for which the output is actually displayed: Character Text Graph Serial ------------------------------------------------------ = = ASCII 16 No No No = = ASCII 17 Yes No No = = ASCII 18 No Yes No = = ASCII 19 Yes Yes No = = ASCII 20 No No Yes = = ASCII 21 Yes No Yes = = ASCII 22 No Yes Yes = = ASCII 23 Yes Yes Yes For example: Text modeGraphics modeSerial port ... will actually print out which mode the console is in! = = ASCII 26 End of file (DOS convention). = = ASCII 7 Beep the speaker. ++++ COMMAND LINE KEYSTROKES ++++ The command line prompt supports the following keystrokes: boot specified command line erase one character erase the whole line display the current SYSLINUX version erase one word force text mode .. help screens (if configured) equivalent to F1..F10 interrupt boot in progress interrupt boot in progress ++++ COMBOOT IMAGES AND OTHER OPERATING SYSTEMS ++++ This version of SYSLINUX supports chain loading of other operating systems (such as MS-DOS and its derivatives, including Windows 95/98), as well as COMBOOT-style standalone executables (a subset of DOS .COM files; see separate section below.) Chain loading requires the boot sector of the foreign operating system to be stored in a file in the root directory of the filesystem. Because neither Linux kernels, boot sector images, nor COMBOOT files have reliable magic numbers, SYSLINUX will look at the file extension. The following extensions are recognized (case insensitive): none or other Linux kernel image .0 PXE bootstrap program (NBP) [PXELINUX only] .bin "CD boot sector" [ISOLINUX only] .bs Boot sector [SYSLINUX only] .bss Boot sector, DOS superblock will be patched in [SYSLINUX only] .c32 COM32 image (32-bit COMBOOT) .cbt COMBOOT image (not runnable from DOS) .com COMBOOT image (runnable from DOS) .img Disk image [ISOLINUX only] For filenames given on the command line, SYSLINUX will search for the file by adding extensions in the order listed above if the plain filename is not found. Filenames in KERNEL statements must be fully qualified. If this is specified with one of the keywords LINUX, BOOT, BSS, FDIMAGE, COMBOOT, COM32, or CONFIG instead of KERNEL, the filetype is considered to be the one specified regardless of the filename. ++++ BOOTING DOS (OR OTHER SIMILAR OPERATING SYSTEMS) ++++ This section applies to SYSLINUX only, not to PXELINUX or ISOLINUX. See isolinux.txt for an equivalent procedure for ISOLINUX. This is the recommended procedure for creating a SYSLINUX disk that can boot either DOS or Linux. This example assumes the drive is A: in DOS and /dev/fd0 in Linux; for other drives, substitute the appropriate drive designator. ---- Linux procedure ---- 1. Make a DOS bootable disk. This can be done either by specifying the /s option when formatting the disk in DOS, or by running the DOS command SYS (this can be done under DOSEMU if DOSEMU has direct device access to the relevant drive): format a: /s or sys a: 2. Boot Linux. Copy the DOS boot sector from the disk into a file: dd if=/dev/fd0 of=dos.bss bs=512 count=1 3. Run SYSLINUX on the disk: syslinux /dev/fd0 4. Mount the disk and copy the DOS boot sector file to it. The file *must* have extension .bss: mount -t msdos /dev/fd0 /mnt cp dos.bss /mnt 5. Copy the Linux kernel image(s), initrd(s), etc to the disk, and create/edit syslinux.cfg and help files if desired: cp vmlinux /mnt cp initrd.gz /mnt 6. Unmount the disk (if applicable.) umount /mnt ---- DOS/Windows procedure ---- To make this installation in DOS only, you need the utility copybs.com (included with SYSLINUX) as well as the syslinux.com installer. If you are on an WinNT-based system (WinNT, Win2k, WinXP or later), use syslinux.exe instead. 1. Make a DOS bootable disk. This can be done either by specifying the /s option when formatting the disk in DOS, or by running the DOS command SYS: format a: /s or sys a: 2. Copy the DOS boot sector from the disk into a file. The file *must* have extension .bss: copybs a: a:dos.bss 3. Run SYSLINUX on the disk: syslinux a: 4. Copy the Linux kernel image(s), initrd(s), etc to the disk, and create/edit syslinux.cfg and help files if desired: copy vmlinux a: copy initrd.gz a: ++++ COMBOOT EXECUTABLES ++++ SYSLINUX supports simple standalone programs, using a file format similar to DOS ".com" files. A 32-bit version, called COM32, is also provided. A simple API provides access to a limited set of filesystem and console functions. See the file comboot.txt for more information on COMBOOT and COM32 programs. ++++ NOVICE PROTECTION ++++ SYSLINUX will attempt to detect booting on a machine with too little memory, which means the Linux boot sequence cannot complete. If so, a message is displayed and the boot sequence aborted. Holding down the Ctrl key while booting disables this feature. Any file that SYSLINUX uses can be marked hidden, system or readonly if so is convenient; SYSLINUX ignores all file attributes. The SYSLINUX installed automatically sets the readonly/hidden/system attributes on LDLINUX.SYS. ++++ NOTES ON BOOTABLE CD-ROMS ++++ SYSLINUX can be used to create bootdisk images for El Torito-compatible bootable CD-ROMs. However, it appears that many BIOSes are very buggy when it comes to booting CD-ROMs. Some users have reported that the following steps are helpful in making a CD-ROM that is bootable on the largest possible number of machines: a) Use the -s (safe, slow and stupid) option to SYSLINUX; b) Put the boot image as close to the beginning of the ISO 9660 filesystem as possible. A CD-ROM is so much faster than a floppy that the -s option shouldn't matter from a speed perspective. Of course, you probably want to use ISOLINUX instead. See isolinux.txt. ++++ BOOTING FROM A FAT FILESYSTEM PARTITION ON A HARD DISK ++++ SYSLINUX can boot from a FAT filesystem partition on a hard disk (including FAT32). The installation procedure is identical to the procedure for installing it on a floppy, and should work under either DOS or Linux. To boot from a partition, SYSLINUX needs to be launched from a Master Boot Record or another boot loader, just like DOS itself would. Under DOS, you can install a standard simple MBR on the primary hard disk by running the command: FDISK /MBR Then use the FDISK command to mark the appropriate partition active. A simple MBR, roughly on par with the one installed by DOS (but unencumbered), is included in the SYSLINUX distribution. To install it under Linux, simply type: cat mbr.bin > /dev/XXX ... where /dev/XXX is the device you wish to install it on. Under DOS or Win32, you can install the SYSLINUX MBR with the -m option to the SYSLINUX installer, and use the -a option to mark the current partition active: syslinux -ma c: Note that this will also install SYSLINUX on the specified partition. ++++ HARDWARE INFORMATION +++ I have started to maintain a web page of hardware with known problems. There are, unfortunately, lots of broken hardware out there; especially early PXE stacks (for PXELINUX) have lots of problems. A list of problems, and workarounds (if known), is maintained at: http://syslinux.zytor.com/hardware.php ++++ BOOT LOADER IDS USED ++++ The Linux boot protocol supports a "boot loader ID", a single byte where the upper nybble specifies a boot loader family (3 = SYSLINUX) and the lower nybble is version or, in the case of SYSLINUX, media: 0x31 (49) = SYSLINUX 0x32 (50) = PXELINUX 0x33 (51) = ISOLINUX 0x34 (52) = EXTLINUX In recent versions of Linux, this ID is available as /proc/sys/kernel/bootloader_type. ++++ BUG REPORTS ++++ I would appreciate hearing of any problems you have with SYSLINUX. I would also like to hear from you if you have successfully used SYSLINUX, *especially* if you are using it for a distribution. If you are reporting problems, please include all possible information about your system and your BIOS; the vast majority of all problems reported turn out to be BIOS or hardware bugs, and I need as much information as possible in order to diagnose the problems. There is a mailing list for discussion among SYSLINUX users and for announcements of new and test versions. To join, or to browse the archive, go to: http://www.zytor.com/mailman/listinfo/syslinux Please DO NOT send HTML messages or attachments to the mailing list (including multipart/alternative or similar.) All such messages will be bounced. syslinux-legacy-3.63+dfsg/doc/SubmittingPatches.txt0000664000175000017500000005052210777447273021163 0ustar evanevanI don't have specific submission guidelines for SYSLINUX, but the ones that appropriate to the Linux kernel are certainly good enough for SYSLINUX. In particular, however, I appreciate if patches sent follow the standard Linux submission format, as I can automatically import them into git, retaining description and author information. Thus, this file from the Linux kernel might be useful. ----------------------------------------------------------------------- How to Get Your Change Into the Linux Kernel or Care And Operation Of Your Linus Torvalds For a person or company who wishes to submit a change to the Linux kernel, the process can sometimes be daunting if you're not familiar with "the system." This text is a collection of suggestions which can greatly increase the chances of your change being accepted. Read Documentation/SubmitChecklist for a list of items to check before submitting code. If you are submitting a driver, also read Documentation/SubmittingDrivers. -------------------------------------------- SECTION 1 - CREATING AND SENDING YOUR CHANGE -------------------------------------------- 1) "diff -up" ------------ Use "diff -up" or "diff -uprN" to create patches. All changes to the Linux kernel occur in the form of patches, as generated by diff(1). When creating your patch, make sure to create it in "unified diff" format, as supplied by the '-u' argument to diff(1). Also, please use the '-p' argument which shows which C function each change is in - that makes the resultant diff a lot easier to read. Patches should be based in the root kernel source directory, not in any lower subdirectory. To create a patch for a single file, it is often sufficient to do: SRCTREE= linux-2.6 MYFILE= drivers/net/mydriver.c cd $SRCTREE cp $MYFILE $MYFILE.orig vi $MYFILE # make your change cd .. diff -up $SRCTREE/$MYFILE{.orig,} > /tmp/patch To create a patch for multiple files, you should unpack a "vanilla", or unmodified kernel source tree, and generate a diff against your own source tree. For example: MYSRC= /devel/linux-2.6 tar xvfz linux-2.6.12.tar.gz mv linux-2.6.12 linux-2.6.12-vanilla diff -uprN -X linux-2.6.12-vanilla/Documentation/dontdiff \ linux-2.6.12-vanilla $MYSRC > /tmp/patch "dontdiff" is a list of files which are generated by the kernel during the build process, and should be ignored in any diff(1)-generated patch. The "dontdiff" file is included in the kernel tree in 2.6.12 and later. For earlier kernel versions, you can get it from . Make sure your patch does not include any extra files which do not belong in a patch submission. Make sure to review your patch -after- generated it with diff(1), to ensure accuracy. If your changes produce a lot of deltas, you may want to look into splitting them into individual patches which modify things in logical stages. This will facilitate easier reviewing by other kernel developers, very important if you want your patch accepted. There are a number of scripts which can aid in this: Quilt: http://savannah.nongnu.org/projects/quilt Andrew Morton's patch scripts: http://www.zip.com.au/~akpm/linux/patches/ Instead of these scripts, quilt is the recommended patch management tool (see above). 2) Describe your changes. Describe the technical detail of the change(s) your patch includes. Be as specific as possible. The WORST descriptions possible include things like "update driver X", "bug fix for driver X", or "this patch includes updates for subsystem X. Please apply." If your description starts to get long, that's a sign that you probably need to split up your patch. See #3, next. 3) Separate your changes. Separate _logical changes_ into a single patch file. For example, if your changes include both bug fixes and performance enhancements for a single driver, separate those changes into two or more patches. If your changes include an API update, and a new driver which uses that new API, separate those into two patches. On the other hand, if you make a single change to numerous files, group those changes into a single patch. Thus a single logical change is contained within a single patch. If one patch depends on another patch in order for a change to be complete, that is OK. Simply note "this patch depends on patch X" in your patch description. If you cannot condense your patch set into a smaller set of patches, then only post say 15 or so at a time and wait for review and integration. 4) Style check your changes. Check your patch for basic style violations, details of which can be found in Documentation/CodingStyle. Failure to do so simply wastes the reviewers time and will get your patch rejected, probably without even being read. At a minimum you should check your patches with the patch style checker prior to submission (scripts/checkpatch.pl). You should be able to justify all violations that remain in your patch. 5) Select e-mail destination. Look through the MAINTAINERS file and the source code, and determine if your change applies to a specific subsystem of the kernel, with an assigned maintainer. If so, e-mail that person. If no maintainer is listed, or the maintainer does not respond, send your patch to the primary Linux kernel developer's mailing list, linux-kernel@vger.kernel.org. Most kernel developers monitor this e-mail list, and can comment on your changes. Do not send more than 15 patches at once to the vger mailing lists!!! Linus Torvalds is the final arbiter of all changes accepted into the Linux kernel. His e-mail address is . He gets a lot of e-mail, so typically you should do your best to -avoid- sending him e-mail. Patches which are bug fixes, are "obvious" changes, or similarly require little discussion should be sent or CC'd to Linus. Patches which require discussion or do not have a clear advantage should usually be sent first to linux-kernel. Only after the patch is discussed should the patch then be submitted to Linus. 6) Select your CC (e-mail carbon copy) list. Unless you have a reason NOT to do so, CC linux-kernel@vger.kernel.org. Other kernel developers besides Linus need to be aware of your change, so that they may comment on it and offer code review and suggestions. linux-kernel is the primary Linux kernel developer mailing list. Other mailing lists are available for specific subsystems, such as USB, framebuffer devices, the VFS, the SCSI subsystem, etc. See the MAINTAINERS file for a mailing list that relates specifically to your change. Majordomo lists of VGER.KERNEL.ORG at: If changes affect userland-kernel interfaces, please send the MAN-PAGES maintainer (as listed in the MAINTAINERS file) a man-pages patch, or at least a notification of the change, so that some information makes its way into the manual pages. Even if the maintainer did not respond in step #4, make sure to ALWAYS copy the maintainer when you change their code. For small patches you may want to CC the Trivial Patch Monkey trivial@kernel.org managed by Adrian Bunk; which collects "trivial" patches. Trivial patches must qualify for one of the following rules: Spelling fixes in documentation Spelling fixes which could break grep(1) Warning fixes (cluttering with useless warnings is bad) Compilation fixes (only if they are actually correct) Runtime fixes (only if they actually fix things) Removing use of deprecated functions/macros (eg. check_region) Contact detail and documentation fixes Non-portable code replaced by portable code (even in arch-specific, since people copy, as long as it's trivial) Any fix by the author/maintainer of the file (ie. patch monkey in re-transmission mode) URL: 7) No MIME, no links, no compression, no attachments. Just plain text. Linus and other kernel developers need to be able to read and comment on the changes you are submitting. It is important for a kernel developer to be able to "quote" your changes, using standard e-mail tools, so that they may comment on specific portions of your code. For this reason, all patches should be submitting e-mail "inline". WARNING: Be wary of your editor's word-wrap corrupting your patch, if you choose to cut-n-paste your patch. Do not attach the patch as a MIME attachment, compressed or not. Many popular e-mail applications will not always transmit a MIME attachment as plain text, making it impossible to comment on your code. A MIME attachment also takes Linus a bit more time to process, decreasing the likelihood of your MIME-attached change being accepted. Exception: If your mailer is mangling patches then someone may ask you to re-send them using MIME. See Documentation/email-clients.txt for hints about configuring your e-mail client so that it sends your patches untouched. 8) E-mail size. When sending patches to Linus, always follow step #7. Large changes are not appropriate for mailing lists, and some maintainers. If your patch, uncompressed, exceeds 40 kB in size, it is preferred that you store your patch on an Internet-accessible server, and provide instead a URL (link) pointing to your patch. 9) Name your kernel version. It is important to note, either in the subject line or in the patch description, the kernel version to which this patch applies. If the patch does not apply cleanly to the latest kernel version, Linus will not apply it. 10) Don't get discouraged. Re-submit. After you have submitted your change, be patient and wait. If Linus likes your change and applies it, it will appear in the next version of the kernel that he releases. However, if your change doesn't appear in the next version of the kernel, there could be any number of reasons. It's YOUR job to narrow down those reasons, correct what was wrong, and submit your updated change. It is quite common for Linus to "drop" your patch without comment. That's the nature of the system. If he drops your patch, it could be due to * Your patch did not apply cleanly to the latest kernel version. * Your patch was not sufficiently discussed on linux-kernel. * A style issue (see section 2). * An e-mail formatting issue (re-read this section). * A technical problem with your change. * He gets tons of e-mail, and yours got lost in the shuffle. * You are being annoying. When in doubt, solicit comments on linux-kernel mailing list. 11) Include PATCH in the subject Due to high e-mail traffic to Linus, and to linux-kernel, it is common convention to prefix your subject line with [PATCH]. This lets Linus and other kernel developers more easily distinguish patches from other e-mail discussions. 12) Sign your work To improve tracking of who did what, especially with patches that can percolate to their final resting place in the kernel through several layers of maintainers, we've introduced a "sign-off" procedure on patches that are being emailed around. The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as a open-source patch. The rules are pretty simple: if you can certify the below: Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. then you just add a line saying Signed-off-by: Random J Developer using your real name (sorry, no pseudonyms or anonymous contributions.) Some people also put extra tags at the end. They'll just be ignored for now, but you can do this to mark internal company procedures or just point out some special detail about the sign-off. 13) When to use Acked-by: The Signed-off-by: tag indicates that the signer was involved in the development of the patch, or that he/she was in the patch's delivery path. If a person was not directly involved in the preparation or handling of a patch but wishes to signify and record their approval of it then they can arrange to have an Acked-by: line added to the patch's changelog. Acked-by: is often used by the maintainer of the affected code when that maintainer neither contributed to nor forwarded the patch. Acked-by: is not as formal as Signed-off-by:. It is a record that the acker has at least reviewed the patch and has indicated acceptance. Hence patch mergers will sometimes manually convert an acker's "yep, looks good to me" into an Acked-by:. Acked-by: does not necessarily indicate acknowledgement of the entire patch. For example, if a patch affects multiple subsystems and has an Acked-by: from one subsystem maintainer then this usually indicates acknowledgement of just the part which affects that maintainer's code. Judgement should be used here. When in doubt people should refer to the original discussion in the mailing list archives. 14) The canonical patch format The canonical patch subject line is: Subject: [PATCH 001/123] subsystem: summary phrase The canonical patch message body contains the following: - A "from" line specifying the patch author. - An empty line. - The body of the explanation, which will be copied to the permanent changelog to describe this patch. - The "Signed-off-by:" lines, described above, which will also go in the changelog. - A marker line containing simply "---". - Any additional comments not suitable for the changelog. - The actual patch (diff output). The Subject line format makes it very easy to sort the emails alphabetically by subject line - pretty much any email reader will support that - since because the sequence number is zero-padded, the numerical and alphabetic sort is the same. The "subsystem" in the email's Subject should identify which area or subsystem of the kernel is being patched. The "summary phrase" in the email's Subject should concisely describe the patch which that email contains. The "summary phrase" should not be a filename. Do not use the same "summary phrase" for every patch in a whole patch series (where a "patch series" is an ordered sequence of multiple, related patches). Bear in mind that the "summary phrase" of your email becomes a globally-unique identifier for that patch. It propagates all the way into the git changelog. The "summary phrase" may later be used in developer discussions which refer to the patch. People will want to google for the "summary phrase" to read discussion regarding that patch. A couple of example Subjects: Subject: [patch 2/5] ext2: improve scalability of bitmap searching Subject: [PATCHv2 001/207] x86: fix eflags tracking The "from" line must be the very first line in the message body, and has the form: From: Original Author The "from" line specifies who will be credited as the author of the patch in the permanent changelog. If the "from" line is missing, then the "From:" line from the email header will be used to determine the patch author in the changelog. The explanation body will be committed to the permanent source changelog, so should make sense to a competent reader who has long since forgotten the immediate details of the discussion that might have led to this patch. The "---" marker line serves the essential purpose of marking for patch handling tools where the changelog message ends. One good use for the additional comments after the "---" marker is for a diffstat, to show what files have changed, and the number of inserted and deleted lines per file. A diffstat is especially useful on bigger patches. Other comments relevant only to the moment or the maintainer, not suitable for the permanent changelog, should also go here. Use diffstat options "-p 1 -w 70" so that filenames are listed from the top of the kernel source tree and don't use too much horizontal space (easily fit in 80 columns, maybe with some indentation). See more details on the proper patch format in the following references. ----------------------------------- SECTION 2 - HINTS, TIPS, AND TRICKS ----------------------------------- This section lists many of the common "rules" associated with code submitted to the kernel. There are always exceptions... but you must have a really good reason for doing so. You could probably call this section Linus Computer Science 101. 1) Read Documentation/CodingStyle Nuff said. If your code deviates too much from this, it is likely to be rejected without further review, and without comment. One significant exception is when moving code from one file to another -- in this case you should not modify the moved code at all in the same patch which moves it. This clearly delineates the act of moving the code and your changes. This greatly aids review of the actual differences and allows tools to better track the history of the code itself. Check your patches with the patch style checker prior to submission (scripts/checkpatch.pl). The style checker should be viewed as a guide not as the final word. If your code looks better with a violation then its probably best left alone. The checker reports at three levels: - ERROR: things that are very likely to be wrong - WARNING: things requiring careful review - CHECK: things requiring thought You should be able to justify all violations that remain in your patch. 2) #ifdefs are ugly Code cluttered with ifdefs is difficult to read and maintain. Don't do it. Instead, put your ifdefs in a header, and conditionally define 'static inline' functions, or macros, which are used in the code. Let the compiler optimize away the "no-op" case. Simple example, of poor code: dev = alloc_etherdev (sizeof(struct funky_private)); if (!dev) return -ENODEV; #ifdef CONFIG_NET_FUNKINESS init_funky_net(dev); #endif Cleaned-up example: (in header) #ifndef CONFIG_NET_FUNKINESS static inline void init_funky_net (struct net_device *d) {} #endif (in the code itself) dev = alloc_etherdev (sizeof(struct funky_private)); if (!dev) return -ENODEV; init_funky_net(dev); 3) 'static inline' is better than a macro Static inline functions are greatly preferred over macros. They provide type safety, have no length limitations, no formatting limitations, and under gcc they are as cheap as macros. Macros should only be used for cases where a static inline is clearly suboptimal [there a few, isolated cases of this in fast paths], or where it is impossible to use a static inline function [such as string-izing]. 'static inline' is preferred over 'static __inline__', 'extern inline', and 'extern __inline__'. 4) Don't over-design. Don't try to anticipate nebulous future cases which may or may not be useful: "Make it as simple as you can, and no simpler." ---------------------- SECTION 3 - REFERENCES ---------------------- Andrew Morton, "The perfect patch" (tpp). Jeff Garzik, "Linux kernel patch submission format". Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer". NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people! Kernel Documentation/CodingStyle: Linus Torvalds's mail on the canonical patch format: -- syslinux-legacy-3.63+dfsg/doc/usbkey.txt0000664000175000017500000000410210777447273017021 0ustar evanevanThe proper mode to boot a USB key drive in is "USB-HDD". That is the ONLY mode in which the C/H/S geometry encoded on the disk itself doesn't have to match what the BIOS thinks it is. Since geometry on USB drives is completely arbitrary, and can vary from BIOS to BIOS, this is the only mode which will work in general. Some BIOSes have been reported (in particular, certain versions of the Award BIOS) that cannot boot USB keys in "USB-HDD" mode. This is a very serious BIOS bug, but it is unfortunately rather typical of the kind of quality we're seeing out of major BIOS vendors these days. On these BIOSes, you're generally stuck booting them in USB-ZIP mode. THIS MEANS THE FILESYSTEM IMAGE ON THE DISK HAS TO HAVE A CORRECT ZIPDRIVE-COMPATIBLE GEOMETRY. A standard zipdrive (both the 100 MB and the 250 MB varieties) have a "geometry" of 64 heads, 32 sectors, and are partitioned devices with a single partition 4 (unlike most other media of this type which uses partition 1.) The 100 MB variety has 96 cylinders, and the 250 MB variety has 239 cylinders; but any number of cylinders will do as appropriate for the size device you have. For example, if your device reports when inserted into a Linux system: usb-storage: device found at 4 Vendor: 32MB Model: HardDrive Rev: 1.88 Type: Direct-Access ANSI SCSI revision: 02 SCSI device sda: 64000 512-byte hdwr sectors (33 MB) ... you would have 64000/(64*32) = 31.25 cylinders; round down to 31. The script "mkdiskimage" which is supplied with the syslinux distribution can be used to initialize USB keys in a Zip-like fashion. To do that, calculate the correct number of cylinders (31 in the example above), and, if your USB key is /dev/sda (CHECK THE KERNEL MESSAGES CAREFULLY - IF YOU ENTER THE WRONG DISK DRIVE IT CANNOT BE RECOVERED), run: mkdiskimage -4 /dev/sda 0 64 32 (The 0 means automatically determine the size of the device, and -4 means mimic a zipdisk by using partition 4.) Then you should be able to run syslinux /dev/sda4 ... and mount /dev/sda4 and put your files on it as needed. syslinux-legacy-3.63+dfsg/doc/keytab-lilo.txt0000664000175000017500000000712210777447273017740 0ustar evanevanThis is the documentation for the keytab-lilo.pl program. It was taken verbatim from the LILO-20 README file; only this header was added. LILO program code, documentation and auxiliary programs are Copyright 1992-1997 Werner Almesberger. All rights reserved. Redistribution and use in source and binary forms of parts of or the whole original or derived work are permitted provided that the original work is properly attributed to the author. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. This work is provided "as is" and without any express or implied warranties. To use a LILO keyboard table with SYSLINUX, specify the KBDMAP command in syslinux.cfg, for example: kbdmap de.ktl ============================================================================ Keyboard translation -------------------- The PC keyboard emits so-called scan codes, which are basically key numbers. The BIOS then translates those scan codes to the character codes of the characters printed on the key-caps. By default, the BIOS normally assumes that the keyboard has a US layout. Once an operating system is loaded, this operating system can use a different mapping. At boot time, LILO only has access to the basic services provided by the BIOS and therefore receives the character codes for an US keyboard. It provides a simple mechanism to re-map the character codes to what is appropriate for the actual layout.* * The current mechanism isn't perfect, because it sits on top of the scan code to character code translation performed by the BIOS. This means that key combinations that don't produce any useful character on the US keyboard will be ignored by LILO. The advantage of this approach is its simplicity. Compiling keyboard translation tables - - - - - - - - - - - - - - - - - - - LILO obtains layout information from the keyboard translation tables Linux uses for the text console. They are usually stored in /usr/lib/kbd/keytables. LILO comes with a program keytab-lilo.pl that reads those tables and generates a table suitable for use by the map installer. keytab-lilo.pl invokes the program loadkeys to print the tables in a format that is easy to parse.* * On some systems, only root can execute loadkeys. It is then necessary to run keytab-lilo.pl as root too. keytab-lilo.pl is used as follows: keytab-lilo.pl [ -p = ] ... [][.] ] [][.] ] -p = Specifies corrections ("patches") to the mapping obtained from the translation table files. E.g. if pressing the upper case "A" should yield an at sign, -p 65=64 would be used. The -p option can be repeated any number of times. The codes can also be given as hexadecimal or as octal numbers if they are prefixed with 0x or 0, respectively. The directory in which the file resides. The default path is /usr/lib/kbd/keytables. Usually the trailing .map, which is automatically added if the file name doesn't contain dots. Is the layout which specifies the translation by the BIOS. If none is specified, us is assumed. Is the actual layout of the keyboard. keytab-lilo.pl writes the resulting translation table as a binary string to standard output. Such tables can be stored anywhere with any name, but the suggested naming convention is /boot/.ktl ("Keyboard Table for Lilo"), where is the name of the keyboard layout. Example: keytab-lilo.pl de >/boot/de.ktl syslinux-legacy-3.63+dfsg/doc/menu.txt0000664000175000017500000003216510777447273016475 0ustar evanevanThere are two menu systems included with SYSLINUX, the advanced menu system, and the simple menu system. +++ THE ADVANCED MENU SYSTEM +++ The advanced menu system, written by Murali Krishnan Ganapathy, is located in the menu/ subdirectly. It allows the user to create hierarchial submenus, dynamic options, checkboxes, and just about anything you want. It requires that the menu is compiled from a simple C file, see menu/simple.c and menu/complex.c for examples. The advanced menu system doesn't support serial console at this time. See menu/README for more information. +++ THE SIMPLE MENU SYSTEM +++ The simple menu system is a single module located at com32/modules/vesamenu.c32 (graphical) or com32/modules/menu.c32 (text mode only). It uses the same configuration file as the regular SYSLINUX command line, and displays all the LABEL statements. To use the menu system, simply make sure [vesa]menu.c32 is in the appropriate location for your boot medium (the same directory as the configuration file for SYSLINUX, EXTLINUX and ISOLINUX, and the same directory as pxelinux.0 for PXELINUX), and put the following options in your configuration file: DEFAULT menu.c32 PROMPT 0 There are a few menu additions to the command line, all starting with the keywords MENU or TEXT; like the rest of the SYSLINUX config file language, it is case insensitive: MENU TITLE title Give the menu a title. The title is presented at the top of the menu. MENU HIDDEN Do not display the actual menu unless the user presses a key. All that is displayed is a timeout message. MENU SEPARATOR Insert an empty line in the menu. MENU LABEL label (Only valid after a LABEL statement.) Changes the label displayed for a specific entry. This allows you to have a label that isn't suitable for the command line, for example: # Soft Cap Linux LABEL softcap MENU LABEL Soft Cap ^Linux 9.6.36 KERNEL softcap-9.6.36.bzi APPEND whatever # A very dense operating system LABEL brick MENU LABEL ^Windows CE/ME/NT KERNEL chain.c32 APPEND hd0 2 The ^ symbol in a MENU LABEL statement defines a hotkey. The hotkey will be highlighted in the menu and will move the menu cursor immediately to that entry. Reusing hotkeys is disallowed, subsequent entries will not be highlighted, and will not work. Keep in mind that the LABELs, not MENU LABELs, must be unique, or odd things will happen to the command-line. MENU INDENT count (Only valid after a LABEL statement.) Will add "count" spaces in front of the displayed menu entry. MENU DISABLE (Only valid after a LABEL statement.) Makes the entry unselectable. This allows you to make a section in your menu with different options below it. for example: # Entries for network boots LABEL - MENU LABEL Network: MENU DISABLE # Soft Cap Linux LABEL softcap MENU LABEL Soft Cap ^Linux 9.6.36 MENU INDENT 1 KERNEL softcap-9.6.36.bzi APPEND whatever # Dos 6.22 LABEL dos MENU LABEL ^Dos 6.22 MENU INDENT 1 KERNEL memdisk APPEND initrd=dos622.imz # Separator MENU SEPARATOR # Entries for local boots LABEL - MENU LABEL Local: MENU DISABLE # Windows 2000 LABEL w2k MENU LABEL ^Windows 2000 MENU INDENT 1 KERNEL chain.c32 APPEND hd0 1 # Windows XP LABEL xp MENU LABEL Windows ^XP MENU INDENT 1 KERNEL chain.c32 APPEND hd0 2 MENU HIDE (Only valid after a LABEL statement.) Suppresses a particular LABEL entry from the menu. MENU DEFAULT (Only valid after a LABEL statement.) Indicates that this entry should be the default. If no default is specified, use the first one. TEXT HELP Help text ... ... which can span multiple lines ENDTEXT (Only valid after a LABEL statement.) Specifies a help text that should be displayed when a particular selection is highlighted. MENU PASSWD passwd (Only valid after a LABEL statement.) Sets a password on this menu entry. "passwd" can be either a cleartext password, a SHA-1 encrypted password (starting with $4$), or and MD5 encrypted password (starting with $1$). Use the included Perl scripts "sha1pass" or "md5pass" to encrypt passwords. MD5 passwords are compatible with most Unix password file utilities; SHA-1 passwords are probably unique to SYSLINUX. Obviously, if you don't encrypt your passwords they will not be very secure at all. If you are using passwords, you want to make sure you also use the settings "NOESCAPE 1", "PROMPT 0", and either set "ALLOWOPTIONS 0" or use a master password (see below.) If passwd is an empty string, this menu entry can only be unlocked with the master password. MENU MASTER PASSWD passwd Sets a master password. This password can be used to boot any menu entry, and is required for the [Tab] and [Esc] keys to work. MENU BACKGROUND background For vesamenu.c32, sets the background image. The background can either be a color (see MENU COLOR) or the name of an image file, which should be 640x480 pixels and either in PNG or JPEG format. MENU BEGIN [tagname] MENU END Begin/end a submenu. The entries between MENU BEGIN and MENU END form a submenu, which is marked with a > mark on the right hand of the screen. Submenus inherit the properties of their parent menus, but can override them, and can thus have their own backgrounds, master passwords, titles, timeouts, messages and so forth. MENU GOTO tagname (Only valid after a LABEL statement.) This label will transfer to the named submenu instead of booting anything. To transfer to the top-level menu, specify "menu goto .top". MENU EXIT [tagname] (Only valid after a label statement inside MENU BEGIN ... MENU END) Exit to the next higher menu, or, if tagname is specified, to the named menu. MENU QUIT (Only valid after a LABEL statement.) This label quits the menu system. WARNING: if MENU MASTER PASSWD or ALLOWOPTIONS 0 is set, this will still allow exiting to the CLI; however, a separate MENU PASSWD can of course be set for this label. MENU START (Only valid inside MENU BEGIN ... MENU END) Indicates that the menu system should start at the menu being defined instead of at the top-level menu. INCLUDE filename [tagname] MENU INCLUDE filename [tagname] Include the contents of the configuration file filename at this point. In the case of MENU INCLUDE, the included data is only seen by the menu system; the core syslinux code does not parse this command, so any labels defined in it are unavailable. If a tagname is included, the whole file is considered to have been bracketed with a MENU BEGIN tagname ... MENU END pair, and will therefore show up as a submenu. MENU AUTOBOOT message Replaces the message "Automatic boot in # second{,s}...". The symbol # is replaced with the number of seconds remaining. The syntax "{singular,[dual,]plural}" can be used to conjugate appropriately. MENU TABMSG message Replaces the message "Press [Tab] to edit options". MENU NOTABMSG message Takes the place of the TABMSG message if option editing is disabled. Defaults to blank. MENU PASSPROMPT message Replaces the message "Password required". MENU COLOR element ansi foreground background shadow Sets the color of element "element" to the specified color sequence: screen Rest of the screen border Border area title Title bar unsel Unselected menu item hotkey Unselected hotkey sel Selection bar hotsel Selected hotkey disabled Disabled menu item scrollbar Scroll bar tabmsg Press [Tab] message cmdmark Command line marker cmdline Command line pwdborder Password box border pwdheader Password box header pwdentry Password box contents timeout_msg Timeout message timeout Timeout counter help Help text msgXX Message (F-key) file attribute XX ... where XX is two hexadecimal digits (the "plain text" is 07). "ansi" is a sequence of semicolon-separated ECMA-48 Set Graphics Rendition ([m) sequences: 0 reset all attributes to their defaults 1 set bold 4 set underscore (simulated with color on a color display) 5 set blink 7 set reverse video 22 set normal intensity 24 underline off 25 blink off 27 reverse video off 30 set black foreground 31 set red foreground 32 set green foreground 33 set brown foreground 34 set blue foreground 35 set magenta foreground 36 set cyan foreground 37 set white foreground 38 set underscore on, set default foreground color 39 set underscore off, set default foreground color 40 set black background 41 set red background 42 set green background 43 set brown background 44 set blue background 45 set magenta background 46 set cyan background 47 set white background 49 set default background color These are used (a) in text mode, and (b) on the serial console. "foreground" and "background" are color codes in #AARRGGBB notation, where AA RR GG BB are hexadecimal digits for alpha (opacity), red, green and blue, respectively. #00000000 represents fully transparent, and #ffffffff represents opaque white. "shadow" controls the handling of the graphical console text shadow. Permitted values are "none" (no shadowing), "std" or "standard" (standard shadowing - foreground pixels are raised), "all" (both background and foreground raised), and "rev" or "reverse" (background pixels are raised.) If any field is set to "*" or omitted (at the end of the line) then that field is left unchanged. The current defaults are: menu color screen 37;40 #80ffffff #00000000 std menu color border 30;44 #40000000 #00000000 std menu color title 1;36;44 #c00090f0 #00000000 std menu color unsel 37;44 #90ffffff #00000000 std menu color hotkey 1;37;44 #ffffffff #00000000 std menu color sel 7;37;40 #e0000000 #20ff8000 all menu color hotsel 1;7;37;40 #e0400000 #20ff8000 all menu color disabled 1;30;44 #60cccccc #00000000 std menu color scrollbar 30;44 #40000000 #00000000 std menu color tabmsg 31;40 #90ffff00 #00000000 std menu color cmdmark 1;36;40 #c000ffff #00000000 std menu color cmdline 37;40 #c0ffffff #00000000 std menu color pwdborder 30;47 #80ffffff #20ffffff std menu color pwdheader 31;47 #80ff8080 #20ffffff std menu color pwdentry 30;47 #80ffffff #20ffffff std menu color timeout_msg 37;40 #80ffffff #00000000 std menu color timeout 1;37;40 #c0ffffff #00000000 std menu color help 37;40 #c0ffffff #00000000 std menu color msg07 37;40 #90ffffff #00000000 std MENU MSGCOLOR fg_filter bg_filter shadow Sets *all* the msgXX colors to a color scheme derived from the fg_filter and bg_filter values. Background color zero is always treated as transparent. The default corresponds to: menu msgcolor #90ffffff #80ffffff std This directive should come before any directive that customizes individual msgXX colors. MENU WIDTH 80 MENU MARGIN 10 MENU PASSWORDMARGIN 3 MENU ROWS 12 MENU TABMSGROW 18 MENU CMDLINEROW 18 MENU ENDROW -1 MENU PASSWORDROW 11 MENU TIMEOUTROW 20 MENU HELPMSGROW 22 MENU HELPMSGENDROW -1 MENU HIDDENROW -2 MENU HSHIFT 0 MENU VSHIFT 0 These options control the layout of the menu on the screen. The values above are the defaults. A negative value is relative to the calculated length of the screen (25 for text mode, 28 for VESA graphics mode.) F1 textfile background ... F12 textfile background Displays full-screen help (also available at the command line.) The same control code sequences as in the command line interface are supported, although some are ignored. Additionally, a second argument allows a different background image (see MENU BACKGROUND for supported formats) to be displayed. The menu system honours the TIMEOUT command; if TIMEOUT is specified it will execute the ONTIMEOUT command if one exists, otherwise it will pick the default menu option. Normally, the user can press [Tab] to edit the menu entry, and [Esc] to return to the SYSLINUX command line. However, if the configuration file specifies ALLOWOPTIONS 0, these keys will be disabled, and if MENU MASTER PASSWD is set, they require the master password. The simple menu system supports serial console, using the normal SERIAL directive. However, it can be quite slow over a slow serial link; you probably want to set your baudrate to 38400 or higher if possible. It requires a Linux/VT220/ANSI-compatible terminal on the other end. +++ USING AN ALTERNATE CONFIGURATION FILE +++ It is also possible to load a secondary configuration file, to get to another menu. To do that, invoke menu.c32 with the name of the secondary configuration file. LABEL othermenu MENU LABEL Another Menu KERNEL menu.c32 APPEND othermenu.conf If you specify more than one file, they will all be read, in the order specified. The dummy filename ~ (tilde) is replaced with the filename of the main configuration file. # The file graphics.conf contains common color and layout commands for # all menus. LABEL othermenu MENU LABEL Another Menu KERNEL vesamenu.c32 APPEND graphics.conf othermenu.conf # Return to the main menu LABEL mainmenu MENU LABEL Return to Main Menu KERNEL vesamenu.c32 APPEND graphics.conf ~ See also the MENU INCLUDE directive above. syslinux-legacy-3.63+dfsg/doc/pxelinux.txt0000664000175000017500000003674610777447273017416 0ustar evanevan PXELINUX A bootloader for Linux using the PXE network booting protocol Copyright 1994-2008 H. Peter Anvin - All Rights Reserved This program is provided under the terms of the GNU General Public License, version 2 or, at your option, any later version. There is no warranty, neither expressed nor implied, to the function of this program. Please see the included file COPYING for details. ---------------------------------------------------------------------- PXELINUX is a SYSLINUX derivative, for booting Linux off a network server, using a network ROM conforming to the Intel PXE (Pre-Execution Environment) specification. PXELINUX is *not* a program that is intended to be flashed or burned into a PROM on the network card; if you want that, check out Etherboot (http://www.etherboot.org/). Etherboot 5.4 or later can also be used to create a PXE-compliant boot PROM for many network cards. ++++ HOW TO CONFIGURE PXELINUX ++++ PXELINUX operates in many ways like SYSLINUX. If you are not familiar with SYSLINUX, read syslinux.txt first, since this documentation only explains the differences. On the TFTP server, create the directory "/tftpboot", and copy the following files to it: pxelinux.0 - from the SYSLINUX distribution any kernel or initrd images you want to boot Finally, create the directory "/tftpboot/pxelinux.cfg". The configuration file (equivalent of syslinux.cfg -- see syslinux.txt for the options here) will live in this directory. Because more than one system may be booted from the same server, the configuration file name depends on the IP address of the booting machine. PXELINUX will search for its config file on the boot server in the following way: First, it will search for the config file using the client UUID, if one is provided by the PXE stack (note, some BIOSes don't have a valid UUID, and you might end up with something like all 1's.) This is in the standard UUID format using lower case hexadecimal digits, e.g. b8945908-d6a6-41a9-611d-74a6ab80b83d. Next, it will search for the config file using the hardware type (using its ARP type code) and address, all in lower case hexadecimal with dash separators; for example, for an Ethernet (ARP type 1) with address 88:99:AA:BB:CC:DD it would search for the filename 01-88-99-aa-bb-cc-dd. Next, it will search for the config file using its own IP address in upper case hexadecimal, e.g. 192.0.2.91 -> C000025B (you can use the included progam "gethostip" to compute the hexadecimal IP address for any host.) If that file is not found, it will remove one hex digit and try again. Ultimately, it will try looking for a file named "default" (in lower case). As an example, if the boot file name is /mybootdir/pxelinux.0, the UUID is b8945908-d6a6-41a9-611d-74a6ab80b83d, the Ethernet MAC address is 88:99:AA:BB:CC:DD and the IP address 192.0.2.91, it will try: /mybootdir/pxelinux.cfg/b8945908-d6a6-41a9-611d-74a6ab80b83d /mybootdir/pxelinux.cfg/01-88-99-aa-bb-cc-dd /mybootdir/pxelinux.cfg/C000025B /mybootdir/pxelinux.cfg/C000025 /mybootdir/pxelinux.cfg/C00002 /mybootdir/pxelinux.cfg/C0000 /mybootdir/pxelinux.cfg/C000 /mybootdir/pxelinux.cfg/C00 /mybootdir/pxelinux.cfg/C0 /mybootdir/pxelinux.cfg/C /mybootdir/pxelinux.cfg/default ... in that order. Note that all filename references are relative to the directory pxelinux.0 lives in. PXELINUX generally requires that filenames (including any relative path) are 127 characters or shorter in length. Starting in release 3.20, PXELINUX will no longer apply a built-in default if it cannot find any configuration file at all; instead it will reboot after the timeout interval has expired. This keeps a machine from getting stuck indefinitely due to a boot server failure. PXELINUX does not support MTFTP, and I have no plans of doing so, as MTFTP is inherently broken for files more than 65535 packets (about 92 MB) in size. It is of course possible to use MTFTP for the initial boot, if you have such a setup. MTFTP server setup is beyond the scope of this document. ++++ SETTING UP THE TFTP SERVER ++++ PXELINUX currently requires that the boot server has a TFTP server which supports the "tsize" TFTP option (RFC 1784/RFC 2349). The "tftp-hpa" TFTP server, which support options, is available at: http://www.kernel.org/pub/software/network/tftp/ ftp://www.kernel.org/pub/software/network/tftp/ ... and on any kernel.org mirror (see http://www.kernel.org/mirrors/). Another TFTP server which supports this is atftp by Jean-Pierre Lefebvre: ftp://ftp.mamalinux.com/pub/atftp/ If your boot server is running Windows (and you can't fix that), try tftpd32 by Philippe Jounin (you need version 2.11 or later; previous versions had a bug which made it incompatible with PXELINUX): http://tftpd32.jounin.net/ ++++ SETTING UP THE DHCP SERVER ++++ The PXE protocol uses a very complex set of extensions to DHCP or BOOTP. However, most PXE implementations -- this includes all Intel ones version 0.99n and later -- seem to be able to boot in a "conventional" DHCP/TFTP configuration. Assuming you don't have to support any very old or otherwise severely broken clients, this is probably the best configuration unless you already have a PXE boot server on your network. A sample DHCP setup, using the "conventional TFTP" configuration, would look something like the following, using ISC dhcp 2.0 dhcpd.conf syntax: allow booting; allow bootp; # Standard configuration directives... option domain-name ""; option subnet-mask ; option broadcast-address ; option domain-name-servers ; option routers ; # Group the PXE bootable hosts together group { # PXE-specific configuration directives... next-server ; filename "/tftpboot/pxelinux.0"; # You need an entry like this for every host # unless you're using dynamic addresses host { hardware ethernet ; fixed-address ; } } Note that if your particular TFTP daemon runs under chroot (tftp-hpa will do this if you specify the -s (secure) option; this is highly recommended), you almost certainly should not include the /tftpboot prefix in the filename statement. If this does not work for your configuration, you probably should set up a "PXE boot server" on port 4011 of your TFTP server; a free PXE boot server is available at: http://www.kano.org.uk/projects/pxe/ With such a boot server defined, your DHCP configuration should look the same except for an "option dhcp-class-identifier" ("option vendor-class-identifier" if you are using DHCP 3.0): allow booting; allow bootp; # Standard configuration directives... option domain-name ""; option subnet-mask ; option broadcast-address ; option domain-name-servers ; option routers ; # Group the PXE bootable hosts together group { # PXE-specific configuration directives... option dhcp-class-identifier "PXEClient"; next-server ; # You need an entry like this for every host # unless you're using dynamic addresses host { hardware ethernet ; fixed-address ; } } Here, the boot file name is obtained from the PXE server. If the "conventional TFTP" configuration doesn't work on your clients, and setting up a PXE boot server is not an option, you can attempt the following configuration. It has been known to boot some configurations correctly; however, there are no guarantees: allow booting; allow bootp; # Standard configuration directives... option domain-name ""; option subnet-mask ; option broadcast-address ; option domain-name-servers ; option routers ; # Group the PXE bootable hosts together group { # PXE-specific configuration directives... option dhcp-class-identifier "PXEClient"; option vendor-encapsulated-options 09:0f:80:00:0c:4e:65:74:77:6f:72:6b:20:62:6f:6f:74:0a:07:00:50:72:6f:6d:70:74:06:01:02:08:03:80:00:00:47:04:80:00:00:00:ff; next-server ; filename "/tftpboot/pxelinux.0"; # You need an entry like this for every host # unless you're using dynamic addresses host { hardware ethernet ; fixed-address ; } } Note that this *will not* boot some clients that *will* boot with the "conventional TFTP" configuration; Intel Boot Client 3.0 and later are known to fall into this category. ++++ SPECIAL DHCP OPTIONS ++++ PXELINUX (starting with version 1.62) supports the following nonstandard DHCP options, which depending on your DHCP server you may be able to use to customize the specific behaviour of PXELINUX. See RFC 5071 for some additional information about these options. Option 208 pxelinux.magic - Earlier versions of PXELINUX required this to be set to F1:00:74:7E (241.0.116.126) for PXELINUX to recognize any special DHCP options whatsoever. As of PXELINUX 3.55, this option is deprecated and is no longer required. Option 209 pxelinux.configfile - Specifies the PXELINUX configuration file name. Option 210 pxelinux.pathprefix - Specifies the PXELINUX common path prefix, instead of deriving it from the boot file name. This almost certainly needs to end in whatever character the TFTP server OS uses as a pathname separator, e.g. slash (/) for Unix. Option 211 pxelinux.reboottime - Specifies, in seconds, the time to wait before reboot in the event of TFTP failure. 0 means wait "forever" (in reality, it waits approximately 136 years.) ISC dhcp 3.0 supports a rather nice syntax for specifying custom options; you can use the following syntax in dhcpd.conf if you are running this version of dhcpd: option space pxelinux; option pxelinux.magic code 208 = string; option pxelinux.configfile code 209 = text; option pxelinux.pathprefix code 210 = text; option pxelinux.reboottime code 211 = unsigned integer 32; NOTE: In earlier versions of PXELINUX, this would only work as a "site-option-space". Since PXELINUX 2.07, this will work both as a "site-option-space" (unencapsulated) and as a "vendor-option-space" (type 43 encapsulated.) This may avoid messing with the dhcp-parameter-request-list, as detailed below. Then, inside your PXELINUX-booting group or class (whereever you have the PXELINUX-related options, such as the filename option), you can add, for example: # Always include the following lines for all PXELINUX clients site-option-space "pxelinux"; option pxelinux.magic f1:00:74:7e; if exists dhcp-parameter-request-list { # Always send the PXELINUX options (specified in hexadecimal) option dhcp-parameter-request-list = concat(option dhcp-parameter-request-list,d0,d1,d2,d3); } # These lines should be customized to your setup option pxelinux.configfile "configs/common"; option pxelinux.pathprefix "/tftpboot/pxelinux/files/"; option pxelinux.reboottime 30; filename "/tftpboot/pxelinux/pxelinux.bin"; Note that the configfile is relative to the pathprefix: this will look for a config file called /tftpboot/pxelinux/files/configs/common on the TFTP server. The "option dhcp-parameter-request-list" statement forces the DHCP server to send the PXELINUX-specific options, even though they are not explicitly requested. Since the DHCP request is done before PXELINUX is loaded, the PXE client won't know to request them. Using ISC dhcp 3.0 you can create a lot of these strings on the fly. For example, to use the hexadecimal form of the hardware address as the configuration file name, you could do something like: site-option-space "pxelinux"; option pxelinux.magic f1:00:74:7e; if exists dhcp-parameter-request-list { # Always send the PXELINUX options (specified in hexadecimal) option dhcp-parameter-request-list = concat(option dhcp-parameter-request-list,d0,d1,d2,d3); } option pxelinux.configfile = concat("pxelinux.cfg/", binary-to-ascii(16, 8, ":", hardware)); filename "/tftpboot/pxelinux.bin"; If you used this from a client whose Ethernet address was 58:FA:84:CF:55:0E, this would look for a configuration file named "/tftpboot/pxelinux.cfg/1:58:fa:84:cf:55:e". ++++ ALTERNATE TFTP SERVERS ++++ PXELINUX supports the following special pathname conventions: ::filename Suppresses the common filename prefix, i.e. passes the string "filename" unmodified to the server. IP address::filename (e.g. 192.0.2.1::filename) Suppresses the common filename prefix, *and* sends a request to an alternate TFTP server. Instead of an IP address, a DNS name can be used. It will be assumed to be fully qualified if it contains dots; otherwise the local domain as reported by the DHCP server (option 15) will be added. :: was chosen because it is unlikely to conflict with operating system usage. However, if you happen to have an environment for which the special treatment of :: is a problem, please contact the SYSLINUX mailing list. ++++ SOME NOTES ++++ If the boot fails, PXELINUX (unlike SYSLINUX) will not wait forever; rather, if it has not received any input for approximately five minutes after displaying an error message, it will reset the machine. This allows an unattended machine to recover in case it had bad enough luck of trying to boot at the same time the TFTP server goes down. Lots of PXE stacks, especially old ones, have various problems of varying degrees of severity. Please see: http://syslinux.zytor.com/hardware.php ... for a list of currently known hardware problems, with workarounds if known. ++++ KEEPING THE PXE STACK AROUND ++++ Normally, PXELINUX will unload the PXE and UNDI stacks before invoking the kernel. In special circumstances (for example, when using MEMDISK to boot an operating system with an UNDI network driver) it might be desirable to keep the PXE stack in memory. If the option "keeppxe" is given on the kernel command line, PXELINUX will keep the PXE and UNDI stacks in memory. (If you don't know what this means, you probably don't need it.) ++++ PROBLEMS WITH YOUR PXE STACK ++++ There are a number of extremely broken PXE stacks in the field. The gPXE project (formerly known as Etherboot) provides an open-source PXE stack that works with a number of cards, and which can be loaded from a CD-ROM, USB key, or floppy if desired. Information on gPXE is available from: http://www.etherboot.org/ ... and ready-to-use ROM or disk images from: http://www.rom-o-matic.net/ Some cards, like may systems with the SiS 900, has a PXE stack which works just barely well enough to load a single file, but doesn't handle the more advanced items required by PXELINUX. If so, it is possible to use the built-in PXE stack to load gPXE, which can then load PXELINUX. See: http://www.etherboot.org/wiki/pxechaining ++++ CURRENTLY KNOWN PROBLEMS ++++ The following problems are known with PXELINUX, so far: + Requires a TFTP server which supports the "tsize" option. + The error recovery routine doesn't work quite right. For right now, it just does a hard reset - seems good enough. + We should probably call the UDP receive function in the keyboard entry loop, so that we answer ARP requests. + Boot sectors/disk images are not supported yet. If you have additional problems, please contact the SYSLINUX mailing list (see syslinux.txt for the address.) syslinux-legacy-3.63+dfsg/doc/distrib.txt0000664000175000017500000000227110777447273017164 0ustar evanevanFor creators of Linux distributions: SYSLINUX is a notoriously hard program to debug, since it runs outside of any operating system, and has a tendency to expose BIOS and hardware bugs on various systems. Therefore, I would appreciate if you would resist the temptation of recompiling the SYSLINUX bootloader itself (ldlinux.asm) if at all possible. If you do that, I will have to refer any bug reports I receive back to the respective distributor. However, I have no such concerns about recompiling the installer programs, and in fact, with both libc 5 and libc 6 in common use in the Linux world today I understand if you wish to relink the Linux-based installer against your system version of libc. Therefore a special makefile targets "make installer" has been included with the SYSLINUX distribution, starting with version 1.42. To rebuild the installer programs *only*, starting from a freshly untarred distribution copy of SYSLINUX, do: make clean make installer If you want to remove all intermediate files, including the ones obtained from assembling ldlinux.asm and which are included in the distribution, do "make spotless". I appreciate your assistance in this matter. H. Peter Anvin syslinux-legacy-3.63+dfsg/bin2hex.pl0000775000175000017500000000311710777447271016113 0ustar evanevan#!/usr/bin/perl ## ----------------------------------------------------------------------- ## ## Copyright 2003-2008 H. Peter Anvin - All Rights Reserved ## ## Permission is hereby granted, free of charge, to any person ## obtaining a copy of this software and associated documentation ## files (the "Software"), to deal in the Software without ## restriction, including without limitation the rights to use, ## copy, modify, merge, publish, distribute, sublicense, and/or ## sell copies of the Software, and to permit persons to whom ## the Software is furnished to do so, subject to the following ## conditions: ## ## The above copyright notice and this permission notice shall ## be included in all copies or substantial portions of the Software. ## ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ## OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ## HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ## WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ## FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ## OTHER DEALINGS IN THE SOFTWARE. ## ## ----------------------------------------------------------------------- eval { use bytes; }; eval { binmode STDIN; }; $len = 0; while ( read(STDIN,$ch,1) ) { $cc = ord($ch); $len += printf ("%x", $cc); if ( $len > 72 ) { print "\n"; $len = 0; } else { print " "; $len++; } } print "\n" if ( $len ); exit 0; syslinux-legacy-3.63+dfsg/ldlinux.bss0000664000175000017500000000100010777447305016367 0ustar evanevanXSYSLINUX1м{W{ػx7V1, x?Gd|M'EufEf|r uB|?|UA1,rUu t}f}~f>$~JLLy:f|f1OUffRfPSWjf`1,Bfadr]f) !uf`11,fa}O]fRfPUSf6|f>|f1ɇfk)9vAň֊1,f`farf []fXfZf)uMuޕ.}u1ּ{fx} t ;.}v.}Boot error ᆳsyslinux-legacy-3.63+dfsg/cmdline.inc0000664000175000017500000000174410777447272016327 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 2003-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; cmdline.inc ;; ;; Common routine to assemble [null-terminated] command line into ;; real_mode_seg:cmd_line_here. ;; Not used by plain kernel due to BOOT_IMAGE= etc. ;; ; ; Assumes DS == CS make_plain_cmdline: push es ; ui.inc has already copied any APPEND options mov ax,real_mode_seg mov es,ax mov si,[CmdOptPtr] mov di,[CmdLinePtr] call strcpy dec di mov [CmdLinePtr],di pop es ret syslinux-legacy-3.63+dfsg/ldlinux.asm0000664000175000017500000011030210777447273016372 0ustar evanevan; -*- fundamental -*- (asm-mode sucks) ; **************************************************************************** ; ; ldlinux.asm ; ; A program to boot Linux kernels off an MS-DOS formatted floppy disk. This ; functionality is good to have for installation floppies, where it may ; be hard to find a functional Linux system to run LILO off. ; ; This program allows manipulation of the disk to take place entirely ; from MS-LOSS, and can be especially useful in conjunction with the ; umsdos filesystem. ; ; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Boston MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; **************************************************************************** %ifndef IS_MDSLINUX %define IS_SYSLINUX 1 %endif %include "head.inc" ; ; Some semi-configurable constants... change on your own risk. ; my_id equ syslinux_id FILENAME_MAX_LG2 equ 6 ; log2(Max filename size Including final null) FILENAME_MAX equ (1< Current directory sector mov si,di .findend: lodsb cmp al,' ' jbe .endpath cmp al,'/' jne .findend .endpath: xchg si,di pop eax ; Current directory sector mov [PrevDir],eax ; Remember last directory searched push di call mangle_dos_name ; MangledBuf <- component call search_dos_dir pop di jz .notfound ; Pathname component missing cmp byte [di-1],'/' ; Do we expect a directory je .isdir ; Otherwise, it should be a file .isfile: test dl,18h ; Subdirectory|Volume Label jnz .badfile ; If not a file, it's a bad thing ; SI and EAX are already set mov edx,eax shr edx,16 ; Old 16-bit remnant... and eax,eax ; EAX != 0 jz .badfile ret ; Done! ; If we expected a directory, it better be one... .isdir: test dl,10h ; Subdirectory jz .badfile xor eax,eax xchg eax,[si+file_sector] ; Get sector number and free file structure jmp .pathwalk ; Walk the next bit of the path .badfile: xor eax,eax mov [si],eax ; Free file structure .notfound: xor eax,eax xor dx,dx ret section .bss alignb 4 CurrentDir resd 1 ; Current directory PrevDir resd 1 ; Last scanned directory section .text ; ; ; kaboom2: once everything is loaded, replace the part of kaboom ; starting with "kaboom.patch" with this part kaboom2: mov si,err_bootfailed call cwritestr cmp byte [kaboom.again+1],18h ; INT 18h version? je .int18 call getchar call vgaclearmode int 19h ; And try once more to boot... .norge: jmp short .norge ; If int 19h returned; this is the end .int18: call vgaclearmode int 18h .noreg: jmp short .noreg ; Nynorsk ; ; mangle_name: Mangle a filename pointed to by DS:SI into a buffer pointed ; to by ES:DI; ends on encountering any whitespace. ; DI is preserved. ; ; This verifies that a filename is < FILENAME_MAX characters, ; doesn't contain whitespace, zero-pads the output buffer, ; and removes trailing dots and redundant slashes, plus changes ; backslashes to forward slashes, ; so "repe cmpsb" can do a compare, and the path-searching routine ; gets a bit of an easier job. ; ; mangle_name: push di push bx xor ax,ax mov cx,FILENAME_MAX-1 mov bx,di .mn_loop: lodsb cmp al,' ' ; If control or space, end jna .mn_end cmp al,'\' ; Backslash? jne .mn_not_bs mov al,'/' ; Change to forward slash .mn_not_bs: cmp al,ah ; Repeated slash? je .mn_skip xor ah,ah cmp al,'/' jne .mn_ok mov ah,al .mn_ok stosb .mn_skip: loop .mn_loop .mn_end: cmp bx,di ; At the beginning of the buffer? jbe .mn_zero cmp byte [es:di-1],'.' ; Terminal dot? je .mn_kill cmp byte [es:di-1],'/' ; Terminal slash? jne .mn_zero .mn_kill: dec di ; If so, remove it inc cx jmp short .mn_end .mn_zero: inc cx ; At least one null byte xor ax,ax ; Zero-fill name rep stosb pop bx pop di ret ; Done ; ; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled ; filename to the conventional representation. This is needed ; for the BOOT_IMAGE= parameter for the kernel. ; NOTE: A 13-byte buffer is mandatory, even if the string is ; known to be shorter. ; ; DS:SI -> input mangled file name ; ES:DI -> output buffer ; ; On return, DI points to the first byte after the output name, ; which is set to a null byte. ; unmangle_name: call strcpy dec di ; Point to final null byte ret ; ; mangle_dos_name: ; Mangle a DOS filename component pointed to by DS:SI ; into [MangledBuf]; ends on encountering any whitespace or slash. ; Assumes CS == DS == ES. ; mangle_dos_name: pusha mov di,MangledBuf mov cx,11 ; # of bytes to write .loop: lodsb cmp al,' ' ; If control or space, end jna .end cmp al,'/' ; Slash, too je .end cmp al,'.' ; Period -> space-fill je .is_period cmp al,'a' jb .not_lower cmp al,'z' ja .not_uslower sub al,020h jmp short .not_lower .is_period: mov al,' ' ; We need to space-fill .period_loop: cmp cx,3 ; If <= 3 characters left jbe .loop ; Just ignore it stosb ; Otherwise, write a period loop .period_loop ; Dec CX and (always) jump .not_uslower: cmp al,ucase_low jb .not_lower cmp al,ucase_high ja .not_lower mov bx,ucase_tab-ucase_low xlatb .not_lower: stosb loop .loop ; Don't continue if too long .end: mov al,' ' ; Space-fill name rep stosb ; Doesn't do anything if CX=0 popa ret ; Done section .bss MangledBuf resb 11 section .text ; ; Case tables for extended characters; this is technically code page 865, ; but code page 437 users will probably not miss not being able to use the ; cent sign in kernel images too much :-) ; ; The table only covers the range 129 to 164; the rest we can deal with. ; section .data ucase_low equ 129 ucase_high equ 164 ucase_tab db 154, 144, 'A', 142, 'A', 143, 128, 'EEEIII' db 142, 143, 144, 146, 146, 'O', 153, 'OUUY', 153, 154 db 157, 156, 157, 158, 159, 'AIOU', 165 section .text ; ; getfssec_edx: Get multiple sectors from a file ; ; This routine makes sure the subtransfers do not cross a 64K boundary, ; and will correct the situation if it does, UNLESS *sectors* cross ; 64K boundaries. ; ; ES:BX -> Buffer ; EDX -> Current sector number ; CX -> Sector count (0FFFFh = until end of file) ; Must not exceed the ES segment ; Returns EDX=0, CF=1 on EOF (not necessarily error) ; All arguments are advanced to reflect data read. ; getfssec_edx: push ebp push eax .getfragment: xor ebp,ebp ; Fragment sector count push edx ; Starting sector pointer .getseccnt: inc bp dec cx jz .do_read xor eax,eax mov ax,es shl ax,4 add ax,bx ; Now AX = how far into 64K block we are not ax ; Bytes left in 64K block inc eax shr eax,SECTOR_SHIFT ; Sectors left in 64K block cmp bp,ax jnb .do_read ; Unless there is at least 1 more sector room... mov eax,edx ; Current sector inc edx ; Predict it's the linearly next sector call nextsector jc .do_read cmp edx,eax ; Did it match? jz .getseccnt .do_read: pop eax ; Starting sector pointer call getlinsecsr lea eax,[eax+ebp-1] ; This is the last sector actually read shl bp,9 add bx,bp ; Adjust buffer pointer call nextsector jc .eof mov edx,eax and cx,cx jnz .getfragment .done: pop eax pop ebp ret .eof: xor edx,edx stc jmp .done ; ; getfssec: Get multiple sectors from a file ; ; Same as above, except SI is a pointer to a open_file_t ; ; ES:BX -> Buffer ; DS:SI -> Pointer to open_file_t ; CX -> Sector count (0FFFFh = until end of file) ; Must not exceed the ES segment ; Returns CF=1 on EOF (not necessarily error) ; All arguments are advanced to reflect data read. ; getfssec: push edx movzx edx,cx cmp edx,[si+4] jbe .sizeok mov edx,[si+4] mov cx,dx .sizeok: sub [si+4],edx mov edx,[si] call getfssec_edx mov [si],edx pop edx ret ; ; nextcluster: Advance a cluster pointer in EDI to the next cluster ; pointed at in the FAT tables. CF=0 on return if end of file. ; nextcluster: jmp strict short nextcluster_fat28 ; This gets patched nextcluster_fat12: push eax push edx push bx push cx push si mov edx,edi shr edi,1 pushf ; Save the shifted-out LSB (=CF) add edx,edi mov eax,edx shr eax,9 call getfatsector mov bx,dx and bx,1FFh mov cl,[gs:si+bx] inc edx mov eax,edx shr eax,9 call getfatsector mov bx,dx and bx,1FFh mov ch,[gs:si+bx] popf jnc .even shr cx,4 .even: and cx,0FFFh movzx edi,cx cmp di,0FF0h pop si pop cx pop bx pop edx pop eax ret ; ; FAT16 decoding routine. ; nextcluster_fat16: push eax push si push bx mov eax,edi shr eax,SECTOR_SHIFT-1 call getfatsector mov bx,di add bx,bx and bx,1FEh movzx edi,word [gs:si+bx] cmp di,0FFF0h pop bx pop si pop eax ret ; ; FAT28 ("FAT32") decoding routine. ; nextcluster_fat28: push eax push si push bx mov eax,edi shr eax,SECTOR_SHIFT-2 call getfatsector mov bx,di add bx,bx add bx,bx and bx,1FCh mov edi,dword [gs:si+bx] and edi,0FFFFFFFh ; 28 bits only cmp edi,0FFFFFF0h pop bx pop si pop eax ret ; ; nextsector: Given a sector in EAX on input, return the next sector ; of the same filesystem object, which may be the root ; directory or a cluster chain. Returns EOF. ; ; Assumes CS == DS. ; nextsector: push edi push edx mov edx,[DataArea] mov edi,eax sub edi,edx jae .isdata ; Root directory inc eax cmp eax,edx cmc jmp .done .isdata: not edi test edi,[ClustMask] jz .endcluster ; It's not the final sector in a cluster inc eax jmp .done .endcluster: push gs ; nextcluster trashes gs push cx not edi mov cl,[ClustShift] shr edi,cl add edi,2 ; Now EDI contains the cluster number call nextcluster cmc jc .exit ; There isn't anything else... ; New cluster number now in EDI sub edi,2 shl edi,cl ; CF <- 0, unless something is very wrong lea eax,[edi+edx] .exit: pop cx pop gs .done: pop edx pop edi ret ; ; getfatsector: Check for a particular sector (in EAX) in the FAT cache, ; and return a pointer in GS:SI, loading it if needed. ; ; Assumes CS == DS. ; getfatsector: add eax,[FAT] ; FAT starting address jmp getcachesector ; ----------------------------------------------------------------------------- ; Common modules ; ----------------------------------------------------------------------------- %include "getc.inc" ; getc et al %include "conio.inc" ; Console I/O %include "plaincon.inc" ; writechr %include "writestr.inc" ; String output %include "configinit.inc" ; Initialize configuration %include "parseconfig.inc" ; High-level config file handling %include "parsecmd.inc" ; Low-level config file handling %include "bcopy32.inc" ; 32-bit bcopy %include "loadhigh.inc" ; Load a file into high memory %include "font.inc" ; VGA font stuff %include "graphics.inc" ; VGA graphics %include "highmem.inc" ; High memory sizing %include "strcpy.inc" ; strcpy() %include "cache.inc" ; Metadata disk cache %include "adv.inc" ; Auxillary Data Vector ; ----------------------------------------------------------------------------- ; Begin data section ; ----------------------------------------------------------------------------- section .data copyright_str db ' Copyright (C) 1994-', year, ' H. Peter Anvin' db CR, LF, 0 err_bootfailed db CR, LF, 'Boot failed: please change disks and press ' db 'a key to continue.', CR, LF, 0 syslinux_cfg1 db '/boot' ; /boot/syslinux/syslinux.cfg syslinux_cfg2 db '/syslinux' ; /syslinux/syslinux.cfg syslinux_cfg3 db '/' ; /syslinux.cfg config_name db 'syslinux.cfg', 0 ; syslinux.cfg ; ; Command line options we'd like to take a look at ; ; mem= and vga= are handled as normal 32-bit integer values initrd_cmd db 'initrd=' initrd_cmd_len equ 7 ; ; Config file keyword table ; %include "keywords.inc" ; ; Extensions to search for (in *forward* order). ; exten_table: db '.cbt' ; COMBOOT (specific) db '.bss' ; Boot Sector (add superblock) db '.bs', 0 ; Boot Sector db '.com' ; COMBOOT (same as DOS) db '.c32' ; COM32 exten_table_end: dd 0, 0 ; Need 8 null bytes here ; ; Misc initialized (data) variables ; %ifdef debug ; This code for debugging only debug_magic dw 0D00Dh ; Debug code sentinel %endif alignb 4, db 0 BufSafe dw trackbufsize/SECTOR_SIZE ; Clusters we can load into trackbuf BufSafeBytes dw trackbufsize ; = how many bytes? %ifndef DEPEND %if ( trackbufsize % SECTOR_SIZE ) != 0 %error trackbufsize must be a multiple of SECTOR_SIZE %endif %endif syslinux-legacy-3.63+dfsg/menu/0000775000175000017500000000000010777447273015160 5ustar evanevansyslinux-legacy-3.63+dfsg/menu/HISTORY0000664000175000017500000000131310777447273016242 0ustar evanevan GCC & 32-bit code ----------------- Due to the limitations of the COM file format, (64KB limit on memory footprint) the code has been changed so that the code compiles to a 32-bit COMBOOT program. Since the code makes use of BIOS calls, this code cannot be compiled into a format which can execute under Linux. As a side effect, there is no nice way to debug this code. In order to debug this code, you will have to run the code under syslinux. GCC & 16-bit code ----------------- The code was ported to GCC by Peter Anvin. OpenWatcom & 16-bit code ------------------------ Originally this code was written for the Openwatcom compiler and generated .COM files, which could execute under DOS as well as SYSLINUX. syslinux-legacy-3.63+dfsg/menu/test2.menu0000664000175000017500000000442110777447273017110 0ustar evanevan title=" COMBOOT Menu System " # location of help directory helpdir="/isolinux/help" pwdfile="/isolinux/password" # skip the menu if shift is pressed or Caps is on # if the menu is skipped run "skipcmd" # in our case we run the OS on the first harddisk skipcondn=shift-caps skipcmd="chain.c32 hd 0" # person with root privileges can exit menu # others just repeat exitcmd=".exit" onerrorcmd=".beep 2 % % .help hlp00025.txt % .exit" startfile="hlp00026.txt" timeoutcmd=".wait" totaltimeoutcmd="chain.c32 hd 0" [netmenu] title=" Init Network " item="one" info="Dont start network" type=radioitem data="network=no" item="hcp" info="Use DHCP" type=radioitem data="network=dhcp" [testing] title=" Testing " item="emory Test" info="Perform extensive memory testing" data="memtest" helpid=25 ipappend=3 item="nvisible" info="You dont see this" type=invisible item="xit menu" info="Go one level up" type=exitmenu [rescue] title=" Rescue Options " item="inux Rescue" info="Run linresc" data="linresc" item="os Rescue" info="dosresc" data="dosresc" item="indows Rescue" info="winresc" data="winresc" item="xit this menu" info="Go one level up" type=exitmenu [prep] title=" Prep options " item="aseurl by IP?" info="Specify gui baseurl by IP address" type=checkbox data="baseurl=http://192.168.0.1" item="ountcd?" info="Mount the cdrom drive?" type=checkbox data="mountcd" item="Network Initialization" info="How to initialise network device?" type=radiomenu data="netmenu" type=sep item="Reinstall indows" info="Re-install the windows side of a dual boot setup" type=checkbox data="repair=win" item="Reinstall inux" info="Re-install the linux side of a dual boot setup" type=checkbox data="repair=lin" type=sep item="un prep now" info="Execute prep with the above options" data="prep" argsmenu="prep" item="xit this menu" info="Go up one level" type=exitmenu [main] title=" Main Menu " type=login item="

repare" info="prep" data="prep" item="

","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("<1>","A",OPT_RUN,"A",0); add_item("<2>","A",OPT_RUN,"A",0); add_item("<3>","A",OPT_RUN,"A",0); add_item("<4>","A",OPT_RUN,"A",0); add_item("<5>","A",OPT_RUN,"A",0); add_item("<6>","A",OPT_RUN,"A",0); add_item("<7>","A",OPT_RUN,"A",0); add_item("<8>","A",OPT_RUN,"A",0); add_item("<9>","A",OPT_RUN,"A",0); MAIN = add_menu(" Main Menu ",8); curr = add_item(loginstr,"Login as a privileged user",OPT_RUN,NULL,0); set_item_options(-1,23); curr->handler = &login_handler; add_item("

repare","prep",OPT_RUN,"prep",0); set_item_options(-1,24); prepopt = add_item("

rep options...","Options for prep image: Requires authenticated user",OPT_INACTIVE,NULL,PREPMENU); set_item_options(-1,25); add_item("escue options...","Troubleshoot a system",OPT_SUBMENU,NULL,RESCUE); set_item_options(-1,26); add_item("esting...","Options to test hardware",OPT_SUBMENU,NULL,TESTING); set_item_options(-1,27); add_item("ong Menu...","test menu system",OPT_SUBMENU,NULL,LONGMENU); set_item_options(-1,28); secret = add_item("ecret Menu...","Secret menu",OPT_INVISIBLE,NULL,SECRETMENU); set_item_options(-1,29); add_item("xit to prompt", "Exit the menu system", OPT_EXITMENU, "exit", 0); set_item_options(-1,30); csprint("Press any key within 5 seconds to show menu...",0x07); if (!checkkeypress(100,50)) // Granularity of 100 milliseconds { csprint("Sorry! Time's up.\r\n",0x07); return 1; } else clearkbdbuf(); // Just in case user pressed something important curr = showmenus(MAIN); if (curr) { if (curr->action == OPT_RUN) { strcpy(cmd,curr->data); if (curr == runprep) { strcat(cmd,infoline); if (network->data == (void *)stat) // We want static { csprint("Enter IP address (last two octets only): ",0x07); strcpy(ip, "Junk"); editstring(ip, sizeof ip); strcat(cmd,"ipaddr=192.168."); strcat(cmd,ip); } } if (issyslinux()) runsyslinuxcmd(cmd); else csprint(cmd,0x07); return 1; // Should not happen when run from SYSLINUX } } // If user quits the menu system, control comes here // If you want to execute some specific command uncomment the next two lines // if (syslinux) runcommand(YOUR_COMMAND_HERE); // else csprint(YOUR_COMMAND_HERE,0x07); // Deallocate space used for these data structures close_passwords(); close_help(); close_menusystem(); // Return to prompt return 0; } syslinux-legacy-3.63+dfsg/menu/README0000664000175000017500000000755610777447273016055 0ustar evanevan Text User Interface using comboot --------------------------------- This is a menu system written by Murali Krishnan Ganapathy and ported from OpenWatcom to gcc by HPA. It is currently being maintained by the original author. To configure the menus, you need to set up a menu configuration file to have the menu items you desire, then build the menu system using make. You can use either simple.c or complex.c as a starting point for your own menu configuration file; If your menu system is only going to have entries corresponding to things which can be executed directly, then you can create a file in ".menu" format instead of the C code. See MENU_FORMAT for the syntax of .menu files The resulting code is a 32-bit COMBOOT code, and hence can be executed only under syslinux. You can use tools like bochs to help debug your code. Menu Features currently supported are: * menu items, * submenus, * disabled items, * checkboxes, * invisible items (useful for dynamic menus), and * Radio menus, * Context sensitive help * Authenticated users * Editing commands associated with items The keys used are: * Arrow Keys, PgUp, PgDn, Home, End Keys * Space to switch state of a checkbox * Enter to choose the item * Escape to exit from it * Shortcut keys Features -------- This is a general purpose menu system implemented using only BIOS calls, so it can be executed in a COMBOOT environment as well. It is highly customizable. Some features include: * Status line Display any help information associated with each menu item. * Window Specify a window within which the menu system draws all its menu's. It is upto the user to ensure that the menu's fit within the window. * Positioning submenus By default, each submenu is positioned just below the corresponding entry of the parent menu. However, the user may position each menu at a specific location of his choice. This is useful, when the menu's have lots of options. * Registering handlers for each menu item This is mainly used for checkboxes and radiomenu's, where a selection may result in disabling other menu items/checkboxes * Global Screen Handler This is called every time the menu is redrawn. The user can display additional information (usually outside the window where the menu is being displayed). See the complex.c for an example, where the global handler is used to display the choices made so far. * Global Keys Handler This is called every time the user presses a key which the menu system does not understand. This can be used to display context sensitive help. See complex.c for how to use this hook to implement a context sensitive help system as well as "On the fly" editing of commands associated with menus. * Shortcut Keys With each item one can register a shortcut key from [A-Za-z0-9]. Pressing a key within that range, will take you to the next item with that shortcut key (so you can have multiple items with the same shortcut key). The default shortcut key for each item, is the lower case version of the first char of the item in the range [A-Za-z0-9]. * Escape Keys Each item entry can have a substring enclosed in < and >. This part is highlighted. Can be used to highlight the shortcut keys. By default if an item has a <, then the first char inside < and > in the range [A-Za-z0-9] is converted to lower case and set as the shortcut key. * Ontimeout handler The user can register an ontimeout handler, which gets called if no key has been pressed for a user specific amount of time (default 5 min). For an example see the complex.c file. Credits ------- * The Watcom developers and Peter Anvin for figuring out an OS independent startup code. * Thomas for porting the crypt function and removing all C library dependencies * Peter Anvin for porting the code to GCC - Murali (gmurali+guicd@cs.uchicago.edu) syslinux-legacy-3.63+dfsg/menu/password0000664000175000017500000000076610777447273016756 0ustar evanevan# This file should be available as /isolinux/password # for complex.c to use. # # All lines starting with # and empty lines are ignored # # All non-comment lines here are of the form # USERNAME:PWDHASH:PERM1:PERM2:...: # # where USERNAME is maximum of 12 chars, # PWDHASH is maximum of 40 chars (DES ENCRYPTED) # PERM1,... are arbitrary strings # # The current lines correspond to # user1:secret1, user2:secret2, user3:secret3 user1:LcMRo3YZGtP0c:editcmd user2:FqewzyxP78a7A: user3:MKjmc.IHoXBNU:root syslinux-legacy-3.63+dfsg/menu/MANUAL0000664000175000017500000003322610777447273016066 0ustar evanevan Overview of writing code using the menu system ---------------------------------------------- This file contains implementation and developer documentation. For simple cases, you should start by using simple.c as a template. complex.c illustrates most of the features available in the menu system. Menu Features currently supported are: * menu items, * submenus, * disabled items, * checkboxes, * invisible items (useful for dynamic menus), and * Radio menus, * Context sensitive help * Authenticated users The keys used are: * Arrow Keys, PgUp, PgDn, Home, End Keys * Space to switch state of a checkbox * Enter to choose the item * Escape to exit from it * Shortcut keys 1. Overview ----------- The code usually consists of many stages. * Configuring the menusytem * Installing global handlers [optional] * Populating the menusystem * Executing the menusystem * Processing the result 1.1 Configuring the menusystem ------------------------------ This includes setting the window the menu system should use, the choice of colors, the title of the menu etc. In most functions calls, a value of -1 indicates that the default value be used. For details about what the arguments are look at function declarations in menu.h // Choose the default title and setup default values for all attributes.... init_menusystem(NULL); set_window_size(1,1,23,78); // Leave one row/col border all around // Choose the default values for all attributes and char's // -1 means choose defaults (Actually the next 4 lines are not needed) set_normal_attr (-1,-1,-1,-1); set_status_info (-1,-1); set_title_info (-1,-1); set_misc_info(-1,-1,-1,-1); 1.2 Populating the menusystem ----------------------------- This involves adding a menu to the system, and the options which should appear in the menu. An example is given below. MAINMENU = add_menu(" Menu Title ",-1); CHECKED = 1; add_item("option1","Status 1",OPT_RUN,"kernel1 arg1=val1",0); add_item("selfloop","Status 2",OPT_SUBMENU,NULL,MAINMENU); add_item("othermenu","Status 3",OPT_SUBMENU,"menuname",0); add_sep(); add_item("checkbox,"Checkbox Info",OPT_CHECKBOX,NULL,CHECKED); add_item("Exit ","Status String",OPT_EXITMENU,NULL,0); The call to add_menu has two arguments, the first being the title of the menu and the second an upper bound on the number of items in the menu. Putting a -1, will use the default (see MENUSIZE in menu.h). If you try to add more items than specified, the extra items will not appear in the menu. The accuracy of this number affects the memory required to run the system. If you do not want to keep track of the return values, you can also use the following variant of add_menu add_named_menu("main"," Menu Title ",-1) This creates a new menu as before and gives it a name "main". When using named menus, you get an alternate way for adding submenu's. See below for details. The call to add_item has five arguments. The first argument is the text which appears in the menu itself. The second argument is the text displayed in the status line. The third argument indicates the type of this menuitem. It is one of the following * OPT_RUN : executable content * OPT_EXITMENU : exits menu to parent * OPT_SUBMENU : if selected, displays a submenu * OPT_CHECKBOX : associates a boolean with this item which can be toggled * OPT_RADIOMENU: associates this with a radio menu. After execution, the data field of this item will point to the option selected. * OPT_SEP : A menu seperator (visually divide menu into parts) * OPT_RADIOITEM: this item is one of the options in a RADIOMENU * OPT_INACTIVE : A disabled item (user cannot select this) * OPT_INVISIBLE: This item will not be displayed. The fourth argument is the value of the data field always a string. Usually this string is just copied and nothing is done with it. Two cases, where it is used. In case of a radiomenu the input string is ignored and the "data" field points to the menuitem chosen (Dont forget to typecast this pointer to (t_menuitem *) when reading this info). In case of a submenu, this string if non-trivial is interpreted as the name of the submenu which should be linked there. This interpretation happens when the menu is first run and not when the menu system is being created. This allows the user to create the menusystem in an arbitrary order. The fifth argument is a number whose meaning depends on the type of the item. For a CHECKBOX it should be 0/1 setting the initial state of the checkbox. For a SUBMENU it should be the index of the menu which should be displayed if this option is chosen. Incase the data field is non-trivial, this number is ignored and computed later. For a RADIOMENU it should be the index of the menu which contains all the options (All items in that menu not of type RADIOITEM are ignored). For all other types, this argument has no meaning at all. A call to add_sep is a convenient shorthand for calling add_item with the type set to OPT_SEP. 1.3 Executing the menusystem ---------------------------- This is the simplest of all. Just call showmenus, with the index of the main menu as its argument. It returns a pointer to the menu item which was selected by the user. choice = showmenus(MAIN); // Initial menu is the one with index MAIN // or choice = showmenus(find_menu_num("main")); // Initial menu is the one named "main" 1.4 Processing the result ------------------------- This pointer will either be NULL (user hit Escape) or always point to a menuitem which can be "executed", i.e. it will be of type OPT_RUN. Usually at this point, all we need to do is to ask syslinux to run the command associated with this menuitem. The following code executes the command stored in choice->data (there is no other use for the data field, except for radiomenu's) if (choice) { if (choice->action == OPT_RUN) { if (syslinux) runcommand(choice->data); else csprint(choice->data,0x07); return 1; } csprint("Error in programming!",0x07); } 2. Advanced features -------------------- Everycall to add_item actually returns a pointer to the menuitem created. This can be useful when using any of the advanced features. 2.1 extra_data -------------- For example, every menuitem has an "extra_data" field (a pointer) which the user can use to point any data he/she pleases. The menusystem itself does not use this field in anyway. 2.2 helpid ---------- Every item also has a field called "helpid". It is meant to hold some kind of identifier which can be referenced and used to generate a context sensitive help system. This can be set after a call to add_item as follows add_item("selfloop","Status 2",OPT_SUBMENU,NULL,MAINMENU); set_item_options('A',4516); The first is the shortcut key for this entry. You can put -1 to ensure that the shortcut key is not reset. The second is some unsigned integer. If this value is 0xFFFF, then the helpid is not changed. 2.3 Installing global handlers ------------------------------ It is possible to register handlers for the menu system. These are user functions which are called by the menusystem in certain situations. Usually the handlers get a pointer to the menusystem datastructure as well as a pointer to the current item selected. Some handlers may get additional information. Some handlers are required to return values while others are not required to do so. Currently the menusystem support three types of global handlers * timeout handler * screen handler * keys handler 2.3.1 timeout handler --------------------- This is installed using a call to "reg_ontimeout(fn,numsteps,stepsize)" function. fn is a pointer to a function which takes no arguments and returns one of CODE_WAIT, CODE_ENTER, CODE_ESCAPE. This function is called when numsteps*stepsize Centiseconds have gone by without any user input. If the function returns CODE_WAIT then the menusystem waits for user input (for another numsteps*stepsize Centiseconds). If CODE_ENTER or CODE_ESCAPE is returned, then the system pretends that the user hit ENTER or ESCAPE on the keyboard and acts accordingly. 2.3.2 Screen handler -------------------- This is installed using a call to "reg_handler(HDLR_SCREEN,fn)". fn is a pointer to a function which takes a pointer to the menusystem datastructure and the current item selected and returns nothing. This is called everytime a menu is drawn (i.e. everytime user changes the current selection). This is meant for displaying any additional information which reflects the current state of the system. 2.3.3 Keys handler ------------------ This is installed using a call to "reg_handler(HDLR_KEYS,fn)". fn is a pointer to a function which takes a pointer to the menusystem datastructure, the current item and the scan code of a key and returns nothing. This function is called when the user presses a key which the menusystem does not know to dealwith. In any case, when this call returns the screen should not have changed in any way. Usually, one can change the active page and display any output needed and reset the active page when you return from this call. complex.c implements a key_handler, which implements a simple context sensitive help system, by displaying the contents of a file whose name is based on the helpid of the active item. Also, complex.c's handler allows certain users to make changes to edit the commands associated with a menu item. 2.4 Installing item level handlers ---------------------------------- In addition to global handlers, one can also install handlers for each individual item. A handler for an individual item is a function which takes a pointer to the menusystem datastructure and a pointer to the current item and return a structure of type t_handler_return. Currently it has two bit fields "valid" and "refresh". This handler is called when the user hits "enter" on a RUN item, or changes the status of a CHECKBOX, or called *after* a radio menu choice has been set. In all other cases, installing a handler has no effect. The handler can change any of the internal datastructures it pleases. For e.g. in a radiomenu handler, one can change the text displayed on the menuitem depending on which choice was selected (see complex.c for an example). The return values are ignored for RADIOMENU's. In case of RUN items: the return values are used as follows. If the return value of "valid" was false, then this user choice is ignored. This is useful if the handler has useful side effects. For e.g. complex.c has a Login item, whose handler always return INVALID. It sets a global variable to the name of the user logged in, and enables some menu items, and makes some invisible items visible. * If the handler does not change the visibility status of any items, the handler should set "refresh" to 0. * If the handler changes the visibility status of items in the current menu set "refresh" to 1. * If you are changing the visibility status of items in menu's currently not displayed, then you can set "refresh" to 0. * Changing the visibility status of items in another menu which is currently displayed, is not supported. If you do it, the screen contents may not reflect the change until you get to the menu which was changed. When you do get to that menu, you may notice pieces of the old menu still on the screen. In case of CHECKBOXES: the return value of "valid" is ignored. Because, the handler can change the value of checkbox if the user selected value is not appropriate. only the value of "refresh" is honored. In this case all the caveats in the previous paragraph apply. menu.h defines two instances of t_handler_return ACTION_VALID and ACTION_INVALID for common use. These set the valid flag to 1 and 0 respectively and the refresh flag to 0. 3. Things to look out for ------------------------- When you define the menu system, always declare it in the opposite order, i.e. all lower level menu's should be defined before the higher level menus. This is because in order to define the MAINMENU, you need to know the index assigned to all its submenus. 4. Additional Modules --------------------- You can make use of the following additional modules, in writing your handlers. * Passwords * Help 4.1 Passwords ------------- This module was written by Th. Gebhardt. This is basically a modification of the DES crypt function obtained by removing the dependence of the original crypt function on C libraries. The following functions are defined init_passwords(PWDFILE) // Read in the password database from the file authenticate_user(user,pwd) // Checks if user,pwd is valid isallowed(user,perm) // Checks if the user has a specified permission close_passwords() // Unloads password database from memory See the sample password file for more details about the file format and the implementation of permissions. See complex.c for a example of how to use this. 4.2 Help -------- This can be used to set up a context sensitive help system. The following functions are defined init_help(HELPBASEDIR) // Initialises the help system. All help files will be loaded // from the directory specified. runhelpsystem(context) // Displays the contents of HELPBASEDIR/hlp.txt In order to have a functioning help system, you just need to create the hlp.txt files and initialize the help system by specifying the base directory. The first line of this file assumed to be the title of the help screen. You can use ^N and ^O to change attributes absolutely and relatively, i.e. [^O]46 (i.e. Ctrl-O followed by chars 4 and 6) will set the attribute to 46, while [^N]08 will XOR the current attribute with specified number, thus in this case the first [^N]08 will turn on highlighting and the second one will turn it off. syslinux-legacy-3.63+dfsg/menu/simple.c0000664000175000017500000000564310777447273016625 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef NULL #define NULL ((void *) 0) #endif #include "menu.h" #include "com32io.h" #include int main(void) { t_menuitem * curr; // Change the video mode here // setvideomode(0) // Choose the default title and setup default values for all attributes.... init_menusystem(NULL); set_window_size(1,1,23,78); // Leave one row/col border all around // Choose the default values for all attributes and char's // -1 means choose defaults (Actually the next 4 lines are not needed) //set_normal_attr (-1,-1,-1,-1); //set_status_info (-1,-1); //set_title_info (-1,-1); //set_misc_info(-1,-1,-1,-1); // menuindex = add_named_menu("name"," Menu Title ",-1); // add_item("Item string","Status String",TYPE,"any string",NUM) // TYPE = OPT_RUN | OPT_EXITMENU | OPT_SUBMENU | OPT_CHECKBOX | OPT_INACTIVE // "any string" useful for storing kernel names // In case of OPT_SUBMENU, "any string" can be set to "name" of menu to be linked // in which case value NUM is ignored // NUM = index of submenu if OPT_SUBMENU, // 0/1 default checked state if OPT_CHECKBOX // unused otherwise. add_named_menu("testing"," Testing ",-1); add_item("Self Loop","Go to testing",OPT_SUBMENU,"testing",0); add_item("Memory Test","Perform extensive memory testing",OPT_RUN, "memtest",0); add_item("Exit this menu","Go one level up",OPT_EXITMENU,"exit",0); add_named_menu("rescue"," Rescue Options ",-1); add_item("Linux Rescue","linresc",OPT_RUN,"linresc",0); add_item("Dos Rescue","dosresc",OPT_RUN,"dosresc",0); add_item("Windows Rescue","winresc",OPT_RUN,"winresc",0); add_item("Exit this menu","Go one level up",OPT_EXITMENU,"exit",0); add_named_menu("main"," Main Menu ",-1); add_item("Prepare","prep",OPT_RUN,"prep",0); add_item("Rescue options...","Troubleshoot a system",OPT_SUBMENU,"rescue",0); add_item("Testing...","Options to test hardware",OPT_SUBMENU,"testing",0); add_item("Exit to prompt", "Exit the menu system", OPT_EXITMENU, "exit", 0); curr = showmenus(find_menu_num("main")); // Initial menu is the one called "main" if (curr) { if (curr->action == OPT_RUN) { if (issyslinux()) runsyslinuxcmd(curr->data); else csprint(curr->data,0x07); return 1; } csprint("Error in programming!",0x07); } return 0; } syslinux-legacy-3.63+dfsg/menu/test.menu0000664000175000017500000000150010777447273017021 0ustar evanevan# choose default title title = "A test of the test.menu file" top = 1 left = 1 bot = 23 right = 78 [testing] title = " Testing " item="Self Loop" info="Go to Testing" type=submenu data=testing item="Memory Test" info="Perform extensive memory testing" data="memtest" item="Exit this menu" info="Go one level up" type=exitmenu [rescue] title = " Rescue Options " row = 10 col = 10 item="Linux Rescue" data="linresc" item="Dos Rescue" data="dosresc" item="Windows Rescue" data="winresc" item="Exit this menu" info="Go one level up" type=exitmenu [main] title = " Main Menu " item="Prepare" data="prep" item="Rescue options..." info="Troubleshoot a system" type=submenu data="rescue" item="Testing..." info="Options to test hardware" type=submenu data="testing" item="Exit this menu" info="Go one level up" type=exitmenu syslinux-legacy-3.63+dfsg/menu/MENU_FORMAT0000664000175000017500000002431610777447273016725 0ustar evanevanA .menu file can be used to describe basic menu structures which can be converted into C code which can then be compiled into a .c32 file for use with SYSLINUX. The format of a .menu file is similar to an ini file, but with important differences. Lines starting with # and ; are treated as comments. Blank lines are used to separate the attributes of one menu item from another. Multiple blank lines are equivalent to a single one. In other contexts Blank lines are not significant. Menus ----- Each menu declaration starts with a line containing the name of menu in [ ]. This is the "nickname" of the menu and should be different for different menus. This is not visible to the user of the menu system. The initial menu must be called "main" The menu declaration is followed by lines which set the attributes of the menu. This is followed by a blank line and followed by declaration of menu items in that menu. All lines which occur before the first menu declaration is considered as a global declaration. Abstract Format --------------- The overall format should look like this -------------------------------------------------------- [menuname1]

... [menuname2] ---------------------------------------------------------- GLOBAL SETTINGS --------------- The following global settings are now supported. Many of the keywords accept what we call a "DOT COMMAND" as argument. Simply put they are instructions to the menu system to perform certain actions. The syntax and semantics of DOT COMMANDS are given later in the section titled "DOT COMMANDS". videomode: (default 0xFF) [Use with care] The textmode in which the whole menu system should operate. Must be a number (use 0x notation for hexadecimal). Lookup Ralph Brown Interrupt List and search for Video Mode to find a number to put here. setting to 0xFF will mean, menu system will use the current video mode. title: The title of the whole menu system top, left, bot, right: (default 0,0,21,79) The area of the screen used by the menu system. The remaining part of the screen can be used by the user for anything. helpdir: (default /isolinux/help) Location of the directory where help information is stored. The help files must be called "hlpNNNNN.txt" where NNNNN is the helpid. pwdfile: (default /isolinux/passwd) The name of the password file which contains user, password and permissions See "passwd" file for details regarding format of this file editrow: (default 23) the row on the screen where one can edit the command line. This must be outside the menu area. Set this to a negative number to disable editing the command line. In case of authenticated users, the current user must have "editcmd" permissions to edit the command line pwdrow: (default 23) The row on the screen used for user authentication. Must be outside menu area (can be same as editrow). Set to negative to disable user authentication skipif: (default 0) The OR of the bits in the Shift-flags any of which can cause the menu system to be skipped all together (0 means menu system always runs). It can also be a combination of "Alt","Ctrl","Shift","Caps","Ins","Scroll". When menu system starts it checks if any of the specified keys are On/pressed. If true, the system exits immediately and executes the skipcmd. e.g. setting it to "shift-alt-caps" means menu will be skipped if alt OR shift is pressed OR caps is on. setting to "0" means menu will always run. skipcmd: (default .exit) valid terminal commands: .exit .ignore or any syslinux command command to execute if menu system is skipped. This must be a non-trivial syslinux command if skipcondn is not "0". ".exit" means menu system quits back to the boot prompt. startfile: (default "") if non-empty the system will display the contents of this file before launching the menusystem. This happens only if the menusystem is not skipped. Can be used to display licensing, usage or welcome messages. A file with given name is expected to be found in the helpdir directory. exitcmd: (default .exit) valid terminal commands: .exit .repeat or any syslinux command The default command to execute when user quits the menu system. exitcmdroot: (default =exitcmd) Same as exitcmd except applies when current user has "root" privileges. If not specified, it is assumed to be the same as exitcmd timeout: (default 3000) The amount of time (in multiple of 0.1 seconds) to wait for user keypress. If no key pressed for specified duration then the timeoutcmd is executed. totaltimeout: (default 0) The total amount of time (in multiples of 0.1 seconds) the system will wait for user to make a decision. If no decision has been made in the specified duration totaltimeoutcmd will be executed NOTE: This does not include the time spent browsing the help system or the time taken for the user to enter his/her authentication credentials. timeoutcmd: (default .beep) valid terminal commands: .wait .enter .escape or any syslinux command command to execute when we timeout waiting for user input. The commands .enter and .escape tell the menu system to pretend the user typed ENTER or ESCAPE on the keyboard, while .wait tells the menusystem to wait for one more time period totaltimeoutcmd: (default .wait) choices are the same as for timeoutcmd MENU SETTINGS ------------- title: (must be specified) Title of this menu row,col: [Usage not recomended] position in screen where this menu should be placed. By default the system will choose an appropriate location. ITEM ATTRIBUTES --------------- item: The string displayed to the user. Characters enclosed in < > are highlighted. shortcut: (default -1) valid values A-Za-z0-9 or -1 [Usage not recommended] Sets the shortcut key for this item. If set to -1, the system scans for the first highlighted letter in the given range and sets that as the shortcut key. info: (default same as data) Additional textual information displayed in the status bar type: the type of entry this item represents. This is one of the following: run: choosing this will run something in SYSLINUX use data to specify the actual command to execute exitmenu: exit to parent menu submenu: choosing will open up submenu use data to specify the "nickname" of the menu which should come here sep: Position a separator here inactive: menu item is disabled checkbox: this is a checkbox use state to set initial state invisible: User does not see this item radioitem: One choice in a radiomenu radiomenu: Allow user to choose one of many choices (initial choice is always NULL) login: Selecting this will allow user to login to system data: for run items, the syslinux command to execute for submenus and radiomenus, nickname of menu for checkboxes, string to be added to kernel command line (if set) for radioitems, string to be added to kernel command line (if chosen) ipappend: ipappend flag to pass to PXELINUX (harmless for other variants of SYSLINUX) See syslinux documentation for meaning of the FLAGS helpid: (default 65535 which is not a valid id) associates a context for the help system. state: (default 0) Initial state of a checkbox (for other items this has no meaning) perms: (default "") string containing the name of the permission which user must have to activate this item. For eg. if this item is a submenu then user needs the permission in order to open the submenu argsmenu: (default "") Name of the menu to be scanned for setting additional arguments to pass to command line when this item is chosen for execution. Submenus of specified menu are also scanned. Only checkboxes and radiomenu's are scanned. Items of other type in this menu is silently ignored. DOT COMMANDS ------------ Dot commands are basically instructions to the menu system to do certain things. A "single command" is one of the following [NT] A syslinux command (any DOT command not starting with a "." is assumed to be this) [NT] .beep [n] [NT] .help [NT] .nop [T] .exit or .quit (equivalent) [T] .repeat or .wait or .ignore (all three are equivalent) A dot command is a sequence of "single commands" separated by a "%". When a dot command is executed the system executes all the given "single commands" in the specified order. All the commands marked "[T]" are terminal commands, i.e. when the system encounters such a command it stops processing the dot command and returns the terminal command which caused the termination to the caller (who usually interprets the command appropriately). All commands marked with [NT] are non-terminal commands, i.e. once these commands are processed the system continues to process the remaining "single commands" specified in the "DOT COMMAND". Note: The case of a syslinux command is tricky. When executed, the command should never return (if the specified kernel exists) so the fact that we consider it a [NT] should be taken with a pinch of salt. However, if the syslinux command does return (in case of no kernel), then remaining "single commands" are processed. In particular "ker1 arg1 % ker2 arg2 % ker3 args" has the effect of executing the first kernel which exists .nop: Does nothing. .beep: .beep [n] produces a beep n times. n must be between 0 and 9. If not specified n=1. (hence .beep 0 is equivalent to .nop) .help: .help Displays the help file which is assumed to be in the "help" directory. Its name does not have to be in the form "hlpNNNNN.txt" (as required by the context sensitive help). Executing this command will mean the appropriate help screen is displayed till the user hits ESCAPE The meaning of the Terminal commands can vary with the context in which it is used. For example, a ".enter" or ".escape" does not have any meaning in the "onerrorcmd" context but it has a meaning in the "ontimeout" context. In case the user gives a Terminal command which does not make sense, it is upto the code (in this case adv_menu.tpl) to do what it pleases. syslinux-legacy-3.63+dfsg/menu/display.c0000664000175000017500000000200510777447273016766 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2006 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef NULL #define NULL ((void *) 0) #endif #include "help.h" #include "com32io.h" #include "menu.h" #include "tui.h" #include #include #include int main(int argc, char *argv[]) { if (argc < 2) { csprint("Usage: display.c32 \n",0x07); exit(1); } init_help(NULL); // No base dir, so all filenames must be absolute runhelp(argv[1]); close_help(); return 0; } syslinux-legacy-3.63+dfsg/version.pl0000775000175000017500000000110510777447273016236 0ustar evanevan#!/usr/bin/perl # # Read the "version" file and produce some macro declarations # use Fcntl; ($vfile, $vout, $def) = @ARGV; sysopen(VERSION, $vfile, O_RDONLY) or die "$0: Cannot open $vfile\n"; $version = ; chomp $version; close(VERSION); unless ( $version =~ /^([0-9]+)\.([0-9]+)$/ ) { die "$0: Cannot parse version format\n"; } $vma = $1+0; $vmi = $2+0; sysopen(VI, $vout, O_WRONLY|O_CREAT|O_TRUNC) or die "$0: Cannot create $vout: $!\n"; print VI "$def VERSION \"$version\"\n"; print VI "$def VER_MAJOR $vma\n"; print VI "$def VER_MINOR $vmi\n"; close(VI); syslinux-legacy-3.63+dfsg/strcpy.inc0000664000175000017500000000034010777447273016230 0ustar evanevan; ; strcpy: Copy DS:SI -> ES:DI up to and including a null byte; ; on exit SI and DI point to the byte *after* the null byte ; section .text strcpy: push ax .loop: lodsb stosb and al,al jnz .loop pop ax ret syslinux-legacy-3.63+dfsg/writestr.inc0000664000175000017500000000213710777447273016575 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; writestr.inc ;; ;; Code to write a simple string. ;; section .text ; ; crlf: Print a newline ; crlf: push ax mov al,CR call writechr mov al,LF call writechr pop ax ret ; ; cwritestr: write a null-terminated string to the console, saving ; registers on entry. ; ; Note: writestr and cwritestr are distinct in SYSLINUX (only) ; cwritestr: pushfd pushad .top: lodsb and al,al jz .end call writechr jmp short .top .end: popad popfd ret syslinux-legacy-3.63+dfsg/mbr/0000775000175000017500000000000010777447343014772 5ustar evanevansyslinux-legacy-3.63+dfsg/mbr/checksize.pl0000775000175000017500000000153710777447273017312 0ustar evanevan## ----------------------------------------------------------------------- ## ## Copyright 2007-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- ## ## checksize.pl ## ## Check the size of a binary file ## ($file, $maxsize) = @ARGV; @st = stat($file); if (!defined($size = $st[7])) { die "$0: $file: $!\n"; } if ($size > $maxsize) { print STDERR "$file: too big ($size > $maxsize)\n"; exit 1; } else { exit 0; } syslinux-legacy-3.63+dfsg/mbr/mbr.bin0000775000175000017500000000062410777447304016246 0ustar evanevan1؎м|WR RAU10rUu s fBZ?Q@RPf1ff!Missing operating system. f`f1һ|fRfPSjjf6{Œ6{A{fa} f`廾1SQt@ރHt[y9Y[G<t$<u"fGfVff!ufrfFfabMultiple active partitions. fDfFfD0r>}U{Z_Operating system load error. ^>b< usyslinux-legacy-3.63+dfsg/mbr/Makefile0000664000175000017500000000251010777447273016432 0ustar evanevan## ----------------------------------------------------------------------- ## ## Copyright 2007-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- # # Makefile for MBR # TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \ then echo $(1); else echo $(2); fi; rm -f $$tmpf) M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,) $(call gcc_ok,-fno-stack-protector) CC = gcc LD = ld -m elf_i386 SFLAGS = $(M32) -march=i386 OBJCOPY = objcopy PERL = perl .SUFFIXES: .S .s .o .elf all: mbr.bin .PRECIOUS: %.o %.o: %.S $(CC) $(SFLAGS) -Wa,-a=$*.lst -c -o $@ $< mbr.elf: mbr.o mbr.ld $(LD) -T mbr.ld -e _start -o $@ $< mbr.bin: mbr.elf checksize.pl $(OBJCOPY) -O binary $< $@ $(PERL) checksize.pl mbr.bin 440 tidy: rm -f *.o *.elf *.lst clean: tidy spotless: clean rm -f *.bin syslinux-legacy-3.63+dfsg/mbr/mbr.S0000664000175000017500000001534510777447273015710 0ustar evanevan/* ----------------------------------------------------------------------- * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ .code16 .text .globl bootsec stack = 0x7c00 driveno = (stack-6) sectors = (stack-8) secpercyl = (stack-12) BIOS_page = 0x462 /* gas/ld has issues with doing this as absolute addresses... */ .section ".bootsec", "a", @nobits .globl bootsec bootsec: .space 512 .text .globl _start _start: cli xorw %ax, %ax movw %ax, %ds movw %ax, %ss movw $stack, %sp movw %sp, %si pushw %es /* es:di -> $PnP header */ pushw %di pushw %dx /* dl -> drive number */ movw %ax, %es sti cld /* Copy down to 0:0x600 */ movw $_start, %di movw $(512/2), %cx rep; movsw ljmpw $0, $next next: /* Check to see if we have EBIOS */ pushw %dx /* drive number */ movb $0x41, %ah /* %al == 0 already */ movw $0x55aa, %bx xorw %cx, %cx xorb %dh, %dh stc int $0x13 jc 1f cmpw $0xaa55, %bx jne 1f shrw %cx /* Bit 0 = fixed disk subset */ jnc 1f /* We have EBIOS; patch in the following code at read_sector_cbios: movb $0x42, %ah ; jmp read_common */ movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \ (read_sector_cbios) 1: popw %dx /* Get (C)HS geometry */ movb $0x08, %ah int $0x13 andw $0x3f, %cx /* Sector count */ pushw %cx /* Save sectors on the stack */ movzbw %dh, %ax /* dh = max head */ incw %ax /* From 0-based max to count */ mulw %cx /* Heads*sectors -> sectors per cylinder */ /* Save sectors/cylinder on the stack */ pushw %dx /* High word */ pushw %ax /* Low word */ xorl %eax, %eax /* Base */ cdq /* Root (%edx <- 0) */ call scan_partition_table /* If we get here, we have no OS */ missing_os: call error .ascii "Missing operating system.\r\n" /* * read_sector: read a single sector pointed to by %eax to 0x7c00. * CF is set on error. All registers saved. */ read_sector: pushal xorl %edx, %edx movw $bootsec, %bx pushl %edx /* MSW of LBA */ pushl %eax /* LSW of LBA */ pushw %es /* Buffer segment */ pushw %bx /* Buffer offset */ pushw $1 /* Sector count */ pushw $16 /* Size of packet */ movw %sp, %si /* This chunk is skipped if we have ebios */ /* Do not clobber %eax before this chunk! */ /* This also relies on %bx and %edx as set up above. */ read_sector_cbios: divl (secpercyl) shlb $6, %ah movb %ah, %cl movb %al, %ch xchgw %dx, %ax divb (sectors) movb %al, %dh orb %ah, %cl incw %cx /* Sectors are 1-based */ movw $0x0201, %ax read_common: movb (driveno), %dl int $0x13 addw $16, %sp /* Drop DAPA */ popal ret /* * read_partition_table: * Read a partition table (pointed to by %eax), and copy * the partition table into the ptab buffer. * * Clobbers %si, %di, and %cx, other registers preserved. * %cx = 0 on exit. * * On error, CF is set and ptab is overwritten with junk. */ ptab = _start+446 read_partition_table: call read_sector movw $bootsec+446, %si movw $ptab, %di movw $(16*4/2), %cx rep ; movsw ret /* * scan_partition_table: * Scan a partition table currently loaded in the partition table * area. Preserve all registers. * * On entry: * %eax - base (location of this partition table) * %edx - root (offset from MBR, or 0 for MBR) * * These get pushed into stack slots: * 28(%bp) - %eax - base * 20(%bp) - %edx - root */ scan_partition_table: pushal movw %sp, %bp /* Search for active partitions */ movw $ptab, %bx movw $4, %cx xorw %ax, %ax push %bx push %cx 5: testb $0x80, (%bx) jz 6f incw %ax movw %bx, %si 6: addw $16, %bx loopw 5b decw %ax /* Number of active partitions found */ jz boot jns too_many_active /* No active partitions found, look for extended partitions */ popw %cx /* %cx <- 4 */ popw %bx /* %bx <- ptab */ 7: movb 4(%bx), %al cmpb $0x0f, %al /* 0x0f = Win9x extended */ je 8f andb $~0x80, %al /* 0x85 = Linux extended */ cmpb $0x05, %al /* 0x05 = MS-DOS extended */ jne 9f /* It is an extended partition. Read the extended partition and try to scan it. If the scan returns, re-load the current partition table and resume scan. */ 8: movl 8(%bx), %eax /* Partition table offset */ movl 20(%bp), %edx /* "Root" */ addl %edx, %eax /* Compute location of new ptab */ andl %edx, %edx /* Is this the MBR? */ jnz 10f movl %eax, %edx /* Offset -> root if this was MBR */ 10: call read_partition_table jc 11f call scan_partition_table 11: /* This returned, so we need to reload the current partition table */ movl 28(%bp), %eax /* "Base" */ call read_partition_table /* fall through */ 9: /* Not an extended partition */ addw $16, %bx loopw 7b /* Nothing found, return */ popal ret too_many_active: call error .ascii "Multiple active partitions.\r\n" /* * boot: invoke the actual bootstrap. (%si) points to the partition * table entry, and 28(%bp) has the partition table base. */ boot: movl 8(%si), %eax addl 28(%bp), %eax movl %eax, 8(%si) /* Adjust in-memory partition table entry */ call read_sector jc disk_error cmpw $0xaa55, (bootsec+510) jne missing_os /* Not a valid boot sector */ movw $driveno, %sp /* driveno == bootsec-6 */ popw %dx /* dl -> drive number */ popw %di /* es:di -> $PnP vector */ popw %es cli jmpw *%sp /* %sp == bootsec */ disk_error: call error .ascii "Operating system load error.\r\n" /* * Print error messages. This is invoked with "call", with the * error message at the return address. */ error: popw %si 2: lodsb movb $0x0e, %ah movb (BIOS_page), %bh movb $0x07, %bl int $0x10 /* May destroy %bp */ cmpb $10, %al /* Newline? */ jne 2b int $0x18 /* Boot failure */ die: hlt jmp die syslinux-legacy-3.63+dfsg/mbr/mbr.ld0000664000175000017500000000353210777447273016100 0ustar evanevan/* * Linker script for MBR */ /* Script for -z combreloc: combine and sort reloc sections */ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) EXTERN(_start) ENTRY(_start) SECTIONS { /* Read-only sections, merged into text segment: */ . = 0x600; .text : { *(.text*) *(.rodata*) } =0x90909090 . = ALIGN(4); .data : { *(.data*) } . = ALIGN(128); .bss : { *(.bss*) } . = 0x7c00; .bootsec : { *(.bootsec) } /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions */ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2 */ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } /* DWARF 2 */ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions */ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } /DISCARD/ : { *(.note.GNU-stack) } } syslinux-legacy-3.63+dfsg/mbr/oldmbr.asm0000664000175000017500000001312210777447273016754 0ustar evanevan; ----------------------------------------------------------------------- ; ; Copyright 2003-2008 H. Peter Anvin - All Rights Reserved ; ; Permission is hereby granted, free of charge, to any person ; obtaining a copy of this software and associated documentation ; files (the "Software"), to deal in the Software without ; restriction, including without limitation the rights to use, ; copy, modify, merge, publish, distribute, sublicense, and/or ; sell copies of the Software, and to permit persons to whom ; the Software is furnished to do so, subject to the following ; conditions: ; ; The above copyright notice and this permission notice shall ; be included in all copies or substantial portions of the Software. ; ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ; OTHER DEALINGS IN THE SOFTWARE. ; ; ----------------------------------------------------------------------- ; ; mbr.asm ; ; Simple Master Boot Record, including support for EBIOS extensions. ; ; The MBR lives in front of the boot sector, and is responsible for ; loading the boot sector of the active partition. The EBIOS support ; is needed if the active partition starts beyond cylinder 1024. ; ; This MBR determines all geometry info at runtime. It uses only the ; linear block field in the partition table. It does, however, pass ; the partition table information unchanged to the target OS. ; ; This MBR should be "8086-clean", i.e. not require a 386. ; %include "bios.inc" ; ; Note: The MBR is actually loaded at 0:7C00h, but we quickly move it down to ; 0600h. ; section .text cpu 8086 org 0600h _start: cli xor ax,ax mov ds,ax mov es,ax mov ss,ax mov sp,7C00h sti cld mov si,sp ; Start address mov di,0600h ; Destination address mov cx,512/2 rep movsw ; ; Now, jump to the copy at 0600h so we can load the boot sector at 7C00h. ; Since some BIOSes seem to think 0000:7C00h and 07C0:0000h are the same ; thing, use a far jump to canonicalize the address. This also makes ; sure that it is a code speculation barrier. ; jmp 0:next ; Jump to copy at 0600h next: mov [DriveNo], dl ; Drive number stored in DL ; ; Check for CHS parameters. This doesn't work on floppy disks, ; but for an MBR we don't care. ; mov ah,08h ; Get drive parameters int 13h and cx,3Fh ; Max sector number mov [Sectors],cx xor ax,ax mov al,dh inc ax ; From 0-based to count mul cx ; Heads*Sectors mov [SecPerCyl],ax ; Note: we actually don't care about the number of ; cylinders, since that's the highest-order division ; ; Now look for one (and only one) active partition. ; mov si,PartitionTable xor ax,ax mov cx,4 checkpartloop: test byte [si],80h jz .notactive inc ax mov di,si .notactive: add si,byte 16 loop checkpartloop cmp ax,byte 1 ; Better be only one jnz not_one_partition ; ; Now we have the active partition partition information in DS:DI. ; Check to see if we support EBIOS. ; mov dl,[DriveNo] mov ax,4100h mov bx,055AAh xor cx,cx xor dh,dh stc int 13h jc no_ebios cmp bx,0AA55h jne no_ebios test cl,1 ; LBA device access jz no_ebios ; ; We have EBIOS. Load the boot sector using LBA. ; push di mov si,dapa mov bx,[di+8] ; Copy the block address mov [si+8],bx mov bx,[di+10] mov [si+10],bx mov dl,[DriveNo] mov ah,42h ; Extended Read jmp short common_tail ; ; No EBIOS. Load the boot sector using CHS. ; no_ebios: push di mov ax,[di+8] mov dx,[di+10] div word [SecPerCyl] ; AX = cylinder DX = sec in cyl ror ah,1 ror ah,1 mov cl,ah mov ch,al ; CL = cyl[9:8], CH = cyl[7:0] mov ax,dx div byte [Sectors] ; AL = head AH = sector mov dh,al inc ah or cl,ah ; CX = cylinder and sector mov dl,[DriveNo] mov bx,7C00h mov ax,0201h ; Read one sector common_tail: int 13h jc disk_error pop si ; DS:SI -> partition table entry ; ; Verify that we have a boot sector, jump ; cmp word [7C00h+510],0AA55h jne missing_os cli jmp 0:7C00h ; Jump to boot sector; far ; jump is speculation barrier ; (Probably not neecessary, but ; there is plenty of space.) not_one_partition: ja too_many_os missing_os: mov si,missing_os_msg jmp short die too_many_os: disk_error: mov si,bad_disk_msg die: .msgloop: lodsb and al,al jz .now mov ah,0Eh ; TTY output mov bh,[BIOS_page] ; Current page mov bl,07h int 10h jmp short .msgloop .now: jmp short .now align 4, db 0 ; Begin data area ; ; EBIOS disk address packet ; dapa: dw 16 ; Packet size .count: dw 1 ; Block count .off: dw 7C00h ; Offset of buffer .seg: dw 0 ; Segment of buffer .lba: dd 0 ; LBA (LSW) dd 0 ; LBA (MSW) ; CHS information SecPerCyl: dw 0 ; Heads*Sectors Sectors: dw 0 ; Error messages missing_os_msg db 'Missing operating system', 13, 10, 0 bad_disk_msg db 'Operating system loading error', 13, 10, 0 ; ; Maximum MBR size: 446 bytes; end-of-boot-sector signature also needed. ; Note that some operating systems (NT, DR-DOS) put additional stuff at ; the end of the MBR, so shorter is better. Location 440 is known to ; have a 4-byte attempt-at-unique-ID for some OSes. ; PartitionTable equ $$+446 ; Start of partition table ; ; BSS data; put at 800h ; DriveNo equ 0800h syslinux-legacy-3.63+dfsg/sample/0000775000175000017500000000000010777447344015474 5ustar evanevansyslinux-legacy-3.63+dfsg/sample/hello2.c0000664000175000017500000000273110777447273017031 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2002-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * hello2.c * * Simple COM32 image * * This version shows how to use the bounce buffer for data transfer * to the BIOS or COMBOOT system calls. */ #include #define NULL ((void *)0) static inline void memset(void *buf, int ch, unsigned int len) { asm volatile("cld; rep; stosb" : "+D" (buf), "+c" (len) : "a" (ch) : "memory"); } static void strcpy(char *dst, const char *src) { while ( *src ) *dst++ = *src++; *dst = '\0'; } static void writemsg(const char *msg) { com32sys_t inreg; memset(&inreg, 0, sizeof inreg); strcpy(__com32.cs_bounce, msg); inreg.eax.w[0] = 0x0002; /* Write string */ inreg.ebx.w[0] = OFFS(__com32.cs_bounce); inreg.es = SEG(__com32.cs_bounce); __com32.cs_intcall(0x22, &inreg, NULL); }; int __start(void) { writemsg("Hello, World!\r\n" "cmdline = "); writemsg(__com32.cs_cmdline); writemsg("\r\n"); return 0; } syslinux-legacy-3.63+dfsg/sample/hello2.c320000775000175000017500000000033110777447317017172 0ustar evanevanL!1  )t$ g;v^WS41|$, @CufD$, ƒfT$ fD$ PjD$Pj" D[_à  1 Hello, World! cmdline = syslinux-legacy-3.63+dfsg/sample/syslogo.ppm.gz0000664000175000017500000005745410777447273020350 0ustar evanevanDG=w62! 040{ yn[pF܄x>EQ*J:۷JUz?_?ƒa}bE,|E~:?k/ s߿s}HG/>˭NU:Ɵ zP}?+7Wgi;S[ۆ8*5Ӑ`nSyhc:I8M{l)tI(_kiƮ"qY+NO!{w2|o]wմL޹}$yO\lXvu8 Vv/T)pĸHa&>l+PG>1l{p\pXC Fcu!;(I ЭЪq}?ݵIF8V;LާH$Œ@R:P*ZaR\_ *ɼDp#3:v;5CLާW3|y_Tl Evq pGDylO ;6Q;]D^eJ^b ݞLjӭӁ/Tޔ']ث߻2y]SዺC ~iowa "\/mJux1~l2U_}.y# %j]%HGy>o_} y#/yyXl Ԟ^BY )WG6L_}yσ/v7:l(A@%H7__}y3{9GcԩD dCS;3|-×5mbзl\GȿrHZwGω`/ gq,O˃ -ddYȎ&4G Vz#_y[,_I_< _<H !F$tV>plyƦYw]c62|?ŀxߒQeYLf@^ 䝶|RVbڴ$МEl&0bȌîZ eWW5,jg-о :4ƗMJ *IFOk3|u%t9EZ3|♨O 탉J$βVv1D:f~FO#nhR3G~g /×##2WIR@65uUIՒVถ 1rhO`ĥHfZjewyedq[Rk$W4-T-QBLVaHWAT8~9|?%#)૑ xoȚ^hs iq,Ћ 088 3GGw3Ju6!ډ`-E_j29+ 7@7+(rLG!>?R>&v㬿 j&S}(pd$A) jl#ݑJ >¯審JBd"nO?חiTS%̃ ,@ԐGJ@*~#ua#$tزAA OVo@Ip E廉]_?r <.?=+T z,e/j㟨_c?l^$#iFxp {U&51_?q;}M"K[b䂦>e q`wc g>ټ+8 m3v^rbr<PoBƛ"o*(:%-_: J6{3YҘ _[7u;K$&}uqpJ>{+˗SxpXPû`kOa (m(aB|kƖ/Ag5(|WDoD*?2+s}<|S+7g@2ZB$"b!NjZa+K f?&TKd^ߑ褉f@nկٟ _ *($yCWyR sv!U,}YM*'26qh^(7ͺW(dY`H8J9Eng%/&oJ^Wz`Qg< :ʐLup%ayF}"2 Hi=Hǒ0jʭ"D[tT1E@ ZGFm+ {Aإ(|ndIOyLӦ Yx#/1$m5X&נ" ="4Fl?8fjÈ8tboc8E`x7o3kз-in#7?{٠ l? VEɛפoק%Ό"w1eFE/fs1|g*(;ZP('ƃ=Ac%(yIҜ{0䄒2g>&-fmӴL),ߕdܕ_U@?ԷŇ@ܿi-k"&mDۥ,J?}_/߿~ bf~T2̺T&.f|z.Dp ^k[8ԕUx$<ַ*'+^Y¤ZmhyN|w.yohVR;p{>o#cs^'nZAjZx[bf%""xMFLSθ^\:TXGj \Ub^M![ Ot NhOpSw/h'7"'vmZ0| v>]Z| ME:M[:ߔ3XbaX%T3!~Q.Q8g\ {@ۡ00Qj7T6W5lX=ԮtHq;L%ɛ ZG]^u&`"[ 6wSڽǼ6_ߡ[ͫ>mL3A_@XrTR#j[i:ȥ8N2v>X?7v`qy7wqZ")ͫZ'ov X0%KSS+_](ZT]@y}(hF}DO^yr}@EBQo{8-S T%ASPo LMzT=(o _yuhK ܛy>C*%88|g:2=gw*-RVA˗ʁƼ[q2(P=vPG Iچ:"1|'~ft: 2TyKc8|ᯪLot9/2XQ>} җ_i̒2<i{+}|Яz lAhcԘ0GZ߳_ʜ|?e[Q{*{u9 |[I𝁿*yI.mG-/9-G*ϲ@pwg|{·$Ls^V&m~.$"e pLo^> nB޽6oP/QQ*R0,}0n-sng[pTt|$;s|ieiݙ(H=B޳Yho oY/?op%_U-De +<,uwWsNWc;YK7ohɭek|l}GໜIϺnggb.1z^W~[ZX)5b-I.g"`-~|}C{3.G.xѲNߏ y%+>_VxiEFLSqn~XUiRw*|7A_@ZFn)_mG\+o_363wX.-WAgW@Vjʰ9o!|5Gv#k/,߿[bM3m,Tu^XB %|t:_I@9p= }O׈; e[jWLfԈ -q⯝+JmgnAZ_b-F;b_r`ê 4DF %(1EOGy@ ,{^o }Γ wFIXjIByX"8Tn7ᕿ⯊lޕ}znD^b{* y~!|eL bC\R@#IX!nN_>C}uy9~p +S*c*s } |m+VxJ.tF!ݺkzv›߆fߨJBKSuCJK]+[~<`:bg|"5_*V{#v* ؊*i0jsY4( ( ꆰh7UNA^,;'ooT+~fj فm/#<|?3>nNx[|O!T k=A(d uT.zᑝf|Eo֫vS's%󚔕K:·2Գ` rrO-<=F^+||%5`hmqqa@t;_SoD@o{?f;z## ;/&f*G=·d!+,rthehFC>#}/ocD@%fU\FfFQ7|cE8 fݯ7Ep]"j%-$2k2^7V̹0G)DoJ^|ZT Х6 }n_lA 72on) …nТLuYnK\0ZIZ@x~ Ww'ZNDO 㸽gw8nT݀8u'U6S7.fgWjQbV^RZih}jx=K]-mZT(_ ߖ3sl+-XYMlWxQȕ60"bN6tFjJyi-5SW%MR'漈oEHZ.=z&|U '%%B"?:_*&qhgP "-)UV7349CΚ 4;÷{F%&q/;H0 kW%m,X2tP"ŶnqG#=pBtKHȠ-6vVҹAw`.vިO߬+Oo%c"s$Ѽ1nf SfP\en% o/WW%ےwjCE׳6 fܷ;؆vK謖VYOi7[%KF^Ưb^4mSmB+ "9K8hiK{nllmI`I-,1OsV֢J 44ɍ q% sw)7kxҥ"6!x=f[?rDّ|1| X//*$%z(l`4*-m+»+~j3ɕC|w#ic1p{)"y:uIǾ+эX6;X}a%f0UuIZ0Jd%7kF>bFa,aDaUK͏,x/: PWg MxyA- >ԕF5߷~ms1Bzx]+Q, e,mჸjipI#^t} _[ub=r,%_W%*wQ$PQOs [JФJ{5:|Oz8Jh-EM׭3`W,å'`YzXhXYPa:y[t)C𦤆YU\2{7=j[GpE*R,Ȇł%Y#.\ ҽtkYI.!`D{я};%DCD382gT%3FDw[nL6ԟ *ְ DX%>#C=+<)/b6VVK7 zV-C3|7Ep]*MnD:(LX{pJVm{ ^%lmɺ^J{H }Z) ʕ Ԏq,e ABf+ ˄fK )yM ZȾ:nh.d@pۂ-gF. 6I0[ŐWx aTuHEƒw,IOr9V^T@5bnĀ 8TmX#ʐQSQЅﲟn(Kؔylφ$䒅SJ=m(`% 8VjXa6ccMޯb񝂀9 UzˡTm%B7l(E۲fEr[ɐV1V:`88 =(\!H޿ƨM/W.ڰ ] i%$3G &u  "V4_Lix*p 5Xo kz!t\o"qk5],L.]*u0[~R .["@6{ M2yer bV4fG ]rg.È"\tm"㺾\r. $PY$,s¡@v@lC m&*F$M[ONgt `*} 吡.3i͞40syAUd+$%b)i.~[5˿`If$-1xΖlTɐrnGs[2zA}˕1H$htj/26#8I͒t5ؾr7{,lUc8ߔX[wFOa65${eMr#+̥0ڿ-|Mػtn낁9LA؅>.qyCLga/?U"t/IKyzD:Q?A#XZ5w{|mQN+ jA/gzEpbVު- n 0I*-9W:IHLjԩHP.Vr`&?fBo5A;|1~X ÷P|n05 rUy[ªgt#$M`l hT{/ <Ҙ1_7PXA^]qzpIݽoe90AU;d V~[x]pڞic|^]'甿ܽmЯbY=<.Z:Tbټ,tلLd3ot2PjT#<ϖ.r lL:lg_oBN)YَP4wnɾEDIGF"3HUU#me wg|RJӱ) fa'!>F ѷU.S I Z,BW h@ 4a14BdWΒ:Ŭ w" w.gs,uJKFwb^i '7q( NEJNf!Ʉa`g.}<똅.LlW `\rw i m̈́K%6aݟ9\=o1fHn-*n֔]t"*찂3ޅaI|H oVݞ@3XB[UD tk6,3Q L +ħoIO-*Ml_SfO iEH2"[SaIl0(Ũr{e n#x36%5> <]!CR)~Gx0=FZ$ähnYC/7I (X\s3KpN|[y{Gzw,dNV1b+A-3Lτ:M5Xa|3ۛoBU[W?KMZdT|?mv h;otsKv3+I9$2V\BAl !<pO*jy a?)зspi`foZ?T[qftSBeRao>q5훰Wp'k[ū~γofYv!7mS<<U(-S6Q6H6Iҥý"CBTBET]kHLSLq$Xam½7juhZ+Uin|A|0'%VafUC  M,6R& *l `=붊Z-_א Rtׄ'=5B0ϹN_y%oGzX"lBa_{b}"1=AaS`11BlM-$bl 豠+(ACцREj4<·%2<{Y*U)t7B{/LI%G3ѻ] ʣ|۸\ +?"@ i+Z(\5~EtU΢/gVSU2vx LX 0wqŕ4ܚ/~F+]ga lp0)΁ I4 Jd IU v fE M|^@0m`*yI.նBSMuLB?+{k  q%̔"J J4ڑ]f {/ xJKח 3!@W%o=A:ZDg#ͥF"]Cw)62 z~p%$z42}QVbMЭw8YcׁU!Db9*V$|oqqKLzJdf\tA,ƤI>,{)񙧎9[_ֳwM*9P&-ֺ,,n炍F M*SuJy/̆p9rH*;.ڱaGMe5`h>6gpѫ6:@Oʶ==͢a g(m.s>r6Nj#9rk5ɛ$bwdᢢKm߬#W_WΡIГ}>eט%nMooN h8c.SGv s{qk)i1'^B2\R4%Wa:4OLWc*KX"z3,-¥ \ڀS:m)ZM[>d]A]>5?TSA(ahTC/L^|LBXCmu8{on;`{y##i Y[>`h乜tUZvg(u.,Np"L2?җ\sV]ruBY+8Nӏu.؊K+*d5עj4VE9o,eG6Ius,%Gu{ ,r7}v=-v@_"^A TJ*|BH l /=~,_ "F^JnUm&J٥Ĩ7Q87F[b9B(SF`DM""6w/|;LNhE^AWN6ihye 8noTMVJ(7 Or]J-n$ʂaֽ7T#*DU1T.N;Sl_K])+oJo_A)qGQ[F"s\أ\1DYK$h:8Б.5P@%2YE2W("+aeaMHe3cyٛk*KI\ٙyfwGBS5b1Ҋj]½kV Ytؘ[[([ re.nB+/_(v6W _Zk>?|^s>c7γx;gzHh?񌝶Na Tـ+i7{j 4A+u8eUlF^h[EV`D7~_ߋm@@w6.B> lҴB4!obk3D X nG7[/ |%E{|1ٟ4YN>N&\?:X#,qj c`WJRh1av|irUir_${Ưbcq|m"=g4i@Q4!`{Oݱ2'ٛ?$JJR^V .eAL6hX LA8? ͚ׄK@%c\dXnGlvud#g"b䗶7b0 ȍZXZoqf;$5Iη3y*Z ߰-&Sx9ǻ[obUBG&cz]va~ymչJηo/}[#s Ն8k0}ׄV q>=P]PVeiG^Q5>)\jhʂW$DI&*s^@>;39[Y)H6%ˢXtW>B·Hjz{)*f}f]rS8[%@I\ ȗJSgCXshB#QA:4&emؑDA+ VA[, NQL;[XIFX|Y{R'&bDŽ%juyEqpii ˆ .'hmEjk6\ 0_ xNZ}|U$H{0_9bNG&^FjS$JBE~Zz؝P5`܁ dTmQH/r=$8 ۻL $[ۥ-*Wz >nj_j%ëH ?-aQuc +HJ"CKseA+ra-3a@«F*aɒ_q+v,yl2>=m+ux)!Xo#?&~ dZT8)ZB[m謦6mׁ\7 ՔpKLh)c,-Ìh@cK6XOﱀ/[C< ,v7+Ai!NWjgC2D^wO䵦vR"Z2op&{*Q_Ԃ=[$sPʢ-8i˅Kiͺ-_|_Eɹ< UjRuG0T_]AB^Qv|5tê(-hV0L!E HSM4@ʖ-qD۽vdrͶ@r)o[$5D p]Wy l+? 6XLj=IWN1Qk`rSRx/%#A53g;W¤gpUX9f7Sx|]R/ yM"PQmucXRGyPhZ`}5jr4$Qy#+ܾC[@TthVNh;8.{kR\+r%&-LX|kBeMx U9m#Z]&uXFnh5Pc $U]R+ݳۄt4Y+=:nDMOݎ|"GdC8ZKjן/#,Cp!GTp3%XmMS$HRl0G Z[ ĩlXdd´d DN^w)҅ܭHR,SnI:fW@74+vQ1w3./e:Pi$Ҥ_CMP%.U3 NeFK %m6¿(eofנg{$* ;+UGpnǃ 1J— uFc'%cwuDu4 ѳY[*9h \ SR-!.E ΕF] wJUIS: M#GqEd~/ڦnmIent^ |~9Rd9RMaք:76W;ZLXp y4As'FthfgVt9wZX+jW7%򭚽Njy; ׃8 rrDH 󜁌MK̪\#WS)?CvB:Pc8K]=֥r,tKz&ʂ ||ni䫗[;ğEPҐ|“rAfj7>PXÅѴ16GL'U+FźA*ymKי,6}{ <ғzjXQ]RRi,#"gQnA2a!RD%i VQ[OiMvUp%)TJX fvV# W 9=c iQqַ+GD~bw|2?Ba{!%p& -D:~M.7g _4{_YY/:~_O/|f %Վla k*zV-,ߋ{.|z:KG@c lVL۫@d^ϷE0Sz j|=E#ɬ:/_+ؽ\n=(J~!Мd~;@M.n&)#C_`ż&}v T> <؀ȳ_qe5fo-`]٘o]#Ke>Ly kX| V!a$1~dر3y[m?9"ГbX>S}n!)x 0S4>eqެ"[ϻ]MTo:7bmޖoV3oI7HA/r|$ mNcScwA[)r,gxG~եݲ|S~jԍF˗E< K%YHJCC(9h+Bwt,(ߏcwwAʡGiw77Zq 眈lg߈ťKaLkĔ: ߾nDG&U͍[,O;{']1/C-#%8Um>Ftl)ec*z'Lkp\7~}Ýj55 :ojfYL`ygF0#‹wfW̫»hA0mD_;1|mw޽%EuFYqf;y4XjTO"8k7\l2Œ`WM#յ'Ҟ3ܽiWux; ǟX[X+#̭qS!uEh2-dse{.f k:Ӷ\BlΞ|SV\)pa9ۿ`$63!ҞMh]RϛFanKycjnskU"F(%Ae3uL`SRm{jnզܮK\qZbקKKxmlwlr#)<4}m Uaط͑D6zfsEXkk/e3gE)+ i|VݍfVin[(LFþn;mMU;4Ts'8\ucUQs[!L˘=ϩ8d#RG Fe 3XF_Qs*}Cgg3Ŝ.@oM`F0Sxn^I6abJEc𝭓oa6~thW1ּŔ/ټk,FRf3Œ`epMY%톯mOɶK:/άscB⾛%Vb3 ( 8 c_$i,_mvn7~Kyə8/ǯ|G5dfߨX@y>_77\hvsƯ\R''ykw--Z|#×us%U_5{-ߺsRjӖțI ;m):2y` l/u3Iߙr/ؾo v;9 y/|ӱJG`1·对X2)GZ̫#jWgwb6Cn;f6mfhŊΘc2`s!^C'5uwi'u?wW&z[2oծ"SPf ?Z (%}W᯻gh||߯9[m*{vlw%>xm tc3`s![:sG-uE^]mQ{h c:7&yKݰ.1毹n{*{N^aM8^N ަ2(j!޺V _{ne _w|SxoSw1WIv>~oۨg2oCiڿΫ=:uWY[۹踶&#_꧰5=$\%Y n&ވ~-*Iʜ 5}o#v;+XdF튳+ۇ4hgQ e1y bF~ &moAÃ# )|y*wEH5i?5[V2$żf2_k~Eۤ"`+v:n3vXjKI-}VFuCo&f 3;(|SW\gۿf{^K;/'IDo5]is =h|#ҹ۹t3e3|0:e qKo}-/zm8?@®'8:߁nn2g6]F0S{?g%wGJƛXaZy$wna{PdZSJ_b+{fզwy2Ei|)Aa&dq/p)s`'# 6#n^LV||K#Ua_$M-v!/,~0E RtnowAsq*8 O_76zOQ/DIxd?f {[G e RnK88&ח=jtߙ|F~լ 9'|{p {;Q-9m^/OF0SxBiA1hsoW)*Vm}zގq'P>}|O/Sx*7#lEH243! {x s"[\_ZƤfφvnj?ݞο/=^_rݤ@dr_C1 v'䂦.nφoeVր*#{涮Ցc,%\G7OF0Sx6iUV޹&m<<g_TJKԹ#w9!?.a#Bj$2Qu _<ہ` XL_{Cad?߃.hAke~'oM)XwUy_ _#Y:b3_143y|*e~9/o:) ɫkO/__<L q JlNk*2y+I BW8/×˓'#q _[| 6Ley_^Q6*KO _/O`c)| 7KDYu/_Z _<<"xYU/! $whŶf2|ydR0h w. uMb2|ydFbU rEˍ]mA,,hFk/_' _<bt7҈9]5_ ~tvjF0ed-QwaFy_&K,"Ѳ/ed3K.eA>`_F0 ed ?HJZbK|cb2ybL ;E.&=Pq0z!ZIpy-mSpI}z uk 8P=F,h~DC~)3Tw6A"a6Zhśnr뷙&zS6&:oCŋt^}!4Q:FD +Y26. h'0MÆo:dd6lnIvC$mr]3Й$[fzAJ]^{ u膷WF^ OR 29vM2 "ە-ZA lsI:#$j(Z!wȜEA(KI}*Ƒ-I "{(H#o+IfRqvuJ0Hsh%C[]o3yjQ\#HBH$M6LSW@ZCZ7s~T h-3wӄ|ӛD\veMMeHߢPcP.1mA@{Ls)aW:Ke2#x+'} ~"DK!ם€C7-um ۥ$р踸vHp˱PiDqma/Gt )X6)iɿ?A:oԍ6 :si'~{$ 8F"7F.d'PpVzht.1 )6StFt۱Dhp 41rghߠ$[a@筒- oaӢez Lldy0{m(FdXQzm38B.Sb`?)2Z9Li@H/k_OC荮%ʽ7 Dɬy&mdМ}K{aǢd6u\VjXLmi7BCHGq)$\ZLجұY-cjvװ`E4IIQ; PDLAD|]j^0C2_H GVRFfgP ƑpɰxWMhLM$ʚ$l/tl f[H2./ciNRbEJ4$G)pxҡi(Z+3Fs)h3 ؆K s5Lt|R)ےUʔ@e^ltY/C&Qt8OMԹq{i1ॽ2OEĀx^#PZ|F¬X;7I+8ZCnfѼydY]{rl;qC)z8"I#IX0vvU`gt*(sApY%͏) $M#Zi@w;OD S\St:B1s[he9i}@lZ#/fҤP0v,1I\}QAu ضy'4h2ދ%nED/knIMF+t oQn ]@jzW,p/ _p6ɟbLN5H]R.ctb2HzB0h-t@Q@$m! 69l=OCz Q'M$BIER=<-9:`d6 .M@ف>7F`R /=8EwY/`48u͉3̋n 6@ }"@wT}xb 2n=[Ma/e `:nM-`!Ó$&ȭLo(nH A\\t `f .-2l@1DHY6SiA0R$۪Ǯ uW:$7mDO0WivF.0A{c۪)ڶ߉L`;' efSEa6 }:0dt&(p} FP7W^Эӣ$oN +5bDSvc"qm>X3*)҉1q 2&"RvgiZ &qpsBܑCA`8R"'i-Zx`Is𥭷v0L*_%6S N`uF֏ʹCOJtfaCPc0nL]neY 6-WWI]dWdծ Zul $T: _K +˘_:x ntItW?63/$c͞I7%b9u_ y3 ^w:OfoK5 vT}"Jc͡&vMmF6GKm*0H12ĔzB(ܓSaEtsN9Q..l[pݬR H-SOUJ x[VV_Ӱ; }FˌpKt%2A6VMCN=>ʃe@DZsI{@-B{A&ґWr6W U.zU !$s<'=djε9&.]KqnLDй6SKH\z{  GPt$ =!+ES] q e Zϲ8;;(AJB70v7OhP{=MAͶ=R&#i:HdS[.?smA8Z C{CčL, H}P ܅̃M"/  ~X~@oqFH Cx"mS5x&}Lv)hwORأؖKo1d\!}1 bӬzO8&@_d3؞-7蹃I/F FrbmHm'DE%Z ]7tAL6@ $EL~i-ӵiЬ. &DLFL}(.0<@0l{kÔ$i6,LTDB[[anmЄ.:}"'22 F䝹plD͓7TW5gMńyHvS7/GC .H>6@{&a6f$z PҒ[`Gen%2 (#8S wN Ut$h@kbTeG^Dm 0\lPl*̝ZÂDo [p 'k+P!ecBEU̘m0tJȢ^-.\ldu[nF--IoQe{ßX[GK-s^Z[ӪZ=AŮh25,nVm2'Ou/'&~LqOey4[\oj3)Ո"wvC/~;U&x V`^cbXia&-\ ̦g W3:5):4.QO/2#ZHiv@ b. 0A$ ^Zmbmhkf4EvΜ>,mw;r6_k"ج[Km,tki$+O*0p{-f8^Иr<3WD {ᙁ;Y队t4ee!k \e::\- K& 869N]U' [:!L;sd>.b_n\nуZgU`^*ob@ \ݧ˔ K \O1XU5VztY}:- pV.d3 $Ii>&yGphø}LU2e:Yz"\Y*`IfY>vyR>R.h$MK.@6N;)ō<,52>+V%9UEX(܅Q;wWӺ/L;.y҉)5b۫`vZ3*t Tc:}fʶ.m 7<,Teh@b5nPN/eWQ6=եctiVg9f©P ߠBR8wٛ[%1 f`9&E]$qHx〮>$Uxm}Tb`b$:縔紗1k&.&ANUEwwRq- z$h&c Ϫ\JyQGdq'̤ FOAh {]txJFs #k$@腤胤 d춉b`&G $Om^#}K'Ht@3&A蛽2[-!$p; 7Z?$0;!H?:@m7BiQ$'lK$qAR` Tz {}c?vA$]/^A{OtM{"4;0`~؋3b.pA[׎zq6# [bPJد H=Z"Nm~S$2 HkDc];܂{rSȌXihuEIIUeixLl-r*V1g62ELmȿ(Ih6+J2#mZH4D!LH4ֱu4Ltc7C}61D+Z2L{*#@~@ ӡ7'}M&Eڬ2;xB4;*9 o >HtfD a\,% CabiХI]rdǨ.)]1)(- ;s !  9eV؏,j95cGF/Y#;Wm2yGգFf\۬ZxX=8^LO+R5 M0dNYji .խcb:vv\s2y^4c83j5ӦqVb Oox 5Jx]^̹-s^XtTql-ZLpqtU+ɞ~:UG L7lb)'p?+?f"!=& tHm!^HHVirB5Q~䉅Zp%JQȓZnkU֊nBi$1\PE,UJ?5 -vA6?TEP lL^DI)*{(K'k] ~%X$4I/ O Dit{ H2C@H7Sjݲ1򄋀cQ>C&YH(O3bE U1#''dOTR~ N5E쀛H7뉀 ?h!iܢ2}21S^>B1Z}wx3M6G@aNSn -oЭ{ Mcif _=Ft#-nni A߈Uo\%1$=цRݦ#c AՊK4uL۔b:Id\_Dp&6XvYAJck'S-neɲ!-bOTNE虅& Bp$)B5 duF-5<G@IR3])}-@s٦lH]g?`f=J$T1& 1AAAdLPbJViOOkc8Lm@wFH(&t *epCz.a^\d^%_N̍)αتOFN q"DLn _'<9SK\mV6`MJ[u>~9ƢG27e괨Hy^%4aK*NYz-$AeEQbw-3W  y CF?QҼ+0֙SXsz:⇏٧_^ X،m@N纮q$v*AQ:.;{5s9!iVLa:`8ۢΜi l%Z貊y>ϱ.3^c,"-+ؼpO^V=Y{UpK`b E~V7.#e~.r[&)t(hm{9sSxE꜂`)95'rD՟O^3qeG^o#uJl%3ĘW*!u3p7\\V9+zRu> TsHo59a7^;9cKNwd<7-M/qfx\h6^i-65$p7N˲@n ( Pg0d$-haqj{׺no+ɳH'ˎlFKwX/&m  M\$ z8󜒎l014ꙸ/a€#cף;\fc%f^4zBZd7f/Ōfh£~V)2GeN;@ߠI\-~E>09oŒ[eʵlRz+ysK;:ShߢylxKە);!D\ۅ!pwD wРYJt  ?1"zXUѮ>h7X]sqtʘ(2ԩWE;b60?줘,A6[3vCACm조 onmnɆ&u擵 (@GFw8˵I n3c3׫} otM%"mn љLWџm Dzce A%6Z4L4X -E *KSeʑvބ dm32w(VXgy ̒wUvԞIT,5Iom6Ka>߹KZ637Z'Dx3xPnq .Et3*FRoahPik}PxD䆲 X=A i8;VS5'.sgS\`  A7L ڔF6BC{Z"4&%lOAҋ+JzݥDMΈ#e{p{toh!Ny5e>\.Zs7 17q^¹'6Qfx*#_$o"}>/R6% ~a[.y0=o,H*+_'ѡ|j&{_%ڌm #S* 7\Y_t4v-u:$ԫmk@SjLNUbD jp )ajIBүo#bcjؤ?d6VAX6^k>lF+gjpް1LmI x\Cz@>2-kk<~C11XVϚoGէ!P|AHeDErH`MSn}*!<Mfˤ dW@Ef|HLʣtB7+zJl hV&dF, Zg@i$Zv"'8yf; ~ekϤ)Uo٦bOU}KLEz \ewFRBeJao5\h5 DY^x,\U9%UٍXX ZecGze֊/f;nnH{mSj(o1qy!\}vVu5Iʹ$} 8#R\$㲰a7K,$ bT$"dۍ ȋrxL-n%,gb{c'ߖ@>Xw@){m$=n&Qڷu$Kb?іvA40LkN#A0E`F"164D [.qpLKAuuclDovʆKEn nME5I$2ƸKMk:EF醟I&E3*0l8ɫV:A8Nk[>`nM6\${TM{H HXTm`6` l6LTs=7HD%Qhqy2cѡEJߡ^I2FDtKUjI 0vY6豇h1t+F |;b!_ n\Vj @MAOSp$lݱ8ENiA"3OQxR0Mn Y1VFA7K=R9䠢ɤNەj"y#TmOTOot\aʭ: Ie "Ct#5bZwV&8v^4EŴD>VǾ|q2s(|c6H&Mİ_첪bMk =ҞOfd7t5Hߝpol]w zyCIhcsZV/c t86Tu$7S*l<҅wpX+Y{MG4^g2䘲Ii8U3`ןXS3좾iRB_SS\1lxp񬍜Nqv8M|[dsB&s? l1n.{6+fx|hh"`m0͛&0c`t=LK6Is&b$Bց\pWbv8zw>Y86"`]`lT`&NGDgp==(ea.FzNjTuClA'zv3=mnZDXi 4f$P 1c'r - 1 5%ۤj;|q6Wm!l1ܴICFqD\;v*:r c.) npu+"6EoUmױT:-@ęHNt1hSAK~ x0;ZU4A"BK}='bم)6vZU6% x3rfy^d}Q/B VN.L}WH$Y!n#B[StL:1C"ӽmhU{/a`܎:ە] )O[uRX^( c&OdK}D$T'Pw d(E5QĵeyI^v_EC"B`5wK#$tuV: jesZ`jTTםP5n;:0-iYi(B\cGVdleY: akUz0 MC4#;[IAbKkaUikV‚HG3 ^)mWFM5(6]S[4KF0 m/6I*6i1U_T4:UW Z."*ZZls.WPڀa7%Mz)C8C8'n^M Æ:*dkYoV#]1曉a G:?U@b|aī45nJ;<q8P1Vz.H./Q1/< ݘ6QIWoٕ&vJXGs\m{ ./czj 1-3 QEC- N.tuG+\浠вy* $'*_=-C.rDSH焚+FP*`E@171xp^tڭ-em \ɦtbgS[zup9-v<ǩR[.~%u;ձ/+AǺ}-RPt)6h{52HU.ipp#y ;8fͬxJabaP G MN 0oHY43L.xg-@,w$w\8"٤RT 괛[̍yڮqZzm0P@UIDEDLn8Y3F\[jeP/q+Bܣc)*z%:̦KA,kXܢp3n-?7k]#6lg1=bҾO:Z ^$OUZDxqPaK&F2F,' 3W5ɪb+=4ˣ9֙On'kKObbq7$ҴMW$/TsKNx7|y+*,[e$Cocb zI:9،UVd̙VwM;N{_SV`*ԛYSsnT}TCIKDSjz)D;bI1ʜ{&$!*lde/pŸ}[@4Lq6Euw aAJC쎓v'D,=Xbv$}ї#sA6G0C ߱fǭԀCd\vDF_$2-!۰D_ۨ +ٺ%&H\x-r)t! a'wD -6l~H ;`#TrwD`ȥO`OcI15%=l-LyC+@蹇Ğez ܐ"׺A]hR1NIʺD6HSoեq }L%@&ZFDqTмDB8#ן6Μxv\úFt asihTJN{ \Fp@츤kH=B?W.y Sq^gHuFP[t;uLKi_&q4,:H+ϻ^&"?U ̥k|\´|wk9瞕=."V9~\F?|Xum*fnׁ7us4xeO%Q552# 1SqzKXϨI#qp!EY)mye0)Sh$9Õicd>spۊ`a'uRd4Lot" "z.iNjE6ؠM:xZ5@[yUg~"ʙH"~ nU:vImHcuYdh`\ĺ$ZpuW[A $ }h\vn#MHmBDO^8\Tq;Cl 4͑XMh{I;7K\8O8QZ^;~t.E '2?xIj8KT):=eu\S"n} 'UHq_&f10{/csF-p(lP[>.6? @UﰸQyune,*/ =0~d\fqH%훎j3%o䘚C )O RSh9%%ʎl}Wpfao縏3Q#R83>auZw I_D=;\ӈ n즊"an{]C=vO-җ36hk1F b:X=e(&~+7evZ&` *H_}N26\&) "~2IsCnd;ܢmQrz` "Sm&dLc1y1*V'D_O``Q$O9GI0l1n FA0'7lCD)`p Cf¦@+tij0P8^Z3ߢȖ-0HJ-Gmebu>L.<7~:'2հy^'Q_Tk<hbӤdikaFeaa gYYn 4 ܨK:\6u$%Gl#W@nuԫ,t盛0Wn՟R/q`+k}R 2:"e RM[k~*-nrTxQv65uP= C#ZIYWX:[dbZKxJNqPMIJjAMC+_=ojXze۬rWS8Gc%zY 될`XopYGt8K@V\C`](M Z'}:ִOTI1<ɕQ!&䒸K@$.|Ӑ&+9:A*&ţrx.;tXIe93hhm3&iG^ֈsZD0;)ݳGT$Ev@dMfP؏Ԫ5jE9PP`u ][d 6Jlup/v2@FKju(Sꁄ4GH/wwećcxD>o^6GEg.OGN(D:~L4&wj,fZkM*ZAlyW@E$Qr@lHRKY- JwY]~@跇h:ʼk AnA,݂ A' $sgٗ=+KLuTk\F5GZ\FIJ @״q֓2UHy$>d';L$ bL ;w s/T;nJGطA;'T106ևgd`\H^\&,{.i#c7N̘2I:zU dAH=ad隬&Azrə^#Q6ӫҚ`cv8yJi&0u\t+A~&OxPؙz³EGbL̍VE#Ҥcap{ =rMGl1i^2l,Ã[Q #5NQg/9W37'm{K3YW W6UUq%f396w,kJϢ=˨.{ Z7_LӨ.rU*-(Wre^^ F+0[-ejeZb֙/Nc%Y v[ºxl o:au378V_c.u""nD0t(BLGHL,>;qs}w7\tGUZ&;*U DA;ܫ؇];&gd璴Ife<5Jc K[`ة ˆZ'Fh}S۱S{)ղ:i0h@,&[Q{F`|/e fR|W,MmUAtQ@jmRʇPu_m.MֹUEQ`cHRꀴ{IݗRAQ f? %yt<8[ЧǢjHH@߬Xނ4!^@+êӠɥTIFoG^^oif:t_DR7uI%X{̤DЫccN{*76BN2(FDomjpEʗS&#N*)2 iU @ZG`l&rnQ~Iv tT봓rqJI?q3q;6Pie-cuz[~. :Qڧq$)$hnM՜9;+M4>u#n5hR09kdӧ>("zfgXeo{s/ʒ;%87#숎MY o!r ~晰K@-tF""OJF LdLcf![K5h$Qã;5:6$M ` $ K ָOe)l*6Z/OZ,6ˉlK_ɢ} K^7Yex2_cMWTyL q* ;N0q$xNdCtXz -mQ3A0eLC5"xH!QOTKv-T Ch7W\ ,HvLo)5b9+TsӼH-q&JD̄m|۶J)=m,\17YP5}+xq .GKl>*A4%\$8 khHuwߏhWRXC%1=xS^ߧ*ݧÏ.NNkZxb Zߕ\;1nGEOQMwIFmkJ7MEky$o݇a*y$,PUW t["r;GEV2W:`d7M1HIMVjCOUG Dn`)SP9͔s-晗Nf4ʐ*GuY]L$Z?yYqɸF˄I9kUa߅O[0%c@\̲Qs{3@6HVx\}`7U*?/ۅ%/i$*U"v*!H$ƛ]2 ([4OI2Nmy=ӫ/D6UD 3~ tzuX pg"-M q3WTy"o¼;AVM9e7.&4\tVhAR¾vXc<& .U1;cGԥժu$}l-*ܨ۶Z_ϩ)dAPH;($CvWEy$,i,DlyX5+ˢ,L@)̨Kf-pu : pD$ždI08UC<!}_TMqVm\H)L)F=tb6)&1DYY~-ƌe߲G aॶ?q.bHB{y +|D2z4'&ULE7}F阜SLv_\s'kw.J\O9yvm50:rԸ4gfK**2Z1|Tn.tk ~UnVDu7/Ù#SNM'4O/_b*@{lCMf/ v^JgtM%=Gs 'yk6 SSK"t FāE9 k4/e'Nt$1Q0x :lxF 76jS% WG{\.&IPvsϙ{A\r> e}r Ȁ %WԦ|ħJaD 0]k|Nq|m-psIA/NbFDrU"|٨jk\8ʌ3JuNH#ʵWzܝ?Q߳͵G=ޣ Gn-6>t:OxΪl 6cy-H."x+y";]C1kɦ['K1 BuRXSc2&:nEՌ3St(uMGd.^#^W/z2kBSoyFi^fx胠A:# j,9 mU~R MOx Eߘ*ȴHn\b)8YpG[*͵1UFM>ЖOW"gGk\QXpbXZq;/>w9z^%(VHz7U&9KUMEͮ]]2-rP94$㴦loESew -%}`L~inʦ ?1G'XdtĀѰR!}H4\a+LDI=RC\5,ERA:yS''e'5Dר$V)q2c;Fv$ "%.6l:w)eg@ի~& O}"Ob0-#`DQm| L&LスT:c}1=Q$OS-f  DQRq{P=uj׆Ce2W{51cqiD&vr^qV5["L_CywTU@x-oGTx& dL-ϻ$4ﲷBm0(HW+a+^Lн[pih%^.-ՠ괰^0 tP͍24{U>na-458ԫT!Y38Ou zwuIZ/y.3j6/[Q!yׇpnl.q,%[g +E)s1nahu>gIP=W7 C+L_-$y %QQ".)s>mi}װ&oMlQ -}йdmQqkŠ+x0ǹ/LE^g-"ߠT >VqXl!$0SlҾ%xic sΚ8.꾥/>>UO ̰bj=i$yLjpבS3)y*t0AW}Wp5I[I-ܯ`1kP,L0de__ 2xS#ɡP4I O8L>OS naEj-qg_3¨lvW迂#L5f,bCCMjS;aiPa_CvO1<4\Ku}GBkxJi?Rۨ[xIsI}:'v.o). 7T,H0?E#N6@("Otg*1,G*h:BL̺QzKo4Ax"ހx?4KDX,ߡ 4Hd[2eh@EG$}L۪ "x2_XoCӋ$MGT,GTւ"9 nhۄM t LsIo!:.x"- I*sk``*N-+h.NOF  A#跳'h pvAZ-.AQ@sUL$=vB֙Y {ki=[tMu#h=0<$nZOHDLt'nؐ{d[K mPZHe1-`bLl"d_h$`9\7`Gr.rA:CfE!0UjĬqI|@li;OusQq͕\Qqvp-6$Q]/P@A4 L0<8^ ъDgON_&2~&qLzA Rf}\K3.V2yLnj_6t,Vaq$X¥5Ȧ%ex 8[u%ϋ"T`h O(ٖhP?ʩ04:,Q'&alC*4dƥGҼYGIad"yLtrَٖ_s𹧗K:0Gl[Xwb* EJZŭ쾽)kE?}~qox1Qg+ûL__O$MFT:k-G^/Y:Gy5'UWlCx}D3̮'R %x+p@cCdTWlEWQ..[wG;[Ө:-?%h2/~nNHi XJ`qhIK>EQ`Ap6ꂭ@tT.JMjjÈ_e 'IH-m 5I0D Wn*Ĺx0%6D\y?UNՓcPL_M9ݠts}W%j;L( t5v,Hu P/di-&NX~đ..lu[m۟0=uA2 T6̒!vOӅsB |t']+-S[; !\@2e{,I0g.>ۤ:FܯKtyƊm(g7= UHO$yNuBaO6<^_j/Z8ƆRi%6ۧBΊ><_TբV Ѩbh_eH/#w~~̰/3ɩDYWyϦp](~;0oXTMWs O|2Yìb<ƉY=e*6thbc鸱8<;WPisC7kSU~âN&Q\7DlJɱFC|[qqZb@ddu)陁)p )]&@\@O$A! B'@li( 7MFuv~-sAE@,vRjS:\ o7JKCĆ 7FFۀѨvŷ)=4KGlƻ2 G"׸GdU5cDP;o)4ؒ%ȧp0m8Ah<®EI٨!f̥DӢkSB@?qci+ , h.[XK BNԵc96J(Hc 3#N5*=oʳt viJu[~Of9B:lK.qҮ6d] d4HI* 0eN'*2eI1ؐƚ]!*z`XT}*%Blb}JN$鹓,.'o \{->s(A#uEl 4^`NK%''o%V{Z. uh\ۑײm ^wAa-ɾp$" _u*dצ#r-={0ͣiZv!-&Et7K<,;:\4g7=*@#zH:+H&?U G GEL8R_,{%9!~`: e&4]n %[`:!RV~mE:t'->.hCp9^ ⱕ|Yg{|{ QFbd?a!K/q#S&J@S*ev熰0Y [#~&ful%iϤ u鶭2׀B!>mWT MǼYzܧ:9v6110,cXֈ*,VRV= j@L,cG,*k\0~i:q^~3jyIi8*&F,`Onq/Pڭ{/pPS 'cұ,z8h6q8WzbO~Za"WU$HnӰKXJw_,s#xL˅ Zֆdz@$ SmTiӳ{pش_腤8: Dm`y!dJD Du<69ųx2ADD')鲖 IOLt4ɁNk06O=J4;)LnB5\Z7=So%-ե +lu,fXIc hǏI.lXܦ@sNLMvH|P*$\~ϫEwCa)#Yu!.&D7JLHP i}J}P rT;GcT%%N@QR URc۷Al7zn dAIdlIBQlI .IVPtϘ0"(5xq٤$/X[{KC M[oS(CoԔ.&@d֚ mͮoxh4q!$G Ł.ixP:7>U De[Hk]?:<_t?"I-ͿTVɎx \tL+ E?DPO!,kLM!Moew K$ ,`&?UbʜZa$uR9nuHJ׫H12[Ilm˞A-m襭{4?6ˁkDYev׫sM5*%$cGV7eJ,*Jdb\5C|sS4Kr#|A=W<.J d̠;=U#0iCiWP0%*ͨCDc8ٕ)i5q`$V{Di2bpFO>fic5|H&7)`s^65M:\8+=M_{o~k~n/ E7 .b7eCD^ac\hn6P; u'n 8!ŗW K P:wjΡ^V|2|=p>7YSp'<5nf8Dȋ -{+b*I=)?b5N]l /TҬ67 Q._dZɤe]q 0\AZփ$ tFD 7OK]`@I<"$L^fq)6&G'$6-LI$V9 izrH$ @IڻJ5Z``.y7p -BMU7{4ۅ5%L< |`)i,7#Ec#CmEim $ɬyJPkhA%FV 3i=Be.!DjІ2!DW~AQ%EwIs A͙Lt4{OԌF29T*s$4Zz*Xa<6*)lfEM([[dtЗ94[;!| .'4YWA PߠOctqeT4dMM֒4d&ЄN6Hp0#t+C5M:Po'rFۙ?It64b/12Bl$nCcaR o6Kq3<*)~|"6lU%3?(NBH1NnbAm'rZLȼ hk ܎I4J}3p0DSEG%LeZ:tV 6odtKTJKSHl}&Suuh4^qS?dnbm]ֽ}^$}kb$ot> yܻ4]i-L*BTo6#f3K HV1`f6^'əw ,G eilŕI" zzՉ H<&Z0l!ˈGg)9hx"vVtA 7IUKZ3ѷ)QkX|:UkmP5كŽRuWDvq\k֪Ej_bj336=Ӈc?]^LJŌ ] l~1?YL 21q#ߠ hkD4 T\j ،Aac.\\r;u|}7|oX# (rl#:ʡ፹s?jYs~ɼ?Ŝ=?̼ʕ+=mhh(D\.sfnBo~g/bjC|Z4\W*SOo5 @5nnjwOSb&+|CPap8!1VAc^H/%m𸌯>%22L$O[7GXH]m}Iپ&Y/.Sa.ibhجv8=43xWrX,x{MqMi'Ri[:`3卹 AsAvD̟Ğ,9JU+өIdxiO߅/s2 4k[UzZZߖ$~cD>6#noEV7 w_y 'giRn"+]D٧հB:@ޫfeVξy 帗Rp~"OtѤb>׋=|&AX<]63Z4^P0$HH"&{&TYV&0[S'^5D57q!}K dvM<3Kc1ؚת16> ID ϗT a&i W߄W|_>"ժ': t:"/~&pfVSG(FaVVnH.uG8A ʬu՘m B7 9Os &>*9Sc\k2&E> 79߉x\IŗSf/NTG q3rgZf#k*徑 _Gs̻+ECBb]Ԩj{K!- Ӵ^$*<'_(|g]Ox6#K mQ:nĨ ƌ,/pq'+[m+]j㒛vWܩmc]@M`G"U#Vcq OlN&@+ nN LVYDks]1쥴ݐz@Nhf$nz_4R#rn@ Ȳ[|i67V QcIo5 zdzLvV4nXl;B6_2Xz"Jg R/껧I!~hnUH͕j#SƑJs\q;&"Z*ĸ^ct4K s1vaA${-I7VVd걼 5mM=[z 5u XiҩTt@Y~n6%R.G7i  #{tHʛ,{]g3`c\X\4'r!\b2U I;Uu|K8/mTҮaNvMill*E\aj%~e7^!&* ð5:O/x7Ų麛_<~xqOÞ Av)3٪l?I.\ ?,3SmeG*/\crr˖14'@v ?ƕNWh{~ڿIMf4/ Vei>ewyxJcVuX AV2xE .4!88 &۲WB=H&Z饤"k@ct!3j-$ܦ(t{X ?0tY~&߂ @T/L;3&Lw^otD4QCM"t$ELq' p:Fd gu/%l27 ]5S9HpWdY,VGkiT CR6}Px1ϋpukeob#0x=}#W ?3ɭF57GV{/{(@W3Ƕ@k0t}o)!-_' KLl_L/Ŏ$Sꏀ.\N괺I{ L_ <qUzى u4f7/a{I.ҭ]%~NmqYʅ~. [?Rx> ,O0DZXPDnlSL^%0tN&j=*??|>|AїQG UGǤ@H 4~&~h-,VyYL} Fo̰+1 OS\?E,"Nk=N3iFO@-d?TF p7Gʅ`d6h+na%?NoNSc(.dE9V $f/L'm m0l& gSC0~:AWMXt= .WJGcQCX ؔ}WdCeԜU! $4XK IȟMvA /Wo};Y6SK2ͥ6 ~d)^n3c? ͓jQp"m)<锆72zil.iͷaIai;NI9kK~d$9լeڛm0L[S;o{J6y, 16ڞq ;]pS58Ɛ`| ):"$ku.o3%cff k>kI_X_1͝Ypt0Ǚ~c( UZbD8eaiҦ cC@{p'?ko&sδ_r,fVᐱ{vp?U׏h8 ‰Ľ k_`_5V'808oQve&,+OGc(Ʃ76 Ko? ԣxe :Q0v_2\qN*/YV_uRʿT?ʼUl%P Xŕ˗,b\q $աXVqZ,ڵnN_,bK\l:pXXRr~JS0A1Y!KTDhctv&y]{_*X{ / ,x>Mǚ&y&,bqSwͨCUeԩgna:^F>RvXM ^/O cC։&Wx?/|̟EWiv!"zp~|L\{e0xHH!0P Xp bHUù .~܌kŒihF $7Bź- Ltoosm"zt*m=Ù*@se'cs=a@no{[5nm썤!p;mu3x{f3Q4Yv[LL8@&J^{o'Wl[_WOL54@` w a7߇2&fXXMZk k3+Q;P[E1fٍ|~c_]jeK#yCF֭Rgԫ7/_9ߕ-puN}du Pc藁.ibl 8a %i@6d94S{/BO$~In6biU}J3qq{s+bեE\('E0O5`w$nQڀAf[mQ|Q +,cb=AHyJ.{2?dK ߻#H_:~@̟VU<#u2^H$?y|@fmL-̏(C>_EǘK OfI#tSmh!2m.w&dz.0pyi8l[\O\ EYz|Exڕ?"IhbSJtl-#{n 1qFm.{'܁ϝx/"nSe<;]SըZ{#`@9KYb/.}jT`ps&&LH0Wy n+$0 Cfnc/.B *cǰ'P:.ɚH~4_A?L/l4Ȑ$vOc\bv{֐@"xZ$Q0&}qcx"gPÁ9@de/h &Ws vdU_O[Q|QSoW {*c:&6CL@-6U`zha$IXRES1 ZfEj4I)Z4wyV!T2d;_[U<I:AmC SvVI%oe7@WuK V _ u}J,x\0KIw qo}!H+"a Xie1iu'7s0} [[N??Eᄀ@6Sq$qU5o#"f]WI$Lt)s+ PHLM/R,ol#jh ɋGC~l_#{$yLu ԯYKQ ?}K>d[n]:S@\|cm{'.6!r ~a5ӌ8ke'|{.}<>deդ>k.㇌|5/0k4nWEg˗.X.\c5v'SktVn l-g ulS"*@ê9-2v?cWRy8MFs~3վ3v} >$3UxZ0C%HIl]Tpp*y?a LSl+ϞGl!*,FKf|=_F2u b%<}s8r:ȵ_?}K78+C aT74Ė\]aNU{<,dGS(\gmD{mZF1nl! oFH X) !H=. 2melI1Ӏaw6)η@6GTb/rIݿsskk= e^$xGN,c xa b:rľ 8\ٖO*Wpq5gW >Pz.%ccK+β7m# ͨQCq%ΠF 9c9^[ՄfxYiY~t{3kgqlN+RLU*0]3;e>{&2_Y󰸖Sq 2kO xsjxZ8e[/թss鍡} +Pʳ/˪DWq5<1a^qy&;Ęu&?ƶhrM1-tSKGȼ#fؼ O^NpCKw.qI<2quA5+S13=Wѱ#3oLvm~qh)XϛI!kx8L3݂+,rYU 5^A<H.tJc|;`(?)0ֽϭ}0ָIJJZmL5+=cD`:]3y\$̞0tЭ4kmcy +5v 62+QCdK[-D4I~#xB3 j_qi{ᡑ~V=o c\ҟqf||HJ_[x ݎpm1cƍWi2 uG4$O^[ 3x񵛔a) ͑c@}F4p6DŦTQ6|?fRp}:[JEeOG `"Z-\!S:@DN콗Oe;2,i|5qRS^Z@#s7e8]죥mj>OeL^Q0Tܳ+֠8&â "lҾ5p9R(yļ'LL}7Ζ4z28@kNoL ; NgE2h@$sZ1N3ڿR΋A&\wK"vL$}Qu=%QL'_dĉJrD4wF]ffY@'@7s 0A"7Jd׳QGgh'1IT.X!y #hQ oQM:9EM4D<1.p'(T$n@n:BqihI2@~Rݺ:K$ؤ=?|SlUr>Sz&YDS8$m&|Mv@q#JNBLD*z]`~ˠt D4ulIt--7C܋1潂dbL$G'|;[E_2\TrTxev&`$FM :7]Km"X0r~qrBr˖1 |C~!8@|ASA ?mWYY߫ V*~'_ωe}Gȼ) Ἶ q4 y~_3%63(>&RA;e~ft~"PqLK]L65=32A㓋}!r-x SY\髫^_=>ƨ٘j}TC+-dmzijLgO pα\*Wpb|bT^\hǶx8 y\"&֎1i':GXxbJmVW=Ѝ.._ z.\HukӤOpvu[q^x-EZ8cn ,3=B8|#d˞;ߥ&N1xiy9kQCmqD_(>+|('Q>&Y@ؓB_Հo $Toߔqvhᰍ=SHy0uwWq J-u -?p>[`tr"W-xùdž0T2tوl-iigawv*W~pd=&9Uär?^^'gT36>LxΎOauN(v ƫqY!6؋H!e 6ʐ͹>s#n5uEL NJV;&;Jd ̍77I)/Fآ &H"{)iH6+L[ERBAf>0V1ZN%V:#lm`- `'+0LuS-nг-1`P;[.S S@qsoh|d=D=w'"44mmشCgA 0B=iP `k L  m )0lA@?5Ip. X}1{"YVY$zv뛤881\uY>ɴƂMR}!9-6Eװ!Ӧ~hdb~RQTݱBhÜZx5 L3œM@qFJܓCoC7R!^ezo=`[djcz<x~Ouad}\5Lɔ>y7ȺOylO.+#O4RP}:MM }4߉vF/G-8JϧŁFGy~Teژ\9څ>!jRg'G19"@z,#Χ|/a^C<= JP\=1Mې _ftt~K/p.)ėoX׊<;̙'#ՖX[glsӹw2e'$XJ/Uz'To&z-}oGd)S2~;& 277DuA'"*xadZ#՝F9Wii 產_oBk `ysCECSL߃ZCLKΔT qMӸwв}9Tk>-3ek`yaP3y)F N . tFp4.mn[fqeK`}K}6 "~{y6QUQ%Z4ᨂ=ir=1p U06;tչO# d SZaAhn!b7"6"jE*^AƩ. :Gk oy(7u#}Hs)=;^ ~6J2=&NRx2@=֎К:@#e4.Ϻe@[W$)4M ~ΦC^!;Z|}ILqdBe7z"Zѽԓ6n:.cKAqo+2xDNOѤq:$ UVu=yFƖ%Evp=¢[ح k.o~ek~isAk=DcA0,DSeGLK/oVoѡBCΠ&{$c^aTaS?*q@ oLk:7M$p'nG1H2E*3V!>a@;K{.{ײ)^Qk z{ftw L{!LYmF^ %ZgꀸI6hf̾{o` ]AoSؒ=s0o" QvMc]6TLo[6r1ƖK8`SsKHҨ[=)$0"0 >/{XKgƗɿݞHv D M=itcA!:J1!Cenp'adA$O(p? 2B3U%a Zc{Fׅ].$y`&&H uB),2&آ; Rg}薶 G6M@ t&z zNtSbZ N m.=I! CN5B@*^ bLMe>`/Ԓg{FLXnc{$t_G(\"d{Ő##syslinux-legacy-3.63+dfsg/sample/hello.c0000664000175000017500000000215710777447273016751 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2002-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * hello.c * * Simple COM32 image */ #include #define NULL ((void *)0) static inline void memset(void *buf, int ch, unsigned int len) { asm volatile("cld; rep; stosb" : "+D" (buf), "+c" (len) : "a" (ch) : "memory"); } int __start(void) { const char *msg = "Hello, World!\r\n"; com32sys_t inreg; const char *p; memset(&inreg, 0, sizeof inreg); for ( p = msg ; *p ; p++ ) { inreg.edx.b[0] = *p; inreg.eax.b[1] = 0x02; /* Write Character */ __com32.cs_intcall(0x21, &inreg, NULL); } return 0; } syslinux-legacy-3.63+dfsg/sample/filetest.c0000664000175000017500000000455710777447273017473 0ustar evanevan#include #include #define NULL ((void *)0) int printf(const char *, ...); int putchar(int); static inline void memset(void *buf, int ch, unsigned int len) { asm volatile("cld; rep; stosb" : "+D" (buf), "+c" (len) : "a" (ch) : "memory"); } static void strcpy(char *dst, const char *src) { while ( *src ) *dst++ = *src++; *dst = '\0'; } static void printregs(const com32sys_t *r) { printf("eflags = %08x ds = %04x es = %04x fs = %04x gs = %04x\n" "eax = %08x ebx = %08x ecx = %08x edx = %08x\n" "ebp = %08x esi = %08x edi = %08x esp = %08x\n", r->eflags.l, r->ds, r->es, r->fs, r->gs, r->eax.l, r->ebx.l, r->ecx.l, r->edx.l, r->ebp.l, r->esi.l, r->edi.l, r->_unused_esp.l); } int __start(void) { unsigned int ax,cx,si,t; com32sys_t inreg,outreg; char *p; /* Test null system call */ inreg.eflags.l = 0xffffffff; inreg.eax.l = 0x11110000; inreg.ecx.l = 0x22222222; inreg.edx.l = 0x33333333; inreg.ebx.l = 0x44444444; inreg.ebp.l = 0x55555555; inreg.esi.l = 0x66666666; inreg.edi.l = 0x77777777; inreg.ds = 0xaaaa; inreg.es = 0xbbbb; inreg.fs = 0xcccc; inreg.gs = 0xdddd; printregs(&inreg); __com32.cs_intcall(0x22, &inreg, &outreg); printregs(&outreg); printf("----\n"); memset(&inreg, 0, sizeof inreg); memset(&outreg, 0, sizeof outreg); strcpy(__com32.cs_bounce, "test.txt"); inreg.eax.w[0] = 0x0006; // Open file inreg.esi.w[0] = OFFS(__com32.cs_bounce); inreg.es = SEG(__com32.cs_bounce); printregs(&inreg); __com32.cs_intcall(0x22, &inreg, &outreg); printregs(&outreg); printf("----\n"); si = outreg.esi.w[0]; /* File handle */ cx = outreg.ecx.w[0]; /* Block size */ ax = outreg.eax.l; /* File length */ while ( si ) { /* We can only read 64K per call */ t = ( ax > 65536 ) ? 65536/cx : (ax+cx-1)/cx; memset(&inreg, 0, sizeof inreg); inreg.esi.w[0] = si; inreg.ecx.w[0] = t; /* Block count */ inreg.eax.w[0] = 0x0007; // Read file inreg.ebx.w[0] = OFFS(__com32.cs_bounce); inreg.es = SEG(__com32.cs_bounce); printregs(&inreg); __com32.cs_intcall(0x22, &inreg, &outreg); printregs(&outreg); printf("----\n"); si = outreg.esi.w[0]; /* Print the buffer */ t = (ax < 65536) ? ax : 65536; p = __com32.cs_bounce; while ( t ) { putchar(*p++); t--; ax--; } } return 0; } syslinux-legacy-3.63+dfsg/sample/c32echo.c0000664000175000017500000000241110777447273017065 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2002-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * c32echo.c * * Simple COM32 program which only prints out its own command line */ #include #define NULL ((void *)0) static inline void memset(void *buf, int ch, unsigned int len) { asm volatile("cld; rep; stosb" : "+D" (buf), "+c" (len) : "a" (ch) : "memory"); } int __start(void) { com32sys_t inreg; const char *p; memset(&inreg, 0, sizeof inreg); inreg.eax.b[1] = 0x02; /* Write Character */ for ( p = __com32.cs_cmdline ; *p ; p++ ) { inreg.edx.b[0] = *p; __com32.cs_intcall(0x21, &inreg, NULL); } inreg.edx.b[0] = '\r'; __com32.cs_intcall(0x21, &inreg, NULL); inreg.edx.b[0] = '\n'; __com32.cs_intcall(0x21, &inreg, NULL); return 0; } syslinux-legacy-3.63+dfsg/sample/printf.c0000664000175000017500000001433610777447273017152 0ustar evanevan/* * Oh, it's a waste of space, but oh-so-yummy for debugging. It's just * initialization code anyway, so it doesn't take up space when we're * actually running. This version of printf() does not include 64-bit * support. "Live with it." * * Most of this code was shamelessly snarfed from the Linux kernel, then * modified. * * FIX THIS: Replace printf() implementation with BSD/MIT-licensed one * from klibc */ #include int puts(const char *); static inline int isdigit(int ch) { return (ch >= '0') && (ch <= '9'); } unsigned int skip_atou(const char **s); unsigned int atou(const char *s); static int strnlen(const char *s, int maxlen) { const char *es = s; while ( *es && maxlen ) { es++; maxlen--; } return (es-s); } #define ZEROPAD 1 /* pad with zero */ #define SIGN 2 /* unsigned/signed long */ #define PLUS 4 /* show plus */ #define SPACE 8 /* space if plus */ #define LEFT 16 /* left justified */ #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ #define do_div(n,base) ({ \ int __res; \ __res = ((unsigned long) n) % (unsigned) base; \ n = ((unsigned long) n) / (unsigned) base; \ __res; }) static char * number(char * str, long num, int base, int size, int precision ,int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; int i; if (type & LARGE) digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (type & LEFT) type &= ~ZEROPAD; if (base < 2 || base > 36) return 0; c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if (type & SIGN) { if (num < 0) { sign = '-'; num = -num; size--; } else if (type & PLUS) { sign = '+'; size--; } else if (type & SPACE) { sign = ' '; size--; } } if (type & SPECIAL) { if (base == 16) size -= 2; else if (base == 8) size--; } i = 0; if (num == 0) tmp[i++]='0'; else while (num != 0) tmp[i++] = digits[do_div(num,base)]; if (i > precision) precision = i; size -= precision; if (!(type&(ZEROPAD+LEFT))) while(size-->0) *str++ = ' '; if (sign) *str++ = sign; if (type & SPECIAL) { if (base==8) *str++ = '0'; else if (base==16) { *str++ = '0'; *str++ = digits[33]; } } if (!(type & LEFT)) while (size-- > 0) *str++ = c; while (i < precision--) *str++ = '0'; while (i-- > 0) *str++ = tmp[i]; while (size-- > 0) *str++ = ' '; return str; } /* Forward decl. needed for IP address printing stuff... */ int sprintf(char * buf, const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args) { int len; unsigned long num; int i, base; char * str; const char *s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ for (str=buf ; *fmt ; ++fmt) { if (*fmt != '%') { *str++ = *fmt; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (isdigit(*fmt)) field_width = skip_atou(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (isdigit(*fmt)) precision = skip_atou(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); } if (precision < 0) precision = 0; } /* get the conversion qualifier */ qualifier = -1; if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { qualifier = *fmt; ++fmt; } /* default base */ base = 10; switch (*fmt) { case 'c': if (!(flags & LEFT)) while (--field_width > 0) *str++ = ' '; *str++ = (unsigned char) va_arg(args, int); while (--field_width > 0) *str++ = ' '; continue; case 's': s = va_arg(args, char *); len = strnlen(s, precision); if (!(flags & LEFT)) while (len < field_width--) *str++ = ' '; for (i = 0; i < len; ++i) *str++ = *s++; while (len < field_width--) *str++ = ' '; continue; case 'p': if (field_width == -1) { field_width = 2*sizeof(void *); flags |= ZEROPAD; } str = number(str, (unsigned long) va_arg(args, void *), 16, field_width, precision, flags); continue; case 'n': if (qualifier == 'l') { long * ip = va_arg(args, long *); *ip = (str - buf); } else { int * ip = va_arg(args, int *); *ip = (str - buf); } continue; case '%': *str++ = '%'; continue; /* integer number formats - set up the flags and "break" */ case 'o': base = 8; break; case 'X': flags |= LARGE; case 'x': base = 16; break; case 'd': case 'i': flags |= SIGN; case 'u': break; default: *str++ = '%'; if (*fmt) *str++ = *fmt; else --fmt; continue; } if (qualifier == 'l') num = va_arg(args, unsigned long); else if (qualifier == 'h') { num = (unsigned short) va_arg(args, int); if (flags & SIGN) num = (short) num; } else if (flags & SIGN) num = va_arg(args, int); else num = va_arg(args, unsigned int); str = number(str, num, base, field_width, precision, flags); } *str = '\0'; return str-buf; } int sprintf(char * buf, const char *fmt, ...) { va_list args; int i; va_start(args, fmt); i=vsprintf(buf,fmt,args); va_end(args); return i; } int printf(const char *fmt, ...) { char printf_buf[1024]; va_list args; int printed; va_start(args, fmt); printed = vsprintf(printf_buf, fmt, args); va_end(args); puts(printf_buf); return printed; } syslinux-legacy-3.63+dfsg/sample/c32exit.S0000664000175000017500000000037510777447273017107 0ustar evanevan# $Id# # # Implementation of exit() for com32 based on c32entry.S # .text .globl exit exit: movl 4(%esp),%eax # Exit code in %eax = return value movl (__entry_esp),%esp # Return stack pointer to entry value ret # Return to termination address syslinux-legacy-3.63+dfsg/sample/filetest.c320000775000175000017500000000445510777447317017637 0ustar evanevanL!1-)O))t$4)g;v@ppp ppp pp$RPRPRPRp(h;DLUWVS|D$xD$tD$p""""D$l3333D$hDDDDD$`UUUUD$\ffffD$XwwwwfD$VfD$TfD$RfD$Pݍ\$PSQt$(VSj"<)=$1,߉@)@AufD$t@)ƒfT$\fD$Tt$PR\$(SVj"<)$4\$@D$TD$l$XvT$D*1t$1L$PL$,|$f\$\ft$pfD$t@)ƒfT$hfD$TD$P5P\$(SD$XPj"<)$T$@fT$*v5@) FP%KFu)\$*1|[^_]ÐWS41\$,|$@ u j D$-D$@D$$PjSj!<)D$PD[_VSt$1 PC3uZ[^ÐUWVSÉ։͋$$@t D$(D$(tE"v1U0D$t.y ID$'-%tID$'+tID$' D$' T$ tuuIuD$>0D$,(D$,1ƋD$(D$,T>@D$,ut$,$9}։)u C@€|$'tL$' C|$ t u0Cu0L$(A!CuT$C@‰0CH9D$,|L$,L$,D >C|$, CH؁Č[^_]UWVS |$(t$ <%u D$@L$$AL$$€+t! t!#u1!-t0u%L$̃L$ŃL$뾃L$ 뷃L$밃0 w D$0PŃ#*tAD$$G/y݃L$NjT$$:.t D$OBD$$J0 w D$0P{D$*uBD$$D$|$yD$D$$htlt Lt@D$$D$$#u=)9r Uu&#&#)ôJ!ߎǿM uʎ&>#&>#&#tA(O0!&#&&#<r/,)1 =nou D=87uE<u<uFF<u&6#&#&#ʎڎ‰.#>#>(>&)>#u ######1##O%>(SPRi=!Z<u)I@!XPzXL!PȎXSQRVWFfMEfMDfISfK?ffffVV1u6!Mu0VVu&EMu VVuDIuVVuSKt1"&0W_^F&=vvN&W_FV0ËF%V&FV0&F0$?&_^ZY[SQR&&&0G0хt &GSQ11B[ÅtFGwFw FPGFFFPfwwfwwGw0PGPRh%AD랉Y[R&&# {GZSRUÃ?u]Z[SUÎ&G&u u][&SQRVWU&&ȁ&s?u:GrފG&tD<uznj]_^ZY[SQVWU|ѿ&&&s?u:GwފG&t:Ls͍D<u]_^Y[QVdt^YÉȉ^YSRUF ^VF#b]Z[SR#J##R##>#u1RPWVIDEOSÉЋ)G[QVWUƉ׉ڋ\ttrGD0\$0dωFuFDt dFLfӉƒ~t dLD tF DЉ]_^Y1USQRVW ^#1@FF+#$‹FF@$AFFu0&&&&&&&^&&'&f_^ZY[]Ë~Ћ6#&W؎_&#W^&F^&QVWU'Ɖ^F< uF< t<tK0<"tv<"u=uFu Ft)0<u!tJ~׋FF<tPF`< u!tր<tр<\u'u|"uF|\t< tD<u|"uFt$F'Cw|\t|"uFa^F7']_^YF<t'>'uá'SRVW&$#$|u '_^Z[ø uA Džt('u|E>'|E |E뱻.&ˉ1^SQRVW#)1ɋ'ׅt,7_G@uGt hA9r*$s1_^ZY[SQVWӋw|t|toDGuiw|up u(G@u?O GG;G u u#?O GwuG;G u t_^Y[øJO 0SVr u Gt@G G wDw|u:gG wODG wDG^[GtG @G 뱀OVWUvމNFFFdFF҉V^ҋVFNjFGF݉~tdFtFڃ&&UUF@tFF)^DtGut~D@_t؉^| Su5Dt"F‹\D|};D~D|F‹\D uDtCDu}~u~u u~t$D‹^BÉT0D^BD T|tD ^\‰^DtL|uH~uB~u 't0'$0tދ^FGDDD^D DSQRVWUFDtl\t;dD u1D tщúًDۃu=u FL \GD~u \Gu^F]_^ZY[ÀdDt΋|}tŋ}Lt~uˉD=u FL )؅u FD=uFSQRVWUDžt+=w&$F=r%F1ҋF;%v>6%t1]_^ZY[Fԉ6%6$u~tBtIF%ۋL 6%9rډt…u!;%wt뺉% tFv(SRVt66'tZ9w.9v&ډ6';6%s D ;%v%(^Z[Étt 9w9wŋwt 9w9w6%u6$t9v?t9w9wtt9w 9vuwt9w9v_9vTSVWǾ't;tM?<6''7_^[SQR'u'ZY[Éˉȉ'SR't ;Gt Z[úZ[S ‰[SQVWUƉV|tb1Du_|tD؋\^щúF~tD Dt\G\\GDt ']_^Y[ÿSRqÉZ[Sf [SZ[SNø [SR@SG t[ËG1tO GuO[SÅt t 7W[ø[QVWU$RFv݉׍^N17.!FFuNGuFډ]_^YVփ u|^B-P t tXSR^&\Z[VWUHSvvvFvv ^vvׅt'‰1;r É14444‰؉ˉ,tډ11;r߉1ԉʉ11;rΉlj1Ë~މ^.!~Fut{uuNvvFuF]_^VWUvv~ u|u rur v v1)׉ω߉lj|-~SR‰Êt,a<vCAZ[VWU$SQFv݉ߋ^؉^^1;r77ʋ^.!FuօuNGuFډ]_^Vރ u|^-؃CSÊ'0[1VWUƍ~ЉډB!66Uʉ1| FV]_^ÉQVWUƉV5t11ɴB!ʅ|&V@!҉ƅ|9t ]_^Y(1QVWUVFPFth9r_$߉G s9wJU]9vQ9wMU)E =rUΉu|GDulju^FPF]_^YË]19v‹_9uFU Mwu|QVWUƉщ߉Puwt^un;]uu_]~M~9u=^;Wuv^O ;ws;GvG^;G vG P]_^Y]9rq;ww]9r^_@~FE 1҉Fv9s$F)9vPu`=t$Ju^_9r29r_9r܋_9rՋ__9rɉG9v뫋^_Ƌ~E~\|uwSVWƋ$1t 9rߋ_|\t=uu<|DDDD|||_^[É6$wS>$t$_;#u[1[SVWUP>J%t>#u1]뱍Ft^#;#sb=tՉ=w9v)É^G9w$Ftu!1u1 ^ZY[ø(ø(SQRøD!€tZY[10123456789abcdefghijklmnopqrstuvwxyzSQRVW=uec!s11،ut`'0W_ '&<ud֎ö&<tZ&T&009KC'=t=t=t7tpl'0W_ '%0HMZR'0W_Gƅ'~CƇ'~ '%1_^ZY[ 'DDU1ظe~!Fs1]%뺅u1ÅuSRÈ0!s9>#r+Pu"r0 %Z[À rv܈0S;%r1[ËH%Ë[S;%r[ËH%É[Sô>![Sôh![USQR=!rkZY[]R¡J%J%Z#SQR;#r<ñu؀>#u +#á#J!u ##ZY[gøs RPXZ) tt  $ %LILOLOADLINSYSLINUXPXELINUXISOLINUXEXTLINUXSYSLINUX familyEtherbootELILOGrUBU-BootunknownDrive %02X is MEMDISK %u.%02u: Address = 0x%08lx, len = %lu sectors, chs = %u/%u/%u, loader = 0x%02x (%s), cmdline = %Fs Not enough memory to allocate file structures Floating-point support not loaded    D : L% Q%1Y%2b%3k%4t%0}%@%P%p%%%syslinux-legacy-3.63+dfsg/sample/Makefile0000664000175000017500000000414710777447273017143 0ustar evanevan## ----------------------------------------------------------------------- ## ## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- ## ## samples for syslinux users ## TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \ then echo $(1); else echo $(2); fi; rm -f $$tmpf) M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-ffreestanding,) $(call gcc_ok,-fno-stack-protector,) CC = gcc LD = ld -m elf_i386 AR = ar NASM = nasm NASMOPT = -O9999 RANLIB = ranlib CFLAGS = $(M32) -W -Wall -march=i386 -Os -fomit-frame-pointer -I../com32/include SFLAGS = $(M32) -march=i386 LDFLAGS = -s OBJCOPY = objcopy PPMTOLSS16 = ../ppmtolss16 LIB = liboldcom32.a GZIP = gzip PNGTOPNM = pngtopnm LIBOBJS = conio.o atou.o skipatou.o printf.o c32exit.o .SUFFIXES: .lss .c .o .elf .c32 all: syslogo.lss comecho.com hello.c32 hello2.c32 filetest.c32 c32echo.c32 \ fd.c32 $(LIB) .PRECIOUS: %.o %.o: %.S $(CC) $(SFLAGS) -c -o $@ $< .PRECIOUS: %.o %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< .PRECIOUS: %.elf %.elf: c32entry.o %.o $(LIB) $(LD) -Ttext 0x101000 -e _start -o $@ $^ %.c32: %.elf $(OBJCOPY) -O binary $< $@ %.com: %.asm $(NASM) $(NASMOPT) -f bin -o $@ -l $*.lst $< $(LIB): $(LIBOBJS) rm -f $@ $(AR) cq $@ $^ $(RANLIB) $@ %.lss: %.ppm.gz $(PPMTOLSS16) $(GZIP) -cd $< | \ $(PPMTOLSS16) \#000000=0 \#d0d0d0=7 \#f6f6f6=15 \ > $@ %.ppm.gz: %.png $(PNGTOPNM) $< | gzip -9 > $@ tidy: rm -f *.o *.a *.lst *.elf # Don't specify *.com since mdiskchk.com can't be built using Linux tools clean: tidy rm -f *.lss *.o *.c32 comecho.com spotless: clean syslinux-legacy-3.63+dfsg/sample/mdiskchk.c0000664000175000017500000000711210777447273017437 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * mdiskchk.c * * DOS program to check for the existence of a memdisk. * * This program can be compiled for DOS with the OpenWatcom compiler * (http://www.openwatcom.org/): * * wcl -3 -osx -mt mdiskchk.c */ #include #include #include /* For MK_FP() */ typedef unsigned long uint32_t; typedef unsigned short uint16_t; typedef unsigned char uint8_t; struct memdiskinfo { uint16_t bytes; /* Bytes from memdisk */ uint16_t version; /* Memdisk version */ uint32_t base; /* Base of disk in high memory */ uint32_t size; /* Size of disk in sectors */ char far * cmdline; /* Command line */ void far * oldint13; /* Old INT 13h */ void far * oldint15; /* Old INT 15h */ uint16_t olddosmem; uint8_t bootloaderid; uint8_t _pad; /* We add our own fields at the end */ int cylinders; int heads; int sectors; }; struct memdiskinfo * query_memdisk(int drive) { static struct memdiskinfo mm; uint32_t _eax, _ebx, _ecx, _edx; uint16_t _es, _di; unsigned char _dl = drive; uint16_t bytes; __asm { .386 ; mov eax, 454d0800h ; mov ecx, 444d0000h ; mov edx, 53490000h ; mov dl, _dl ; mov ebx, 3f4b0000h ; int 13h ; mov _eax, eax ; mov _ecx, ecx ; mov _edx, edx ; mov _ebx, ebx ; mov _es, es ; mov _di, di ; } if ( _eax >> 16 != 0x4d21 || _ecx >> 16 != 0x4d45 || _edx >> 16 != 0x4944 || _ebx >> 16 != 0x4b53 ) return NULL; memset(&mm, 0, sizeof mm); bytes = *(uint16_t far *)MK_FP(_es, _di); /* 27 is the most we know how to handle */ if ( bytes > 27 ) bytes = 27; _fmemcpy((void far *)&mm, (void far *)MK_FP(_es,_di), bytes); mm.cylinders = ((_ecx >> 8) & 0xff) + ((_ecx & 0xc0) << 2) + 1; mm.heads = ((_edx >> 8) & 0xff) + 1; mm.sectors = (_ecx & 0x3f); return &mm; } const char *bootloadername(uint8_t id) { static const struct { uint8_t id, mask; const char *name; } *lp, list[] = { { 0x10, 0xf0, "LILO" }, { 0x20, 0xf0, "LOADLIN" }, { 0x31, 0xff, "SYSLINUX" }, { 0x32, 0xff, "PXELINUX" }, { 0x33, 0xff, "ISOLINUX" }, { 0x34, 0xff, "EXTLINUX" }, { 0x30, 0xf0, "SYSLINUX family" }, { 0x40, 0xf0, "Etherboot" }, { 0x50, 0xf0, "ELILO" }, { 0x70, 0xf0, "GrUB" }, { 0x80, 0xf0, "U-Boot" }, { 0x00, 0x00, "unknown" } }; for ( lp = list ; ; lp++ ) { if ( ((id ^ lp->id) & lp->mask) == 0 ) return lp->name; } } int main(int argc, char *argv[]) { int d; int found = 0; struct memdiskinfo *m; for ( d = 0 ; d <= 0xff ; d++ ) { if ( (m = query_memdisk(d)) != NULL ) { printf("Drive %02X is MEMDISK %u.%02u:\n" "\tAddress = 0x%08lx, len = %lu sectors, chs = %u/%u/%u,\n" "\tloader = 0x%02x (%s),\n" "\tcmdline = %Fs\n", d, m->version >> 8, m->version & 0xff, m->base, m->size, m->cylinders, m->heads, m->sectors, m->bootloaderid, bootloadername(m->bootloaderid), m->cmdline); found++; } } return found; } syslinux-legacy-3.63+dfsg/sample/README0000664000175000017500000000042310777447273016354 0ustar evanevanThis directory contains files intended to be used as sample code. This includes COMBOOT, COM32, and MS-DOS programs as well as LSS icons. For developing COM32 programs, you probably want to use the new com32 toolkit (libcom32 and libutil), available in the com32 directory. syslinux-legacy-3.63+dfsg/sample/atou.c0000664000175000017500000000030610777447273016610 0ustar evanevanstatic inline int isdigit(int ch) { return (ch >= '0') && (ch <= '9'); } unsigned int atou(const char *s) { unsigned int i = 0; while (isdigit(*s)) i = i*10 + (*s++ - '0'); return i; } syslinux-legacy-3.63+dfsg/sample/comecho.com0000664000175000017500000000004410777447317017607 0ustar evanevan1Ɋ<!´!  !> $syslinux-legacy-3.63+dfsg/sample/comecho.asm0000664000175000017500000000065310777447273017620 0ustar evanevan; ; Simple COMBOOT program that just prints out its own command line. ; This also works in DOS. ; org 100h _start: xor cx,cx mov cl,[80h] ; Command line len mov si,81h ; Command line mov dl,"<" mov ah,02h int 21h .writechar: lodsb mov dl,al mov ah,02h int 21h loop .writechar mov dx,end_str mov ah,09h int 21h ; Exit with near return, INT 20h, or INT 21h AX=4C00h ret end_str db ">", 0Dh, 0Ah, "$" syslinux-legacy-3.63+dfsg/sample/fd.c320000775000175000017500000000353210777447317016404 0ustar evanevanL!1Z'')t$d'g;vVS5h'1ۃ h f'f'''p'f'f' h'h'jl''tCug h Cf' f'p'''%''f' jh'j"l'Z[^ÐST$1k BHЃ v[ÐUWVSÉ։͋$$@t D$(D$(5tE"v1U0D$t.y ID$'-%tID$'+tID$' D$' T$ tuuIuD$>0D$,(D$,1ƋD$(D$,T>@D$,ut$,$9}։)u C@€|$'tL$' C|$ t u0Cu0L$(A!CuT$C@‰0CH9D$,|L$,L$,D >C|$, CH؁Č[^_]UWVS |$(t$ <%u D$@L$$AL$$€+t! t!#u1!-t0u%L$̃L$ŃL$뾃L$ 뷃L$밃0 w D$0PRŃ#*tAD$$G/y݃L$NjT$$:.t D$OBD$$J0 w D$0PD$*uBD$$D$|$yD$D$$htlt Lt@D$$D$$! 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzsyslinux-legacy-3.63+dfsg/sample/conio.c0000664000175000017500000000240010777447273016744 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2001-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * conio.c * * Output to the screen */ #include #include #define NULL ((void *)0) static inline void memset(void *buf, int ch, unsigned int len) { asm volatile("cld; rep; stosb" : "+D" (buf), "+c" (len) : "a" (ch) : "memory"); } int putchar(int ch) { com32sys_t regs; memset(®s, 0, sizeof regs); if ( ch == '\n' ) { /* \n -> \r\n */ putchar('\r'); } regs.eax.b[1] = 0x02; regs.edx.b[0] = ch; __com32.cs_intcall(0x21, ®s, NULL); return ch; } /* Note: doesn't put '\n' like the stdc version does */ int puts(const char *s) { int count = 0; while ( *s ) { putchar(*s); count++; s++; } return count; } syslinux-legacy-3.63+dfsg/sample/fd.c0000664000175000017500000000342310777447273016234 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * fd.c * * Chainload a floppy disk (currently rather braindead.) */ #include #define NULL ((void *)0) int printf(const char *, ...); unsigned int atou(const char *); int __start(void) { int whichfd = atou(__com32.cs_cmdline); static com32sys_t inreg, outreg; /* In bss, so zeroed automatically */ int retry; for ( retry = 0 ; retry < 6 ; retry++ ) { printf(">"); inreg.eax.w[0] = 0x0201; /* Read one sector */ inreg.ecx.w[0] = 0x0001; /* Cyl 0 sector 1 */ inreg.edx.b[1] = 0; /* Head 0 */ inreg.edx.b[0] = whichfd; /* Drive number */ inreg.es = SEG(__com32.cs_bounce); /* Read into the bounce buffer */ inreg.ebx.w[0] = OFFS(__com32.cs_bounce); __com32.cs_intcall(0x13, &inreg, &outreg); if ( (outreg.eflags.l & 1) == 0 ) break; } if ( (outreg.eflags.l & 1) == 0 ) { printf("!\n"); inreg.eax.w[0] = 0x000d; inreg.edx.w[0] = 0; inreg.edi.l = (uint32_t) __com32.cs_bounce; inreg.ecx.l = 512; inreg.ebx.l = whichfd & 0xff; inreg.esi.l = 0; /* No partitions */ inreg.ds = 0; /* No partitions */ __com32.cs_intcall(0x22, &inreg, NULL); } /* If we get here, badness happened */ return 255; } syslinux-legacy-3.63+dfsg/sample/skipatou.c0000664000175000017500000000030610777447273017477 0ustar evanevanstatic inline int isdigit(int ch) { return (ch >= '0') && (ch <= '9'); } unsigned int skip_atou(const char **s) { int i=0; while (isdigit(**s)) i = i*10 + *((*s)++) - '0'; return i; } syslinux-legacy-3.63+dfsg/sample/hello.c320000775000175000017500000000021310777447317017107 0ustar evanevanL!1  )t$ g;vW81|$ ,{D$(D$1PjD$Pj! Gu18_Hello, World! syslinux-legacy-3.63+dfsg/sample/c32echo.c320000775000175000017500000000024010777447317017232 0ustar evanevanL!1  )t$ g;vWS41|$,D$-= D$$QjSj!G\$ uD$$ PjSj!D$4 jSj! 1D[_syslinux-legacy-3.63+dfsg/sample/sample.msg0000664000175000017500000000054610777447273017473 0ustar evanevansample.msg Note that ... can be used to delimit something that is effectively a comment. This message is displayed before the image. syslogo.lss This message is displayed after the image.  Please note colors do not work quite as expected in graphics mode!  04 RED 07 02 GREEN 07 01 BLUE 07 47 RED 07 27 GREEN 07 17 BLUE 07 syslinux-legacy-3.63+dfsg/sample/syslogo.lss0000664000175000017500000006225310777447317017726 0ustar evanevan=@ !+4445* ***<.:3===P1U0BbE!#PdEh1A"d&A1Vh&UA$3GDeaB! 1X#2nUC3(3A0AA5$ABEXc!81bQS aUB$3@E4eQ4E#"`UC3(ESXa`E 6D!C BhDQA"bUaa1VfbX3aaaE43+3Uc5"Qf0P8D1" T3XA`5X(6hX6CR4"2ESCa&Uf&XXdE$3'3""`aUC3( v@XR#Q3#5"%PTV8B$"6HEEhUn&XVD1C"af@P8D2" fQ0A ^0"1e hAAUC(CCa fXF3!3Ac`!daUDUB3#@aUC!3'fRRDD%&DC3Qa4R2aX4"3fS2ETe3!"%bUB3&aUC"3'""3A$Ua"1DQf3Ae(C!d1cbbh0fU"h&1&&6`Fh4V4aUA3!fQ%D12AHfQeD2C"QgfULd3 ЈaUC#3'0!"3A$Ua2Tf2T2ae0V8X#aE#hE3!fQD2"(fT%D5#"AiFUMd3 ЈaUpC$3'҆(!"1#DQ!Ce1@8a1QVD1"aUA3!"0b6UBT3#bfUD6" fP7DP2}"f8!"1#T%!CBXXpDB24aUA3! b6UC43$RfUD7" fP6D`2}"f8!2Da8BX #Q%(@%V4"!8fQED2C"AgfUJ3 pa U`C(3'e!SV(1[#3!cUC$3$BhfVD9"fP5D2{"e!ah%6(fcE1ea aUC3%2XfWD9"fP4D2z"fa$C%acF5(fA"AfQ%D1C"QdUG3-`Pa U0C,3'3eTXx6fbE3#"8fWuD:"0fP2D2y"D2@"Q3%HA3@(`E$3"8fXUD:"0fP1D2y"3a5apXA85AhUa5"AcvUE3*  aUC/3'8cT`d8Xf6F3!"8fWED:"PfQ/D3w" HP!@IA&UE3#2(fVED:"Pf Q.D 3v"020VEbUb3A(fU5D;s"`f0Q-D03v"0691H4BVV"c6UC3&`UB43P'a@B$`@ 5"!d&UB3&`UB43P'Q@&UA"QhUC3% `UB53@'Ua$!!$XDa%(hUB3% `UB630'cdCH6fQED6C" f`Q)D3r"`1c&U!3Q$a&UED3$ `UB93'&hPTHaFUD43# p`UpB:3'4DdE#VD1"aFUD3# ``UPB;3'"1bDQF"Q84HRD1C"pfQ%D3o"d5A2F1e04EhE3$P`U@B=3& 8(%E2"(VD2C"qpfQ#D3m"P%V6D0fQ%D2c"qpfQ!D3m"1d4#5h#hUBD3&b `UB?3& ΁6A!C#fRD5c"a`fQD4k"XAV4h6UAT3&B`UAB3& EVfQDaeeR%D5S"aPfQD 4i"%$4Vbb82fQeVD2"a@fQD04i"bD1h!e 6`#f@fA#nUA8E%J43&؅#4f!1&"FhV4"a fQDD2\"pe0&@C$V4"afQD@3#`3%$!!C"2h(SX4#"afQD@D1U"%3!h$Pa43"afQDSDA3@% efER2hE3#RЈkU`A1A3 %2$EXQ`UDeU"aUB3#RjUPA/B3$d`f1VD1#"aUA$3#rjUPA.4N" 1XhE3"fQ%D3#"fQD2!64K"0XE3"fSD4#"fQDR!`4I"@C&hUA$#28UA43! `iU A,E3$$5 2VaFfR4#"fpQD")C4F"P5Hf2XS4RU1H#E3$b@iU@+!I)P4D"`&!"U%%HbShE$3)"0hU@*%0!9[@3P$ca %0"Q!bb5fQD53DQ@#" iU@+@[E3 $C` %2$Qu&E3!"0hU@)!)4;@B3$"Q#fR%h&UaX4(Cf@Q D2P;"E3$`eBXTA@#aQ%$S#V# iU@)P+;)4>"`P3bhTT12!#hUA"f Q D2`"p4>"P !h6EUcT#"CQ4"!fQ D2`!)!=="%f1bTbUA3D6hEE5"AfQ DpR"4;" 4V43"1d42&V$(E"QfPD49"@5D2BVF#"!2fQbUa&eU1afPDP0:"@XD2!BF#8a1E3"`j U@&047"pFhE#HfS5D1C"afPDp046"$SE3!fTED2C"afPD`236"CSCRH3!fU%D3C"afPDPR 35"AC6VT#aFUBD3#RlUP@$3@# U1(6fS%D43"Qf`PDP3@# QQ31"Qa$(fRD5#"Af@PD@RA) )03"F(5hE3!8fQD4"1f0PD@p019)?3"EUaUA3"BV%D3"1fPD0R1A3#"!8("EV%hfE3!RЈoU0@"+ 4/"0$%hA!&h4B"R!E3#"ЈoU @#'++`@˻,˻!N3"$ C`dd4!hUab@hVD33"!f]DR̲)lǛ4."@a0 a3 "a$a4"fQ1A#oU@!`r+` lwÛ 4-"P4dKF#c&CTa%$5F#nU@!w,""f(3TDQ2Ua@Pp @p@`0@d]%TUcaE#@gvUO^ @O3"1UaF2f2e#ooooopo 3VfQDo3Fe&4S$0kvUOP{q]=| 0 "T%f2#%U P  0&3BiUBt5"9fXD!}2 0" DQ5f1h(e___? RiUBT53"fYD0э 0"0DR5f1EP3XP?O??RfR%D_"fZD0~ @3!3C$UbRQFh(Da` (fAQTXbUC$ PnU@ P*N 3!43BUa"5(#Xd!3ap b1be2)"!UO"f\D0ڍ 3!4"1#TCXV525F&p   DQdc!TXO# nU@ 0ӝz 3!5"3DaXD2DQfhU   @8AaO3"nU@ ..0"`"4#T%%"#23BUadh???R!UAQ3!D3"nU @ :^~ 3!6"5#DQ58#3AeXd2(??OcXV(SD2#"afPDP0ڝ*ݣ0"p"53DR5f(#cU1U"aU `    06U1?UA43#lU@ ݡݡ B3!7"53DT%f#C2#p/??FT#?V%D43"Af@PD 0ڍ* A3`!8"5CDUf"3AeebEBP?P??ERVh$l&UBD3$RkU @ ݡ~玪ݡ0@3P!9!B3DTUaF"2#T%BB 0  P `%h5hFUAT3%2jU0@ .-ښF)I3P!9!"3ETUa&SDR02e0 P p`eaX3)(fRD6C"1fpPD>Im "p2""3DTUa!#$&3FcC58dA  P p`HP4$d`#$Q%D4S"1fPD<Κ-K)P4""3AUgDQV(dR"TaA ` ` phB@XUAehUG3!h UP@@I-*!P30!;#c($f1"SQV ` ``UY15fST$Јh UP@ ̱^Iڪr Pk@A3!;#Ce6Q"F$5 `?O75U!QV!(C&X4"1xfPD |Ii.ڪw,%P4"#"3Af1Da45VhQf   @ J2U25V3QFh4#"1xfPD0ǧz:*w&4"#23BfSD   @  0SdCXRS1h53"AhfPD0ǚڪrG|̱[3 =#B3BUa"1dBSQ&4b    0 Rc54e4"aUA3"Be U@4,ڪڪ,w'K`3 >#R3BUb!c&RAB    0 0!D5a$fQ%D1#"QXfPD0ڪѪr|'7| `;pB3 >#R3B4Ua&"1T "    P"b1V4h6UA43!b@e U@3:*qq|v'PI3 ?"b3ADUa6"1dRc@     P3BAV3"a6ET#b0d U0|||̡wwH3 ?!R3AV5X!V5(VVB1P/??)P `VXbEV5F3"Bd UP0wǫ:wwA3 @B3E$U!!%#$EU(U1`a@  p  p10@`X!`#VVC"1"XD1s"!HfP|g|̡rq|{ 4"5VDRB`55CTbb&(`QA//??HHP h&&hE3Cda%QDS5E#HfPPwww,˻\,w14"V(h%e&UcAh/6!b//?i(O]bUb&AC0fXFHfP`{r'||qqG|'|g 4"!CVVDa!4#e4EUaF64W?e56?/?G4?EWdH%bcUA3aSdhQ3!d UpOwLw"A30 B#Vf1EFX0HQTT?edAp `  pEV@ @1S6#a0FA$fU% d U!$_www 4"  $3D4Ua(dbQ8!e%#hV@SPSQVD_?OWO(&QT@a5D!hf!e5VD33"AXfP!w||||t||7PA3 B@$"3C4U"2dc4#ASF&(!1bX_(0e ($pp  fQ$C%f!&62b!eC141F3!#QD33"AXfpP)0{ww73 C`$23B4eBS$a&hb3B od$5T"p `hOB!CAU`F`4"QHC#HEhE43"2`fUy||||q|' 4"0#R3AUa&1E`@V5d(H0TaWdoDRPp 4f!Fh 4VB2U 8#fQD2"AxfPPU w 7`@3.D#RCUbH$8!4CThUaSQf!3A"T@ p` oFfQEA a%VFaE3C!CafRD1"1f@P5`ww 2"@"B3a(C(XD"RBCePhCePP P  @ m4#DQF8X4TDQ"5EU25!H#RhU1w`0"P"23AThcS2d5"4(eC@0CT&fQQ0@` 0Pc?S0`4X#B'3QF3b"QDE3!2jp p70!` 4"P!"3BeChQF3!(f2f"6d@CP` X4"U(0f("3A h5VD1#"f{p@3+E!3B$f!S0aSAV$f!`3R4,Cb3a812!`E0lQ fA%QD! fTa3b2f!C1%6a&D2#f pqr 4"`!c(e3"AVFUa aFUcX(1fa31bF122V4D `*%XB1e!5"!c612a%#Qa&Uc6!XP%SbA8X4d1h(Hf,@3(F"C(A"Q$""EVUDS%f"AX$(f(!T#a(!h(#%CSQ#!hX#(f!C`4"fTDTUc"!R6%11a4fE-p4c"p"3BUaD!6!hHUCUb&2&$bH4e28cc%4h&E4QR6bRd#fR%DZ%D(f"ehUA3!"o{@3%G#2C$R5h6UbeUAUb!(a&Uhf5"2#T81Z#U1X43"1hUh&!h@fQ%D^FV%f!SX&aD2"1-4C"p$BCeAhXAhUG$3JdUb$TbUFDUb12Ta1QhE#8V5DSeP@V%D6DRuf#eVD1"1w. 3$Hp%Rc8baEt3&3K$Ua$E&hUCUa&!RCa2HQ LS6eR0(fQ%DZEAUB3@@dU!B#BJw.@3"Hp&RCeAafQD53"DR%f1BF#f! H3""3SX0 Ff0&AQ/p??//ZD T(aXX&SREX#3C%5e2D1#fQB3!-"C($SV%D5"5sq|||'$1"P"3$E#3CFfQ%1RaUB""<DTAfDQV3!$CVCeQh%T#cUD30DQ@004B!ah#DR&(FOA2eCaR0VD3#""AUbaaUbUD1s0ppg||q2)3!D"2Db%E3I$!5H3# (3BD%3aX5"1$((!DQ(0"Q6@VD1"Aeb/ `@ /O#6X4R@Q/S?2d/?D1##",3C$U1!EXD1www3#DDbd82FUb1R32%X3# )r3C4e1R!E!cbF23!VThU0E%XARHb/%h/1&2@&?/@"bU//o$!("/fO///D2$"*3Be10RXF&h|rW|q`)"PeA%CAhUaHhUa65aUV4"p"63DRfRff2TP43TX&AQ#S&"?B"QK/a$B"a410@"X1RR6bFaob&/aB$"/p"1T(Vf"5AA)|r7|I)#CUbSB&#!#!1FAD`e#")B3DUbCh6UC4UdF25#""3TV5fQ/3/C?//C/Xb?"/Ab?/"!2T_#b6SS%b1R%?3?Q"B!DS61I w0ww#CD13DbahV%$h&D1SD!6"1"3CT%QBfQ5DYEf1a"a"1XcDf6R?/?oQc#/??Da2"ah/EB4RCV2#" #B3EX&;0{' sG)1" 4"FF43A3AeaUA$3!C%("3CeEBUCU1P!F#3Fb&////_#_3/$h/VB$B4Be/cB3/"@C#4ww"3!Aa"45"63&PA3# P (3Ae2H%1hUAUR&cv!"33R(BO?////2//2/E3"/(fRXB$A4B$Q%a%V2V1 @07ww9#A"1TX4# q2T%!$AF3O4eAaA"1R/hp0 pp0!b?UA!aVaF1B$2?2#?/!ROA"@9w@.BAaBedE#@&C&A$V4DQf$bB!@ ppRBOcA"/ffQ5S2#4213T"d$@@@;w 022 " !A2d1"!(A2!F3(3D4UhVA?6/oo/o??4cP#fOU_/3/"?"2#2#/$/@H3!@@s'0!I)9" !"1%6.1"1bUA$EE3#3CtUd&!"1Dae.$chD1"!c&UDt?3"P0#O%E$eB5"1-@+ );)1,B@@P!45P@@!4C"03DY%f(!"3AUaAcQX4#"bUB3#3D3Q"!.@0 9#@ @B2fb5""@0CDY42DQ!#aXb"B3!aUA3#,Rdf@;0t992" Q f  "0CDX&6h!PV7B`Xc@(VD9C" f 00q0t !I$?ff  ">CDW1EU2/41c3QHUA0VD7C" f H00P10#?fp";CDWf(!3QQ(!&33T#Xa3!fQD7C"f" @qP)@#>fPUf`"9SDU%f2TR8A3D1AQX3!fSD6C"f@$`t "f P f0"7SDT%fBe`%UP#X$h%fS5D4S" fR )"Upb:'R3E$UcF"1dPC&&6%5"hFUC$3%Ri,yp<#=Ub6 %B3DUd6bEU2470"Aa(QDQ$fSE4S"apf0!H #=U0c3 %"3Cee2V&$8``Da2Q0$41Va#8fQV43"Qpf"## )A #=DR5fpA"1TQ20T4E6TdTSR3eb#1BQ3dTFCB2bE3!i,09p+2"DU7f12d$8$3A!HUA"d44A1hE6#0ebhF"1pfB#tpN"DY8fp1BUb!Be(!$Da%#41aT!2hU31pfR0*#;D\:f`1"13DaUdV8"1#TA66"c4ER4CfUEF3#j(U@0pЛ/ .*9"0DUf1"9DQ%f166V%D2"1fUDڝ=$M* #8"0DUfPA"9T!C1$V4"1`fVD}ޝ 0{Pp­.^""0DUf @A"9#fAeT@8Ee%2"A@ fYDPݡݑ6m~-9"1DUf A"9T%2c4(V4"A f\DP}޽$Ps#8" 1DUfQ"8DQ%f2d$fRD1"Q fPD_M]=- P@ݧ~""@1DUfPa"7DSf2V$a&UA43!rЈP`ULԕ*ݡp smڪ.-9"`1DUfa"5#DTf1e5fQD4#"afPD\ݡ.wݧ*}""p1 DUfa"43DT!CHH#VD43"afPDY:ݡ,wmڪҭ#8"1!DUfa"2CDTF@F$VD4C"afQDUYݒr|m)ڝ""1"DUf0a"1CDR%f!A5a&UB3$PhUMڪڽ] (wwݦ:խ*8"1"DUfPhQ"1CUdhC!!#fQ54Caxf@Qm޽- pr'|--ڪJ"p"1#DUfPhABQ5RDecfUAcDQ!(aUb0AXf`QժM]m rpwݤ꭭"p"2$DUf`X!2dEf!eB5hF1Th4"!HfpQŭݠݡ $wݤݡ0"`" 2&DUfpH2$(cUbUfH2B#DVefQ&54HfpQݡݠ 1#wwݢݡ*ݡ$5"@2&DUfp81cD1SDU!aD5cdE38fQ݀.0r||ݦݡݡ#4"`2'DpUfp8"2SDSfPaE43&"cUj ޭM- rWݡݡݡݲ"@"2(DPUfp8"6DQaBV4#"8fpQŭpݡ rr||*ݢݡݣݡݡݘ#2"2)D@Uf`8"7&5!5"8f`QPݒ{r|̡ݡݥݡݢݢ#2"2*D@Uf`8a"6TV4"a8f`Qݠݡ yr'|-]-=ލI""2+D UfPHQ"5DQfA$#RpdUkMm=}M-===L!wǪ}-=ڭm+0"2,DUf@H1"3D"$6E$#BdUݡ r|*ݡݢݡݧ7""3-DTf0H!"1#DQ5fQD1"Hf@QŦݡ;!w©Jݡݩ@M"" 3/DTf X2TUhU1#Hf Qիݰݡ!Ǘ}]]޽#,"@30DTfXU1""1ReUݢr =m=M;""`31DTfh2#Tf1fQ4#hfQիݡ ` *ݤ#("31DTfx"1DSA3!"gUm} ލ--- @ :`ݾ#'"33DTfЀx"3T1V$2h U-mލ] |0ݡݐ3"p"34DpT f!"C5"!fP妭ݢ' P:݀P '"35D`T f!"3$a4"!fP.}P) ޝ=Mm"p"36D@T fA"1TP4"AfP妭ݨ#Mѝލ-m-"p"48D0T fpQ2#f4QfpP --]]-! -=--m.'" 49DT f`aC%X4Qf`Pݡݢ:)'"@4:DTf@a%QQfPP]}ޭ=]ލ)ޭMM}m;"p"`4;DSf0Q2TE3Qf Pݢ*qڪ-}Mލޭ-}#)"p4=DSf1"1#&6#"1fP꭭ Й*ݮ#)"4>DSf!"2T(E3!"`U`mm-MmލMޝݢI""4?DSf"2DQXVD1"f^m-=mm=}ޭ꭭q q)}ލ=ޭm$+"4ADpSf!CX&db&5`Uݨݡ *ݧD!-"4CDPSf!CaC!hX4`U`ݡݫ*yp")ڭM}m]J#."5DD@Sf"2DbbD2"f[ =ښ)!wpڍ-ލM}ڪA#0" 5ED Sf"2TVV4"!fZݢݪ* r'̱;9)ڝޭ Y#2"@5FDSfA"1$5#"1fXݦݡ*A)=mD!4"P5HDRfQ2TE#0lU ] =-=]ڪ@MJ#7"p5JDRfaCAb$0kvU ڪ=- ڪ)0)ڍ ڪ;"p"5KDRfaBFafVݡݢ@ݬJ# ]= ڪR3#6"5LDRfQ2#E3!PhfU `ѪѪ-=M9 ) ڪC3%6"5NDRfhA"1#6#"AxfUZݡJ$0*U1s"P"5OD`RfX1"2TE3!2dVU@`ܪ ڪ9 )ڽ-ڪ4"P"6QD@Rf8"4DcD1"!8fT:*ݡZ$*ݢݦݢݡ*4"@" 6RD0Rf("5TfQV4"8fSfQتժѪ) ڪE3-4"@6SDRf"54"fS fQ꭭JݨݡJ$*ݡݡj9"@"P6UDRf"1f1DSdCb!VD4#a6U`eEJݡz #3!3!3!3!3!3!3!3!3!3!#)ժڪC3 3"p6WDQf"B%c6!3$(fQ1E#h&U@aU)ܪҪڪڪiGT3ADI֪ڪѪѪ4"0"6XDQf22DR&aFdfERD34h&U`aiߪѪ9BD3A jA3@ 2"6YDQf1"1U1DSFC16UA$3b5"1fS3YتiB3B9ڪ5" "6\DQf"V%V%"fSfQDyIPD1"Iު)5""6]DpQf"E$(E"(fRDQ%9iP4$$ !5""7^D`Qf(!"3DaX4"8fRDU4JY4&YI4 "" 7`D@QfH1"1#5"1HfSDXY9)IP4($5 ""@7aD QfXA"1TS3!Pf6UA Y4*y4 ""P7cDQfxQDa`4PgFUAԒS3BɑD1""p7eDPfQCFQfTD]9D1/D! 9D1""7fDPf12%5AfUDPTT42D0D2""7gDPf!"15"!fVD0h""7iDPf"2D!H"fWD0i""7jDPf!Ca#f!4nvU A 3&."8lDPf Cc"aC3nUA 3&-" 8nDpPf"BA"fYDp0m""@8oD`P f"14"!fZ DP0o""`8pDPP f12541f[ D@0q""8qD@P fQ V jU@3 ',"8sD PfACCAf]D 0s""8tDPf!24!xf_D0t""8uDPfx"BQ"xf_D0v""9vD_fh"AH#peU@@3p'+"9xD^f H3AX3!peU @3p'+"09yD]f HaEEcU@3'+"P9zD\f@82T48f@PD<z""p9{D\fP("Be4"8f@PD;{""9|D[fP(!"2R&2PaUL3'*"9}DZfP(A"BA#"@aUK3'*"9~DYf`(a"1e5"Qf`PD9~""9~DYf`q2#6#qf`PD9~"":DXuf`q2TS4fPPuD8""0:DXef@(#rSDRfA4&raUF3')"P:DWUf ("AHD&QaDdHf PUD8""p:DWEf8!2ea!H5a5!8f^ED7"":DV5fHA2D11D1AHfYED6"":DV5fhQRT=QVQhfU5D6"":DV%fh1"1D%eH#pe6UBd3((";DVfX'23Be1$U!6dU1#"hfQ%D5"" ;DVX!"15T(fQ5(c5U3HfQ44"1XVD6""@;DU23A3b3!"3D$Tf1ddEhD2C"25TS#%hUAT3(("`;DU"@'2!$3!aQ#0$QD5"";DUxqB$@#F$qxVD5"";DUfQ2Da(c3ffV4iET3'(";~DT%f!2fBX1fB6!fTD5~"";}DUf (BH3B4XD1##bUBT3'(!3GTUb"!RFeU!"2fPP%D4}"$3GDUc6TF#hUCD3'((3GTUc $C6AfPPED4{"-3GTUd ##0hUED3'( 3GTUf@!#@aUFD3')P 3`GTUgP!##PaUGT3`') 3PGTUh`QS`bUHT3P') 3@GTUjP268f_D5t" !3 GdUjֈ0!4Hf]D5s"p!3GdUl BfULd3'*!3FdUn!4gUNd3&*"3FdUo!D!hUOd3&*@"3FdU`vQfVD7l""3FtU0`V""gVU0@t3&+"3FU@`F1%fFU@@t3&+ #3pFU``&!!HfSD8g"p#3PFU`0! 0cU@3P&,#30FU`@@bU@30&,$3FU`@c#V D:a"`$3EU`"Q$hU@3&-syslinux-legacy-3.63+dfsg/sample/c32entry.S0000664000175000017500000000422410777447273017274 0ustar evanevan# ----------------------------------------------------------------------- # # Copyright 2003-2008 H. Peter Anvin - All Rights Reserved # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom # the Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall # be included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # ----------------------------------------------------------------------- # COM32 start up code - must be linked first in the binary .section ".text","ax" .globl _start _start: # This first instruction acts as COM32 magic number movl $0x21cd4cff,%eax # Upwards string operations cld # Zero the .bss segment xorl %eax,%eax movl $__bss_start,%edi # Symbol provided by linker movl $_end+3,%ecx # Symbol provided by linker subl %edi,%ecx shrl $2,%ecx rep ; stosl # Copy COM32 invocation parameters leal 4(%esp),%esi # Argument list movl $__com32,%edi movl $6,%ecx movl %esp,-4(%edi) # Save the initial stack ptr cmpl (%esi),%ecx jbe 1f movl (%esi),%ecx 1: rep ; movsl # Run program; we call this __start rather than main since we # did not parse the command line or anything like that. jmp __start .section ".bss","aw" .globl __entry_esp __entry_esp: .space 4 .globl __com32 __com32: .space 4*6 syslinux-legacy-3.63+dfsg/sample/syslinux_splash.jpg0000664000175000017500000015575310777447273021467 0ustar evanevanJFIFExifMM*C  !"$"$C" M !1A"Qaq2#BR3b$Cr %5T&4Scs4!1AQ"a2q#3B$ ? CR"cVV޽"i6ocҼBI≛G߀Ef2l8ܩq.%GX`"mKtsŁ3Sr\ w"X.pd2$*hu&K =sV#Ey68g Js\z@Д@z׵ x$*2qz\f`↝j$o /#"s_)rsִdnPGF=h85⼧NDc'NXF>BvJ9dB k `Q[P0I\ҥhWfs5(۸ц8HF1EKzI> . J"dbr)m{*=w09`3BNz V ?1 Ztp3#T9l_,D=h'?!$㑞8-@BqZt !Ͻ5);s -6*@H$GzUzۧڬGG8W=Mf感9$#hVE9緽kcӳ p:~N n+Fp@aڳd"y\u.A`OzT&2[k}Ӭt`J_q[(^3Mޏ<)}s;<8bX^O+HgjV,mZ׸ܱQmUc0'lŏdCylʀM +֫Y g9JiTFyOo9. Pp3T1+g⣖I&OYI6Xؤhti$)!9 L6M.R9S0NxJ`+2dec&R=ilblyO=7 Q^!'?1;WVt3p)chk :VV=c$⦕Odː<`RH,Azh@)a3] ^J!:TO>TZ2.WbbšSR $(Ej玵 @C:fhMJ=>-b Ƿӥb" 3=zK9Yn3k>p*,-blvpHWR!<ӮYƼCjL-cJr3UFNjegw?erOS͕ % v9wWuz Clb!-YFktxƊMm. f%<9E`Ha.ԓ0AO.}Ʀ# ܽ2J\LTe8a"*OZc% lڴ#)8l & @ȩ2X2ڱQ}4*ſh,)#KEhb4/`bx#BZNh%R3<8籦[mxU)E>;Wn9cR'L8,AܦNr=(F }Y 18Ek Ǩe/w~@&'JmQcY#Zo$Yb4m#BG>\4NLO|#lL@W 'm3#DPn#jt{CJO0^a V~!й70$0;7N+m']0qږȐ5`CZzFXPNآYR!OY^M sVhEpjG$*E #V3Yx^5V*ފw,{vsDb$Mdʑ٠R?֘hr<7 ߭T!rH^ ex]A{? r<>ٓQHOD{J|tY|,C&Y;TŎc>*;.1R++X~z-"I/lzRqW&rŸ@^ANi"e~Jn8$y㩥mk'4.FRF:Z5ax+߽Rqi[bT{Vc,<܃Gz,rj[D-n0M(9D+|V+q ${ŞJ)= ِK ]hWvg$$F!8t?ޗtm[ 2s@nH8@֢LUq @0kah` n"'aOJ*IHxCTȖ}>]>Qv gR[ڇUЕ@WU牿#/'7xg@A>LUf9犯 8;f^K JAan3޼Lm/RNGcL*" 7vTt$E֭z֓oQЏ;v$\g+|urFjΞb(ln{QWdV.Y=^h׀Oz@.GRaq Og~ ǞhS8Wl x5c SDDL$,pUFNrO,D{d.*2IE =EKkp21D[ۙRGdcYfBs'{q#zٙ8J`y:U }7)9Ew; {Ҕ_o}.zP:I;qU+;Xi'd[g ;BsַLgju[!zgj@ղ-աo0"@ަ*6s8#jg3E0@8T(8_|dTR\i PVk{O.69GJ%h 1S b Mt2hF hڋM`'?ik]Il jiZVBT|W+&#qà~C#UR/ q*2[pxLnⵒg59ցgGm#j&sbUFlsڶw1Г˃Td^Yj$Y3y&^rzR4>ELg9C69B !o9ssӚ'm"sVSOlK։FOOޞipqk`.Y Buxc >08L`l_jYi|J.8=NƒLB"E :EF sާ{4>*Y.;D:~Giռ0OqF^c :aPh͹e1NaYtTn_|{TlLeF WhQw)ƥjC`J\c昲ڰR~k[A (mHn~zPnELb{6.Ea4?1 ӚOr0xge!\ |һ)iB[!E'Pdl tZf~@m.NhȥmQ8fr{PUj Xo+ *Dy[58桢lq seXyHF:b( c&Vú 2H"w)Abȯ[A05T|p;TѦN91o/3q(%Csǵ%E2xY|Y#2d ~O:Bp@=pzW_࢐Ó%9IqqQ3U;  z cdvpEY-l1q5G$tdBw6j*v$/H<㊂?ːSib`ULbkBsOBI-ivڢ.2L!+4*쨒78mG8v8ssk ^gI2X!'kql#h[ E_QvW;v]L.G wiN|T9<֦vrzt_1ޤFrIt34RwCh#)Bw%pXpMYtr ]99~j,U卵@6l;r=uK V-̏$wFFNΊthV=^(b1;R]st; @A=>zWW fg&3qXЫFzח<_&̱-HHhV^G&887znh9n}[?k_KlP~ev!ǯ/p%wYQ˖Su'ɨK$H'"a nGdZ1q| 9hY,}44 ayޓK2HP`lkyry`q$!&64R81D$~412i `Vq1n์y?,ֲl 2T `oŷlwBtq"95tpȸ u0Yy`9v+X4sއv{Ӎ>%)0E-d\1i 90JE8*q5h|7\dXYpx1V\>(P 1gN.RRH{R۫u=ޙ]KC*q@nWC8vϵ 3?&ɧKmriVl!dpZDT+ (`[*q5A}出+NǨxwCf( OEv3 &^`Y9ONT9[ Lp1ojI$W;AqZوӊ^&lTmHeoW\R#`eƤt+v*}@_IJj(,s}xqs}%lW v3*i[#%To_0IX@E|6x29ȹ`~S\s1mћc䌂:$=8sֽooǔr5~ih<7[(,1(/|ULZFvHķV$moԬ,!E+G IPK6:Ҩz2*#0V޲Ͽ:^nCKCڐ]E$SQ&{}Hݫi! yc"VkEq { RTՎHd|1 *TQ""x Gpphfx16x'yBh%$aԊ +,šV*p==Mg3$zj,q?UwRS1੔5ﰱF#Mn,{nf$QMU\dW50U o͊]JrUojzCqE,[H=hMλoѳ*3V` Un' ziI\gUP}餬Oh"hr{pJ}C*:桊B ]Fv rDNǭ !ˍi'4.yX ':@re%.RT#,y#ڧKFesݫhl)?܋?{Ey76b1| [0>{yb瞧hm2{~У'!,8)K~~\=)s&;O^ q%F'=ZB~ry`,=sjb8Ҥ9y: Wc'UFlVPY޷F F4aROnjq)CĪK>ݜβH'o|fLGHJ'969D S5\OS~+X10p=Ӌr2USqa[GW yĵGw(Qr#s'9dUkм)޷ߕ+Y@긭F#,~+a@Fڧ'48g1L ;OA\Lb7`R<hȌa@!S+3Cn)<3g&hW$1\ݽqK;]Qⓒ`Ӛ]X;676ۜߊ\Ӯ O$Rie~ۯC$t1ɑh\r:N:Qw[[/1nQJ8=jͪCv{jIrr6{=`DWvюu,1'^C6{w4cƓ$Q$gRf)n=4.'$cHcN VɌ\Krѱf*VՔzE=6Rvef'8XRur#ak"2nNS&| m¢X$MV?ssժ+D㞃b<5,(X8R',ln4ΡvcDSڧo@01fܥqXVOelIL̮97lR}NiQFO c}tb;acޡI&Lr;t?vmRE6jFzT&#KԴ\>Iܕ7 )Pp6ѩ4teNHsHbހ.)kUA({G6H}- ,M1 b@4"Ab9bmݹlKmydoOj9N#iB9p3{dFӑږ4 ,7i cbLcRCzv^*ȾUSU$jH'Q2*zBRKIlR <)l%ISnT˰t W[?w~ѷcAQbO5T\6GQWDgu qU_iFKz ^[xgqzߦhԿql[]| *A=Nsw q=^"s.)zg"+Rb}_i?cXA5ö@=* 9 Cܒ<sMYOR'G 1K"Ղ.((TRh~Džfmܠ I6\cW*/-Ge.s"TSô(1ڀ3ySePR%G5T,vFڪZI|UY b;|j1I(ߑ% n'9[.0)෽'")lɦ`Ih[\zG#^ybA^BbxkBAڧsVׂIr ITW<"7?r)|#9my$+MT,vRDƈ 6cb~Dc>ixt3`td2ҭG,պJX6Yup `ZflsFab5=+ sȭƙqǽ OZMJ;έ$$.;$ϩz# Uwh: FsL`t3"%OXOIV onocr v[2愘fM}x3EgWϽ? c8AKT=V录g%x#"-ʹo&xѷ'he& " ?\UBVgQ0۷SB`[=i5q[! #vzCC3ҝ2cQN߸ NhWNPIzIlUPqҮ>qn/,XYT;;zGΎ7o#?x(z ##i =ϨFDeda R1_9F[xfƥ%e Ec g?ް=<_/5SU$2<$*|qޖ8QTxԚ&F~ ,펔+]|V[[ Ue^_z3҈ԗzNH!;sAu (bE_r$ћۻⅆ,@ێHi S-m(ME2ro`&"2Hl:"uRV RXCe 9SźC0 P8^E+2xwlSMOX0G[X\IڭYc4-2*h Hn{V# d7RM̌8$Q sm$ߵy-?3ʹ̘RFyB53PQ<|te ^:(|ҲޝjpJ5H2¨穡lS.<)]IJGx dC,m`EqұcQ1BB;UER^A;{O̊Owv!U O ST]K7}e 8jcc5z*S3[(gۤi${s((Tp:R,@٣n.;WIlg!RUY+K#/rKH*h+E]*JzQV#HkFxJ9 90(mLs[=|\_8(&m@$v ٨.TFY:~M*ÐL<+: X9\79Sn$T&)”wQƹ XRW=z՗z֬'2qRB= ?9D; ;?xq:%O⠸JJz/Q֐rFҤ >9<Df$sڊI ߥ(s|Q0) x8(c7*HcI?f\N3G~n?vA\r45',oU;G,"6|d+c4v0̻VxIP؆uIpd@8VѣyE|Ǭ\"ZE2OіG3Jv8Io ǔםsO,=k+kWoLZH$,u8QRqQKAr5f1MI^i!EO(hebbz|Tsʀ T1/(f? *@itrpk2>[$T̒lŅQ1!{J));O\Q4zr}Evg5hd[Cw&{Ul <2'jlw^3R--աhe!`OVukI,o$N mھTe}[j z2 䊫ӚftUhڄ/ I=9?/NJ88͌I5v2&:gOˏ%4crsÁ1ޔmxUzKJrKgY PM*cZ-: iڅ%L#l*0xCIhrn~*{;1;QN]Y94xZ +)ԧ! Q.۫{NqZղsvZ'.%"t;A?҃ԭ%{syތGۆ;C"&ʳWKjѶJH(djשiQ7`7#" h{OGN}Vd12cz{/~*dd*-ls՚YBZaR ddؿWEґGna'Kx=x3U 0#nHkOf3,}Dn+Fr7rGVkČYA;>ɤg v-WD!BP2r{R)1 =ԁdukdާv:)9@OcEs=G=8 Bč8㌚)Gfdvﴜ޵uU3Dz[X\8F#HqB#A;Љ/ \LbG۰T׾i:Kz&8ؠ9Nd7FH.8` {e}Φ̖6L2U$z4Da6JHZ};ׄ^wB8Axsj(Y&b./|^dǹe.JQvol~TE,jn$A8nP*^ 8Cvoy,3z1䊴xY4 -cU9d?o0TBpI^crG5#4O [{Uܤ`nIZ&$f sWFI H eێ*sK/;8p&k$R4rTR]V_6+ri(\F=T8G-ץ_u<*$m,I'Rf,`Qm:A,Qd{֮uMY%%*+Wkh[ sSC0zQoxf\ZYiaƔe߼u @ 淒Wqu).*+=K#ׂ8pSOقebM!|Gnb\U^ye9sjJd ۲jX.by@CJY F S0:9ꮄߑ]v"8D#6$5%uZiRy==ޏdfI/iK=ITFwj5.)|W8ĝp#ӒpR;w(8G}3*yf/oipgچ'U3.^i[+1gOn]s5fg/:9Z~F#?Ll˅>s϶hفxKOaJa\g=MAlggnrqڳ|09'YҭZd}I.'=\DسUrA!Amg7pHOvpzHXa=ET juы;ANnTxZ. „omq}FX.y#ZU{^q`|_WxƔR7 I,3:1 Pox*ۃg$U䭖TA]9lž H2}CDO#:b!NȐlrI7n#$w 1W õZT/i]oL 38PőM 8 ŜcV:p6ԑCmQ )2WZ}.U@=HY,C{UYkp@Ϲ&y[0 OOom:"π i`8,҈yE4X!꣠3ߥ29;j;:Sq~ 8<Qh--`ͼ?^*+ ;sD‡`I50{:H-NpFAbp"֋HPj,Kt @wZ3+~b}7 aH 444-Rc}5Λ qM%nn% O,}RtXF996]7j/ENqd^K;u.͎RFĄ|TdKF9^wlJ R &ޅyZMߥfH+Ol#)K=X+M6@)h{ԑihxHڕœt7Ӥo3>ݶS9휁#ڋ2&7@B+no <Ւk#=ꋥc`8NsVUюr8DmٲfUCS;bA1{Q*TSp3RyjZeBgi?n4Fp?鼒GzD,U.zڭ:c/`ȂP,;0zg*eD)@GkYͽHzQ(%'ͤgAqj՜GaVM@͹ie;FhR 'ƮN:PȊ;ItuxXzRB+&71[. 26WMԦ˜Qޝ)"ݒu, TWp$:A[zC R\Eu|Kh.;p֠m TPh_C¥>L/$)lfBϠcX_qb80<}ջ!6lym*ԡʼnoz8.a:d}bAF$+7PNc;КKUQ#m~揼;c ~]PvmBqHszر9Qzlcd9,'⋕g>Ժq\=xbn3oCקD`.nfc#X܊J#m2 vY\maA7O>cثJH=zһЎ2R:bWr6߽ q6Fsۚ%yLJjvxe$5u3d*@QhązQVKpmHǵjEF[Zu:pN:⪳Z$.vLY!5847ERuqPMHqrBVl瑌TI:: <4  =EkD3/"2ѴyԶ-s}@u[; z.tn=UuL_S}N+ѩ|ץ?m SKBXOZ_5.*KiN횱 tth"i$Q.qČ8.-ӡy,6z*җ9TWHt i Ԏap0#$*O:ώy>c~~kF-8SCI+qҷ)e**<^WT˕`784iX}ۂ ,e',tcѹ=hVQ@Q6t\>Wh1rq0UGC1ȭN)lql(FjէȟS!I-nL]K=,qfeEtܸ֙h!@ ]]RU$`C#,q09>ǙGF{vO,M)by{UFqW?x;sCFOC@<#\9T~DPXۓѩ)%5SԚcℷY1 tL u<,rqIm=H7@fw;TG4]$ڄQ o,}yg, lprzbX~z i$?RFލa({eTسݪ+RjqV 6Hy41s( PDY3ǵ<;]ڬwL6>Ԗ{Y!Qmފ[C v+ެPOO#کZ,E7P@+i'dUlʋ Ę &l.QJ|1s=-2nfB~-CZQ~@ ܦ풨n:yݹ#k/oքKLtێhH`G':ϖHZz5h bӊQkUE)iѤh9F-)lj~>ǿcS6F斣r,xjf*7vZ*l`0p #6[HmI sDhՌQ[nq!8'a*-JdflWq\큚VpXkҮ &v"" qޠ1ژ\ Kn6t ~Fxޘ"kfDEaQ3NQXn[&'ik"{xn^9vHbuqՖXҲVO6XW,{Ճ,g~NBڢ'M@=qp=yB}ݗxrRեH-qESAyZs0T|ӏJ>GyHN~ǼtkŨ4-yXe!9=MqzhrOqeaA䚊OaҊm cPy5KV\9>@=:U?\S96#C VAqsU/VHǴtxϖV^5mN)?ގy&:Sq*OިvfǏujp !@S[cvbn=j;L0<3Ա"$$i28WoڇmH?c@, ފ+՛tM#Ti&B*nyzl?Uʥ>iXFіZL(vXku_P<{x$AdPZRߠǿ 8)e* (4WX<qLoޣ*{Qİ.HOڶ Xew*w6]8eЕP2:S$޵[T08cQN zqHelG=o]&2^,exW v`qJv3rz0O8= !LL q -KIx&s}_DGj#.@OcGG W)r*㸭U'M}Y%hXKsqC8 Vc;5@$ X2(lp{qQYsHdNᙁڦMqQ#9xO7,1ʾ^ TmnO&P#,X"vVู!#Urm6d,hSdMd%cpxEݵvޝJ>D7EiV,TcFy}sxIZ5*J_ץ.PR$Hڞ~t dcU|،5I}]/g$}ꋨ=IF)H{*xbym+in_#3l͌! :q !\sCQnU$OBi);lv% p2y^h8H6J)7ƃc#OZVq[]]K4{d9=Hjut_x)uԚV! )抹Ӱzނj~f MS􆥩i`T\>p=kupc$)_Ѧ[k<60:`1mg\A)# r^<%Iqr`}"h\+x;vMYFIX]`o2S[@$GQY˴ѷϳAI>F7*9~ M$0,{Edfiz[PwT8I)IrԬAl?3nIaʎ T3TJ-מeZ#CʎڂtV R|\a}5Z/CU[V0ԌUT$.py="rr%bh{JHq3ދ]Uu$JOor#DI$34$g*!SStR]*c5ǘsOsLZyQv~KU79 hN j7zԲG,3\X$АhV;(sMn&bœҔp;qP>IUTljXUp>k$`'Arcة'D-Cq C"n5uf[ )]#]]1V 1TS8=EՊkd|R5xȄ w9d[%$(;7ZUt%R8 ʁ};M*WQ.2̴6҆Z&2c4dW{UT T & H#Y<YrڗxQƤ񓱜8&֍' s2i(ʢ#:QZG$xs#py9E@ #{1!#}%g=\v03fBn9̛Z3UFI)RI#>pB=];i-`qS+&Uz\sv%Dޤgژ^4Hb1Nr?\԰#\圓Вң&Rb]_K3F^VڪڥQIҫHfm@ao7~*@N)c=R,cۭIix>Ui/Cvf}Q|/\k]9s`vQv"`-5'>$u4Kg]+6ݾw"09FN1;47U1L{T)U++b@`*ϣKcG`zA(߃1ϧC,dT *VrxUs/YG'lcUtS9(%ϧܤi錊䊡Ktq5g]36уTW{)s3X4%掕lOUn<(8Tsg%hE[8][ {QbNKNR=fNީeG:B7N}#j gV(Zu܁qzU~lzT-gȟU`v3t&hjǤ Ͻ>hSLgrњ" (i=.:_A+dJqnCwڦ(|w^1TḞd,O~Է6Vxe6\s3H?zkw^:s׌5%\~=G+l[۰<F&>- Y{\)#A5 M.CdzĪ4&"n8-a=ꓭ]7)zzmsm>1֬Qi66>$qEYc?Z:Wtf Ww㡡U>sCa^ʑ<ԷS(/Ɖ Pℽ *sPߑH>[q}iu TXs@ItP\G)$_ꈔ"Se\T~~Br4[ԃ qb;=/YenO'g@o #g{`Gyr r6#ށvBnAcƘDfz}۸4w'RX)8$Tŋ8wCu# HP}B0OޕrɎ[2u۸lWᕱ͖}+EI#PF33`Ny ށOSu=<%AJv=9ǵtjW4MFgqE$/ VcGt=ɀ,B{TgʨXHs֌"2f>9(h/5qY6;]wʣ cbJ8"o(E8.ՇPxM QfΧg70H@ TռӵZ&RrV2y1דxZUWq@':ϧL9pBRxʑ(u 8T{WX_i}/%lrs{F]86V Nk51JG$t⷏kH94+ɻ֗ʊOSTXڡcIjzKؒs i$w=})M?ū+|RY,SNi9ɪqPJHy"{Vz-XAs+ך}O9،ZGsoC#sֳIjY6)haۚgg"Y3SM07=jX iz淛P &{Xx'szjV.#Jלu5@C%y"e|(qX"$SnHe@M:xRQCV솚meKP+@Yf6zviGc<_AGdFW$g]$aZ0sA_HOO7 KA -Qˋfu;pGIvbۖǦr/cx;EEM\a1O5KC4ozk4GA!rYH=pHA &$r<;U-U*R\ww j)v*EOU5ɅI%>⠎e }]¨-ڂM/$cݽHpSyerj`[tf2 QTϫ5Z:v =Y1TM&,q6Ad(, 2InAcpɵ^iI5Kf|z+Fخg8Y2c-zs #ވhȑ]9+i^1?'%e?+cNm)kkC!}UprWV\~Ot!z- QԩX4Y%Ԑ k$24zEޱrLN9zyف(6,a{U(ޠd ō*$؛3қ[H yX 2y 6lEaֵg !JNȥlwjKPsT0Iq%msյ;@2i>eQ-VZjPɴSLַt##?U:0;ASGYU)=)o|6tm8e((fNqZ9} dMY/0 w506 |VDMK\s'<QpǾ(o +)P( ̬3UA- 7ZۊhjɌLD N>FĂA# EOp1Z4[$xb@W%P{~Պ;h#$&G޶CP[9&rx2(W*?ZK6ӪwrGj{ .nX= +UuoJT +Cr)p19ȪV1NQ$%F"YCI$ .~:WxN@w4QȘ"c >?35Hk,л*Fze8jwrs5< ]yV現1]7pgU^&tu[gq}5]| u6"ux_DXrF+kJXy\4 BG=RH$[uvٳ7î%/r1h٤fqzJ=9cM%mX, 9(I1fO&Ý7/*yge6^P!y"Sۘ䁑U]Rw,?)5t蜲,j@E 8#9#gBTҸ U/VTQrmS_8ۧj7:{Ur1 %l^lڔfbĎxpbC=)RK0L 3IJd8RsO5iL͆ LlrrOk^5 (߹zLt&8E$H|o[隋˦Ɉ6jQcٛ{Y Eqws9&irrhhx#[|]'@JjmbIɮW^Cvޡzںi6z3\0=^gq[[Ϗ&3d``S-6FI^XZ=M% kkfsG^wbbEdҋ{2/Jy]`'$О*{I",L㜎Gw7WHXVe_AI!*"1T?TktEh6nI#GһȘi4ӋIc>IɔPXĀSOLS+`6d= ZqpnglnW8<&)r^r쏜4ȕ IL>@hRT3c* H?ڷHXC3VjvREvD)o/ЗN &X%eA\}d-#nԵKtc. &A`gW/&8`?:aQ*:v MBnyfmČ""0'iycZzP96+ԑ!'<2zkYT:{P wc{Fb@~'n?5īCMO~̙FX #5A]0Oj;<[)r*+mȋIuOD\V<uf!d`ќYIS&%qhb|[XͰjsjAyLr6gޫ!c;7HbS\Y&LMs̪Oʌ[${to'<3X28@q9dɻ^齱.(H۞m[vCg" TF8' %QJ/1GZ&f%QB@T^`TQʯh(ABvYw,|q!by =)/BTYbH`ŏl`#SOAO-..C [Nй'B[p4wdyҬzdUuf"l6j5eY'kYO^)ȘaLҮLLG5[=+,U>疌gSK&2Au~*9Q?GENL%P#Q쥼r{ }d>s"g`I?vg }/O<EI*%+dZeޕGh.eW`˕Jw`~8>U-eu"vc>Z~GV6+\C T =Oڹok{co ʫxuo_v(ᯨ/R-RŽDG*Kv<_0V+}c30#5WAfW]Ш=ǧ|r'PHAtުH\*;POm}y"y,/K {|SKTYmȮi}951~Nj23M9BUE3j3H:&MLg mLdc5 aPIdG+8ڣv "xe>{6Ee}*Jg9_xV>|Ɗ2ŗ!x(8ǰeP 济A" V:]]9nyً/HqqN;I*ܑ{V&,~r%"y"Ki|e,2740lzW,\d⛖-%ٖU8[S+K瀾VO>{Rr:֎'Z<2}V÷QcHnj{ jV;G4T|XsQ;qGORB~ bIF1P9=O3G"n?JBoKnY\}q9lt_Bz|d%H* n{ڵ%kC*^/%2iֳ- F>U>iebWUW9 8#Ei7ǑTsMIyrA 2n~5ci#1YIJ[ U+%A,2:V2xc<{H;QHP}4V<  ($<'k<WfI}h%cۯ1%{f,s5+F*#2ElV' eUheK =Vtg0hm(IWt)$y'4̌yj4)0X U"oݕl{t捂FN9o?=Xuo,Wd L6JO%Ȥ ڞۨ|g+ջM+d[H@䝧*r%ǁi:LM=.,)i"mB+9-&O=szP+S?[RҦHn4 'lVvH (~W'5Q]tYݥ {Q$":9ɢ좎mG(I;K?{w2 ?{7G hRM2EvHוLOɣĚxH䖰L'P\Ra޷)<~">FEO)GDW '01FT@#W=gPD(*H7#q$\I8nϨᓊ\\ԶQ<_y̛@N8Y#U;-MJbj}pݱ.w[r2sC@"E Sspp8^"BJ͑,siqzzeNsȦ7vC6Qt;]Bg8<4emˆPY2acK$)I6i4ʫ8r 1aއ(,C~o6jd=k9V80NYz7S6SoH..˂6=|Q/_SsTҵdk;`eK_5aqQV5~\yw|)>KL[\-PY=O?7wߨu7]/MΡk8H*$h4[i.ۡH[ڵ6,89ޅjhq#W͞j O/VRŎ="r\"Wn@8P: R˨7HDA$FeŴ+X~<k2<*X_5ϠӦΫ^N |aQռ-os6D Pɘʞ;}֜47kk @jEI% iӽzǼ\L9,kػo$jy-1DH4F6b$&1RA9-Pg(`͆ 3P]0>bDRJS[S S'^:QkhMISo#{mGAӀGZ¢cV4<3j2c<ޠ*G8)Tl_(޼c[(chc.#-ª`s q&e h+r{֫tVZU9w&78Qvϵk+d wO[YH2:`kֹkv0$ =-UC񆯤Z]Eiq̉U6Z,a r[b BkRVEp0>+e3??dKl%[sR8l27ɞU>LLۉmb fp1T4e \Fʍ6v֗}6[9RDM~;7PF_|w'25N$Ad'%mnms"F@J[o+>i"t,N, *OVg?8OHت#߭iX{.1Nr0@5 mC+۲ ®\֐겈)ΈZ -Ƿm1\c>4`{sJqm`CҦ*Δ ‚({VivIDEh[i:mZj<#au 0XMy+InF=IUzqQ&^_`yInsC]F0 1G0j f{R hK BG4 9`-,7k6CBQؚM=DnYذ-)[ș-Oz0c<Qy#t̄dֱjwV6]sc N09R%+ϫqڤIH隍;OG۰6J@!Uƚfg @d$Un,IuݲMs_Ep;V`S#ڀYG)bQ!=})C ZWUm~'XA rQ^>ҭ6ۺ?_`՛kN&bՇJgxL-1"}>g8mMn<8_Koc=b;r3+շ7rzD~ozkWk};r\[/BP}˫v!86$TF2TkeH\qA0ޖ߽k܉ e29|Sa'7f./$FYIke)>hxq 9ӴtE<ֺ[.=̲&FY8?c>u}G,/:{G5[g (!8q\8S^V=Č$z\F`~A5 FO*MIF t~S#>zgIQyŨhR[p1ET 7%XSm9sׯQɶlAuT@|wFy޷A cjzxA5h`0S]\*`1ڢ EpNM6)E# qLlq*B{z[yh{׵)x_''SFA|qӮfnZ Vu4IFX%`Ml 5% NOj?Q;HVB[`LKpA'`2>cYHL%OaؚcOڃ#93*)^VMݦ$gvp "g.=i)i_nIKYr2N),'9#)-B3ڧ\eVB -ٵS2xQM!(wICHj69Kfqv[Tօ@zNI8#60dbpj;VGiEw/Y#XؖQO6sG-⠕8M*J&O,kQ(+ڈxwc,@;xC!'#%Ls$\OZxe C;eUiz'{Bc-qCܞ/)^kgĩ 1kdʓ)sX^^$M}o -Q5UEɯtikW>c`ҿN}?< k" og=an_Swo-̖.C*N.^ʜ6<.O;:/X&XuI>ڮ{ІyOzmӯZ!vC$R80:]g't ʨ?4mY(Td{zYp MLbVDc;~1OkʆC\$a r(W!6BG@ނ9޶Y TlEK`$|<b+IJN(( x^y:dRR3bF%<rx-lrE}Ԯq<ǏKn[7H޶$K ;A''(=SċjRKa6&pL& rEXrCFA\}13ߊ F?z8wWroв0nZ( sQx7v=?jE [ƃ:}RzQq]&z=ӋFo?Ԍ匁hg8&^U24#n\IZ*250lQ_goD REpz<z&Ż9% `=j1??~ ]=st@I8N$H'5BKi/=fxzEBn)FI#n}V4 $wɫ }p7'vrN|{4jx櫷20[wU71ĩʭU/7cqM&E, z5++lsm!$:oc c틧R քt2T)Ƈh,0MCV- ;795= Vcڣ;wB]Ӧ;#6]˯&Pewd?Lߠ]~,([?Ĕ0NG)oBW[2VeeZ]b`O7i|Qz:[GQŹ-KYiЀdqkZ gxv ֈg#05n=Z4,_"Yz\~׺׫WߥqǺ|WwZB۩[ &ɚ0]?֯TY"xe]H#[}rDk'lР -ҏB?AYŏ_u7j7H4 Y_>V}l* & y+vӾ34ӛ,lnQ(`aT} /pَ G`. Trp>i YOV\'KfܕТƄ"ܹ\{H-$:2BeJ3GGeҰZũa>sQDsZ (:L^Qw IvY6涒@I@ⅺ+Fz? )t-GĞ%4ӈFy,O`I>®R#n|K0F{5[΁n`zյd]:9Hg玔}l##گ<_|?@> Uۉ|HMQ H\;( c5~}w skO/dx.,EPi3ERʣvm'1 I i|շzF}BNt8bσ$nvõ䍋0r__qg\\F3ԁ#]c# rqڱ/$^J DGc#M ]Y7k HrKPUYQ~| xEo5'gɎhV/"8$W\1Q@ciER">@#!G鷅>Y &iq._+DJ*"Go4o ."Y\=WQ*99(ұnWVz;@+kO$\Q,;##琬CqkJ?K"&$lKjn}s+8Zco~yܒ 늹%м9GJW;iw0o0?ؾkV]\i[EJ;w!&p'X#犆yz lZ#ʢ$ң9oxڼ0yq*tG~p#o=e.nwz)eIfAuy+,uJ@+Q*^ 5_^HDZ͗ڨ%X$Jrx`]I_x H{oFs֖qSK.cET22@\Wi7,&$HyVE%dlCz݇: ri-'#U#Yx8FzEEvccd%'%vFE)"Boea~8jֻYw-7~P\" w=qׯz ,2FG/aM 'PHRr-/MJ6'xePpT/D)Gr ,k@8jW:޹>q̷/P<(-OCx[N=Ig#+5\"9 ]:CU2UB$Z4xI?E z['^ʗZ9*N׫ꃏWW~00{w5\LGp](!T e2k?Z>A\[\[BG[TO܏4MzR,?Ɖuy om(2ß43 j}$ auG['K'+\rmRI<9؊Yủ夤6}+{Y@UϧJ>P{@OQhT= m(UIR:{ӣŦ=l@2O=kD?ݫy?z"O|\x-f>d9tedp8>^韃5xMG+:nῦw./xGլ5d($$ fTA6dgqv 68Ǥ,B?gviKDi#5<)J3,؆NG`q>"ǚjj2XG  ,-SeeVI:0\"ܯk,#r31& uY?Wk}7鿉EcLWpяg)E駉6H-8,c6.gĚ<!"QO|!ĿHuoV2]jvz$qX±"c#nu婷-GguH+:fNqs+z-xo[YMv_`u5oꖚ4kkأu,ϬIBşXRÛ/e+h=BY18#7ᦶUN@*g[ứ6FLYifie6cԓ?}W"O:w,U$k{dSOܢk:eCe[u5$9b iRk#ths^GGm?9 } .H|/x^̈YLĻT}UiqJ6id;LqYJO'ui5/WvwA`0*VC+ I_Dq]g/k:ɭ.c#)|{W{~n-]ʤ`vifa$MzU;A&eKh^FQs\ku2dѴ0>c6 suR!OӣXѤH?%(ᛜa_ne ˈ•q[ĸHPpG`uugiRwz[MrnIVI=X_ŗOI-#u$7kkSu?4ě%ilc##g="1bUIA\:"YS997ѭƚ:-dX ?ՋF@ⅹ,z*V=^O;H *c=E8FS=jVmLA<~Lڃ\S~٣`*&h+|xuN PAL JaTG p)\4s79YF[8避] _,)rRPe$' nHR[ rI'K36I'$O(8mTcDoarxMPMlI+L ԚX۲7cSCFHaQ2A6rxij?K{ˏ/УpmϘL!TqKI95pzƆY*GLAiQFi<a-aPK[=Aw&AF!Ѳk]Wl$YrQS@ 9#kn6EAݘcUrW>ƹy+ .Yg'g@HMf8>,.%}=+hѷޠszޚ^Js;.)$&7޽rp sIߊk6w'AqPrqt0}D <כEմˤm]oZϚ{Iy2oXMԼ>Նm`-md0)|mWGqcm2qgGPiyo ݬʅpA"gҿPr'$rop1j?//}UOhkƒ d8eZ鿭~cPuߣRUPH{ ll%>z5=#|Ri#U ͈+?}ۇ]J)K>/uہL*o3aZ,:׿zAǹWW!K;)ϗ m#c i^Ymb%dK]2Łydu.TkEraׂi~wxş[m+<$正/|um\8]l*WϮ:-Bdc,r$>Bi޿Fker1yeeYGtoYghf Fb}ݥx\4ޘiWzoc~}6Omo5+i!ѡq$<v{$vVȊИߨ?RNjR~}opd%(jy%0) 'A.1ZJZ4ҿ ͥy8jH;{n=M"v4c/,9ށ旋1["u+(bzԲ$cZ޷>xՃƪ20OP 'M(JSKYKJGn-onD6Z[ ;W=[~4kxŲL_tw̋ e=p;w|KMWFoSImBM8;K")yYcklێq@|{-cƾ#4]L@n>HH~*.]s\ gKxPwڠ$tވDγ7Kuwڕ.-Lq$ɭm| [HX^G⭩Z 49u0([=9⩺˽1m^f.cvS# S,6)mXm0+!D5Miqk;DN27)*/iW!Z\Coq{2ϻ`v V#m_C֥f4)So!N܌iSm?x#zOTC:f(3)js*@v1ROcsnGtX< Tܬ3jmwx:ei~$l-,_K *4ELj|C]]뺥I$l,r r=&<r ~unp8'?mZxZj^#/mn/d#*In2Us( hZuCVEEO>v1a&3<$+噏$zGq55C*YO##i,^y])݌5oQڎA9$f8rr@<ӏhi=4)0q"w'U2l ,-cVooTE 6.g9+o{$`]:3.B:j+,+Qq:|c[PZ{ʗ7O";߉y93Tݵm 46\֖9w3W ?`d}9{Ə$Oʓ9$s#/a#b8ۣB2tw=lD{iq R)$) qR?Ֆ$gD|n!'~f>\`NJ tX—Jԋѧ7)d5Nyw=j⩘=_U;(XŸsѱʁ7;?aTPG*j3 ) 6=19>ԍyc d{PM$6g= 9k3ZWtrA‰47JPA>1ƅ8Kd>(^,,:1^H\t2]F3)lsM4 6R,Γ4 vNxa0J2^\2B≳lyEfl$3^2Fُh=V&'C4 0ښd r*1=h9㏏zX#ֲO-Ғ"g r~´ T;S%D/@H]飧;OoGYhTq[/+z 5VȬת)Z uQ{3Z~?Z^7P Uຶ8oӇOܰ(8n_D Ń+l?0~X^N 6O|erngtۦ_9N{j~w:վh>)G4]..仺$A=2~WWꃏWaR7&OQH?ć-.A %Σ%C<|'b8>ƒ6mO@؟LBD-umѱW][7"XEڤ3Z)[68uFܱBN4,pii =h}Ԍ!h6Y)oaױǏ-{nKRΟ:R{;Q&$u9W^#4{O{-Bߕ Ƹ>^zS4S͓6\Ҿ. WY??Դs눹]GcRaXq֍kGRFzj!}S+9h8ػQU,Nz ,Wq@Redmjߵz3)TlSS:w-,Hh ^s#ŀuԎ7qګdY*OWgm cGt?IG |i< r1>Q-"M* /ToE8T%!9 @5tNtk6Z{H$%j/D=y5%Oӭ}8=O$8Z'u9E5=0L1(gz.J߾xޕaqM,WIr4Ŋ)Lьڣ括h:zv kY8Ioii"౜-wr'$l:qZ\gjXۼ c(I=qֆYTrLSOjכEg>3\.s[pݩe~(ZRZMJ\K#4DUEf݌\E/thgONdx^1FxM19$s(HݳI4_We}=ّXn$•lؼYxƞ-յ+XFK4mͨa"tWG`99_k֥sujWȚky"mbr<ӭ;>"5(nn;Y&>|fQ_s9?QyzAGi0ʧp(Q' e<Og' 0H@O#tO-ڿ'0j>E]yo٥4qEyp6v ހRa 㺅8^Q^Ck QJ V[iI*AQ$ji$J=>:(59B4aU?~O{ex։{=dd7u\@x[[W- iP`5հW#k_5x!M{\b| ڔTqjb7eec!$䓞:|-tW_G Yމmk-x$s 039 җ(bѤQ9h?MA"߇2 s8BC"0 ڳs} }iK6l_]4#0Q:|՟L񥼪7qkx pq; C pCm̱XcRk )f5Vzy{26{2T/JZFs"U~7~ 9' YU%S{׸%X.y3ɽ{ޥ".D* {g yq`Cڔ NceuCB׎)TV )]>LH0r2@?\d%g+G]1 etޙC(8]1KӮX-`2Nz=i۫YZkeY Sȫ):zuW2n۸<[雦NQT'RA!;W<Ѻnc'Di\H3KlM5K9ݽǣ'b Ge76ч;G>3IXIFcUxLzPwaqS!URT~K*AI#O4YGW;v/tY⍈PW#OH^Y^.XO7Kl#be1n%rr8&W&LhR,2=h h NQ(}&m* RFn0i OjWĔkDrѰolԐǚay"܊G9@G#OR%-U:1aҥqi\ ǓP 2lsyslinux-legacy-3.63+dfsg/isolinux-debug.asm0000664000175000017500000000006110777447273017651 0ustar evanevan%define DEBUG_MESSAGES 1 %include "isolinux.asm" syslinux-legacy-3.63+dfsg/md5pass0000775000175000017500000000111310777447273015512 0ustar evanevan#!/usr/bin/perl use bytes; use Crypt::PasswdMD5; use MIME::Base64; sub random_bytes($) { my($n) = @_; my($v, $i); if ( open(RANDOM, '<', '/dev/random') || open(RANDOM, '<', '/dev/urandom') ) { read(RANDOM, $v, $n); } else { # No real RNG available... srand($$ ^ time); $v = ''; for ( $i = 0 ; $i < $n ; $i++ ) { $v .= ord(int(rand() * 256)); } } return $v; } ($pass, $salt) = @ARGV; unless (defined($salt)) { $salt = MIME::Base64::encode(random_bytes(6), ''); $salt =~ tr/\+/./; # . not + } print unix_md5_crypt($pass, $salt), "\n"; syslinux-legacy-3.63+dfsg/bcopy32.inc0000664000175000017500000003324310777447271016173 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; bcopy32.inc ;; ;; 32-bit bcopy routine for real mode ;; ; ; 32-bit bcopy routine for real mode ; ; We enter protected mode, set up a flat 32-bit environment, run rep movsd ; and then exit. IMPORTANT: This code assumes cs == 0. ; ; This code is probably excessively anal-retentive in its handling of ; segments, but this stuff is painful enough as it is without having to rely ; on everything happening "as it ought to." ; ; NOTE: this code is relocated into low memory, just after the .earlybss ; segment, in order to support to "bcopy over self" operation. ; section .bcopy32 align 8 __bcopy_start: ; This is in the .text segment since it needs to be ; contiguous with the rest of the bcopy stuff ; GDT descriptor entry %macro desc 1 bcopy_gdt.%1: PM_%1 equ bcopy_gdt.%1-bcopy_gdt %endmacro bcopy_gdt: dw bcopy_gdt_size-1 ; Null descriptor - contains GDT dd bcopy_gdt ; pointer for LGDT instruction dw 0 desc CS16 dd 0000ffffh ; 08h Code segment, use16, readable, dd 00009b00h ; present, dpl 0, cover 64K desc DS16_4G dd 0000ffffh ; 10h Data segment, use16, read/write, dd 008f9300h ; present, dpl 0, cover all 4G desc DS16_RM dd 0000ffffh ; 18h Data segment, use16, read/write, dd 00009300h ; present, dpl 0, cover 64K ; The next two segments are used for COM32 only desc CS32 dd 0000ffffh ; 20h Code segment, use32, readable, dd 00cf9b00h ; present, dpl 0, cover all 4G desc DS32 dd 0000ffffh ; 28h Data segment, use32, read/write, dd 00cf9300h ; present, dpl 0, cover all 4G ; TSS segment to keep Intel VT happy. Intel VT is ; unhappy about anything that doesn't smell like a ; full-blown 32-bit OS. desc TSS dw 104-1, DummyTSS ; 30h 32-bit task state segment dd 00008900h ; present, dpl 0, 104 bytes @DummyTSS ; 16-bit stack segment, which may have a different ; base from DS16 (e.g. if we're booted from PXELINUX) desc SS16 dd 0000ffffh ; 38h Data segment, use16, read/write, dd 00009300h ; present, dpl 0, cover 64K bcopy_gdt_size: equ $-bcopy_gdt ; ; bcopy: ; 32-bit copy, overlap safe ; ; Inputs: ; ESI - source pointer (-1 means do bzero rather than bcopy) ; EDI - target pointer ; ECX - byte count ; DF - zero ; ; Outputs: ; ESI - first byte after source (garbage if ESI == -1 on entry) ; EDI - first byte after target ; bcopy: pushad push word pm_bcopy call simple_pm_call popad add edi,ecx add esi,ecx ret ; ; This routine is used to invoke a simple routine in 16-bit protected ; mode (with 32-bit DS and ES, and working 16-bit stack.) ; Note that all segment registers including CS, except possibly SS, ; are zero-based in the protected-mode routine. ; ; No interrupt thunking services are provided; interrupts are disabled ; for the duration of the routine. Don't run for too long at a time. ; ; Inputs: ; On stack - pm entrypoint ; EAX, EBP preserved until real-mode exit ; EBX, ECX, EDX, ESI and EDI passed to the called routine ; ; Outputs: ; EAX, EBP restored from real-mode entry ; All other registers as returned from called function ; PM entrypoint cleaned off stack ; simple_pm_call: push eax push ebp mov bp,sp pushfd ; Saves, among others, the IF flag push ds push es push fs push gs cli call enable_a20 mov byte [cs:bcopy_gdt.TSS+5],89h ; Mark TSS unbusy ; Convert the stack segment to a base xor eax,eax mov ax,ss shl eax,4 or eax,93000000h mov [cs:bcopy_gdt.SS16+2],eax push ss ; Save real-mode SS selector o32 lgdt [cs:bcopy_gdt] mov eax,cr0 or al,1 mov cr0,eax ; Enter protected mode jmp PM_CS16:.in_pm .in_pm: mov ax,PM_SS16 ; Make stack usable mov ss,ax mov al,PM_DS16_4G ; Data segment selector mov es,ax mov ds,ax ; Set fs, gs, tr, and ldtr in case we're on a virtual ; machine running on Intel VT hardware -- it can't ; deal with a partial transition, for no good reason. mov al,PM_DS16_RM ; Real-mode-like segment mov fs,ax mov gs,ax mov al,PM_TSS ; Intel VT really doesn't want ltr ax ; an invalid TR and LDTR, so give xor ax,ax ; it something that it can use... lldt ax ; (sigh) call [bp+2*4+2] ; Call actual routine .exit: mov ax,PM_DS16_RM ; "Real-mode-like" data segment mov es,ax mov ds,ax pop bp ; Previous value for ss mov eax,cr0 and al,~1 mov cr0,eax ; Disable protected mode jmp 0:.in_rm .in_rm: ; Back in real mode mov ss,bp pop gs pop fs pop es pop ds %if DISABLE_A20 call disable_a20 %endif popfd ; Re-enables interrupts pop ebp pop eax ret 2 ; Drops the pm entry ; ; pm_bcopy: ; ; This is the protected-mode core of the "bcopy" routine. ; pm_bcopy: cmp esi,-1 je .bzero cmp esi,edi ; If source < destination, we might jb .reverse ; have to copy backwards .forward: mov al,cl ; Save low bits and al,3 shr ecx,2 ; Convert to dwords a32 rep movsd ; Do our business ; At this point ecx == 0 mov cl,al ; Copy any fractional dword a32 rep movsb ret .reverse: std ; Reverse copy lea esi,[esi+ecx-1] ; Point to final byte lea edi,[edi+ecx-1] mov eax,ecx and ecx,3 shr eax,2 a32 rep movsb ; Change ESI/EDI to point to the last dword, instead ; of the last byte. sub esi,3 sub edi,3 mov ecx,eax a32 rep movsd cld ret .bzero: xor eax,eax mov si,cx ; Save low bits and si,3 shr ecx,2 a32 rep stosd mov cx,si ; Write fractional dword a32 rep stosb ret ; ; Routines to enable and disable (yuck) A20. These routines are gathered ; from tips from a couple of sources, including the Linux kernel and ; http://www.x86.org/. The need for the delay to be as large as given here ; is indicated by Donnie Barnes of RedHat, the problematic system being an ; IBM ThinkPad 760EL. ; ; We typically toggle A20 twice for every 64K transferred. ; %define io_delay call _io_delay %define IO_DELAY_PORT 80h ; Invalid port (we hope!) %define disable_wait 32 ; How long to wait for a disable ; Note the skip of 2 here %define A20_DUNNO 0 ; A20 type unknown %define A20_NONE 2 ; A20 always on? %define A20_BIOS 4 ; A20 BIOS enable %define A20_KBC 6 ; A20 through KBC %define A20_FAST 8 ; A20 through port 92h slow_out: out dx, al ; Fall through _io_delay: out IO_DELAY_PORT,al out IO_DELAY_PORT,al ret enable_a20: pushad mov byte [cs:A20Tries],255 ; Times to try to make this work try_enable_a20: ; ; Flush the caches ; %if DO_WBINVD call try_wbinvd %endif ; ; If the A20 type is known, jump straight to type ; mov bp,[cs:A20Type] jmp word [cs:bp+A20List] ; ; First, see if we are on a system with no A20 gate ; a20_dunno: a20_none: mov byte [cs:A20Type], A20_NONE call a20_test jnz a20_done ; ; Next, try the BIOS (INT 15h AX=2401h) ; a20_bios: mov byte [cs:A20Type], A20_BIOS mov ax,2401h pushf ; Some BIOSes muck with IF int 15h popf call a20_test jnz a20_done ; ; Enable the keyboard controller A20 gate ; a20_kbc: mov dl, 1 ; Allow early exit call empty_8042 jnz a20_done ; A20 live, no need to use KBC mov byte [cs:A20Type], A20_KBC ; Starting KBC command sequence mov al,0D1h ; Command write out 064h, al call empty_8042_uncond mov al,0DFh ; A20 on out 060h, al call empty_8042_uncond ; Verify that A20 actually is enabled. Do that by ; observing a word in low memory and the same word in ; the HMA until they are no longer coherent. Note that ; we don't do the same check in the disable case, because ; we don't want to *require* A20 masking (SYSLINUX should ; work fine without it, if the BIOS does.) .kbc_wait: push cx xor cx,cx .kbc_wait_loop: call a20_test jnz a20_done_pop loop .kbc_wait_loop pop cx ; ; Running out of options here. Final attempt: enable the "fast A20 gate" ; a20_fast: mov byte [cs:A20Type], A20_FAST ; Haven't used the KBC yet in al, 092h or al,02h and al,~01h ; Don't accidentally reset the machine! out 092h, al .fast_wait: push cx xor cx,cx .fast_wait_loop: call a20_test jnz a20_done_pop loop .fast_wait_loop pop cx ; ; Oh bugger. A20 is not responding. Try frobbing it again; eventually give up ; and report failure to the user. ; dec byte [cs:A20Tries] jnz try_enable_a20 mov si, err_a20 jmp abort_load section .data err_a20 db CR, LF, 'A20 gate not responding!', CR, LF, 0 section .bcopy32 ; ; A20 unmasked, proceed... ; a20_done_pop: pop cx a20_done: popad ret ; ; This routine tests if A20 is enabled (ZF = 0). This routine ; must not destroy any register contents. ; a20_test: push es push cx push ax mov cx,0FFFFh ; HMA = segment 0FFFFh mov es,cx mov cx,32 ; Loop count mov ax,[cs:A20Test] .a20_wait: inc ax mov [cs:A20Test],ax io_delay ; Serialize, and fix delay cmp ax,[es:A20Test+10h] loopz .a20_wait .a20_done: pop ax pop cx pop es ret %if DISABLE_A20 disable_a20: pushad ; ; Flush the caches ; %if DO_WBINVD call try_wbinvd %endif mov bp,[cs:A20Type] jmp word [cs:bp+A20DList] a20d_bios: mov ax,2400h pushf ; Some BIOSes muck with IF int 15h popf jmp short a20d_snooze ; ; Disable the "fast A20 gate" ; a20d_fast: in al, 092h and al,~03h out 092h, al jmp short a20d_snooze ; ; Disable the keyboard controller A20 gate ; a20d_kbc: call empty_8042_uncond mov al,0D1h out 064h, al ; Command write call empty_8042_uncond mov al,0DDh ; A20 off out 060h, al call empty_8042_uncond ; Wait a bit for it to take effect a20d_snooze: push cx mov cx, disable_wait .delayloop: call a20_test jz .disabled loop .delayloop .disabled: pop cx a20d_dunno: a20d_none: popad ret %endif ; ; Routine to empty the 8042 KBC controller. If dl != 0 ; then we will test A20 in the loop and exit if A20 is ; suddenly enabled. ; empty_8042_uncond: xor dl,dl empty_8042: call a20_test jz .a20_on and dl,dl jnz .done .a20_on: io_delay in al, 064h ; Status port test al,1 jz .no_output io_delay in al, 060h ; Read input jmp short empty_8042 .no_output: test al,2 jnz empty_8042 io_delay .done: ret ; ; Execute a WBINVD instruction if possible on this CPU ; %if DO_WBINVD try_wbinvd: wbinvd ret %endif ; ; shuffle_and_boot: ; ; This routine is used to shuffle memory around, followed by ; invoking an entry point somewhere in low memory. This routine ; can clobber any memory above 7C00h, we therefore have to move ; necessary code into the trackbuf area before doing the copy, ; and do adjustments to anything except BSS area references. ; ; NOTE: Since PXELINUX relocates itself, put all these ; references in the ".earlybss" segment. ; ; After performing the copy, this routine resets the stack and ; jumps to the specified entrypoint. ; ; IMPORTANT: This routine does not canonicalize the stack or the ; SS register. That is the responsibility of the caller. ; ; Inputs: ; DS:BX -> Pointer to list of (dst, src, len) pairs(*) ; AX -> Number of list entries ; [CS:EntryPoint] -> CS:IP to jump to ; On stack - initial state (fd, ad, ds, es, fs, gs) ; ; (*) If dst == -1, then (src, len) entry refers to a set of new ; descriptors to load. ; If src == -1, then the memory pointed to by (dst, len) is bzeroed; ; this is handled inside the bcopy routine. ; shuffle_and_boot: .restart: and ax,ax jz .done .loop: mov edi,[bx] mov esi,[bx+4] mov ecx,[bx+8] cmp edi, -1 je .reload call bcopy add bx,12 dec ax jnz .loop .done: pop gs pop fs pop es pop ds popad popfd jmp far [cs:EntryPoint] .reload: mov bx, trackbuf ; Next descriptor movzx edi,bx push ecx ; Save byte count call bcopy pop eax ; Byte count xor edx,edx mov ecx,12 div ecx ; Convert to descriptor count jmp .restart ; ; trampoline_to_pm: ; ; This routine is chained to from shuffle_and_boot to invoke a ; flat 32-bit protected mode operating system. ; trampoline_to_pm: cli call enable_a20 mov byte [cs:bcopy_gdt.TSS+5],89h ; Mark TSS unbusy o32 lgdt [cs:bcopy_gdt] mov eax,cr0 or al,1 mov cr0,eax ; Enter protected mode jmp PM_CS32:.next ; Synchronize and go to 32-bit mode bits 32 .next: xor eax,eax lldt ax ; TR <- 0 to be nice to Intel VT mov al,PM_TSS ltr ax ; Bogus TSS to be nice to Intel VT mov al,PM_DS32 mov es,ax ; 32-bit data segment selector mov ds,ax mov ss,ax mov fs,ax mov gs,ax jmp word TrampolineBuf bits 16 align 2 A20List dw a20_dunno, a20_none, a20_bios, a20_kbc, a20_fast %if DISABLE_A20 A20DList dw a20d_dunno, a20d_none, a20d_bios, a20d_kbc, a20d_fast %endif A20Type dw A20_NONE ; A20 type ; Total size of .bcopy32 section alignb 4, db 0 ; Even number of dwords __bcopy_size equ $-__bcopy_start section .earlybss alignb 2 EntryPoint resd 1 ; CS:IP for shuffle_and_boot A20Test resw 1 ; Counter for testing status of A20 A20Tries resb 1 ; Times until giving up on A20 ; ; This buffer contains synthesized code for shuffle-and-boot. ; For the PM case, it is 9*5 = 45 bytes long; for the RM case it is ; 8*6 to set the GPRs, 6*5 to set the segment registers (including a dummy ; setting of CS), 5 bytes to set CS:IP, for a total of 83 bytes. ; TrampolineBuf resb 83 ; Shuffle and boot trampoline ; ; Space for a dummy task state segment. It should never be actually ; accessed, but just in case it is, point to a chunk of memory not used ; for anything real. ; alignb 4 DummyTSS resb 104 syslinux-legacy-3.63+dfsg/keytab-lilo.pl0000775000175000017500000000563610777447273017002 0ustar evanevan#!/usr/bin/perl # -------------------------------------------------------------------------- # This program was taken from the LILO-20 distribution; only this header # was added. # # LILO program code, documentation and auxiliary programs are # Copyright 1992-1997 Werner Almesberger. # All rights reserved. # # Redistribution and use in source and binary forms of parts of or the # whole original or derived work are permitted provided that the # original work is properly attributed to the author. The name of the # author may not be used to endorse or promote products derived from # this software without specific prior written permission. This work # is provided "as is" and without any express or implied warranties. # -------------------------------------------------------------------------- eval { use bytes; }; eval { binmode STDOUT; }; $DEFAULT_PATH = "/usr/lib/kbd/keytables"; $DEFAULT_MAP = "us"; $DEFAULT_EXT = ".map"; sub usage { print STDERR "usage: $0 [ -p old_code=new_code ] ...\n". (" "x(8+length $0))."[path]default_layout[.map] ] ". "[path]kbd_layout[.map]\n"; exit 1; } while ($ARGV[0] eq "-p") { shift(@ARGV); &usage unless $ARGV[0] =~ /=/; $table[eval($`)] = eval($'); shift(@ARGV); } &usage unless defined $ARGV[0]; load_map("def",defined $ARGV[1] ? $ARGV[0] : undef); load_map("kbd",defined $ARGV[1] ? $ARGV[1] : $ARGV[0]); &build_table("plain","shift","ctrl","altgr","shift_ctrl", "altgr_ctrl","alt","shift_alt","ctrl_alt"); for ($i = 0; $i < 256; $i++) { printf("%c",$table[$i] ? $table[$i] : $i) || die "print: $!"; } close STDOUT || die "close: $!"; sub load_map { local ($pfx,$map) = @_; local ($empty,$current); $map = $DEFAULT_MAP unless defined $map; $map = $DEFAULT_PATH."/".$map unless $map =~ m|/|; $map .= $DEFAULT_EXT unless $map =~ m|/[^/]+\.[^/]+$|; if (!open(FILE,"loadkeys -m $map |")) { print STDERR "loadkeys -m $map: $!\n"; exit 1; } undef $current; $empty = 1; while () { chop; if (/^u_short\s+(\S+)_map\[\S+\]\s+=\s+{\s*$/) { die "active at beginning of map" if defined $current; $current = $pfx.":".$1; next; } undef $current if /^};\s*$/; next unless defined $current; s/\s//g; $map{$current} .= $_; $empty = 0; } close FILE; return unless $empty; print STDERR "Keymap is empty\n"; exit 1; } sub build_table { local (@maps) = @_; local (@tmp); $set = 0; for $map (@maps) { $code = $set; for (split(",",$map{"def:".$map})) { die "bad map entry $_ (def, map $map)" unless /^0x\S\S(\S\S)$/; $tmp[$code] = hex $1 unless $tmp[$code]; $code++; } $set += 256; } $set = 0; for $map (@maps) { $code = $set; for (split(",",$map{"kbd:".$map})) { die "bad map entry $_ (kbd, map $map)" unless /^0x\S\S(\S\S)$/; $table[$tmp[$code]] = hex $1 unless $table[$tmp[$code]]; $code++; } $set += 256; } $table[0] = 0; } syslinux-legacy-3.63+dfsg/lstadjust.pl0000775000175000017500000000252610777447273016576 0ustar evanevan#!/usr/bin/perl # # Take a NASM list and map file and make the offsets in the list file # absolute. This makes debugging a lot easier. # # Usage: # # lstadjust.pl listfile mapfile outfile # ($listfile, $mapfile, $outfile) = @ARGV; open(LST, "< $listfile\0") or die "$0: cannot open: $listfile: $!\n"; open(MAP, "< $mapfile\0") or die "$0: cannot open: $mapfile: $!\n"; open(OUT, "> $outfile\0") or die "$0: cannot create: $outfile: $!\n"; %vstart = (); undef $sec; while (defined($line = )) { chomp $line; if ($line =~ /^\-+\s+Section\s+(\S+)\s+\-/) { $sec = $1; } next unless (defined($sec)); if ($line =~ /^vstart:\s+([0-9a-f]+)/i) { $vstart{$sec} = hex $1; } } close(MAP); $offset = 0; @ostack = (); while (defined($line = )) { chomp $line; $source = substr($line, 40); if ($source =~ /^([^;]*);/) { $source = $1; } ($label, $op, $arg, $tail) = split(/\s+/, $source); if ($op =~ /^(|\[)section$/i) { $offset = $vstart{$arg}; } elsif ($op =~ /^(absolute|\[absolute)$/i) { $offset = 0; } elsif ($op =~ /^struc$/i) { push(@ostack, $offset); $offset = 0; } elsif ($op =~ /^endstruc$/i) { $offset = pop(@ostack); } if ($line =~ /^(\s*[0-9]+ )([0-9A-F]{8})(\s.*)$/) { $line = sprintf("%s%08X%s", $1, (hex $2)+$offset, $3); } print OUT $line, "\n"; } syslinux-legacy-3.63+dfsg/regdump.inc0000664000175000017500000000323210777447273016352 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 2003-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; regdump.inc ;; ;; Dump as much as possible of the register state; for debugging ;; disk_dumpregs: mov ah,02h call dumpregs int 13h ret dumpregs: push gs push fs push es push ds push ss push cs pushad pushfd push cs pop ds mov bp,sp mov di,regnames mov cx,9 ; 9 32-bit registers .reg8: mov si,[di] inc di inc di call cwritestr mov eax,[bp] add bp,4 call writehex8 loop .reg8 mov cx,7 ; 6 16-bit registers .reg4: mov si,[di] inc di inc di call cwritestr mov eax,[bp] inc bp inc bp call writehex4 loop .reg4 call crlf popfd popad add sp,4 ; Skip CS, SS pop ds pop es pop fs pop gs ret regnames: dw .eflags dw .edi dw .esi dw .ebp dw .esp dw .ebx dw .edx dw .ecx dw .eax dw .cs dw .ss dw .ds dw .es dw .fs dw .gs dw .ip .eflags db 'EFL: ', 0 .edi db 13,10,'EDI: ', 0 .esi db ' ESI: ', 0 .ebp db ' EBP: ', 0 .esp db ' ESP: ', 0 .ebx db 13,10,'EBX: ', 0 .edx db ' EDX: ', 0 .ecx db ' ECX: ', 0 .eax db ' EAX: ', 0 .cs db 13,10,'CS: ',0 .ss db ' SS: ',0 .ds db ' DS: ',0 .es db ' ES: ',0 .fs db ' FS: ',0 .gs db ' GS: ',0 .ip db ' IP: ',0 syslinux-legacy-3.63+dfsg/extlinux.sys0000664000175000017500000002636510777447307016646 0ustar evanevan EXTLINUX 3.63 2008-04-10 >JLLy9~c>}u604O4~*~!1ffEIt fBf9u8 ݾ~(~fMfff!t; t f`Cfa Load error - CBIOSEBIOSUf1 |/Nf0f+ff1fB+ &0fff0 %0f f0fHf0ff0ff 0200f1fH4u=s Т8IH(fmf}>nth 11 r !L>t+u H4[">v+I4tfh+f@4fd+f<43f&<4 <t;< rwtI4uJsԪ< <t-<t<<t<utOj)dI40&I4<0rt <9vr+ W_1۠¢J4&>x+t[VW0Ǿʿl+>r+_^J4 0uO>D4(S f[f6D4fDaWP 0uOfMX_>J4$f f.comxf.cbtmf.c32f.bsstUVfD91fL4>r+Τ  6F4 1d4 t~< vNff=vga=t/f=mem=tVϦu< v.6d41.d4< wN뼃fDf==nortKf==exttKf==asktrωɃr.fL46`4fP47&f>HdrS&f4==r&$&=r &f,fP4&4f1&f&h4&!ub4 AfL4f-f;T4[f6b4F ff)fQff Bo fY^fT4f-v1һ f>\40BE>d4t D2T0f4h4tr df(d ?d>"rd$v df( `49vd󤪁r&>h4u?11df>b4G@) f1ffT4ff&>u& ÎێӼ߃ Sj19d4tMh4f4m0.6d4< wN1VPN.;6d4t<,uFV ^X_.;6d4wȎ؎ > f0fQfL4fJfP4f9vffBf)ʁf;\4r\&f>t &ff)&f&fffJfP4V6l fA`^fX þK EþV2!u=sV_01@f1f& &} & t ,&^ ؎1j0hȀ\ffĈffff`͎ݎʼn? ٤:FЉF,fa8hȀ1[1؎м{ IDeÊFÊFLJÎF&v&<$tÀ>5ufȈFfFSYfFSLfFINfFUXÀ>5u[ u&45Fà45f`͎ݎʼnRr1FF?F4N^$F~FUÎ^$vÎ^$vhhj^$v tFVFvÎF$^vN8 s1vËvF4F $0FN"F{N$F{á~+F:9F<9&>9`+ùFf{fx11fFffFff|ff(fvfV^&N$FFÁ~Uw/NQg If$vWdffFf(fvfV^&pÌN$F7FÊF<wJ4^&v w6844464^$v1O0؎16&E >r+F46FwHNV02uNà6 t 4^$FH9Ffvf vufFF$^nÁ~UwFNQg If$vWdff&vf( @dfEf)}f(+1QÁ~UwXPNQg If$vWdff&v(d؀Eꐐfdfdff((Ì^$FFVRPe0r+A)dffX^1һ-fEȎ؉&脝u)(r "' 1а(؎а0؋%g&D9f1 1QY`5(OhҎhPhhhXhjYf%1꼍؎Ўx $"ۍȎ؎&hfRfNfaf.&.&ff`f.&.ff$1ۋf]aϜ`D$(`D$(g>g6fg>ߋt$,1ɱ 󥫸G% Gffg6g|$0!u1ɱ g6aÜ`L$0g>gfg>)σfg>ߋD$(*t$,f)ag06F4>r+O>r+Òfff>fW1һ ff>f|ff(f1f1f{fx$0{W1^1jhx1؎{W_&fU&fu &]{{&E&][Xft ` <t<taþ~Ȁ1؎м{Vp+!f`11faýf;0fPQf1fYfXf@MuQ00@f?tYf1[_WSuQfHf1fWf6+fRff1f60f+f@%0ffRf ffZXeftfXf+ff60ffRf ffGZW $ֹ l4efl4Gfp4fPff ffXfff!Y[_!tfSQU29@f0~=/u fGfP"t*L t+t f11f!]Y[Ã=tf,9=tڀ=/uG0Q ى09YS[V;09sWf?t Owt __^sf=t=/u[^<[^29wf=mf1f94f94u44Wf^<t/@ <4W _f,9HWS1< v8t 0}t ^  fSfVfWfQfRfUfP%0ffPfDA w fXfg(f fXf f.0f9rdf\f)f. 0f9r-f`f)f1f6 0Pfef(ff [ff1f60Pfef(ff [fPfef(ff [effXff#0ff]fZfYf_f^f[fUfPfRfWff; v fDffPff1EIt%f1f@f 9sfGfBff9tfXf`KfaU ]flf),uf<f_fZfXf]"t$S0r7GW1GG @[1[SVW>] !u0ƃmru&Fu_^[KA ] f`0]5fMg&fvfMf)M 5fa뤉Mfa0SV7b^[WS>] A C] [_Yr <t < t < v8ÿ /sW6_r<-s fPfQUf1ff1<-u<0rSt<9wM <0r% b 69@:89w%69>b69ø149þ@9t6979@:99w791ɋ89679>b+믾@9t1ɉ6989>?9r/@9t?949r@9t?9496p!?949.< t< v>npsG>n76nppt`>b69a$@9@9t+ff`~+!tP&=9W tB 8uXSfaf@9t tf`u~+!ttB&>9 8faôu"~+!tWtB&>9 8u0ôbfafP Xff` tfafaf1Ԫ`++)f 0ŪfdYfD9ÿEÿ ҉>n+ÿډ>p+À>+wʉ>l+ÿƒu >-u1>À>+t /P^rf*fffP^rPb uXPQ uX|+rSgs[Lv<9r)fSPr7as1ۀ>>9߁<9f[f%_fKrfff:9Pw狽>~+U'X!BBB<u:JJ0Bt~U~+Pk_1V+ʿ‹l+/(&#r ff%f=ENDTuff%f=EXTuÿW^ÿ1 s|+u¿ǹ)1f>D9 f>D9þh%QfSfR1f1fOfg[fOgI8t1Cgy؀rg(ufGCf8u sCIbs ~fOg fgfOg'NfZf[Yhy詍W1fNg,s fNgs ~fNgـfNgY)tUr<#tQ ffShf[r@< v f0t*rئ*ff9tf¥륰 ]< tr!tYSfPf=vffPff fW1>f_fYfQfWt &gfAfVf袌f^f_fYfXff)[uP.XVD=6ui<wb>rY wT>4H9f6Ht6t@H9>40Ht1Ɉ2H99!0H89ù1Ҹ0۸` u99̈&89aVu84rtf>4=ui<1۹:4H1:99r99Ȉƴ1:lQWf1f_W8^Nj>l^lPY148tIu1$tQوY)w Ãt.$úB`ˬՇwavH<t@t O1w%7Hf0Eb+1f`Ȏ؎H ttOHb+faf`_f` >Hu faf`f`Yf\Yf1f!txf fPAMSf1ɱHYsf!u[pf=PAMSuhf>LYwfHYf>XYtf=rf;`Ysf`Yf;\YwfPYrf>TYtff;\Yvf\Y~f\Yf;`Yvf`Yf=w8r=Tz*~f|f,~f0~fffLfP$0T>Tt9t,1t%f/-Zffgff1}ffd(fÿfVff=/-Zuf1ҹ~fffguff=d(^P18t tƁr =v1XPVW uYQ18t t#Ɓr|Wƹ)r%^^NY΁sވЪȪd)1_^Xf`}f1fffgf)Ѝ|fDffaf>Ltf>Pt>Tt PXPXÈ&t]f`T Ҵr uBr]?p]UATwrGfL fPfaf1VfRfPSjjf`T@ &t]fadr^^fRfPUf6p]f>r]f1ɇff=w'Aň֊T&t]f`far]fXfZMuIt appears your computer has less than 256K of low ("DOS") RAM. Linux needs at least this amount to boot. If you get this message in error, hold down the Ctrl key while booting, and I will take your word for it. boot:  Invalid image type for this media type! Could not find kernel image: Invalid or corrupt kernel image. "CC6 Loading ..ready. Cannot load a ramdisk with an old kernel image. Could not find ramdisk image: Not enough memory to load specified kernel. BOOT_IMAGE=#19A F Y0mL׉ى"E\׉d׉׉׉׉2A΋Q%: attempted DOS system call COMBOOT image too large.  aborted. 0 linux autoOut of memory parsing config file Unknown keyword in configuration file. Missing parameter in configuration file. A20 gate not responding!   Copyright (C) 1994-2008 H. Peter Anvin Boot failed: please change disks and press a key to continue. extlinux.confinitrd=7t;}bQ9ؘYQ@ Q2@x+6P@̴h 6 0  e N  R2 G @t:t+6YtLhg1`+62d+Qh+^hɘHz+6 v+6 7 7 7 7 7 7 7 7 77 777.cbt.img.bs.com.c32 ?(g\(f`h) fafffPfUf.)f1ff .f )f.( "b)8аذ01V ] $")ff]fXftCf9r$fgfgfgtfg|fffgfffgff1΃fgfgf`.(..Z+.P+.Z+du_.Z+$RuMouF.Z+d^`WQ1/u)Y.Z+ $Q1uY.(uveYfaQP .(@.(e&;(XY0t uLdtC`u8!tf?fwfOft) Hufaf..(ffQfXf1f f.)f.( "6+ 1а0ذ(؎Ўf**(*:*`*syslinux-legacy-3.63+dfsg/checkov.pl0000664000175000017500000000331410777447272016173 0ustar evanevan#!/usr/bin/perl # # checkov.pl # # Check NASM map output for overflow # # This assumes that a section for which start != vstart, both # ranges need to be checked for overflow (true for SYSLINUX) # ($in, $target) = @ARGV; sub overlap($$$$) { my($s1,$e1,$s2,$e2) = @_; return 1 if ( $s2 < $e1 && $e2 > $s1 ); return 1 if ( $s1 < $e2 && $e1 > $s2 ); return 0; } open(IN, '<', $in) or die "$0: Cannot open input file: $in\n"; $section = undef; while ( $line = ) { if ( $line =~ /^-/ ) { if ( $line =~ /^\-\-\-\- Section (\S+) / ) { $section = $1; } else { $section = undef; } } elsif ( defined($section) ) { if ( $line =~ /^length\:\s*(\S+)/ ) { $length{$section} = hex $1; } elsif ( $line =~ /^start\:\s*(\S+)/ ) { $start{$section} = hex $1; } elsif ( $line =~ /^vstart\:\s*(\S+)/ ) { $vstart{$section} = hex $1; } } } close(IN); $err = 0; foreach $s ( keys(%start) ) { $sstart = $start{$s}; $svstart = $vstart{$s}; $send = $sstart + $length{$s}; $svend = $svstart + $length{$s}; if ( $send > 0x10000 || $svend > 0x10000 ) { print STDERR "$target: 16-bit overflow on section $s\n"; $err++; } foreach $o ( keys(%start) ) { next if ( $s ge $o ); $ostart = $start{$o}; $ovstart = $vstart{$o}; $oend = $ostart + $length{$o}; $ovend = $ovstart + $length{$o}; if ( overlap($sstart, $send, $ostart, $oend) || overlap($svstart, $svend, $ostart, $oend) || overlap($sstart, $send, $ovstart, $ovend) || overlap($svstart, $svend, $ovstart, $ovend) ) { print STDERR "$target: section $s overlaps section $o\n"; $err++; } } } if ( $err ) { unlink($target); exit(1); } else { exit(0); } syslinux-legacy-3.63+dfsg/keywords0000664000175000017500000000041710777447273016010 0ustar evanevanmenu text include append config default display font implicit ipappend kbdmap kernel linux boot bss pxe fdimage comboot com32 label localboot prompt say serial console timeout totaltimeout allowoptions ontimeout onerror noescape f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 syslinux-legacy-3.63+dfsg/conio.inc0000664000175000017500000002362410777447273016025 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; conio.inc ;; ;; Console I/O code, except: ;; writechr, writestr - module-dependent ;; cwritestr, crlf - writestr.inc ;; writehex* - writehex.inc ;; ; ; loadkeys: Load a LILO-style keymap; SI and DX:AX set by searchdir ; section .text loadkeys: and dx,dx ; Should be 256 bytes exactly jne loadkeys_ret cmp ax,256 jne loadkeys_ret mov bx,trackbuf mov cx,1 ; 1 cluster should be >= 256 bytes call getfssec mov si,trackbuf mov di,KbdMap mov cx,256 >> 2 rep movsd loadkeys_ret: ret ; ; get_msg_file: Load a text file and write its contents to the screen, ; interpreting color codes. Call with the file already ; on the top of the open/getc stack. ; ; Assumes CS == DS == ES. ; get_msg_file: mov byte [TextAttribute],07h ; Default grey on white mov byte [DisplayMask],07h ; Display text in all modes call msg_initvars print_msg_file: .getc: call getc jc .done cmp al,1Ah ; DOS EOF? je .done movzx cx,byte [UsingVGA] and cl,01h inc cx ; CL <- 01h = text mode, ; 02h = graphics mode call [NextCharJump] ; Do what shall be done jmp .getc .done: jmp close ; Tailcall! msg_putchar: ; Normal character cmp al,0Fh ; ^O = color code follows je msg_ctrl_o cmp al,0Dh ; Ignore je msg_ignore cmp al,0Ah ; = newline je msg_newline cmp al,0Ch ; = clear screen je msg_formfeed cmp al,07h ; = beep je msg_beep cmp al,19h ; = return to text mode je msg_novga cmp al,18h ; = VGA filename follows je msg_vga jnb .not_modectl cmp al,10h ; 10h to 17h are mode controls jae msg_modectl .not_modectl: msg_normal: call write_serial_displaymask ; Write to serial port test [DisplayMask],cl jz msg_ignore ; Not screen test byte [DisplayCon],01h jz msg_ignore mov bl,[TextAttribute] mov bh,[BIOS_page] mov ah,09h ; Write character/attribute mov cx,1 ; One character only int 10h ; Write to screen mov al,[CursorCol] inc ax cmp al,[VidCols] ja msg_line_wrap ; Screen wraparound mov [CursorCol],al msg_gotoxy: mov bh,[BIOS_page] mov dx,[CursorDX] mov ah,02h ; Set cursor position int 10h msg_ignore: ret msg_beep: mov ax,0E07h ; Beep xor bx,bx int 10h ret msg_ctrl_o: ; ^O = color code follows mov word [NextCharJump],msg_setbg ret msg_newline: ; Newline char or end of line mov si,crlf_msg call write_serial_str_displaymask msg_line_wrap: ; Screen wraparound test [DisplayMask],cl jz msg_ignore mov byte [CursorCol],0 mov al,[CursorRow] inc ax cmp al,[VidRows] ja msg_scroll mov [CursorRow],al jmp short msg_gotoxy msg_scroll: xor cx,cx ; Upper left hand corner mov dx,[ScreenSize] mov [CursorRow],dh ; New cursor at the bottom mov bh,[ScrollAttribute] mov ax,0601h ; Scroll up one line int 10h jmp short msg_gotoxy msg_formfeed: ; Form feed character mov si,crff_msg call write_serial_str_displaymask test [DisplayMask],cl jz msg_ignore xor cx,cx mov [CursorDX],cx ; Upper lefthand corner mov dx,[ScreenSize] mov bh,[TextAttribute] mov ax,0600h ; Clear screen region int 10h jmp msg_gotoxy msg_setbg: ; Color background character call unhexchar jc msg_color_bad shl al,4 test [DisplayMask],cl jz .dontset mov [TextAttribute],al .dontset: mov word [NextCharJump],msg_setfg ret msg_setfg: ; Color foreground character call unhexchar jc msg_color_bad test [DisplayMask],cl jz .dontset or [TextAttribute],al ; setbg set foreground to 0 .dontset: jmp short msg_putcharnext msg_vga: mov word [NextCharJump],msg_filename mov di, VGAFileBuf jmp short msg_setvgafileptr msg_color_bad: mov byte [TextAttribute],07h ; Default attribute msg_putcharnext: mov word [NextCharJump],msg_putchar ret msg_filename: ; Getting VGA filename cmp al,0Ah ; = end of filename je msg_viewimage cmp al,' ' jbe msg_ret ; Ignore space/control char mov di,[VGAFilePtr] cmp di,VGAFileBufEnd jnb msg_ret mov [di],al ; Can't use stosb (DS:) inc di msg_setvgafileptr: mov [VGAFilePtr],di msg_ret: ret msg_novga: call vgaclearmode jmp short msg_initvars msg_viewimage: mov si,[VGAFilePtr] mov byte [si],0 ; Zero-terminate filename mov si,VGAFileBuf mov di,VGAFileMBuf call mangle_name call open jz msg_putcharnext ; Not there call vgadisplayfile ; Fall through ; Subroutine to initialize variables, also needed ; after loading a graphics file msg_initvars: pusha mov bh,[BIOS_page] mov ah,03h ; Read cursor position int 10h mov [CursorDX],dx popa jmp short msg_putcharnext ; Initialize state machine msg_modectl: and al,07h mov [DisplayMask],al jmp short msg_putcharnext ; ; write_serial: If serial output is enabled, write character on serial port ; write_serial_displaymask: d:o, but ignore if DisplayMask & 04h == 0 ; write_serial_displaymask: test byte [DisplayMask], 04h jz write_serial.end write_serial: pushfd pushad mov bx,[SerialPort] and bx,bx je .noserial push ax mov ah,[FlowInput] .waitspace: ; Wait for space in transmit register lea dx,[bx+5] ; DX -> LSR in al,dx test al,20h jz .waitspace ; Wait for input flow control inc dx ; DX -> MSR in al,dx and al,ah cmp al,ah jne .waitspace .no_flow: xchg dx,bx ; DX -> THR pop ax call slow_out ; Send data .noserial: popad popfd .end: ret ; ; write_serial_str: write_serial for strings ; write_serial_str_displaymask: d:o, but ignore if DisplayMask & 04h == 0 ; write_serial_str_displaymask: test byte [DisplayMask], 04h jz write_serial_str.end write_serial_str: .loop lodsb and al,al jz .end call write_serial jmp short .loop .end: ret ; ; pollchar: check if we have an input character pending (ZF = 0) ; pollchar: pushad mov ah,11h ; Poll keyboard int 16h jnz .done ; Keyboard response mov dx,[SerialPort] and dx,dx jz .done ; No serial port -> no input add dx,byte 5 ; DX -> LSR in al,dx test al,1 ; ZF = 0 if data pending jz .done inc dx ; DX -> MSR mov ah,[FlowIgnore] ; Required status bits in al,dx and al,ah cmp al,ah setne al dec al ; Set ZF = 0 if equal .done: popad ret ; ; getchar: Read a character from keyboard or serial port ; getchar: RESET_IDLE .again: DO_IDLE mov ah,11h ; Poll keyboard int 16h jnz .kbd ; Keyboard input? mov bx,[SerialPort] and bx,bx jz .again lea dx,[bx+5] ; DX -> LSR in al,dx test al,1 jz .again inc dx ; DX -> MSR mov ah,[FlowIgnore] in al,dx and al,ah cmp al,ah jne .again .serial: xor ah,ah ; Avoid confusion xchg dx,bx ; Data port in al,dx ret .kbd: mov ah,10h ; Get keyboard input int 16h cmp al,0E0h jnz .not_ext xor al,al .not_ext: and al,al jz .func_key mov bx,KbdMap ; Convert character sets xlatb .func_key: ret %ifdef DEBUG_TRACERS ; ; debug hack to print a character with minimal code impact ; debug_tracer: pushad pushfd mov bp,sp mov bx,[bp+9*4] ; Get return address mov al,[cs:bx] ; Get data byte inc word [bp+9*4] ; Return to after data byte call writechr popfd popad ret %endif ; DEBUG_TRACERS section .data %if IS_ISOLINUX == 0 ; Defined elsewhere for ISOLINUX crlf_msg db CR, LF null_msg db 0 %endif crff_msg db CR, FF, 0 section .config ; This is a word to pc_setint16 can set it DisplayCon dw 01h ; Console display enabled ScrollAttribute db 07h ; Grey on white (normal text color) section .bss alignb 2 NextCharJump resw 1 ; Routine to interpret next print char CursorDX equ $ CursorCol resb 1 ; Cursor column for message file CursorRow resb 1 ; Cursor row for message file ScreenSize equ $ VidCols resb 1 ; Columns on screen-1 VidRows resb 1 ; Rows on screen-1 ; Serial console stuff... BaudDivisor resw 1 ; Baud rate divisor FlowControl equ $ FlowOutput resb 1 ; Outputs to assert for serial flow FlowInput resb 1 ; Input bits for serial flow FlowIgnore resb 1 ; Ignore input unless these bits set TextAttribute resb 1 ; Text attribute for message file DisplayMask resb 1 ; Display modes mask syslinux-legacy-3.63+dfsg/win32/0000775000175000017500000000000010777447344015155 5ustar evanevansyslinux-legacy-3.63+dfsg/win32/hello.c0000664000175000017500000000031410777447273016423 0ustar evanevan/* * Test program for C compiler; if this doesn't compile, the * C compiler is seriously broken. */ #include #include int main(void) { printf("Hello, World!\n"); return 0; } syslinux-legacy-3.63+dfsg/win32/syslinux.exe0000775000175000017500000006000010777447313017551 0ustar evanevanMZ@ !L!This program cannot be run in DOS mode. $PELNG 8\p0@2 4.text``.data102"@.rdatapT@@.bss.idata4Z@U]E1ۉu1=wC=r[$1҉T$Ttzt$л؋u]]=twJ=t؋u]]=t[=u$1t$tjt$=$D$vl$ 1D$t0R$ ?$L$l%$ D$R 'US$$@MEED$`a@$@D$ ED$@D$"@tYpa@@t@D$@@0$@t@D$@@P$t&pa@fD$@D$@$ 3$[D$@@$W@VU$t@&U$t@&U @]t&U @]ᐐU]S$1jD$PjD$Pjjht$Ht\$$[Á$P&1|$u|$w u |$uĠPjjD$PhPjh4$@t$ @hp@Pt$WVS$$hp@$ S[jjjjjhS uhp@f1^nPZ=thS$h4p@?jD$PhD$PS`uhhp@1Y($=thPhzp@@1@P$t>t:_@v@1@Php@4XZD$Rh_@PP $t/t 1ҍ$G9B$~t^jjjSjD$PhD$PS]uhp@1,Y($=th1P@hp@@PS u hq@1ZĄ[^_S1PjD$Pj t$jjh-t$(t h&q@XY[UWVSSSl$$D$(T$jD$PQt$(9u&;|$u jD$PUt$,t$,t$9tt$(@@hMq@PjZY[^_]á@@Phdq@jUWV1SP] :DžDžDžDžDžDž~u@@Phq@@S@{8-usxHa$s@Dž<Dž0)DžDžzt A9uuk=@t@:V@tAh@8u@P% hRZYt@x:uxtgLá@P _H@uPhq@0@ 0@0@h0@1t@@Phr@OAv@@Ph.r@4jjjjjhh0@-@uhAr@'jPhh@uhVr@t@@Phjr@h@YtPhr@@@Phh 0@h 0@jjjjjhh 0@su hr@ljR52@h2@P2@9t@@Phr@VJu hr@1h@jhr@jPY PS& t.GQS5XZ1҃@…S WP4jjjVTu+jR52@h2@V#t 2@9t hr@B taPZYt4u%@@Phs@@@PhHs@_XV1эA! Dž@|$OG:G\>t</\ ШtuDž\ DžAF뿍G9vRu\AldliAnux.AsyshWEW/Wh 0@u jh 0@jWh@^tZjj jjjhu hs@jRhh@PAu hs@mV/jjj*jPhh@t@@Phs@=jVe1[^_]Ð0@D$f0@PZhh0@P% UWVS(T$<B2@x2@t ;>fs ՍC$fkhjSM Nt $>2@@19}+@$P1Z[^_]ÐSD$X,@,ۉt [P X[UWVS|$l$_,t 9+tT[h ÅXuWh Y1^t6UshVw=tS Z1C +G,C_,[^_]ÐD$T$u BuB Ã~;B|ËJB$UWVS|$T$w O$N9s;W SB9ʉH1A)ˉЅtB-Ok;oGr\ GPW^X%C4 GPWXY ƃt1j\- GPW=^ƒ]tf148 GPWXYt114t$|$[^_]Y[^_]ÐUWVSPj0]6@,D$D$jSCD$^_@ f=1 $8A t G~{$S pup s($jBCuj$ $QՍAS  9C$su)ƉP=SwC(=w C=w6C 9w{u $B,CC StY1Z[^_]S\$S@X\$[UUWVSl$ t$t$Y[tgtPt$'ÅXZuo1j t$ S u1tj ESPu }1{t9CS);u ~Vt$nm[^_]ÐUu@Q@u@r]ÐU]ÐUa@8ta@BRa@uÍ&US-@t)t'-@Ku$%@JY[]1=-@ @-@u뾍'U @t]f] @냐U@]HUBSdT$U1ۉT$$ u=Jx|Au Jy;Tu؋]$4u@du@T$D$L$u@du@\$L$.&'UWVS=@te[^_]EAAAAu@}EAAAAEAAAAEu@EAAAAEAAAAEu@EAAAAEAAAAEu@EAAAAEġ u@Eȡ$u@E̡(u@EС,u@E0u@fE؉<$p$TJ$1ɾTL$t$C+@C%@@@TD@C(Ca@Sa@CP@C,S C0a@a@C4`@S8d@C$~JLLy:f|f1OUffRfPSWjf`1,Bfadr]f) !uf`11,fa}O]fRfPUSf6|f>|f1ɇfk)9vAň֊1,f`farf []fXfZf)uMuޕ.}u1ּ{fx} t ;.}v.}Boot error ᆳNG, SYSLINUX 3.63 2008-04-10 >JLLy5~c>}u68.O0~*~!1ffEIt fBf9u8 ݾ~(~fMfff!t; t f`Gfa Load error - CBIOSEBIOS9f1 |+Nf0ff+!uf |f$,f+f,f+!uf$|f+ff,f,f+f ,ff,f+Ȉ2,Q 3,YHf,,@f f(,f$,f+,ff=r$Sf=r2,f,|fff,f,vP.u=s 8(fT8,f1ff}u ut fx.ft.B11r\ L>t+u P.[">v+kQ.tfh+fH.fd+fD.3f&D. <t;< rwtQ.uJsԪ< <t-<t<<t<utOrjdQ.0&Q.<0rt <9vr+WD@_1۠R.&>x+t[VW0Ǿȿl+>r+_^R.0;uO>L.SR[f6L.fD,v݋p+!uW^p? ؿVWQQW_[tۍE1Y_^ 6lu(X;ltfD.tfH.uYпn+YË6@.f<.>.`M>aWP0@uOfMX_>R.f f.comf.cbtf.c32 f.bss f.binx ff.bsi f.0] `Ia{v!u=PRVh0fff f\.ff f`. f@f;`.vf`.f)`.1^ &>UVf.1fT.>r+  6N.1l. t~< vNff=vga=t/f=mem=tVu< v.6l.1.l.< wN뼃fDf==nortKf==exttKf==asktyrωɃkr.fT.6h.fX.7&f>HdrS&n.==r&$&=r &f,fX.&1f1&f&p.&!uj.?9fT.f-f;\.xf6j.F ff)fQff詢( fY^f\.f-v1һf>d.0>l.t# 0n.p.tr df(d ?d>"rd$v df( h.9vd󤪁r&>p.u?11df>j.G@) f1ff\.ff觡&>u&.6x.>e.x.z= ÎێӼ߃ Sj19l.t p.n.P0.6l.< wN1VPN.;6l.t<,uFV ^X_.;6l.wȎ؎/ >俑d f0fQfT.fJfX.f9vffBf)ʁf;d.r\&f>t &ff)&f&fffJfX.V^fXzþ?p`þs!u=sV_01@f1f& &} & t ,&^ ؎1j0h=\f3fXfEfff`͎ݎʼn :FЉF,fah=1[1؎м{s enÊFfÊF JÎF&v&<$tHÀ>u ȈFfFSYfFSLfFINfFUXÀ>u u&Fàf`͎ݎʼnr1FF?F1N^$F~F9Î^$vÎ^$v*hyh_^$vAtFVFvÎF$^vNs1vËvF1F 1,FN"F{N$F{á~+F.F.&.`+ùFf{fx11fFffFff|ff(fvfV^&N$FFÁ~Uw/NQg If$vWdffFf(fvfV^&ÌN$FFÊF<wR.^&vw6@.<.>.^$v10؎1&E >r+N.Fw,NV@Buà t ^$F.Ffvf vufFF$^ngÁ~UwFNQg If$vWdff&vf( @dfEf)}f(+1tÁ~UwXPNQg If$vWdff&v(d؀Eꐐfdfdff((Ì^$FFVRPe0r+A)dffX^1һfٍȎ؉& "ul)(2 "껍 1а(؎а0؋%(g&.f1 1QY`Ɇ(OhfhhhhhjŁf%(1P؎Ў8 $"oȎ؎& hfRffaf.&,.&,ff`f<.&,.f$f1ۋf]aϜ`D$(`D$(g> g"6fg> ߋt$,1ɱ 󥫸G% Gffg6 g"|$0!u1ɱ g 6aÜ`L$0g> g"fg>,)σfg> ߋD$(t$,fag$06N.>r+O>r+0,0,Offf>fW1һ! ff>f|ff(f0,f |f f1f1f{fx1,{W1^1jh3x1؎{W_&fU&fu &]{{&E&][Xf71t `U<t<taþ>=Ȑ1؎м{p+!hf`11faQ8,@f?tYSu8Qe<t"eD uQVW|. e_^Yt sY[f1efDff fG2,eTfeTfff,fefDeT !Y[!tfft.=/uf,GfP< v}t   WS1?< v<\u/8t 0,,tf@&Qf׊2,ffr fffgYfZf_f, t$Sn@rn7GW1GG @[J1[SVW>n] !u0ƃmru&Fu_^[KA ] f`@]5fMg&fvfMf)M A5fa뤉Mfa0SVn7n^[WS>n] A C] [_Yr <t < t < v8ÿ0?sW6_r<-s0fPfQUf1ff1<-u<0rSt<9wM <0r% b .@:.w%.>b.ø1.þp.t..@:.w.1ɋ.6.>b+믾s.t1ɉ..>.r/.t..r.t..9!..1< t< v>~sG>~76~t`>b.a$..t+ff`~+!tP&.W tB 8uXPfaf.t tf`u~+!ttB&. 8faôu"~+!tWtB&. 8u0ôbfafP Xff` tfafaf1Ī`++)fv 󤿈0ŪfNf.ÿEÿЉ>n+ÿ؉>p+À>+wȉ>l+ÿu >-u1>À>+t DP^rf*fffP^rPbQ8uXPQQuX|+rSgs[Lv.r)fSPr7as1ۀ>.߁.f[f%_fKrfff.Pw狽>~+U$XBBB<u:JJ0Bt~9~+Pk_B1V+@󤾈ȿl+/!&#r ff%f=ENDTuff%f=EXTuÿW^ÿ1s|+uǹ)1f>. f>.þh"QfSfR1f1fOfg[fOgI8t1Cgy؀rg(ufGCf8u sCIbs ~fOg fgfOg'NfZf[Yh|覍W1fNg,s fNgs ~fNgـfNgY)tUr<#tQ ffShf[r@< v f0t*rȦ*ff9tfϥ ]< tr!tYSfPf=vffPff fW1f_fYfQfWt &gfAfVf蟌f^f_fYfXff)[uP.X 4J=6ui<wb>rY wT>.f,tt@.>0,t1ɈBH.!@H.ù1Ҹ0۸` u.̈&.aVu8Drtf>D=uiL1۹JH1:.r.Ȉƴ1J|QWf1f_WH^Nj>|罀^|PY148tIu1$tQوY)w Ãt.$úB`ˬՇwav,<t@t O1w%,f@Eb+1f`Ȏ؎, ttO,b+faf`_f` >,u faf`fNfNf1f!txf fPAMSf1ɱNsf!u[pf=PAMSuhf>NwfNf>Ntf=rf;NsfNf;NwfNrf>Ntff;NvfN~fNf;NvfNf=w8r=8O>8t9t,1t%f/-Zffgff1}ffd(fÿfVff=/-Zuf1ҹ~fffguff=d(^P18t tƁr =v1XPVW uYQ18t t#Ɓr|Wƹ)r%^^NY΁sވЪȪd)1_^Xf`}f1fffgf)Ѝ|fDffaf>0tf>4t>8t PXPXÈ&Rf`8 Ҵr uBR?RUA8;r f0 f4faf1VfRfPSjjf`8@ &Rfadr^^fRfPUf6Rf>Rf1ɇff=w'Aň֊8&Rf`far]fXfZMuIt appears your computer has less than 256K of low ("DOS") RAM. Linux needs at least this amount to boot. If you get this message in error, hold down the Ctrl key while booting, and I will take your word for it. boot:  Invalid image type for this media type! Could not find kernel image: Invalid or corrupt kernel image. !׏ޏ׏ʈT| Loading ..ready. Cannot load a ramdisk with an old kernel image. Could not find ramdisk image: Not enough memory to load specified kernel. BOOT_IMAGE=3ʼn͉Չ ډ 0L3kmيk?O~kkkkƋՋ>bxF%: attempted DOS system call COMBOOT image too large.  aborted. AAEEEIIIOOUUYAIOU@ linux autoOut of memory parsing config file Unknown keyword in configuration file. Missing parameter in configuration file. A20 gate not responding!   Copyright (C) 1994-2008 H. Peter Anvin Boot failed: please change disks and press a key to continue. /boot/syslinux/syslinux.cfginitrd=7t;eT9ۘYQ@ T2Cx+9PC̴h60eNR2GCt:t+9YwLhj1`+92d+"Qh+"^h̘Hz+9 v+9 : : : H: : : : H: :: ::H:.cbt.bss.bs.com.c32 ?(g\(f`h) fafffPfUf.)f1ff .f )f.( "b)8аذ01V ] $")ff]fXftCf9r$fgfgfgtfg|fffgfffgff1΃fgfgf`.(..Z+.P+.Z+du_.Z+$RuMouF.Z+d^`WQ1/u)Y.Z+ $Q1uY.(u-fYfaQP .(@.(e&;(XY0t uLdtC`u8!tf?fwfOft) Hufaf..(ffQfXf1f f.)f.( "6+ 1а0ذ(؎Ўf**(*:*`*NG1؎м|WR RAU10rUu s fBZ?Q@RPf1ff!Missing operating system. f`f1һ|fRfPSjjf6{Œ6{A{fa} f`廾1SQt@ރHt[y9Y[G<t$<u"fGfVff!ufrfFfabMultiple active partitions. fDfFfD0r>}U{Z_Operating system load error. ^>b< u@-@%s: %s\\.\PHYSICALDRIVE%dAccessing physical driveError: Sector size of this drive is %d; must be %d Reading raw driveError: ReadFile on drive only got %d of %d bytes Error: MBR will not fit; not writing Writing MBRError: WriteFile on drive only wrote %d of %d bytes CloseFile on driveGetDriveNumber: DeviceIoControl failedCannot read sector %u Usage: syslinux.exe [-sfmar][-d directory] : [bootsecfile] You need to be running at least Windows NT; use syslinux.com instead. No such drive %c: Not a removable drive (use -f to override) Unsupported media Could not open driveReading boot sectorCould not read the whole boot sector %s Unable to create ldlinux.sysCould not write whole ldlinux.sys FlushFileBuffers failedLDLINUX SYSCould not write ldlinux.sysDid not successfully update the MBR; continuing... Could not find device number for updating MBR; continuing... Unable to create bootsector fileCould not write boot sector fileCould not write the whole boot sector !@@@-@@@@@@@@@@@@@@@@only 512-byte sectors are supportedFAT12 more than 4084 clusters but claims FAT12FAT16 less than 4084 clusters but claims FAT16FAT FAT32 this doesn't look like a valid FAT filesystem-LIBGCCW32-EH-3-SJLJ-GTHR-MINGW32w32_sharedptr->size == sizeof(W32_EH_SHARED)../../gcc/config/i386/w32-shared-ptr.cGetAtomNameA (atom, s, sizeof(s)) != 0@(d̑ؑ,8L`p̒ؒ$0@P`pȓԓܓ $0<HT̑ؑ,8L`p̒ؒ$0@P`pȓԓܓ $0<HTAddAtomA&CloseHandleDCreateFileAlDeleteFileAsDeviceIoControlExitProcessFindAtomAFlushFileBuffersFormatMessageAGetAtomNameA(GetDriveTypeACGetLastErrorIGetLogicalDrivesGetVersionExALocalFree'MoveFileAeReadFileSetFileAttributesASetFilePointerSetUnhandledExceptionFilter8WriteFile'__getmainargs0__mb_cur_max<__p__environ>__p__fmodeP__set_app_typeo_asserty_cexit_iob_isctype^_onexitg_pctype_setmodeabortatexit*exit9fprintf;fputs?freermallocwmemcmpxmemcpyzmemsetsignalsprintftolowerKERNEL32.dllmsvcrt.dllsyslinux-legacy-3.63+dfsg/win32/Makefile0000664000175000017500000000414410777447273016621 0ustar evanevan## ----------------------------------------------------------------------- ## ## Copyright 1998-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- # # Makefile for SYSLINUX Win32 # # This is separated out mostly so we can have a different set of Makefile # variables. # OSTYPE = $(shell uname -msr) ifeq ($(findstring CYGWIN,$(OSTYPE)),CYGWIN) WINCC = gcc WINAR = ar WINRANLIB = ranlib WINCFLAGS = -mno-cygwin -W -Wall -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64 WINPIC = WINLDFLAGS = -mno-cygwin -Os -s else ifeq ($(findstring MINGW32,$(OSTYPE)),MINGW32) WINCC = gcc WINAR = ar WINRANLIB = ranlib else WINCC = i386-mingw32-gcc WINAR = i386-mingw32-ar WINRANLIB = i386-mingw32-ranlib endif WINCFLAGS = -W -Wall -Wno-sign-compare -Os -fomit-frame-pointer \ -D_FILE_OFFSET_BITS=64 WINPIC = WINLDFLAGS = -Os -s endif WINCFLAGS += -I. -I.. -I../libfat -I../libinstaller WINCC_IS_GOOD := $(shell $(WINCC) $(WINCFLAGS) $(WINLDFLAGS) -o hello.exe hello.c >/dev/null 2>&1 ; echo $$?) .SUFFIXES: .c .o .i .s .S SRCS = syslinux.c ../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c \ ../mbr_bin.c $(wildcard ../libfat/*.c) OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS))) VPATH = .:..:../libfat:../libinstaller TARGETS = syslinux.exe ifeq ($(WINCC_IS_GOOD),0) all: $(TARGETS) else all: rm -f $(TARGETS) endif tidy: -rm -f *.o *.i *.s *.a .*.d *_bin.c hello.exe clean: tidy spotless: clean -rm -f *~ $(TARGETS) installer: syslinux.exe: $(OBJS) $(WINCC) $(WINLDFLAGS) -o $@ $^ %.o: %.c $(WINCC) -Wp,-MT,$@,-MMD,.$@.d $(WINCFLAGS) -c -o $@ $< %.i: %.c $(WINCC) $(WINCFLAGS) -E -o $@ $< %.s: %.c $(WINCC) $(WINCFLAGS) -S -o $@ $< -include .*.d syslinux-legacy-3.63+dfsg/win32/README0000664000175000017500000000034210777447273016035 0ustar evanevanBuilding the Win32 installer requires the MinGW compiler, available at: http://www.mingw.org/ Prepackaged versions of the MinGW cross-compiler in RPM format for Linux are available at: http://mirzam.it.vu.nl/mingw/ syslinux-legacy-3.63+dfsg/win32/syslinux.c0000664000175000017500000003252110777447273017223 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2003 Lars Munch Christensen - All Rights Reserved * Copyright 1998-2008 H. Peter Anvin - All Rights Reserved * * Based on the Linux installer program for SYSLINUX by H. Peter Anvin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * syslinux-mingw.c - Win2k/WinXP installer program for SYSLINUX */ #include #include #include #include "syslinux.h" #include "libfat.h" #ifdef __GNUC__ # define noreturn void __attribute__((noreturn)) #else # define noreturn void #endif void error(char* msg); /* Begin stuff for MBR code */ #include #define SECTOR_SIZE 512 #define PART_TABLE 0x1be #define PART_SIZE 0x10 #define PART_COUNT 4 #define PART_ACTIVE 0x80 // The following struct should be in the ntddstor.h file, but I didn't have it. // TODO: Make this a conditional compilation typedef struct _STORAGE_DEVICE_NUMBER { DEVICE_TYPE DeviceType; ULONG DeviceNumber; ULONG PartitionNumber; } STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER; BOOL GetStorageDeviceNumberByHandle( HANDLE handle, const STORAGE_DEVICE_NUMBER *sdn ) { BOOL result = FALSE; DWORD count; if ( DeviceIoControl( handle, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, (LPVOID)sdn, sizeof( *sdn ), &count, NULL ) ) { result = TRUE; } else { error("GetDriveNumber: DeviceIoControl failed"); } return( result ); } int GetBytesPerSector( HANDLE drive ) { int result = 0; DISK_GEOMETRY g; DWORD count; if ( DeviceIoControl( drive, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &g, sizeof( g ), &count, NULL ) ) { result = g.BytesPerSector; } return( result ); } BOOL FixMBR(int driveNum, int partitionNum, int write_mbr, int set_active) { BOOL result = TRUE; HANDLE drive; char driveName[128]; sprintf( driveName, "\\\\.\\PHYSICALDRIVE%d", driveNum ); drive = CreateFile( driveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( drive == INVALID_HANDLE_VALUE ) { error("Accessing physical drive"); result = FALSE; } if( result ) { unsigned char sector[SECTOR_SIZE]; DWORD howMany; if( GetBytesPerSector( drive ) != SECTOR_SIZE ) { fprintf(stderr, "Error: Sector size of this drive is %d; must be %d\n", GetBytesPerSector( drive ), SECTOR_SIZE ); result = FALSE; } if ( result ) { if ( ReadFile( drive, sector, sizeof( sector ), &howMany, NULL ) == 0 ) { error("Reading raw drive"); result = FALSE; } else if ( howMany != sizeof( sector ) ) { fprintf(stderr, "Error: ReadFile on drive only got %d of %d bytes\n", (int)howMany, sizeof( sector ) ); result = FALSE; } } // Copy over the MBR code if specified (-m) if ( write_mbr ) { if ( result ) { if ( syslinux_mbr_len >= PART_TABLE ) { fprintf(stderr, "Error: MBR will not fit; not writing\n" ); result = FALSE; } else { memcpy( sector, syslinux_mbr, syslinux_mbr_len ); } } } // Check that our partition is active if specified (-a) if ( set_active ) { if ( sector[ PART_TABLE + ( PART_SIZE * ( partitionNum - 1 ) ) ] != 0x80 ) { int p; for ( p = 0; p < PART_COUNT; p++ ) sector[ PART_TABLE + ( PART_SIZE * p ) ] = ( p == partitionNum - 1 ? 0x80 : 0 ); } } if ( result ) { SetFilePointer( drive, 0, NULL, FILE_BEGIN ); if ( WriteFile( drive, sector, sizeof( sector ), &howMany, NULL ) == 0 ) { error("Writing MBR"); result = FALSE; } else if ( howMany != sizeof( sector ) ) { fprintf(stderr, "Error: WriteFile on drive only wrote %d of %d bytes\n", (int)howMany, sizeof( sector ) ); result = FALSE; } } if( !CloseHandle( drive ) ) { error("CloseFile on drive"); result = FALSE; } } return( result ); } /* End stuff for MBR code */ const char *program; /* Name of program */ const char *drive; /* Drive to install to */ /* * Check Windows version. * * On Windows Me/98/95 you cannot open a directory, physical disk, or * volume using CreateFile. */ int checkver(void) { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); return (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) && ((osvi.dwMajorVersion > 4) || ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 0))); } /* * Windows error function */ void error(char* msg) { LPVOID lpMsgBuf; /* Format the Windows error message */ FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); /* Print it */ fprintf(stderr, "%s: %s", msg, (char*) lpMsgBuf); /* Free the buffer */ LocalFree(lpMsgBuf); } /* * Wrapper for ReadFile suitable for libfat */ int libfat_readfile(intptr_t pp, void *buf, size_t secsize, libfat_sector_t sector) { uint64_t offset = (uint64_t)sector * secsize; LONG loword = (LONG)offset; LONG hiword = (LONG)(offset >> 32); LONG hiwordx = hiword; DWORD bytes_read; if ( SetFilePointer((HANDLE)pp, loword, &hiwordx, FILE_BEGIN) != loword || hiword != hiwordx || !ReadFile((HANDLE)pp, buf, secsize, &bytes_read, NULL) || bytes_read != secsize ) { fprintf(stderr, "Cannot read sector %u\n", sector); exit(1); } return secsize; } noreturn usage(void) { fprintf(stderr, "Usage: syslinux.exe [-sfmar][-d directory] : [bootsecfile]\n"); exit(1); } int main(int argc, char *argv[]) { HANDLE f_handle, d_handle; DWORD bytes_read; DWORD bytes_written; DWORD drives; UINT drive_type; static unsigned char sectbuf[512]; char **argp, *opt; static char drive_name[] = "\\\\.\\?:"; static char drive_root[] = "?:\\"; static char ldlinux_name[] = "?:\\ldlinux.sys" ; const char *errmsg; struct libfat_filesystem *fs; libfat_sector_t s, *secp, sectors[65]; /* 65 is maximum possible */ uint32_t ldlinux_cluster; int nsectors; const char *bootsecfile = NULL; const char *subdir = NULL; int force = 0; /* -f (force) option */ int mbr = 0; /* -m (MBR) option */ int setactive = 0; /* -a (set partition active) */ int stupid = 0; /* -s (stupid) option */ int raid_mode = 0; /* -r (RAID) option */ (void)argc; if (!checkver()) { fprintf(stderr, "You need to be running at least Windows NT; use syslinux.com instead.\n"); exit(1); } program = argv[0]; drive = NULL; for ( argp = argv+1 ; *argp ; argp++ ) { if ( **argp == '-' ) { opt = *argp + 1; if ( !*opt ) usage(); while ( *opt ) { switch ( *opt ) { case 's': /* Use "safe, slow and stupid" code */ stupid = 1; break; case 'r': /* RAID mode */ raid_mode = 1; break; case 'f': /* Force install */ force = 1; break; case 'm': /* Install MBR */ mbr = 1; break; case 'a': /* Mark this partition active */ setactive = 1; break; case 'd': if ( argp[1] ) subdir = *++argp; break; default: usage(); break; } opt++; } } else { if ( bootsecfile ) usage(); else if ( drive ) bootsecfile = *argp; else drive = *argp; } } if ( !drive || !isalpha(drive[0]) || drive[1] != ':' || drive[2] ) usage(); /* Test if drive exists */ drives = GetLogicalDrives(); if(!(drives & ( 1 << (tolower(drive[0]) - 'a')))) { fprintf(stderr, "No such drive %c:\n", drive[0]); exit(1); } /* Determines the drive type */ drive_name[4] = drive[0]; ldlinux_name[0] = drive[0]; drive_root[0] = drive[0]; drive_type = GetDriveType(drive_root); /* Test for removeable media */ if ((drive_type == DRIVE_FIXED) && (force == 0)) { fprintf(stderr, "Not a removable drive (use -f to override) \n"); exit(1); } /* Test for unsupported media */ if ((drive_type != DRIVE_FIXED) && (drive_type != DRIVE_REMOVABLE)) { fprintf(stderr, "Unsupported media\n"); exit(1); } /* * First open the drive */ d_handle = CreateFile(drive_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); if (d_handle == INVALID_HANDLE_VALUE) { error("Could not open drive"); exit(1); } /* * Make sure we can read the boot sector */ if ( !ReadFile(d_handle, sectbuf, 512, &bytes_read, NULL) ) { error("Reading boot sector"); exit(1); } if (bytes_read != 512) { fprintf(stderr, "Could not read the whole boot sector\n"); exit(1); } /* Check to see that what we got was indeed an MS-DOS boot sector/superblock */ if( (errmsg = syslinux_check_bootsect(sectbuf)) ) { fprintf(stderr, "%s\n", errmsg); exit(1); } /* Change to normal attributes to enable deletion */ /* Just ignore error if the file do not exists */ SetFileAttributes(ldlinux_name, FILE_ATTRIBUTE_NORMAL); /* Delete the file */ /* Just ignore error if the file do not exists */ DeleteFile(ldlinux_name); /* Create ldlinux.sys file */ f_handle = CreateFile(ldlinux_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, NULL ); if (f_handle == INVALID_HANDLE_VALUE) { error("Unable to create ldlinux.sys"); exit(1); } /* Write ldlinux.sys file */ if (!WriteFile(f_handle, syslinux_ldlinux, syslinux_ldlinux_len, &bytes_written, NULL)) { error("Could not write ldlinux.sys"); exit(1); } if (bytes_written != syslinux_ldlinux_len) { fprintf(stderr, "Could not write whole ldlinux.sys\n"); exit(1); } /* Now flush the media */ if(!FlushFileBuffers(f_handle)) { error("FlushFileBuffers failed"); exit(1); } /* Map the file (is there a better way to do this?) */ fs = libfat_open(libfat_readfile, (intptr_t)d_handle); ldlinux_cluster = libfat_searchdir(fs, 0, "LDLINUX SYS", NULL); secp = sectors; nsectors = 0; s = libfat_clustertosector(fs, ldlinux_cluster); while ( s && nsectors < 65 ) { *secp++ = s; nsectors++; s = libfat_nextsector(fs, s); } libfat_close(fs); /* * Patch ldlinux.sys and the boot sector */ syslinux_patch(sectors, nsectors, stupid, raid_mode); /* * Rewrite the file */ if ( SetFilePointer(f_handle, 0, NULL, FILE_BEGIN) != 0 || !WriteFile(f_handle, syslinux_ldlinux, syslinux_ldlinux_len, &bytes_written, NULL) || bytes_written != syslinux_ldlinux_len ) { error("Could not write ldlinux.sys"); exit(1); } /* If desired, fix the MBR */ if( mbr || setactive ) { STORAGE_DEVICE_NUMBER sdn; if( GetStorageDeviceNumberByHandle( d_handle, &sdn ) ) { if( !FixMBR(sdn.DeviceNumber, sdn.PartitionNumber, mbr, setactive) ) { fprintf(stderr, "Did not successfully update the MBR; continuing...\n"); } } else { fprintf(stderr, "Could not find device number for updating MBR; continuing...\n"); } } /* Close file */ CloseHandle(f_handle); /* Move the file to the desired location */ if (subdir) { char new_ldlinux_name[strlen(subdir)+16]; char *cp = new_ldlinux_name+3; const char *sd; int slash = 1; new_ldlinux_name[0] = drive[0]; new_ldlinux_name[1] = ':'; new_ldlinux_name[2] = '\\'; for (sd = subdir; *sd; sd++) { char c = *sd; if (c == '/' || c == '\\') { if (slash) continue; c = '\\'; slash = 1; } else { slash = 0; } *cp++ = c; } /* Skip if subdirectory == root */ if (cp > new_ldlinux_name+3) { if (!slash) *cp++ = '\\'; memcpy(cp, "ldlinux.sys", 12); /* Delete any previous file */ SetFileAttributes(new_ldlinux_name, FILE_ATTRIBUTE_NORMAL); DeleteFile(new_ldlinux_name); if (!MoveFile(ldlinux_name, new_ldlinux_name)) SetFileAttributes(ldlinux_name, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); else SetFileAttributes(new_ldlinux_name, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); } } /* Make the syslinux boot sector */ syslinux_make_bootsect(sectbuf); /* Write the syslinux boot sector into the boot sector */ if ( bootsecfile ) { f_handle = CreateFile(bootsecfile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL ); if (f_handle == INVALID_HANDLE_VALUE) { error("Unable to create bootsector file"); exit(1); } if (!WriteFile(f_handle, sectbuf, 512, &bytes_written, NULL)) { error("Could not write boot sector file"); exit(1); } CloseHandle(f_handle); } else { SetFilePointer(d_handle, 0, NULL, FILE_BEGIN); WriteFile( d_handle, sectbuf, 512, &bytes_written, NULL ) ; } if(bytes_written != 512) { fprintf(stderr, "Could not write the whole boot sector\n"); exit(1); } /* Close file */ CloseHandle(d_handle); /* Done! */ return 0; } syslinux-legacy-3.63+dfsg/libinstaller/0000775000175000017500000000000010777447273016700 5ustar evanevansyslinux-legacy-3.63+dfsg/libinstaller/syslxmod.c0000664000175000017500000001717610777447273020742 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 1998-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * syslxmod.c - Code to provide a SYSLINUX code set to an installer. */ #define _XOPEN_SOURCE 500 /* Required on glibc 2.x */ #define _BSD_SOURCE #include #include #include #include #include "syslinux.h" #define LDLINUX_MAGIC 0x3eb202fe enum bs_offsets { bsJump = 0x00, bsOemName = 0x03, bsBytesPerSec = 0x0b, bsSecPerClust = 0x0d, bsResSectors = 0x0e, bsFATs = 0x10, bsRootDirEnts = 0x11, bsSectors = 0x13, bsMedia = 0x15, bsFATsecs = 0x16, bsSecPerTrack = 0x18, bsHeads = 0x1a, bsHiddenSecs = 0x1c, bsHugeSectors = 0x20, /* FAT12/16 only */ bs16DriveNumber = 0x24, bs16Reserved1 = 0x25, bs16BootSignature = 0x26, bs16VolumeID = 0x27, bs16VolumeLabel = 0x2b, bs16FileSysType = 0x36, bs16Code = 0x3e, /* FAT32 only */ bs32FATSz32 = 36, bs32ExtFlags = 40, bs32FSVer = 42, bs32RootClus = 44, bs32FSInfo = 48, bs32BkBootSec = 50, bs32Reserved = 52, bs32DriveNumber = 64, bs32Reserved1 = 65, bs32BootSignature = 66, bs32VolumeID = 67, bs32VolumeLabel = 71, bs32FileSysType = 82, bs32Code = 90, bsSignature = 0x1fe }; #define bsHead bsJump #define bsHeadLen (bsOemName-bsHead) #define bsCode bs32Code /* The common safe choice */ #define bsCodeLen (bsSignature-bs32Code) /* * Access functions for littleendian numbers, possibly misaligned. */ static inline uint8_t get_8(const unsigned char *p) { return *(const uint8_t *)p; } static inline uint16_t get_16(const unsigned char *p) { #if defined(__i386__) || defined(__x86_64__) /* Littleendian and unaligned-capable */ return *(const uint16_t *)p; #else return (uint16_t)p[0] + ((uint16_t)p[1] << 8); #endif } static inline uint32_t get_32(const unsigned char *p) { #if defined(__i386__) || defined(__x86_64__) /* Littleendian and unaligned-capable */ return *(const uint32_t *)p; #else return (uint32_t)p[0] + ((uint32_t)p[1] << 8) + ((uint32_t)p[2] << 16) + ((uint32_t)p[3] << 24); #endif } static inline void set_16(unsigned char *p, uint16_t v) { #if defined(__i386__) || defined(__x86_64__) /* Littleendian and unaligned-capable */ *(uint16_t *)p = v; #else p[0] = (v & 0xff); p[1] = ((v >> 8) & 0xff); #endif } static inline void set_32(unsigned char *p, uint32_t v) { #if defined(__i386__) || defined(__x86_64__) /* Littleendian and unaligned-capable */ *(uint32_t *)p = v; #else p[0] = (v & 0xff); p[1] = ((v >> 8) & 0xff); p[2] = ((v >> 16) & 0xff); p[3] = ((v >> 24) & 0xff); #endif } void syslinux_make_bootsect(void *bs) { unsigned char *bootsect = bs; memcpy(bootsect+bsHead, syslinux_bootsect+bsHead, bsHeadLen); memcpy(bootsect+bsCode, syslinux_bootsect+bsCode, bsCodeLen); } /* * Check to see that what we got was indeed an MS-DOS boot sector/superblock; * Return NULL if OK and otherwise an error message; */ const char *syslinux_check_bootsect(const void *bs) { int veryold; int sectorsize; long long sectors, fatsectors, dsectors; long long clusters; int rootdirents, clustersize; const unsigned char *sectbuf = bs; veryold = 0; /* Must be 0xF0 or 0xF8..0xFF */ if ( get_8(sectbuf+bsMedia) != 0xF0 && get_8(sectbuf+bsMedia) < 0xF8 ) goto invalid; sectorsize = get_16(sectbuf+bsBytesPerSec); if ( sectorsize == 512 ) ; /* ok */ else if ( sectorsize == 1024 || sectorsize == 2048 || sectorsize == 4096 ) return "only 512-byte sectors are supported"; else goto invalid; clustersize = get_8(sectbuf+bsSecPerClust); if ( clustersize == 0 || (clustersize & (clustersize-1)) ) goto invalid; /* Must be nonzero and a power of 2 */ sectors = get_16(sectbuf+bsSectors); sectors = sectors ? sectors : get_32(sectbuf+bsHugeSectors); dsectors = sectors - get_16(sectbuf+bsResSectors); fatsectors = get_16(sectbuf+bsFATsecs); fatsectors = fatsectors ? fatsectors : get_32(sectbuf+bs32FATSz32); fatsectors *= get_8(sectbuf+bsFATs); dsectors -= fatsectors; rootdirents = get_16(sectbuf+bsRootDirEnts); dsectors -= (rootdirents+sectorsize/32-1)/sectorsize; if ( dsectors < 0 || fatsectors == 0 ) goto invalid; clusters = dsectors/clustersize; if ( clusters < 0xFFF5 ) { /* FAT12 or FAT16 */ if ( !get_16(sectbuf+bsFATsecs) ) goto invalid; if ( get_8(sectbuf+bs16BootSignature) == 0x29 ) { if ( !memcmp(sectbuf+bs16FileSysType, "FAT12 ", 8) ) { if ( clusters >= 0xFF5 ) return "more than 4084 clusters but claims FAT12"; } else if ( !memcmp(sectbuf+bs16FileSysType, "FAT16 ", 8) ) { if ( clusters < 0xFF5 ) return "less than 4084 clusters but claims FAT16"; } else if ( memcmp(sectbuf+bs16FileSysType, "FAT ", 8) ) { static char fserr[] = "filesystem type \"????????\" not supported"; memcpy(fserr+17, sectbuf+bs16FileSysType, 8); return fserr; } } } else if ( clusters < 0x0FFFFFF5 ) { /* FAT32 */ /* Moving the FileSysType and BootSignature was a lovely stroke of M$ idiocy */ if ( get_8(sectbuf+bs32BootSignature) != 0x29 || memcmp(sectbuf+bs32FileSysType, "FAT32 ", 8) ) goto invalid; } else { goto invalid; } return NULL; invalid: return "this doesn't look like a valid FAT filesystem"; } /* * This patches the boot sector and the first sector of ldlinux.sys * based on an ldlinux.sys sector map passed in. Typically this is * handled by writing ldlinux.sys, mapping it, and then overwrite it * with the patched version. If this isn't safe to do because of * an OS which does block reallocation, then overwrite it with * direct access since the location is known. * * Return 0 if successful, otherwise -1. */ int syslinux_patch(const uint32_t *sectors, int nsectors, int stupid, int raid_mode) { unsigned char *patcharea, *p; int nsect = (syslinux_ldlinux_len+511) >> 9; uint32_t csum; int i, dw; if ( nsectors < nsect ) return -1; /* Patch in options, as appropriate */ if (stupid) { /* Access only one sector at a time */ set_16(syslinux_bootsect+0x1FC, 1); } i = get_16(syslinux_bootsect+0x1FE); if (raid_mode) set_16(syslinux_bootsect+i, 0x18CD); /* INT 18h */ set_16(syslinux_bootsect+0x1FE, 0xAA55); /* First sector need pointer in boot sector */ set_32(syslinux_bootsect+0x1F8, *sectors++); nsect--; /* Search for LDLINUX_MAGIC to find the patch area */ for ( p = syslinux_ldlinux ; get_32(p) != LDLINUX_MAGIC ; p += 4 ); patcharea = p+8; /* Set up the totals */ dw = syslinux_ldlinux_len >> 2; /* COMPLETE dwords! */ set_16(patcharea, dw); set_16(patcharea+2, nsect); /* Does not include the first sector! */ /* Set the sector pointers */ p = patcharea+8; memset(p, 0, 64*4); while ( nsect-- ) { set_32(p, *sectors++); p += 4; } /* Now produce a checksum */ set_32(patcharea+4, 0); csum = LDLINUX_MAGIC; for ( i = 0, p = syslinux_ldlinux ; i < dw ; i++, p += 4 ) csum -= get_32(p); /* Negative checksum */ set_32(patcharea+4, csum); return 0; } syslinux-legacy-3.63+dfsg/libinstaller/syslinux.h0000664000175000017500000000345010777447273020751 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 1998-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef SYSLINUX_H #define SYSLINUX_H #include #include "advconst.h" /* The standard boot sector and ldlinux image */ extern unsigned char syslinux_bootsect[]; extern unsigned int syslinux_bootsect_len; extern int syslinux_bootsect_mtime; extern unsigned char syslinux_ldlinux[]; extern unsigned int syslinux_ldlinux_len; extern int syslinux_ldlinux_mtime; extern unsigned char syslinux_mbr[]; extern unsigned int syslinux_mbr_len; extern int syslinux_mbr_mtime; /* This takes a boot sector and merges in the syslinux fields */ void syslinux_make_bootsect(void *); /* Check to see that what we got was indeed an MS-DOS boot sector/superblock */ const char *syslinux_check_bootsect(const void *bs); /* This patches the boot sector and ldlinux.sys based on a sector map */ int syslinux_patch(const uint32_t *sectors, int nsectors, int stupid, int raid_mode); /* ADV information */ #define ADV_SIZE 512 /* Total size */ #define ADV_LEN (ADV_SIZE-3*4) /* Usable data size */ extern unsigned char syslinux_adv[2*ADV_SIZE]; int syslinux_setadv(int tag, size_t size, const void *data); void syslinux_reset_adv(unsigned char *advbuf); int syslinux_validate_adv(unsigned char *advbuf); #endif syslinux-legacy-3.63+dfsg/libinstaller/setadv.c0000664000175000017500000000710410777447273020334 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * setadv.c * * (Over)write a data item in the auxilliary data vector. To * delete an item, set its length to zero. * * Return 0 on success, -1 on error, and set errno. * */ #include #include #include "syslxint.h" unsigned char syslinux_adv[2*ADV_SIZE]; #define ADV_MAGIC1 0x5a2d2fa5 /* Head signature */ #define ADV_MAGIC2 0xa3041767 /* Total checksum */ #define ADV_MAGIC3 0xdd28bf64 /* Tail signature */ static void cleanup_adv(unsigned char *advbuf) { int i; uint32_t csum; /* Make sure both copies agree, and update the checksum */ set_32(advbuf, ADV_MAGIC1); csum = ADV_MAGIC2; for (i = 8; i < ADV_SIZE-4; i += 4) csum -= get_32(advbuf+i); set_32(advbuf+4, csum); set_32(advbuf+ADV_SIZE-4, ADV_MAGIC3); memcpy(advbuf+ADV_SIZE, advbuf, ADV_SIZE); } int syslinux_setadv(int tag, size_t size, const void *data) { uint8_t *p; size_t left; uint8_t advtmp[ADV_SIZE]; if ((unsigned)tag-1 > 254) { errno = EINVAL; return -1; /* Impossible tag value */ } if (size > 255) { errno = ENOSPC; /* Max 255 bytes for a data item */ return -1; } left = ADV_LEN; p = advtmp; memcpy(p, syslinux_adv+2*4, left); /* Make working copy */ while (left >= 2) { uint8_t ptag = p[0]; size_t plen = p[1]+2; if (ptag == ADV_END) break; if (ptag == tag) { /* Found our tag. Delete it. */ if (plen >= left) { /* Entire remainder is our tag */ break; } memmove(p, p+plen, left-plen); } else { /* Not our tag */ if (plen > left) break; /* Corrupt tag (overrun) - overwrite it */ left -= plen; p += plen; } } /* Now (p, left) reflects the position to write in and how much space we have for our data. */ if (size) { if (left < size+2) { errno = ENOSPC; /* Not enough space for data */ return -1; } *p++ = tag; *p++ = size; memcpy(p, data, size); p += size; left -= size+2; } memset(p, 0, left); /* If we got here, everything went OK, commit the write */ memcpy(syslinux_adv+2*4, advtmp, ADV_LEN); cleanup_adv(syslinux_adv); return 0; } void syslinux_reset_adv(unsigned char *advbuf) { /* Create an all-zero ADV */ memset(advbuf+2*4, 0, ADV_LEN); cleanup_adv(advbuf); } static int adv_consistent(const unsigned char *p) { int i; uint32_t csum; if (get_32(p) != ADV_MAGIC1 || get_32(p+ADV_SIZE-4) != ADV_MAGIC3) return 0; csum = 0; for (i = 4; i < ADV_SIZE-4; i += 4) csum += get_32(p+i); return csum == ADV_MAGIC2; } /* * Verify that an in-memory ADV is consistent, making the copies consistent. * If neither copy is OK, return -1 and call syslinux_reset_adv(). */ int syslinux_validate_adv(unsigned char *advbuf) { if (adv_consistent(advbuf+0*ADV_SIZE)) { memcpy(advbuf+ADV_SIZE, advbuf, ADV_SIZE); return 0; } else if (adv_consistent(advbuf+1*ADV_SIZE)) { memcpy(advbuf, advbuf+ADV_SIZE, ADV_SIZE); return 0; } else { syslinux_reset_adv(advbuf); return -1; } } syslinux-legacy-3.63+dfsg/libinstaller/advconst.h0000777000175000017500000000000010777463574027340 2../com32/include/syslinux/advconst.hustar evanevansyslinux-legacy-3.63+dfsg/libinstaller/syslxint.h0000664000175000017500000000367010777447273020754 0ustar evanevan/* ----------------------------------------------------------------------- * * * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef SYSLXINT_H #define SYSLXINT_H #include "syslinux.h" /* * Access functions for littleendian numbers, possibly misaligned. */ static inline uint8_t get_8(const unsigned char *p) { return *(const uint8_t *)p; } static inline uint16_t get_16(const unsigned char *p) { #if defined(__i386__) || defined(__x86_64__) /* Littleendian and unaligned-capable */ return *(const uint16_t *)p; #else return (uint16_t)p[0] + ((uint16_t)p[1] << 8); #endif } static inline uint32_t get_32(const unsigned char *p) { #if defined(__i386__) || defined(__x86_64__) /* Littleendian and unaligned-capable */ return *(const uint32_t *)p; #else return (uint32_t)p[0] + ((uint32_t)p[1] << 8) + ((uint32_t)p[2] << 16) + ((uint32_t)p[3] << 24); #endif } static inline void set_16(unsigned char *p, uint16_t v) { #if defined(__i386__) || defined(__x86_64__) /* Littleendian and unaligned-capable */ *(uint16_t *)p = v; #else p[0] = (v & 0xff); p[1] = ((v >> 8) & 0xff); #endif } static inline void set_32(unsigned char *p, uint32_t v) { #if defined(__i386__) || defined(__x86_64__) /* Littleendian and unaligned-capable */ *(uint32_t *)p = v; #else p[0] = (v & 0xff); p[1] = ((v >> 8) & 0xff); p[2] = ((v >> 16) & 0xff); p[3] = ((v >> 24) & 0xff); #endif } #define SECTOR_SHIFT 9 /* 512-byte sectors */ #define SECTOR_SIZE (1 << SECTOR_SHIFT) #endif /* SYSLXINT_H */ syslinux-legacy-3.63+dfsg/checksumiso.pl0000775000175000017500000000117210777447272017071 0ustar evanevan#!/usr/bin/perl # # Construct a checksum for isolinux*.bin, compatible # with an mkisofs boot-info-table # use bytes; use integer; ($file) = @ARGV; open(FILE, '+<', $file) or die "$0: Cannot open $file: $!\n"; binmode FILE; if ( !seek(FILE,64,0) ) { die "$0: Cannot seek past header\n"; } $csum = 0; $bytes = 64; while ( ($n = read(FILE, $dw, 4)) > 0 ) { $dw .= "\0\0\0\0"; # Pad to at least 32 bits ($v) = unpack("V", $dw); $csum = ($csum + $v) & 0xffffffff; $bytes += $n; } if ( !seek(FILE,16,0) ) { die "$0: Cannot seek to header\n"; } print FILE pack("VV", $bytes, $csum); close(FILE); exit 0; syslinux-legacy-3.63+dfsg/bin2c.pl0000664000175000017500000000331510777447271015546 0ustar evanevan#!/usr/bin/perl ## ----------------------------------------------------------------------- ## ## Copyright 1998-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- # # bin2c.pl: binary file to C source converter # eval { use bytes; }; eval { binmode STDIN; }; ($table_name, $pad) = @ARGV; if ( !defined($table_name) ) { print STDERR "Usage: $0 table_name [pad] < input_file > output_file\n"; exit 1; } $pad = 1 if ($pad < 1); printf "unsigned char %s[] = {\n", $table_name; $pos = 0; $linelen = 8; $total_len = 0; while ( ($n = read(STDIN, $data, 4096)) > 0 ) { $total_len += $n; for ( $i = 0 ; $i < $n ; $i++ ) { $byte = substr($data, $i, 1); if ( $pos >= $linelen ) { print ",\n\t"; $pos = 0; } elsif ( $pos > 0 ) { print ", "; } else { print "\t"; } printf("0x%02x", unpack("C", $byte)); $pos++; } } $align = $total_len % $pad; if ($align != 0) { $n = $pad - $align; $total_len += $n; for ( $i = 0 ; $i < $n ; $i++ ) { if ( $pos >= $linelen ) { print ",\n\t"; $pos = 0; } elsif ( $pos > 0 ) { print ", "; } else { print "\t"; } print '0x00'; $pos++; } } printf "\n};\n\nunsigned int %s_len = %u;\n", $table_name, $total_len; @st = stat STDIN; printf "\nint %s_mtime = %d;\n", $table_name, $st[9]; exit 0; syslinux-legacy-3.63+dfsg/copybs.com0000664000175000017500000000063010777447307016210 0ustar evanevan0!ģ=s&1ɾ;I< v s 1Ҡ%Xr3 !rL!KjR !Z !L!Usage: copybs : $ERROR: $DOS version 2.00 or later required $Filesystem not found on disk $Boot sector read failed $File write failed $syslinux-legacy-3.63+dfsg/genhash.pl0000775000175000017500000000113610777447273016172 0ustar evanevan#!/usr/bin/perl # # Generate hash values for keywords # eval { use bytes; }; while ( defined($keywd = ) ) { chomp $keywd; ($keywd,$keywdname) = split(/\s+/, $keywd); $keywdname = $keywd unless ( $keywdname ); $l = length($keywd); $h = 0; for ( $i = 0 ; $i < $l ; $i++ ) { $c = ord(substr($keywd,$i,1)) | 0x20; $h = ((($h << 5)|($h >> 27)) ^ $c) & 0xFFFFFFFF; } if ( $seenhash{$h} ) { printf STDERR "$0: hash collision (0x%08x) %s %s\n", $h, $keywd, $seenhash{$h}; } $seenhash{$h} = $keywd; printf("%-23s equ 0x%08x\n", "hash_${keywdname}", $h); } syslinux-legacy-3.63+dfsg/bootsect.inc0000664000175000017500000000744010777447271016534 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; bootsect.inc ;; ;; Load a boot sector (or other bootstrap program.) ;; ;; Unlike previous versions of this software, this doesn't require that ;; the length is 512 bytes. This allows PXE bootstraps and WinNT ;; "CD boot sectors" to be invoked. ;; ; ; Load a boot sector ; is_bootsector: %if IS_SYSLINUX || IS_MDSLINUX ; Transfer zero bytes mov byte [CopySuper],0 jmp short load_bootsec is_bss_sector: ; Transfer the superblock mov byte [CopySuper],superblock_len %endif load_bootsec: xchg dx,ax shl eax,16 xchg dx,ax ; Now EAX = file length mov edi, 100000h mov [trackbuf+4],edi ; Copy from this address push edi ; Save load address xor dx,dx ; No padding mov bx,abort_check ; Don't print dots, but allow abort call load_high sub edi,100000h mov [trackbuf+8],edi ; Save length mov eax,7C00h ; Entry point mov [trackbuf],eax ; Copy to this address mov [EntryPoint],eax ; Jump to this address when done %if IS_SYSLINUX || IS_MDSLINUX movzx ecx,byte [CopySuper] jcxz .not_bss ; For a BSS boot sector we have to patch. mov esi,superblock mov edi,100000h+(superblock-bootsec) call bcopy .not_bss: %endif xor edx,edx xor esi,esi %if IS_SYSLINUX || IS_MDSLINUX || IS_EXTLINUX ; Restore original FDC table mov eax,[OrigFDCTabPtr] mov [fdctab],eax mov dl,[DriveNumber] mov si,PartInfo ; Partition info buffer mov di,800h-18 ; Put partition info here push di mov cx,8 ; 16 bytes xor ax,ax rep movsw pop si ; DS:SI points to partition info %elif IS_ISOLINUX mov dl,[DriveNumber] %elif IS_PXELINUX mov byte [KeepPXE],1 ; Chainloading another NBP call reset_pxe %endif xor bx,bx ; ; replace_bootstrap for the special case where we have exactly one ; descriptor, and it's the first entry in the trackbuf ; replace_bootstrap_one: push word 1 ; Length of descriptor list push word trackbuf ; Address of descriptor list ; Fall through ; ; Entrypoint for "shut down and replace bootstrap" -- also invoked by ; the COMBOOT API. This routine expects two words on the stack: ; address of the copy list (versus DS) and count. Additionally, ; the values of ESI and EDX are passed on to the new bootstrap; ; the value of BX becomes the new DS. ; replace_bootstrap: ; ; Prepare for shutting down ; call vgaclearmode call cleanup_hardware ; ; Set up initial stack frame (not used by PXE if keeppxe is ; set - we use the PXE stack then.) ; AFTER THIS POINT ONLY .earlybss IS AVAILABLE, NOT .bss ; xor ax,ax mov ds,ax mov es,ax %if IS_PXELINUX test byte [KeepPXE],01h jz .stdstack les di,[InitStack] ; Reset stack to PXE original jmp .stackok %endif .stdstack: mov di,7C00h-44 push di mov cx,22 ; 44 bytes rep stosw pop di .stackok: mov [es:di+28],edx ; New EDX mov [es:di+12],esi ; New ESI mov [es:di+6],bx ; New DS %if IS_PXELINUX == 0 ; DON'T DO THIS FOR PXELINUX... ; For PXE, ES:BX -> PXENV+, and this would corrupt ; that use. ; Restore ES:DI -> $PnP (if we were ourselves called ; that way...) mov ax,[OrigESDI] mov bx,[OrigESDI+2] mov [es:di+8],ax ; New DI mov [es:di+4],bx ; New ES %endif pop bx ; Copy from... pop ax ; Copy list count cli mov cx,es mov ss,cx movzx esp,di jmp shuffle_and_boot syslinux-legacy-3.63+dfsg/lss16toppm0000775000175000017500000000465710777447273016206 0ustar evanevan#!/usr/bin/perl ## ----------------------------------------------------------------------- ## ## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- ## ## lss16toppm: ## Convert an LSS-16 image to PPM ## ## Usage: ## ## lss16toppm [-map] < file.lss > file.ppm ## ## The -map causes the color map to be output on stderr. ## eval { use bytes; }; eval { binmode STDIN; }; eval { binmode STDOUT; }; $map = 0; foreach $arg ( @ARGV ) { if ( $arg eq '-map' ) { $map = 1; } else { print STDERR "$0: Unknown option: $arg\n"; exit 127; } } if ( read(STDIN, $header, 56) != 56 ) { print STDERR "$0: Short file\n"; exit 1; } ($magic, $xsize, $ysize, @colorset) = unpack("Vvvc48", $header); if ( $magic != 0x1413f33d ) { print STDERR "$0: Invalid file format\n"; exit 1; } %color = (); for ( $i = 0 ; $i < 16 ; $i++ ) { $r = int((shift @colorset) * 255 / 63 + 0.5); $g = int((shift @colorset) * 255 / 63 + 0.5); $b = int((shift @colorset) * 255 / 63 + 0.5); $color{$i} = pack("ccc", $r, $g, $b); if ( $map ) { printf STDERR "#%02x%02x%02x=%d\n", $r, $g, $b, $i; } } sub get_nybble() { my($ch,$n); if ( defined($nybble_buf) ) { $n = $nybble_buf; undef $nybble_buf; } else { if ( read(STDIN, $ch, 1) != 1 ) { print STDERR "$0: Short read on input (file corrupt)\n"; exit 1; } $ch = ord($ch); $nybble_buf = $ch >> 4; $n = $ch & 0xF; } return $n; } print "P6\n"; print "$xsize $ysize\n"; print "255\n"; for ( $y = 0 ; $y < $ysize ; $y++ ) { $x = 0; $last = 0; undef $nybble_buf; # Nybble buffer starts clear on each line while ( $x < $xsize ) { $n = get_nybble(); if ( $n != $last ) { print $color{$n}; $last = $n; $x++; } else { $c = get_nybble(); if ( $c == 0 ) { # Double-nybble run $c = get_nybble(); $c += get_nybble() << 4; $c += 16; } # Truncate overlong runs $c = $xsize-$x if ( $c > $xsize-$x ); # Output run print $color{$n} x $c; $x += $c; } } } syslinux-legacy-3.63+dfsg/loadhigh.inc0000664000175000017500000000550310777447273016471 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; loadhigh.inc ;; ;; Load a file into high memory ;; section .text ; ; load_high: loads (the remainder of) a file into high memory. ; This routine prints dots for each 64K transferred, and ; calls abort_check periodically. ; ; The xfer_buf_seg is used as a bounce buffer. ; ; The input address (EDI) should be dword aligned, and the final ; stretch is padded with zeroes if necessary. ; ; Inputs: SI = file handle/cluster pointer ; EDI = target address in high memory ; EAX = size of remaining file in bytes ; DX = zero-padding mask (e.g. 0003h for pad to dword) ; BX = subroutine to call at the top of each loop ; (to print status and check for abort) ; ; Outputs: SI = file handle/cluster pointer ; EDI = first untouched address (not including padding) ; load_high: push es ; ES mov cx,xfer_buf_seg mov es,cx .read_loop: and si,si ; If SI == 0 then we have end of file jz .eof call bx push bx ; Pausebird function push eax ; Total bytes to transfer cmp eax,(1 << 16) ; Max 64K in one transfer jna .size_ok mov eax,(1 << 16) .size_ok: push eax ; Bytes transferred this chunk add eax,SECTOR_SIZE-1 shr eax,SECTOR_SHIFT ; Convert to sectors ; Now (e)ax contains the number of sectors to get push edi ; Target buffer mov cx,ax xor bx,bx ; ES:0 call getfssec ; Load the data into xfer_buf_seg pop edi ; Target buffer pop ecx ; Byte count this round push ecx ; Byte count this round push edi ; Target buffer .fix_slop: test cx,dx jz .noslop ; The last dword fractional - pad with zeroes ; Zero-padding is critical for multi-file initramfs. mov byte [es:ecx],0 inc ecx jmp short .fix_slop .noslop: push esi ; File handle/cluster pointer mov esi,(xfer_buf_seg << 4) ; Source address call bcopy ; Copy to high memory pop esi ; File handle/cluster pointer pop edi ; Target buffer pop ecx ; Byte count this round pop eax ; Total bytes to transfer add edi,ecx sub eax,ecx pop bx ; Pausebird function jnz .read_loop ; More to read... .eof: pop es ; ES ret dot_pause: push ax mov al,'.' call writechr pop ax jmp abort_check ; Handles the return syslinux-legacy-3.63+dfsg/cpuinit.inc0000664000175000017500000000420410777447273016362 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; cpuinit.inc ;; ;; CPU-dependent initialization and related checks. ;; check_escapes: mov ah,02h ; Check keyboard flags int 16h mov [KbdFlags],al ; Save for boot prompt check test al,04h ; Ctrl->skip 386 check jnz skip_checks ; ; Now check that there is sufficient low (DOS) memory ; ; NOTE: Linux doesn't use all of real_mode_seg, but we use the same ; segment for COMBOOT images, which can use all 64K ; dosram_k equ (real_mode_seg+0x1000) >> 6 ; Minimum DOS memory (K) int 12h cmp ax,dosram_k jae enough_ram mov si,err_noram call writestr jmp kaboom enough_ram: skip_checks: ; ; Initialize the bcopy32 code in low memory ; mov si,section..bcopy32.start mov di,__bcopy_start mov cx,__bcopy_size >> 2 rep movsd ; ; Check if we're 386 (as opposed to 486+); if so we need to blank out ; the WBINVD instruction ; ; We check for 486 by setting EFLAGS.AC ; %if DO_WBINVD pushfd ; Save the good flags pushfd pop eax mov ebx,eax xor eax,(1 << 18) ; AC bit push eax popfd pushfd pop eax popfd ; Restore the original flags xor eax,ebx jnz is_486 ; ; 386 - Looks like we better blot out the WBINVD instruction ; mov byte [try_wbinvd],0c3h ; Near RET is_486: %endif ; DO_WBINVD section .data err_noram db 'It appears your computer has less than ' asciidec dosram_k db 'K of low ("DOS")' db CR, LF db 'RAM. Linux needs at least this amount to boot. If you get' db CR, LF db 'this message in error, hold down the Ctrl key while' db CR, LF db 'booting, and I will take your word for it.', CR, LF, 0 section .text syslinux-legacy-3.63+dfsg/cleanup.inc0000664000175000017500000000262310777447272016340 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 2007-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; cleanup.inc ;; ;; Some final tidying before jumping to a kernel or bootsector ;; section .text ; ; cleanup_hardware: ; ; Shut down anything transient. *No segment assumptions*. ; Can trash any registers. ; cleanup_hardware: pushad ; ; Linux wants the floppy motor shut off before starting the kernel, ; at least bootsect.S seems to imply so. If we don't load the floppy ; driver, this is *definitely* so! ; xor ax,ax xor dx,dx int 13h %if 0 ; This bug report has not been substantiated! ; Vmware crashes if we scroll in the decompressor! Try to detect vmware ; and if it is Vmware, clear the screen... mov eax,'VMXh' xor ebx, ebx mov ecx, 10 ; Get version mov dx, 'VX' in eax, dx cmp ebx, 'VMXh' jne .no_vmware mov ax,0x0003 ; Set mode (clear screen/home cursor) int 10h .no_vmware: %endif popad ret syslinux-legacy-3.63+dfsg/pxe.inc0000664000175000017500000001256410777447273015513 0ustar evanevan;; ----------------------------------------------------------------------- ;; ;; Copyright 1999-2008 H. Peter Anvin - All Rights Reserved ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ;; Boston MA 02111-1307, USA; either version 2 of the License, or ;; (at your option) any later version; incorporated herein by reference. ;; ;; ----------------------------------------------------------------------- ;; ;; pxe.inc ;; ;; PXE opcodes ;; %ifndef _PXE_INC %define _PXE_INC 1 %define PXENV_TFTP_OPEN 0020h %define PXENV_TFTP_CLOSE 0021h %define PXENV_TFTP_READ 0022h %define PXENV_TFTP_READ_FILE 0023h %define PXENV_TFTP_READ_FILE_PMODE 0024h %define PXENV_TFTP_GET_FSIZE 0025h %define PXENV_UDP_OPEN 0030h %define PXENV_UDP_CLOSE 0031h %define PXENV_UDP_READ 0032h %define PXENV_UDP_WRITE 0033h %define PXENV_START_UNDI 0000h %define PXENV_UNDI_STARTUP 0001h %define PXENV_UNDI_CLEANUP 0002h %define PXENV_UNDI_INITIALIZE 0003h %define PXENV_UNDI_RESET_NIC 0004h %define PXENV_UNDI_SHUTDOWN 0005h %define PXENV_UNDI_OPEN 0006h %define PXENV_UNDI_CLOSE 0007h %define PXENV_UNDI_TRANSMIT 0008h %define PXENV_UNDI_SET_MCAST_ADDR 0009h %define PXENV_UNDI_SET_STATION_ADDR 000Ah %define PXENV_UNDI_SET_PACKET_FILTER 000Bh %define PXENV_UNDI_GET_INFORMATION 000Ch %define PXENV_UNDI_GET_STATISTICS 000Dh %define PXENV_UNDI_CLEAR_STATISTICS 000Eh %define PXENV_UNDI_INITIATE_DIAGS 000Fh %define PXENV_UNDI_FORCE_INTERRUPT 0010h %define PXENV_UNDI_GET_MCAST_ADDR 0011h %define PXENV_UNDI_GET_NIC_TYPE 0012h %define PXENV_UNDI_GET_IFACE_INFO 0013h %define PXENV_UNDI_ISR 0014h %define PXENV_STOP_UNDI 0015h ; Overlap...? %define PXENV_UNDI_GET_STATE 0015h ; Overlap...? %define PXENV_UNLOAD_STACK 0070h %define PXENV_GET_CACHED_INFO 0071h %define PXENV_RESTART_DHCP 0072h %define PXENV_RESTART_TFTP 0073h %define PXENV_MODE_SWITCH 0074h %define PXENV_START_BASE 0075h %define PXENV_STOP_BASE 0076h %define PXENV_EXIT_SUCCESS 0x0000 %define PXENV_EXIT_FAILURE 0x0001 %define PXENV_STATUS_SUCCESS 0x00 %define PXENV_STATUS_FAILURE 0x01 %define PXENV_STATUS_BAD_FUNC 0x02 %define PXENV_STATUS_UNSUPPORTED 0x03 %define PXENV_STATUS_KEEP_UNDI 0x04 %define PXENV_STATUS_KEEP_ALL 0x05 %define PXENV_STATUS_OUT_OF_RESOURCES 0x06 %define PXENV_STATUS_ARP_TIMEOUT 0x11 %define PXENV_STATUS_UDP_CLOSED 0x18 %define PXENV_STATUS_UDP_OPEN 0x19 %define PXENV_STATUS_TFTP_CLOSED 0x1A %define PXENV_STATUS_TFTP_OPEN 0x1B %define PXENV_STATUS_MCOPY_PROBLEM 0x20 %define PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x21 %define PXENV_STATUS_BIS_VALIDATE_FAILURE 0x22 %define PXENV_STATUS_BIS_INIT_FAILURE 0x23 %define PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x24 %define PXENV_STATUS_BIS_GBOA_FAILURE 0x25 %define PXENV_STATUS_BIS_FREE_FAILURE 0x26 %define PXENV_STATUS_BIS_GSI_FAILURE 0x27 %define PXENV_STATUS_BIS_BAD_CKSUM 0x28 %define PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x30 %define PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x32 %define PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x33 %define PXENV_STATUS_TFTP_READ_TIMEOUT 0x35 %define PXENV_STATUS_TFTP_ERROR_OPCODE 0x36 %define PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x38 %define PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x39 %define PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x3A %define PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x3B %define PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x3C %define PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x3D %define PXENV_STATUS_TFTP_NO_FILESIZE 0x3E %define PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x3F %define PXENV_STATUS_DHCP_TIMEOUT 0x51 %define PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x52 %define PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x53 %define PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x54 %define PXENV_STATUS_UNDI_INVALID_FUNCTION 0x60 %define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x61 %define PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x62 %define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x63 %define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x64 %define PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x65 %define PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x66 %define PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x67 %define PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x68 %define PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x69 %define PXENV_STATUS_UNDI_INVALID_STATE 0x6A %define PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x6B %define PXENV_STATUS_UNDI_INVALID_PARAMETER 0x6C %define PXENV_STATUS_BSTRAP_PROMPT_MENU 0x74 %define PXENV_STATUS_BSTRAP_MCAST_ADDR 0x76 %define PXENV_STATUS_BSTRAP_MISSING_LIST 0x77 %define PXENV_STATUS_BSTRAP_NO_RESPONSE 0x78 %define PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x79 %define PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0xA0 %define PXENV_STATUS_BINL_NO_PXE_SERVER 0xA1 %define PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0xA2 %define PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0xA3 %define PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0xB0 %define PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0xC0 %define PXENV_STATUS_LOADER_NO_BC_ROMID 0xC1 %define PXENV_STATUS_LOADER_BAD_BC_ROMID 0xC2 %define PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0xC3 %define PXENV_STATUS_LOADER_NO_UNDI_ROMID 0xC4 %define PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0xC5 %define PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0xC6 %define PXENV_STATUS_LOADER_NO_PXE_STRUCT 0xC8 %define PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0xC9 %define PXENV_STATUS_LOADER_UNDI_START 0xCA %define PXENV_STATUS_LOADER_BC_START 0xCB %endif ; _PXE_INC syslinux-legacy-3.63+dfsg/isolinux-debug.bin0000664000175000017500000003114510777447306017645 0ustar evanevan@|e2ᆳᆳᆳᆳᆳᆳᆳᆳᆳᆳ.&p.r1м{W؎f1@|fff>hy|"f1fKyy8kbf> |u3ځTff!t EfhfG^f(f |f|f-fflff vf |f@@3@1ۋ.vP_ X rflf>h&fffIt !u؎f9>|t u*Trying BrokenAwardHack first ... BAH: Original Int 13 vector : BAH: Int 13 vector changed to : BAH: SUCCESS BAH: FAILURE |L}}fLf7~4~1W;~_Gq(~f7~f tAfL;&fEf;7~tfLfP}fX4~Kyr~p `K~ar.UpM8u Ayy8t 8tJsyrɂ38 ˾ PV^Xff`1fafý\É\fDU;.܃v.܃lVyB^]fDfD)D!ufD{f`r È&xfat{t$P{&<w <w &܃&X¾rBx\~Ct]7E"1؎м{rP  Xff` tfafff`fff`fff`ffP$< s07fXfaf ISOLINUX 3.63 2008-04-10 Copyright (C) 1994-2008 H. Peter Anvin isolinux: Starting up, DL = Loaded spec packet OK, drive = Sector size appears to be Loading main image from LBA = Sectors to load = Loaded boot image, verifying... Image checksum verified. Main image read, jumping to main code... No boot info table, assuming single session disk... Spec packet missing LBA information, trying to wing it... Loading spec packet failed, trying to wing it... Found something at drive = Looks like it might be right, continuing... Extremely broken BIOS detected, last ditch attempt with drive = Failed to locate CD-ROM device; boot failed. See http://syslinux.zytor.com/sbm for more information. Disk error , AX = , drive Image checksum error, sorry... Boot failed: press a key to retry... Lf1f+u=s G(fQ#f|Jff\fP @ff`fTff fdfXf=u k3t$fTfDfXf1ffPVĩ^uCt >11WrE>t+u +[>v+\+tfh+f+fd+f+7f&+ <t;< rwt+uJsԪ < <t-<t<<t<utOj"d+0&+<0rt <9vr+ WŹ_1۠Ƣ+>u,>x+t[VW Ǿοl+>r+_^+ 0uO>+S [f6+fDv݋p+!u WЦ:^6փ ޿VWQQW_[tۍE1Y_^ 6lu(X;ltf+tf+uYcֿn+YMË6+f++` l >aWP 0uOfMX_>+f f.comf.cbtf.c32f.imgE f.bsstUVf+1f+>r+  6+1+ < vNff=vga=t/f=mem=tVu< v.6+1.+< wN뺃fDf==nortKf==exttKf==asktrωɃrf.f+6+f+7&f>HdrS&+==r&$&=r &f,f+&3f1&f&+&!u+ i1cf+f-f;+[f6+F ff)fQff잾2% fY^f+f-v1һf>+ 2>+t 45 ++tr df(d ?d>"Drd$v df( +9vd󤪁r&>+u?11df>+G@) f1ff+ff&>u& ÎێӼ߃ Sj19+t=++m .6+< wN1VPN.;6+t<,uFV A ^X_.;6+wȎ؎ Y > f fQf+fJf+f9vffBf)ʁf;+r\&f>t &ff)&f&fffJf+V&" 1^fXþo փþFz!u=sV_ 1@f1f& &} & t ,&^P ؎1j h\fӌfff,ff`͎ݎʼn  ɧ:FЉF,fa(h1[1؎м{ yeyÊFÊF^ JÎF&v&<$tÀ>%ux ȈFfFSYfFSLfFINfFUXÀ>%um u&$%Fà$%f`͎ݎʼn3r1FF?F3N^$FFÎ^$vÎ^$vhhK^$v q9tFVFvÎF$^vNs1vËvF3F yFN"F{N$Fá~+F+F+&+`+ùF11fFffFff|ff(fvfV^&N$FFÁ~Uw/NQg If$vWdffFf(fvfV^&_ËFN$F'FÊF<w⢦+^&v Jy6+++^$v18 ؎1&E >r++&Fw4NV(*u1à" t ^$F+Ffvf vufFF$^nDÁ~UwFNQg If$vWdff&vf( @dfEf)}f(+1:Á~UwXRNQg If$vWdff&v(d؀Eꐐfdfdff((Ì^$FFVRPe r+A)dffX^1һfwȎ؉& RuΘ)(b "Y 1а(؎а0؋%g&+f1 1QY`g(Ohhhhhhj'~f%1؎Ўh $" Ȏ؎&h*fRffaf.&.&ff`fڒ.&.f fV1ۋf"]aϜ`D$(`D$(g>g 6fg>ߋt$,1ɱ 󥫸CG% Gff3g6g |$0!u1ɱ g6aÜ`L$0g>g fg>)σfg>ߋD$(\t$,f[ag  6+>r+yO>r+Òfff>fW1һ ff>f|ff(f1f1y1jh x1؎{W_&fU&fu &]{{&E&][XfӖt `4<t<taþn,1؎м{%p+!f`11faf¿fffEf;f> U 1}t ufPfR0C0ff f[f1ff!tf@f=vHf[fܰآff Ly&pA꾂(8v܊\?8v] .&l1ҎڎŽAt/0R1PDZ|f.&p|!tf10zuP=/uG\fDfGfffT G t/uEzWQhhf`ދfafz] !u ƃmru&Fu_^[KA ] f`(]5fMg&fvfMf)M 05fa뤉Mfa0SVz7z^[WS>z] A C] [_Yr <t < t < v8ÿ'sW6_r<-sfPfQUf1ff1<-u<0rSt<9wM <0r% b +@:+w%+>b+ø1+<þփ+t++@:+w+1ɋ+6+>b+믾|+t1ɉ++>+r/+t++Tr+t++|h!++t< t< v>fhsG>f6fhh)t`>b+a$++t+ff`~+!tP&+W tB 8uX faf+t tf`u~+!ttB&+ 8faôu"~+!tWtB&+ 8u0ôn+ÿ%މ>p+À>+wΉ>l+ÿƃu >-u1>,>+t1À>+t P^rf*fffP^rPb u>uXPQ duX|+rSs[}+r)fSrhs1ۀ>+߁+f[f%_fKrfff+Pw狽>~+UX BBB<u:JJ0Bt~+Pk_Ĺ1Vi+ĹοƋl+/&#r ff%f=ENDTuff%f=EXTuÿW.^ÿ1 s|+uƿǹ)1f>+ f>+þEhQfSfR1f1fOfg[fOgI8t1Cgy؀rg(ufGCf8u sCIbs ~fOg fgfOg'NfZf[Yh蔊W1fNg,s fNgs ~fNgـfNgY)PtUr<#tQ ffSf[r@< v f0%t*r (+ff9tfب 2< tLr!tYSfPf=vffPff fW1f_fYfQfWt &gfAfVf草f^f_fYfXff)[uP.X\j=6ui<wb>rY wT> +f"4t"t@+> 04t1Ɉ*H+!(H+ù1Ҹ0۸` u+̈&+aVu8,"rtf>,=ui41۹2 H1:+r+Ȉƴ12dQWf1f_W0^Nj>d^dPY!148tIu1$tQوY)w Ãt_$úB`ˬՇwav4<t@t O1w%#4f(Eb+1f`Ȏ؎4 ttO4b+faf`_f` >4u faf`fKfKf1f!txf fPAMSf1ɱKsf!u[pf=PAMSuhf>KwfKf>Ktf=rf;KsfKf;KwfKrf>Ktff;KvfK~fKf;KvfKf=w8r=bPX<tV< tN< tR>b Z:+v 0:6+w>bfafΊ>b>b+1ɋ+0ӀsΊ+s0>@O>@t9t,1t%f/-Zffgff1}ffd(fÿfVff=/-Zuf1ҹ~fffguff=d(^P18t tƁr =v1XPVW uYQ18t t#Ɓr|Wƹ)r%^^NY΁sވЪȪd)1_^Xf`}f1fffgf)Ѝ|fDffaf>8tf><t>@t PXPXÈ&Kf`@ Ҵr uBK?KUA@ir9f8 f<faf1VfRfPSjjf`@@ &Kfadr^^fRfPUf6Kf>Kf1ɇff=w'Aň֊@&Kf`far]fXfZMuIt appears your computer has less than 192K of low ("DOS") RAM. Linux needs at least this amount to boot. If you get this message in error, hold down the Ctrl key while booting, and I will take your word for it. boot:  Invalid image type for this media type! Could not find kernel image: Invalid or corrupt kernel image. ̇MuDuDj0 Loading ..ready. Cannot load a ramdisk with an old kernel image. Could not find ramdisk image: Not enough memory to load specified kernel. BOOT_IMAGE=ӌWemu z 0Lӌ, .9KQVy ߎ & ^ds܏4䐴(: attempted DOS system call COMBOOT image too large.  aborted. ( linux autoOut of memory parsing config file Unknown keyword in configuration file. Missing parameter in configuration file. A20 gate not responding!  Booting from local disk... default/boot/isolinuxisolinux.cfgCannot load disk image (invalid file)? Root directory at LBA = isolinux directory at LBA = About to load config file... Configuration file opened... initrd=7t;wf9ԛYQ@ Lf2Ux+KP-U̴h 6 0  e N  R2 G Ut:t+KYLh|1`+K2d+4Qh+4^hśHz+K v+K L L L L L L L L LL LLL.cbt.img.bin.com.c32OO-O$ ?(g\(f`h) fafffPfUf.)f1ff .f )f.( "b)8аذ01V ] $")ff]fXftCf9r$fgfgfgtfg|fffgfffgff1΃fgfgf`.(..Z+.P+.Z+du_.Z+$RuMouF.Z+d^`WQ1/u)Y.Z+ $Q1uY.(uiYfaQP .(@.(e&;(XY0t uLdtC`u8!tf?fwfOft) Hufaf..(ffQfXf1f f.)f.( "6+ 1а0ذ(؎Ўf**(*:*`*syslinux-legacy-3.63+dfsg/pxelinux.asm0000664000175000017500000016121410777447273016577 0ustar evanevan; -*- fundamental -*- (asm-mode sucks) ; **************************************************************************** ; ; pxelinux.asm ; ; A program to boot Linux kernels off a TFTP server using the Intel PXE ; network booting API. It is based on the SYSLINUX boot loader for ; MS-DOS floppies. ; ; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, Inc., 53 Temple Place Ste 330, ; Boston MA 02111-1307, USA; either version 2 of the License, or ; (at your option) any later version; incorporated herein by reference. ; ; **************************************************************************** %define IS_PXELINUX 1 %include "head.inc" %include "pxe.inc" ; ; Some semi-configurable constants... change on your own risk. ; my_id equ pxelinux_id FILENAME_MAX_LG2 equ 7 ; log2(Max filename size Including final null) FILENAME_MAX equ (1 << FILENAME_MAX_LG2) NULLFILE equ 0 ; Zero byte == null file name NULLOFFSET equ 4 ; Position in which to look REBOOT_TIME equ 5*60 ; If failure, time until full reset %assign HIGHMEM_SLOP 128*1024 ; Avoid this much memory near the top MAX_OPEN_LG2 equ 5 ; log2(Max number of open sockets) MAX_OPEN equ (1 << MAX_OPEN_LG2) PKTBUF_SIZE equ (65536/MAX_OPEN) ; Per-socket packet buffer size TFTP_PORT equ htons(69) ; Default TFTP port PKT_RETRY equ 6 ; Packet transmit retry count PKT_TIMEOUT equ 12 ; Initial timeout, timer ticks @ 55 ms ; Desired TFTP block size ; For Ethernet MTU is normally 1500. Unfortunately there seems to ; be a fair number of networks with "substandard" MTUs which break. ; The code assumes TFTP_LARGEBLK <= 2K. TFTP_MTU equ 1440 TFTP_LARGEBLK equ (TFTP_MTU-20-8-4) ; MTU - IP hdr - UDP hdr - TFTP hdr ; Standard TFTP block size TFTP_BLOCKSIZE_LG2 equ 9 ; log2(bytes/block) TFTP_BLOCKSIZE equ (1 << TFTP_BLOCKSIZE_LG2) %assign USE_PXE_PROVIDED_STACK 1 ; Use stack provided by PXE? SECTOR_SHIFT equ TFTP_BLOCKSIZE_LG2 SECTOR_SIZE equ TFTP_BLOCKSIZE ; ; This is what we need to do when idle ; *** This is disabled because some PXE stacks wait for unacceptably ; *** long if there are no packets receivable. %define HAVE_IDLE 0 ; idle is not a noop %if HAVE_IDLE %macro RESET_IDLE 0 call reset_idle %endmacro %macro DO_IDLE 0 call check_for_arp %endmacro %else %macro RESET_IDLE 0 ; Nothing %endmacro %macro DO_IDLE 0 ; Nothing %endmacro %endif ; ; TFTP operation codes ; TFTP_RRQ equ htons(1) ; Read request TFTP_WRQ equ htons(2) ; Write request TFTP_DATA equ htons(3) ; Data packet TFTP_ACK equ htons(4) ; ACK packet TFTP_ERROR equ htons(5) ; ERROR packet TFTP_OACK equ htons(6) ; OACK packet ; ; TFTP error codes ; TFTP_EUNDEF equ htons(0) ; Unspecified error TFTP_ENOTFOUND equ htons(1) ; File not found TFTP_EACCESS equ htons(2) ; Access violation TFTP_ENOSPACE equ htons(3) ; Disk full TFTP_EBADOP equ htons(4) ; Invalid TFTP operation TFTP_EBADID equ htons(5) ; Unknown transfer TFTP_EEXISTS equ htons(6) ; File exists TFTP_ENOUSER equ htons(7) ; No such user TFTP_EOPTNEG equ htons(8) ; Option negotiation failure ; ; The following structure is used for "virtual kernels"; i.e. LILO-style ; option labels. The options we permit here are `kernel' and `append ; Since there is no room in the bottom 64K for all of these, we ; stick them in high memory and copy them down before we need them. ; struc vkernel vk_vname: resb FILENAME_MAX ; Virtual name **MUST BE FIRST!** vk_rname: resb FILENAME_MAX ; Real name vk_ipappend: resb 1 ; "IPAPPEND" flag vk_type: resb 1 ; Type of file vk_appendlen: resw 1 alignb 4 vk_append: resb max_cmd_len+1 ; Command line alignb 4 vk_end: equ $ ; Should be <= vk_size endstruc ; ; Segment assignments in the bottom 640K ; 0000h - main code/data segment (and BIOS segment) ; real_mode_seg equ 3000h pktbuf_seg equ 2000h ; Packet buffers segments xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem comboot_seg equ real_mode_seg ; COMBOOT image loading zone ; ; BOOTP/DHCP packet pattern ; struc bootp_t bootp: .opcode resb 1 ; BOOTP/DHCP "opcode" .hardware resb 1 ; ARP hardware type .hardlen resb 1 ; Hardware address length .gatehops resb 1 ; Used by forwarders .ident resd 1 ; Transaction ID .seconds resw 1 ; Seconds elapsed .flags resw 1 ; Broadcast flags .cip resd 1 ; Client IP .yip resd 1 ; "Your" IP .sip resd 1 ; Next server IP .gip resd 1 ; Relay agent IP .macaddr resb 16 ; Client MAC address .sname resb 64 ; Server name (optional) .bootfile resb 128 ; Boot file name .option_magic resd 1 ; Vendor option magic cookie .options resb 1260 ; Vendor options endstruc BOOTP_OPTION_MAGIC equ htonl(0x63825363) ; See RFC 2132 ; ; TFTP connection data structure. Each one of these corresponds to a local ; UDP port. The size of this structure must be a power of 2. ; HBO = host byte order; NBO = network byte order ; (*) = written by options negotiation code, must be dword sized ; struc open_file_t tftp_localport resw 1 ; Local port number (0 = not in use) tftp_remoteport resw 1 ; Remote port number tftp_remoteip resd 1 ; Remote IP address tftp_filepos resd 1 ; Bytes downloaded (including buffer) tftp_filesize resd 1 ; Total file size(*) tftp_blksize resd 1 ; Block size for this connection(*) tftp_bytesleft resw 1 ; Unclaimed data bytes tftp_lastpkt resw 1 ; Sequence number of last packet (NBO) tftp_dataptr resw 1 ; Pointer to available data resw 2 ; Currently unusued ; At end since it should not be zeroed on socked close tftp_pktbuf resw 1 ; Packet buffer offset endstruc %ifndef DEPEND %if (open_file_t_size & (open_file_t_size-1)) %error "open_file_t is not a power of 2" %endif %endif ; --------------------------------------------------------------------------- ; BEGIN CODE ; --------------------------------------------------------------------------- ; ; Memory below this point is reserved for the BIOS and the MBR ; section .earlybss trackbufsize equ 8192 trackbuf resb trackbufsize ; Track buffer goes here ; ends at 2800h alignb open_file_t_size Files resb MAX_OPEN*open_file_t_size alignb FILENAME_MAX BootFile resb 256 ; Boot file from DHCP packet PathPrefix resb 256 ; Path prefix derived from boot file DotQuadBuf resb 16 ; Buffer for dotted-quad IP address IPOption resb 80 ; ip= option buffer InitStack resd 1 ; Pointer to reset stack (SS:SP) PXEStack resd 1 ; Saved stack during PXE call section .bss alignb 4 RebootTime resd 1 ; Reboot timeout, if set by option StrucPtr resd 1 ; Pointer to PXENV+ or !PXE structure APIVer resw 1 ; PXE API version found IPOptionLen resw 1 ; Length of IPOption IdleTimer resw 1 ; Time to check for ARP? LocalBootType resw 1 ; Local boot return code PktTimeout resw 1 ; Timeout for current packet RealBaseMem resw 1 ; Amount of DOS memory after freeing OverLoad resb 1 ; Set if DHCP packet uses "overloading" DHCPMagic resb 1 ; PXELINUX magic flags ; The relative position of these fields matter! MAC_MAX equ 32 ; Handle hardware addresses this long MACLen resb 1 ; MAC address len MACType resb 1 ; MAC address type MAC resb MAC_MAX+1 ; Actual MAC address BOOTIFStr resb 7 ; Space for "BOOTIF=" MACStr resb 3*(MAC_MAX+1) ; MAC address as a string ; The relative position of these fields matter! UUIDType resb 1 ; Type byte from DHCP option UUID resb 16 ; UUID, from the PXE stack UUIDNull resb 1 ; dhcp_copyoption zero-terminates ; ; PXE packets which don't need static initialization ; alignb 4 pxe_unload_stack_pkt: .status: resw 1 ; Status .reserved: resw 10 ; Reserved pxe_unload_stack_pkt_len equ $-pxe_unload_stack_pkt alignb 16 ; BOOTP/DHCP packet buffer section .bss2 alignb 16 packet_buf resb 2048 ; Transfer packet packet_buf_size equ $-packet_buf section .text ; ; PXELINUX needs more BSS than the other derivatives; ; therefore we relocate it from 7C00h on startup. ; StackBuf equ $ ; Base of stack if we use our own ; ; Primary entry point. ; bootsec equ $ _start: pushfd ; Paranoia... in case of return to PXE pushad ; ... save as much state as possible push ds push es push fs push gs xor ax,ax mov ds,ax mov es,ax %ifndef DEPEND %if TEXT_START != 0x7c00 ; This is uglier than it should be, but works around ; some NASM 0.98.38 bugs. mov di,section..bcopy32.start add di,__bcopy_size-4 lea si,[di-(TEXT_START-7C00h)] lea cx,[di-(TEXT_START-4)] shr cx,2 std ; Overlapping areas, copy backwards rep movsd %endif %endif jmp 0:_start1 ; Canonicalize address _start1: mov bp,sp les bx,[bp+48] ; ES:BX -> !PXE or PXENV+ structure ; That is all pushed onto the PXE stack. Save the pointer ; to it and switch to an internal stack. mov [InitStack],sp mov [InitStack+2],ss %if USE_PXE_PROVIDED_STACK ; Apparently some platforms go bonkers if we ; set up our own stack... mov [BaseStack],sp mov [BaseStack+4],ss %endif cli ; Paranoia lss esp,[BaseStack] sti ; Stack set up and ready cld ; Copy upwards ; ; Initialize screen (if we're using one) ; push es ; Save ES -> PXE entry structure push ds pop es ; ES <- DS %include "init.inc" pop es ; Restore ES -> PXE entry structure ; ; Tell the user we got this far ; mov si,syslinux_banner call writestr mov si,copyright_str call writestr ; ; Assume API version 2.1, in case we find the !PXE structure without ; finding the PXENV+ structure. This should really look at the Base ; Code ROM ID structure in have_pxe, but this is adequate for now -- ; if we have !PXE, we have to be 2.1 or higher, and we don't care ; about higher versions than that. ; mov word [APIVer],0201h ; ; Now we need to find the !PXE structure. It's *supposed* to be pointed ; to by SS:[SP+4], but support INT 1Ah, AX=5650h method as well. ; FIX: ES:BX should point to the PXENV+ structure on entry as well. ; We should make that the second test, and not trash ES:BX... ; cmp dword [es:bx], '!PXE' je have_pxe ; Uh-oh, not there... try plan B mov ax, 5650h %if USE_PXE_PROVIDED_STACK == 0 lss sp,[InitStack] %endif int 1Ah ; May trash regs %if USE_PXE_PROVIDED_STACK == 0 lss esp,[BaseStack] %endif jc no_pxe cmp ax,564Eh jne no_pxe ; Okay, that gave us the PXENV+ structure, find !PXE ; structure from that (if available) cmp dword [es:bx], 'PXEN' jne no_pxe cmp word [es:bx+4], 'V+' je have_pxenv ; Nothing there either. Last-ditch: scan memory call memory_scan_for_pxe_struct ; !PXE scan jnc have_pxe call memory_scan_for_pxenv_struct ; PXENV+ scan jnc have_pxenv no_pxe: mov si,err_nopxe call writestr jmp kaboom have_pxenv: mov [StrucPtr],bx mov [StrucPtr+2],es mov si,found_pxenv call writestr mov si,apiver_str call writestr mov ax,[es:bx+6] mov [APIVer],ax call writehex4 call crlf cmp ax,0201h ; API version 2.1 or higher jb old_api mov si,bx mov ax,es les bx,[es:bx+28h] ; !PXE structure pointer cmp dword [es:bx],'!PXE' je have_pxe ; Nope, !PXE structure missing despite API 2.1+, or at least ; the pointer is missing. Do a last-ditch attempt to find it. call memory_scan_for_pxe_struct jnc have_pxe ; Otherwise, no dice, use PXENV+ structure mov bx,si mov es,ax old_api: ; Need to use a PXENV+ structure mov si,using_pxenv_msg call writestr mov eax,[es:bx+0Ah] ; PXE RM API mov [PXENVEntry],eax mov si,undi_data_msg call writestr mov ax,[es:bx+20h] call writehex4 call crlf mov si,undi_data_len_msg call writestr mov ax,[es:bx+22h] call writehex4 call crlf mov si,undi_code_msg call writestr mov ax,[es:bx+24h] call writehex4 call crlf mov si,undi_code_len_msg call writestr mov ax,[es:bx+26h] call writehex4 call crlf ; Compute base memory size from PXENV+ structure xor esi,esi movzx eax,word [es:bx+20h] ; UNDI data seg cmp ax,[es:bx+24h] ; UNDI code seg ja .use_data mov ax,[es:bx+24h] mov si,[es:bx+26h] jmp short .combine .use_data: mov si,[es:bx+22h] .combine: shl eax,4 add eax,esi shr eax,10 ; Convert to kilobytes mov [RealBaseMem],ax mov si,pxenventry_msg call writestr mov ax,[PXENVEntry+2] call writehex4 mov al,':' call writechr mov ax,[PXENVEntry] call writehex4 call crlf jmp have_entrypoint have_pxe: mov [StrucPtr],bx mov [StrucPtr+2],es mov eax,[es:bx+10h] mov [PXEEntry],eax mov si,undi_data_msg call writestr mov eax,[es:bx+2Ah] call writehex8 call crlf mov si,undi_data_len_msg call writestr mov ax,[es:bx+2Eh] call writehex4 call crlf mov si,undi_code_msg call writestr mov ax,[es:bx+32h] call writehex8 call crlf mov si,undi_code_len_msg call writestr mov ax,[es:bx+36h] call writehex4 call crlf ; Compute base memory size from !PXE structure xor esi,esi mov eax,[es:bx+2Ah] cmp eax,[es:bx+32h] ja .use_data mov eax,[es:bx+32h] mov si,[es:bx+36h] jmp short .combine .use_data: mov si,[es:bx+2Eh] .combine: add eax,esi shr eax,10 mov [RealBaseMem],ax mov si,pxeentry_msg call writestr mov ax,[PXEEntry+2] call writehex4 mov al,':' call writechr mov ax,[PXEEntry] call writehex4 call crlf have_entrypoint: push cs pop es ; Restore CS == DS == ES ; ; Network-specific initialization ; xor ax,ax mov [LocalDomain],al ; No LocalDomain received ; ; The DHCP client identifiers are best gotten from the DHCPREQUEST ; packet (query info 1). ; query_bootp_1: mov dl,1 call pxe_get_cached_info call parse_dhcp ; We don't use flags from the request packet, so ; this is a good time to initialize DHCPMagic... ; Initialize it to 1 meaning we will accept options found; ; in earlier versions of PXELINUX bit 0 was used to indicate ; we have found option 208 with the appropriate magic number; ; we no longer require that, but MAY want to re-introduce ; it in the future for vendor encapsulated options. mov byte [DHCPMagic],1 ; ; Now attempt to get the BOOTP/DHCP packet that brought us life (and an IP ; address). This lives in the DHCPACK packet (query info 2). ; query_bootp_2: mov dl,2 call pxe_get_cached_info call parse_dhcp ; Parse DHCP packet ; ; Save away MAC address (assume this is in query info 2. If this ; turns out to be problematic it might be better getting it from ; the query info 1 packet.) ; .save_mac: movzx cx,byte [trackbuf+bootp.hardlen] cmp cx,16 jna .mac_ok xor cx,cx ; Bad hardware address length .mac_ok: mov [MACLen],cl mov al,[trackbuf+bootp.hardware] mov [MACType],al mov si,trackbuf+bootp.macaddr mov di,MAC rep movsb ; Enable this if we really need to zero-pad this field... ; mov cx,MAC+MAC_MAX+1 ; sub cx,di ; xor ax,ax ; rep stosb ; ; Now, get the boot file and other info. This lives in the CACHED_REPLY ; packet (query info 3). ; mov dl,3 call pxe_get_cached_info call parse_dhcp ; Parse DHCP packet ; ; Generate the bootif string, and the hardware-based config string. ; make_bootif_string: mov si,bootif_str mov di,BOOTIFStr mov cx,bootif_str_len rep movsb movzx cx,byte [MACLen] mov si,MACType inc cx .hexify_mac: push cx mov cl,1 ; CH == 0 already call lchexbytes mov al,'-' stosb pop cx loop .hexify_mac mov [di-1],cl ; Null-terminate and strip final dash ; ; Generate ip= option ; call genipopt ; ; Print IP address ; mov eax,[MyIP] mov di,DotQuadBuf push di call gendotquad ; This takes network byte order input xchg ah,al ; Convert to host byte order ror eax,16 ; (BSWAP doesn't work on 386) xchg ah,al mov si,myipaddr_msg call writestr call writehex8 mov al,' ' call writechr pop si ; DotQuadBuf call writestr call crlf mov si,IPOption call writestr call crlf ; ; Check to see if we got any PXELINUX-specific DHCP options; in particular, ; if we didn't get the magic enable, do not recognize any other options. ; check_dhcp_magic: test byte [DHCPMagic], 1 ; If we didn't get the magic enable... jnz .got_magic mov byte [DHCPMagic], 0 ; If not, kill all other options .got_magic: ; ; Initialize UDP stack ; udp_init: mov eax,[MyIP] mov [pxe_udp_open_pkt.sip],eax mov di,pxe_udp_open_pkt mov bx,PXENV_UDP_OPEN call pxenv jc .failed cmp word [pxe_udp_open_pkt.status], byte 0 je .success .failed: mov si,err_udpinit call writestr jmp kaboom .success: ; ; Common initialization code ; %include "cpuinit.inc" ; ; Now we're all set to start with our *real* business. First load the ; configuration file (if any) and parse it. ; ; In previous versions I avoided using 32-bit registers because of a ; rumour some BIOSes clobbered the upper half of 32-bit registers at ; random. I figure, though, that if there are any of those still left ; they probably won't be trying to install Linux on them... ; ; The code is still ripe with 16-bitisms, though. Not worth the hassle ; to take'm out. In fact, we may want to put them back if we're going ; to boot ELKS at some point. ; ; ; Store standard filename prefix ; prefix: test byte [DHCPMagic], 04h ; Did we get a path prefix option jnz .got_prefix mov si,BootFile mov di,PathPrefix cld call strcpy mov cx,di sub cx,PathPrefix+1 std lea si,[di-2] ; Skip final null! .find_alnum: lodsb or al,20h cmp al,'.' ; Count . or - as alphanum je .alnum cmp al,'-' je .alnum cmp al,'0' jb .notalnum cmp al,'9' jbe .alnum cmp al,'a' jb .notalnum cmp al,'z' ja .notalnum .alnum: loop .find_alnum dec si .notalnum: mov byte [si+2],0 ; Zero-terminate after delimiter cld .got_prefix: mov si,tftpprefix_msg call writestr mov si,PathPrefix call writestr call crlf ; ; Load configuration file ; find_config: ; ; Begin looking for configuration file ; config_scan: test byte [DHCPMagic], 02h jz .no_option ; We got a DHCP option, try it first call .try jnz .success .no_option: mov di,ConfigName mov si,cfgprefix mov cx,cfgprefix_len rep movsb ; Have to guess config file name... ; Try loading by UUID. cmp byte [HaveUUID],0 je .no_uuid push di mov bx,uuid_dashes mov si,UUID .gen_uuid: movzx cx,byte [bx] jcxz .done_uuid inc bx call lchexbytes mov al,'-' stosb jmp .gen_uuid .done_uuid: mov [di-1],cl ; Remove last dash and zero-terminate pop di call .try jnz .success .no_uuid: ; Try loading by MAC address push di mov si,MACStr call strcpy pop di call .try jnz .success ; Nope, try hexadecimal IP prefixes... .scan_ip: mov cx,4 mov si,MyIP call uchexbytes ; Convert to hex string mov cx,8 ; Up to 8 attempts .tryagain: mov byte [di],0 ; Zero-terminate string call .try jnz .success dec di ; Drop one character loop .tryagain ; Final attempt: "default" string mov si,default_str ; "default" string call strcpy call .try jnz .success mov si,err_noconfig call writestr jmp kaboom .try: pusha mov si,trying_msg call writestr mov di,ConfigName mov si,di call writestr call crlf mov si,di mov di,KernelName ; Borrow this buffer for mangled name call mangle_name call open popa ret .success: ; ; Linux kernel loading code is common. However, we need to define ; a couple of helper macros... ; ; Handle "ipappend" option %define HAVE_SPECIAL_APPEND %macro SPECIAL_APPEND 0 test byte [IPAppend],01h ; ip= jz .noipappend1 mov si,IPOption mov cx,[IPOptionLen] rep movsb mov al,' ' stosb .noipappend1: test byte [IPAppend],02h jz .noipappend2 mov si,BOOTIFStr call strcpy mov byte [es:di-1],' ' ; Replace null with space .noipappend2: %endmacro ; Unload PXE stack %define HAVE_UNLOAD_PREP %macro UNLOAD_PREP 0 call unload_pxe %endmacro ; ; Now we have the config file open. Parse the config file and ; run the user interface. ; %include "ui.inc" ; ; Boot to the local disk by returning the appropriate PXE magic. ; AX contains the appropriate return code. ; local_boot: push cs pop ds mov [LocalBootType],ax call vgaclearmode mov si,localboot_msg call writestr ; Restore the environment we were called with lss sp,[InitStack] pop gs pop fs pop es pop ds popad mov ax,[cs:LocalBootType] popfd retf ; Return to PXE ; ; kaboom: write a message and bail out. Wait for quite a while, ; or a user keypress, then do a hard reboot. ; kaboom: RESET_STACK_AND_SEGS AX .patch: mov si,bailmsg call writestr ; Returns with AL = 0 .drain: call pollchar jz .drained call getchar jmp short .drain .drained: mov edi,[RebootTime] mov al,[DHCPMagic] and al,09h ; Magic+Timeout cmp al,09h je .time_set mov edi,REBOOT_TIME .time_set: mov cx,18 .wait1: push cx mov ecx,edi .wait2: mov dx,[BIOS_timer] .wait3: call pollchar jnz .keypress cmp dx,[BIOS_timer] je .wait3 loop .wait2,ecx mov al,'.' call writechr pop cx loop .wait1 .keypress: call crlf mov word [BIOS_magic],0 ; Cold reboot jmp 0F000h:0FFF0h ; Reset vector address ; ; memory_scan_for_pxe_struct: ; ; If none of the standard methods find the !PXE structure, look for it ; by scanning memory. ; ; On exit, if found: ; CF = 0, ES:BX -> !PXE structure ; Otherwise CF = 1, all registers saved ; memory_scan_for_pxe_struct: push ds pusha mov ax,cs mov ds,ax mov si,trymempxe_msg call writestr mov ax,[BIOS_fbm] ; Starting segment shl ax,(10-4) ; Kilobytes -> paragraphs ; mov ax,01000h ; Start to look here dec ax ; To skip inc ax .mismatch: inc ax cmp ax,0A000h ; End of memory jae .not_found call writehex4 mov si,fourbs_msg call writestr mov es,ax mov edx,[es:0] cmp edx,'!PXE' jne .mismatch movzx cx,byte [es:4] ; Length of structure cmp cl,08h ; Minimum length jb .mismatch push ax xor ax,ax xor si,si .checksum: es lodsb add ah,al loop .checksum pop ax jnz .mismatch ; Checksum must == 0 .found: mov bp,sp xor bx,bx mov [bp+8],bx ; Save BX into stack frame (will be == 0) mov ax,es call writehex4 call crlf popa pop ds clc ret .not_found: mov si,notfound_msg call writestr popa pop ds stc ret ; ; memory_scan_for_pxenv_struct: ; ; If none of the standard methods find the PXENV+ structure, look for it ; by scanning memory. ; ; On exit, if found: ; CF = 0, ES:BX -> PXENV+ structure ; Otherwise CF = 1, all registers saved ; memory_scan_for_pxenv_struct: pusha mov si,trymempxenv_msg call writestr ; mov ax,[BIOS_fbm] ; Starting segment ; shl ax,(10-4) ; Kilobytes -> paragraphs mov ax,01000h ; Start to look here dec ax ; To skip inc ax .mismatch: inc ax cmp ax,0A000h ; End of memory jae .not_found mov es,ax mov edx,[es:0] cmp edx,'PXEN' jne .mismatch mov dx,[es:4] cmp dx,'V+' jne .mismatch movzx cx,byte [es:8] ; Length of structure cmp cl,26h ; Minimum length jb .mismatch xor ax,ax xor si,si .checksum: es lodsb add ah,al loop .checksum and ah,ah jnz .mismatch ; Checksum must == 0 .found: mov bp,sp mov [bp+8],bx ; Save BX into stack frame mov ax,bx call writehex4 call crlf clc ret .not_found: mov si,notfound_msg call writestr popad stc ret ; ; close_file: ; Deallocates a file structure (pointer in SI) ; Assumes CS == DS. ; ; XXX: We should check to see if this file is still open on the server ; side and send a courtesy ERROR packet to the server. ; close_file: and si,si jz .closed mov word [si],0 ; Not in use .closed: ret ; ; searchdir: ; ; Open a TFTP connection to the server ; ; On entry: ; DS:DI = mangled filename ; If successful: ; ZF clear ; SI = socket pointer ; DX:AX = file length in bytes ; If unsuccessful ; ZF set ; searchdir: push es push bx push cx mov ax,ds mov es,ax mov si,di push bp mov bp,sp call allocate_socket jz .ret mov ax,PKT_RETRY ; Retry counter mov word [PktTimeout],PKT_TIMEOUT ; Initial timeout .sendreq: push ax ; [bp-2] - Retry counter push si ; [bp-4] - File name mov di,packet_buf mov [pxe_udp_write_pkt.buffer],di mov ax,TFTP_RRQ ; TFTP opcode stosw lodsd ; EAX <- server override (if any) and eax,eax jnz .noprefix ; No prefix, and we have the server push si ; Add common prefix mov si,PathPrefix call strcpy dec di pop si mov eax,[ServerIP] ; Get default server .noprefix: call strcpy ; Filename mov [bx+tftp_remoteip],eax push bx ; [bp-6] - TFTP block mov bx,[bx] push bx ; [bp-8] - TID (local port no) mov [pxe_udp_write_pkt.status],byte 0 mov [pxe_udp_write_pkt.sip],eax ; Now figure out the gateway xor eax,[MyIP] and eax,[Netmask] jz .nogwneeded mov eax,[Gateway] .nogwneeded: mov [pxe_udp_write_pkt.gip],eax mov [pxe_udp_write_pkt.lport],bx mov ax,[ServerPort] mov [pxe_udp_write_pkt.rport],ax mov si,tftp_tail mov cx,tftp_tail_len rep movsb sub di,packet_buf ; Get packet size mov [pxe_udp_write_pkt.buffersize],di mov di,pxe_udp_write_pkt mov bx,PXENV_UDP_WRITE call pxenv jc .failure cmp word [pxe_udp_write_pkt.status],byte 0 jne .failure ; ; Danger, Will Robinson! We need to support timeout ; and retry lest we just lost a packet... ; ; Packet transmitted OK, now we need to receive .getpacket: push word [PktTimeout] ; [bp-10] push word [BIOS_timer] ; [bp-12] .pkt_loop: mov bx,[bp-8] ; TID mov di,packet_buf mov word [pxe_udp_read_pkt.status],0 mov [pxe_udp_read_pkt.buffer],di mov [pxe_udp_read_pkt.buffer+2],ds mov word [pxe_udp_read_pkt.buffersize],packet_buf_size mov eax,[MyIP] mov [pxe_udp_read_pkt.dip],eax mov [pxe_udp_read_pkt.lport],bx mov di,pxe_udp_read_pkt mov bx,PXENV_UDP_READ call pxenv and ax,ax jz .got_packet ; Wait for packet .no_packet: mov dx,[BIOS_timer] cmp dx,[bp-12] je .pkt_loop mov [bp-12],dx dec word [bp-10] ; Timeout jnz .pkt_loop pop ax ; Adjust stack pop ax shl word [PktTimeout],1 ; Exponential backoff jmp .failure .got_packet: mov si,[bp-6] ; TFTP pointer mov bx,[bp-8] ; TID mov eax,[si+tftp_remoteip] cmp [pxe_udp_read_pkt.sip],eax ; This is technically not to the TFTP spec? jne .no_packet ; Got packet - reset timeout mov word [PktTimeout],PKT_TIMEOUT pop ax ; Adjust stack pop ax mov ax,[pxe_udp_read_pkt.rport] mov [si+tftp_remoteport],ax ; filesize <- -1 == unknown mov dword [si+tftp_filesize], -1 ; Default blksize unless blksize option negotiated mov word [si+tftp_blksize], TFTP_BLOCKSIZE mov cx,[pxe_udp_read_pkt.buffersize] sub cx,2 ; CX <- bytes after opcode jb .failure ; Garbled reply mov si,packet_buf lodsw cmp ax, TFTP_ERROR je .bailnow ; ERROR reply: don't try again cmp ax, TFTP_OACK jne .no_tsize ; Now we need to parse the OACK packet to get the transfer ; size. SI -> first byte of options; CX -> byte count .parse_oack: jcxz .no_tsize ; No options acked .get_opt_name: mov di,si mov bx,si .opt_name_loop: lodsb and al,al jz .got_opt_name or al,20h ; Convert to lowercase stosb loop .opt_name_loop ; We ran out, and no final null jmp .err_reply .got_opt_name: ; si -> option value dec cx ; bytes left in pkt jz .err_reply ; Option w/o value ; Parse option pointed to by bx; guaranteed to be ; null-terminated. push cx push si mov si,bx ; -> option name mov bx,tftp_opt_table mov cx,tftp_opts .opt_loop: push cx push si mov di,[bx] ; Option pointer mov cx,[bx+2] ; Option len repe cmpsb pop si pop cx je .get_value ; OK, known option add bx,6 loop .opt_loop pop si pop cx jmp .err_reply ; Non-negotiated option returned .get_value: pop si ; si -> option value pop cx ; cx -> bytes left in pkt mov bx,[bx+4] ; Pointer to data target add bx,[bp-6] ; TFTP socket pointer xor eax,eax xor edx,edx .value_loop: lodsb and al,al jz .got_value sub al,'0' cmp al, 9 ja .err_reply ; Not a decimal digit imul edx,10 add edx,eax mov [bx],edx loop .value_loop ; Ran out before final null, accept anyway jmp short .done_pkt .got_value: dec cx jnz .get_opt_name ; Not end of packet ; ZF == 1 ; Success, done! .done_pkt: pop si ; Junk pop si ; We want the packet ptr in SI mov eax,[si+tftp_filesize] cmp eax,-1 jz .no_tsize mov edx,eax shr edx,16 ; DX:AX == EAX and eax,eax ; Set ZF depending on file size pop bp ; Junk pop bp ; Junk (retry counter) jz .error_si ; ZF = 1 need to free the socket .ret: pop bp pop cx pop bx pop es ret .no_tsize: .err_reply: ; Option negotiation error. Send ERROR reply. ; ServerIP and gateway are already programmed in mov si,[bp-6] mov ax,[si+tftp_remoteport] mov word [pxe_udp_write_pkt.rport],ax mov word [pxe_udp_write_pkt.buffer],tftp_opt_err mov word [pxe_udp_write_pkt.buffersize],tftp_opt_err_len mov di,pxe_udp_write_pkt mov bx,PXENV_UDP_WRITE call pxenv ; Write an error message and explode mov si,err_oldtftp call writestr jmp kaboom .bailnow: mov word [bp-2],1 ; Immediate error - no retry .failure: pop bx ; Junk pop bx pop si pop ax dec ax ; Retry counter jnz .sendreq ; Try again .error: mov si,bx ; Socket pointer .error_si: ; Socket pointer already in SI call free_socket ; ZF <- 1, SI <- 0 jmp .ret ; ; allocate_socket: Allocate a local UDP port structure ; ; If successful: ; ZF set ; BX = socket pointer ; If unsuccessful: ; ZF clear ; allocate_socket: push cx mov bx,Files mov cx,MAX_OPEN .check: cmp word [bx], byte 0 je .found add bx,open_file_t_size loop .check xor cx,cx ; ZF = 1 pop cx ret ; Allocate a socket number. Socket numbers are made ; guaranteed unique by including the socket slot number ; (inverted, because we use the loop counter cx); add a ; counter value to keep the numbers from being likely to ; get immediately reused. ; ; The NextSocket variable also contains the top two bits ; set. This generates a value in the range 49152 to ; 57343. .found: dec cx push ax mov ax,[NextSocket] inc ax and ax,((1 << (13-MAX_OPEN_LG2))-1) | 0xC000 mov [NextSocket],ax shl cx,13-MAX_OPEN_LG2 add cx,ax ; ZF = 0 xchg ch,cl ; Convert to network byte order mov [bx],cx ; Socket in use pop ax pop cx ret ; ; Free socket: socket in SI; return SI = 0, ZF = 1 for convenience ; free_socket: push es pusha xor ax,ax mov es,ax mov di,si mov cx,tftp_pktbuf >> 1 ; tftp_pktbuf is not cleared rep stosw popa pop es xor si,si ret ; ; parse_dotquad: ; Read a dot-quad pathname in DS:SI and output an IP ; address in EAX, with SI pointing to the first ; nonmatching character. ; ; Return CF=1 on error. ; ; No segment assumptions permitted. ; parse_dotquad: push cx mov cx,4 xor eax,eax .parseloop: mov ch,ah mov ah,al lodsb sub al,'0' jb .notnumeric cmp al,9 ja .notnumeric aad ; AL += 10 * AH; AH = 0; xchg ah,ch jmp .parseloop .notnumeric: cmp al,'.'-'0' pushf mov al,ah mov ah,ch xor ch,ch ror eax,8 popf jne .error loop .parseloop jmp .done .error: loop .realerror ; If CX := 1 then we're done clc jmp .done .realerror: stc .done: dec si ; CF unchanged! pop cx ret ; ; mangle_name: Mangle a filename pointed to by DS:SI into a buffer pointed ; to by ES:DI; ends on encountering any whitespace. ; DI is preserved. ; ; This verifies that a filename is < FILENAME_MAX characters ; and doesn't contain whitespace, and zero-pads the output buffer, ; so "repe cmpsb" can do a compare. ; ; The first four bytes of the manged name is the IP address of ; the download host. ; ; No segment assumptions permitted. ; mangle_name: push di push si mov eax,[cs:ServerIP] cmp byte [si],0 je .noip ; Null filename?!?! cmp word [si],'::' ; Leading ::? je .gotprefix .more: inc si cmp byte [si],0 je .noip cmp word [si],'::' jne .more ; We have a :: prefix of some sort, it could be either ; a DNS name or a dot-quad IP address. Try the dot-quad ; first... .here: pop si push si call parse_dotquad jc .notdq cmp word [si],'::' je .gotprefix .notdq: pop si push si call dns_resolv cmp word [si],'::' jne .noip and eax,eax jnz .gotprefix .noip: pop si xor eax,eax jmp .prefix_done .gotprefix: pop cx ; Adjust stack inc si ; Skip double colon inc si .prefix_done: stosd ; Save IP address prefix mov cx,FILENAME_MAX-5 .mn_loop: lodsb cmp al,' ' ; If control or space, end jna .mn_end stosb loop .mn_loop .mn_end: inc cx ; At least one null byte xor ax,ax ; Zero-fill name rep stosb ; Doesn't do anything if CX=0 pop di ret ; Done ; ; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled ; filename to the conventional representation. This is needed ; for the BOOT_IMAGE= parameter for the kernel. ; ; NOTE: The output buffer needs to be able to hold an ; expanded IP address. ; ; DS:SI -> input mangled file name ; ES:DI -> output buffer ; ; On return, DI points to the first byte after the output name, ; which is set to a null byte. ; unmangle_name: push eax lodsd and eax,eax jz .noip call gendotquad mov ax,'::' stosw .noip: call strcpy dec di ; Point to final null byte pop eax ret ; ; pxenv ; ; This is the main PXENV+/!PXE entry point, using the PXENV+ ; calling convention. This is a separate local routine so ; we can hook special things from it if necessary. In particular, ; some PXE stacks seem to not like being invoked from anything but ; the initial stack, so humour it. ; pxenv: %if USE_PXE_PROVIDED_STACK == 0 mov [cs:PXEStack],sp mov [cs:PXEStack+2],ss lss sp,[cs:InitStack] %endif .jump: call 0:pxe_thunk ; Default to calling the thunk %if USE_PXE_PROVIDED_STACK == 0 lss sp,[cs:PXEStack] %endif cld ; Make sure DF <- 0 ret ; Must be after function def due to NASM bug PXENVEntry equ pxenv.jump+1 ; ; pxe_thunk ; ; Convert from the PXENV+ calling convention (BX, ES, DI) to the !PXE ; calling convention (using the stack.) ; ; This is called as a far routine so that we can just stick it into ; the PXENVEntry variable. ; pxe_thunk: push es push di push bx .jump: call 0:0 add sp,byte 6 cmp ax,byte 1 cmc ; Set CF unless ax == 0 retf ; Must be after function def due to NASM bug PXEEntry equ pxe_thunk.jump+1 ; ; getfssec: Get multiple clusters from a file, given the starting cluster. ; ; In this case, get multiple blocks from a specific TCP connection. ; ; On entry: ; ES:BX -> Buffer ; SI -> TFTP socket pointer ; CX -> 512-byte block count; 0FFFFh = until end of file ; On exit: ; SI -> TFTP socket pointer (or 0 on EOF) ; CF = 1 -> Hit EOF ; getfssec: push si push fs mov di,bx mov bx,si mov ax,pktbuf_seg mov fs,ax movzx ecx,cx shl ecx,TFTP_BLOCKSIZE_LG2 ; Convert to bytes jz .hit_eof ; Nothing to do? .need_more: push ecx movzx eax,word [bx+tftp_bytesleft] cmp ecx,eax jna .ok_size mov ecx,eax jcxz .need_packet ; No bytes available? .ok_size: mov ax,cx ; EAX<31:16> == ECX<31:16> == 0 mov si,[bx+tftp_dataptr] sub [bx+tftp_bytesleft],cx fs rep movsb ; Copy from packet buffer mov [bx+tftp_dataptr],si pop ecx sub ecx,eax jnz .need_more .hit_eof: pop fs pop si ; Is there anything left of this? mov eax,[si+tftp_filesize] sub eax,[si+tftp_filepos] jnz .bytes_left ; CF <- 0 cmp [si+tftp_bytesleft],ax jnz .bytes_left ; CF <- 0 ; The socket is closed and the buffer drained ; Close socket structure and re-init for next user call free_socket stc .bytes_left: ret ; ; No data in buffer, check to see if we can get a packet... ; .need_packet: pop ecx mov eax,[bx+tftp_filesize] cmp eax,[bx+tftp_filepos] je .hit_eof ; Already EOF'd; socket already closed pushad push es mov si,bx call get_packet pop es popad jmp .need_more ; ; Get a fresh packet; expects fs -> pktbuf_seg and ds:si -> socket structure ; get_packet: mov ax,ds mov es,ax .packet_loop: ; Start by ACKing the previous packet; this should cause the ; next packet to be sent. mov cx,PKT_RETRY mov word [PktTimeout],PKT_TIMEOUT .send_ack: push cx ; Retry count mov ax,[si+tftp_lastpkt] call ack_packet ; Send ACK ; We used to test the error code here, but sometimes ; PXE would return negative status even though we really ; did send the ACK. Now, just treat a failed send as ; a normally lost packet, and let it time out in due ; course of events. .send_ok: ; Now wait for packet. mov dx,[BIOS_timer] ; Get current time mov cx,[PktTimeout] .wait_data: push cx ; Timeout push dx ; Old time mov bx,[si+tftp_pktbuf] mov [pxe_udp_read_pkt.buffer],bx mov [pxe_udp_read_pkt.buffer+2],fs mov [pxe_udp_read_pkt.buffersize],word PKTBUF_SIZE mov eax,[si+tftp_remoteip] mov [pxe_udp_read_pkt.sip],eax mov eax,[MyIP] mov [pxe_udp_read_pkt.dip],eax mov ax,[si+tftp_remoteport] mov [pxe_udp_read_pkt.rport],ax mov ax,[si+tftp_localport] mov [pxe_udp_read_pkt.lport],ax mov di,pxe_udp_read_pkt mov bx,PXENV_UDP_READ push si ; call pxenv pop si ; and ax,ax jz .recv_ok ; No packet, or receive failure mov dx,[BIOS_timer] pop ax ; Old time pop cx ; Timeout cmp ax,dx ; Same time -> don't advance timeout je .wait_data ; Same clock tick loop .wait_data ; Decrease timeout pop cx ; Didn't get any, send another ACK shl word [PktTimeout],1 ; Exponential backoff loop .send_ack jmp kaboom ; Forget it... .recv_ok: pop dx ; pop cx ; cmp word [pxe_udp_read_pkt.buffersize],byte 4 jb .wait_data ; Bad size for a DATA packet mov bx,[si+tftp_pktbuf] cmp word [fs:bx],TFTP_DATA ; Not a data packet? jne .wait_data ; Then wait for something else mov ax,[si+tftp_lastpkt] xchg ah,al ; Host byte order inc ax ; Which packet are we waiting for? xchg ah,al ; Network byte order cmp [fs:bx+2],ax je .right_packet ; Wrong packet, ACK the packet and then try again ; This is presumably because the ACK got lost, ; so the server just resent the previous packet mov ax,[fs:bx+2] call ack_packet jmp .send_ok ; Reset timeout .right_packet: ; It's the packet we want. We're also EOF if the size < blocksize pop cx ; Don't need the retry count anymore mov [si+tftp_lastpkt],ax ; Update last packet number movzx ecx,word [pxe_udp_read_pkt.buffersize] sub cx,byte 4 ; Skip TFTP header ; If this is a zero-length block, don't mess with the pointers, ; since we may have just set up the previous block that way jz .last_block ; Set pointer to data block lea ax,[bx+4] ; Data past TFTP header mov [si+tftp_dataptr],ax add [si+tftp_filepos],ecx mov [si+tftp_bytesleft],cx cmp cx,[si+tftp_blksize] ; Is it a full block? jb .last_block ; If so, it's not EOF ; If we had the exact right number of bytes, always get ; one more packet to get the (zero-byte) EOF packet and ; close the socket. mov eax,[si+tftp_filepos] cmp [si+tftp_filesize],eax je .packet_loop ret .last_block: ; Last block - ACK packet immediately mov ax,[fs:bx+2] call ack_packet ; Make sure we know we are at end of file mov eax,[si+tftp_filepos] mov [si+tftp_filesize],eax ret ; ; ack_packet: ; ; Send ACK packet. This is a common operation and so is worth canning. ; ; Entry: ; SI = TFTP block ; AX = Packet # to ack (network byte order) ; Exit: ; ZF = 0 -> Error ; All registers preserved ; ; This function uses the pxe_udp_write_pkt but not the packet_buf. ; ack_packet: pushad mov [ack_packet_buf+2],ax ; Packet number to ack mov ax,[si] mov [pxe_udp_write_pkt.lport],ax mov ax,[si+tftp_remoteport] mov [pxe_udp_write_pkt.rport],ax mov eax,[si+tftp_remoteip] mov [pxe_udp_write_pkt.sip],eax xor eax,[MyIP] and eax,[Netmask] jz .nogw mov eax,[Gateway] .nogw: mov [pxe_udp_write_pkt.gip],eax mov [pxe_udp_write_pkt.buffer],word ack_packet_buf mov [pxe_udp_write_pkt.buffersize], word 4 mov di,pxe_udp_write_pkt mov bx,PXENV_UDP_WRITE call pxenv cmp ax,byte 0 ; ZF = 1 if write OK popad ret ; ; unload_pxe: ; ; This function unloads the PXE and UNDI stacks and unclaims ; the memory. ; unload_pxe: test byte [KeepPXE],01h ; Should we keep PXE around? jnz reset_pxe push ds push es mov ax,cs mov ds,ax mov es,ax mov si,new_api_unload cmp byte [APIVer+1],2 ; Major API version >= 2? jae .new_api mov si,old_api_unload .new_api: .call_loop: xor ax,ax lodsb and ax,ax jz .call_done xchg bx,ax mov di,pxe_unload_stack_pkt push di xor ax,ax mov cx,pxe_unload_stack_pkt_len >> 1 rep stosw pop di call pxenv jc .cant_free mov ax,word [pxe_unload_stack_pkt.status] cmp ax,PXENV_STATUS_SUCCESS jne .cant_free jmp .call_loop .call_done: mov bx,0FF00h mov dx,[RealBaseMem] cmp dx,[BIOS_fbm] ; Sanity check jna .cant_free inc bx ; Check that PXE actually unhooked the INT 1Ah chain movzx eax,word [4*0x1a] movzx ecx,word [4*0x1a+2] shl ecx,4 add eax,ecx shr eax,10 cmp ax,dx ; Not in range jae .ok cmp ax,[BIOS_fbm] jae .cant_free ; inc bx .ok: mov [BIOS_fbm],dx .pop_ret: pop es pop ds ret .cant_free: mov si,cant_free_msg call writestr push ax xchg bx,ax call writehex4 mov al,'-' call writechr pop ax call writehex4 mov al,'-' call writechr mov eax,[4*0x1a] call writehex8 call crlf jmp .pop_ret ; We want to keep PXE around, but still we should reset ; it to the standard bootup configuration reset_pxe: push es push cs pop es mov bx,PXENV_UDP_CLOSE mov di,pxe_udp_close_pkt call pxenv pop es ret ; ; gendotquad ; ; Take an IP address (in network byte order) in EAX and ; output a dotted quad string to ES:DI. ; DI points to terminal null at end of string on exit. ; gendotquad: push eax push cx mov cx,4 .genchar: push eax cmp al,10 ; < 10? jb .lt10 ; If so, skip first 2 digits cmp al,100 ; < 100 jb .lt100 ; If so, skip first digit aam 100 ; Now AH = 100-digit; AL = remainder add ah,'0' mov [es:di],ah inc di .lt100: aam 10 ; Now AH = 10-digit; AL = remainder add ah,'0' mov [es:di],ah inc di .lt10: add al,'0' stosb mov al,'.' stosb pop eax ror eax,8 ; Move next char into LSB loop .genchar dec di mov [es:di], byte 0 pop cx pop eax ret ; ; uchexbytes/lchexbytes ; ; Take a number of bytes in memory and convert to upper/lower-case ; hexadecimal ; ; Input: ; DS:SI = input bytes ; ES:DI = output buffer ; CX = number of bytes ; Output: ; DS:SI = first byte after ; ES:DI = first byte after ; CX = 0 ; ; Trashes AX, DX ; lchexbytes: mov dl,'a'-'9'-1 jmp xchexbytes uchexbytes: mov dl,'A'-'9'-1 xchexbytes: .loop: lodsb mov ah,al shr al,4 call .outchar mov al,ah call .outchar loop .loop ret .outchar: and al,0Fh add al,'0' cmp al,'9' jna .done add al,dl .done: stosb ret ; ; pxe_get_cached_info ; ; Get a DHCP packet from the PXE stack into the trackbuf. ; ; Input: ; DL = packet type ; Output: ; CX = buffer size ; ; Assumes CS == DS == ES. ; pxe_get_cached_info: pushad mov di,pxe_bootp_query_pkt push di xor ax,ax stosw ; Status movzx ax,dl stosw ; Packet type mov ax,trackbufsize stosw ; Buffer size mov ax,trackbuf stosw ; Buffer offset xor ax,ax stosw ; Buffer segment pop di ; DI -> parameter set mov bx,PXENV_GET_CACHED_INFO call pxenv jc .err and ax,ax jnz .err popad mov cx,[pxe_bootp_query_pkt.buffersize] ret .err: mov si,err_pxefailed jmp kaboom ; ; ip_ok ; ; Tests an IP address in EAX for validity; return with ZF=1 for bad. ; We used to refuse class E, but class E addresses are likely to become ; assignable unicast addresses in the near future. ; ip_ok: push ax cmp eax,-1 ; Refuse the all-ones address jz .out and al,al ; Refuse network zero jz .out cmp al,127 ; Refuse loopback jz .out and al,0F0h cmp al,224 ; Refuse class D .out: pop ax ret ; ; parse_dhcp ; ; Parse a DHCP packet. This includes dealing with "overloaded" ; option fields (see RFC 2132, section 9.3) ; ; This should fill in the following global variables, if the ; information is present: ; ; MyIP - client IP address ; ServerIP - boot server IP address ; Netmask - network mask ; Gateway - default gateway router IP ; BootFile - boot file name ; DNSServers - DNS server IPs ; LocalDomain - Local domain name ; MACLen, MAC - Client identifier, if MACLen == 0 ; ; This assumes the DHCP packet is in "trackbuf" and the length ; of the packet in in CX on entry. ; parse_dhcp: mov byte [OverLoad],0 ; Assume no overload mov eax, [trackbuf+bootp.yip] call ip_ok jz .noyip mov [MyIP], eax .noyip: mov eax, [trackbuf+bootp.sip] and eax, eax call ip_ok jz .nosip mov [ServerIP], eax .nosip: sub cx, bootp.options jbe .nooptions mov si, trackbuf+bootp.option_magic lodsd cmp eax, BOOTP_OPTION_MAGIC jne .nooptions call parse_dhcp_options .nooptions: mov si, trackbuf+bootp.bootfile test byte [OverLoad],1 jz .nofileoverload mov cx,128 call parse_dhcp_options jmp short .parsed_file .nofileoverload: cmp byte [si], 0 jz .parsed_file ; No bootfile name mov di,BootFile mov cx,32 rep movsd xor al,al stosb ; Null-terminate .parsed_file: mov si, trackbuf+bootp.sname test byte [OverLoad],2 jz .nosnameoverload mov cx,64 call parse_dhcp_options .nosnameoverload: ret ; ; Parse a sequence of DHCP options, pointed to by DS:SI; the field ; size is CX -- some DHCP servers leave option fields unterminated ; in violation of the spec. ; ; For parse_some_dhcp_options, DH contains the minimum value for ; the option to recognize -- this is used to restrict parsing to ; PXELINUX-specific options only. ; parse_dhcp_options: xor dx,dx parse_some_dhcp_options: .loop: and cx,cx jz .done lodsb dec cx jz .done ; Last byte; must be PAD, END or malformed cmp al, 0 ; PAD option je .loop cmp al,255 ; END option je .done ; Anything else will have a length field mov dl,al ; DL <- option number xor ax,ax lodsb ; AX <- option length dec cx sub cx,ax ; Decrement bytes left counter jb .done ; Malformed option: length > field size cmp dl,dh ; Is the option value valid? jb .opt_done mov bx,dhcp_option_list .find_option: cmp bx,dhcp_option_list_end jae .opt_done cmp dl,[bx] je .found_option add bx,3 jmp .find_option .found_option: pushad call [bx+1] popad ; Fall through ; Unknown option. Skip to the next one. .opt_done: add si,ax jmp .loop .done: ret section .data dhcp_option_list: section .text %macro dopt 2 section .data db %1 dw dopt_%2 section .text dopt_%2: %endmacro ; ; Parse individual DHCP options. SI points to the option data and ; AX to the option length. DL contains the option number. ; All registers are saved around the routine. ; dopt 1, subnet_mask mov ebx,[si] mov [Netmask],ebx ret dopt 3, router mov ebx,[si] mov [Gateway],ebx ret dopt 6, dns_servers mov cx,ax shr cx,2 cmp cl,DNS_MAX_SERVERS jna .oklen mov cl,DNS_MAX_SERVERS .oklen: mov di,DNSServers rep movsd mov [LastDNSServer],di ret dopt 16, local_domain mov bx,si add bx,ax xor ax,ax xchg [bx],al ; Zero-terminate option mov di,LocalDomain call dns_mangle ; Convert to DNS label set mov [bx],al ; Restore ending byte ret dopt 43, vendor_encaps mov dh,208 ; Only recognize PXELINUX options mov cx,ax ; Length of option = max bytes to parse call parse_some_dhcp_options ; Parse recursive structure ret dopt 52, option_overload mov bl,[si] mov [OverLoad],bl ret dopt 54, server mov eax,[si] cmp dword [ServerIP],0 jne .skip ; Already have a next server IP call ip_ok jz .skip mov [ServerIP],eax .skip: ret dopt 61, client_identifier cmp ax,MAC_MAX ; Too long? ja .skip cmp ax,2 ; Too short? jb .skip cmp [MACLen],ah ; Only do this if MACLen == 0 jne .skip push ax lodsb ; Client identifier type cmp al,[MACType] pop ax jne .skip ; Client identifier is not a MAC dec ax mov [MACLen],al mov di,MAC jmp dhcp_copyoption .skip: ret dopt 67, bootfile_name mov di,BootFile jmp dhcp_copyoption dopt 97, uuid_client_identifier cmp ax,17 ; type byte + 16 bytes UUID jne .skip mov dl,[si] ; Must have type 0 == UUID or dl,[HaveUUID] ; Capture only the first instance jnz .skip mov byte [HaveUUID],1 ; Got UUID mov di,UUIDType jmp dhcp_copyoption .skip: ret dopt 209, pxelinux_configfile mov di,ConfigName or byte [DHCPMagic],2 ; Got config file jmp dhcp_copyoption dopt 210, pxelinux_pathprefix mov di,PathPrefix or byte [DHCPMagic],4 ; Got path prefix jmp dhcp_copyoption dopt 211, pxelinux_reboottime cmp al,4 jne .done mov ebx,[si] xchg bl,bh ; Convert to host byte order rol ebx,16 xchg bl,bh mov [RebootTime],ebx or byte [DHCPMagic],8 ; Got RebootTime .done: ret ; Common code for copying an option verbatim ; Copies the option into ES:DI and null-terminates it. ; Returns with AX=0 and SI past the option. dhcp_copyoption: xchg cx,ax ; CX <- option length rep movsb xchg cx,ax ; AX <- 0 stosb ; Null-terminate ret section .data dhcp_option_list_end: section .text section .data HaveUUID db 0 uuid_dashes db 4,2,2,2,6,0 ; Bytes per UUID dashed section section .text ; ; genipopt ; ; Generate an ip=::: ; option into IPOption based on a DHCP packet in trackbuf. ; Assumes CS == DS == ES. ; genipopt: pushad mov di,IPOption mov eax,'ip=' stosd dec di mov eax,[MyIP] call gendotquad mov al,':' stosb mov eax,[ServerIP] call gendotquad mov al,':' stosb mov eax,[Gateway] call gendotquad mov al,':' stosb mov eax,[Netmask] call gendotquad ; Zero-terminates its output sub di,IPOption mov [IPOptionLen],di popad ret ; ; Call the receive loop while idle. This is done mostly so we can respond to ; ARP messages, but perhaps in the future this can be used to do network ; console. ; ; hpa sez: people using automatic control on the serial port get very ; unhappy if we poll for ARP too often (the PXE stack is pretty slow, ; typically.) Therefore, only poll if at least 4 BIOS timer ticks have ; passed since the last poll, and reset this when a character is ; received (RESET_IDLE). ; %if HAVE_IDLE reset_idle: push ax mov ax,[cs:BIOS_timer] mov [cs:IdleTimer],ax pop ax ret check_for_arp: push ax mov ax,[cs:BIOS_timer] sub ax,[cs:IdleTimer] cmp ax,4 pop ax jae .need_poll ret .need_poll: pushad push ds push es mov ax,cs mov ds,ax mov es,ax mov di,packet_buf mov [pxe_udp_read_pkt.status],al ; 0 mov [pxe_udp_read_pkt.buffer],di mov [pxe_udp_read_pkt.buffer+2],ds mov word [pxe_udp_read_pkt.buffersize],packet_buf_size mov eax,[MyIP] mov [pxe_udp_read_pkt.dip],eax mov word [pxe_udp_read_pkt.lport],htons(9) ; discard port mov di,pxe_udp_read_pkt mov bx,PXENV_UDP_READ call pxenv ; Ignore result... pop es pop ds popad RESET_IDLE ret %endif ; HAVE_IDLE ; ----------------------------------------------------------------------------- ; Common modules ; ----------------------------------------------------------------------------- %include "getc.inc" ; getc et al %include "conio.inc" ; Console I/O %include "writestr.inc" ; String output writestr equ cwritestr %include "writehex.inc" ; Hexadecimal output %include "configinit.inc" ; Initialize configuration %include "parseconfig.inc" ; High-level config file handling %include "parsecmd.inc" ; Low-level config file handling %include "bcopy32.inc" ; 32-bit bcopy %include "loadhigh.inc" ; Load a file into high memory %include "font.inc" ; VGA font stuff %include "graphics.inc" ; VGA graphics %include "highmem.inc" ; High memory sizing %include "strcpy.inc" ; strcpy() %include "rawcon.inc" ; Console I/O w/o using the console functions %include "dnsresolv.inc" ; DNS resolver %include "adv.inc" ; Auxillary Data Vector ; ----------------------------------------------------------------------------- ; Begin data section ; ----------------------------------------------------------------------------- section .data copyright_str db ' Copyright (C) 1994-', year, ' H. Peter Anvin' db CR, LF, 0 err_bootfailed db CR, LF, 'Boot failed: press a key to retry, or wait for reset...', CR, LF, 0 bailmsg equ err_bootfailed err_nopxe db "No !PXE or PXENV+ API found; we're dead...", CR, LF, 0 err_pxefailed db 'PXE API call failed, error ', 0 err_udpinit db 'Failed to initialize UDP stack', CR, LF, 0 err_noconfig db 'Unable to locate configuration file', CR, LF, 0 err_oldtftp db 'TFTP server does not support the tsize option', CR, LF, 0 found_pxenv db 'Found PXENV+ structure', CR, LF, 0 using_pxenv_msg db 'Old PXE API detected, using PXENV+ structure', CR, LF, 0 apiver_str db 'PXE API version is ',0 pxeentry_msg db 'PXE entry point found (we hope) at ', 0 pxenventry_msg db 'PXENV entry point found (we hope) at ', 0 trymempxe_msg db 'Scanning memory for !PXE structure... ', 0 trymempxenv_msg db 'Scanning memory for PXENV+ structure... ', 0 undi_data_msg db 'UNDI data segment at: ',0 undi_data_len_msg db 'UNDI data segment size: ',0 undi_code_msg db 'UNDI code segment at: ',0 undi_code_len_msg db 'UNDI code segment size: ',0 cant_free_msg db 'Failed to free base memory, error ', 0 notfound_msg db 'not found', CR, LF, 0 myipaddr_msg db 'My IP address seems to be ',0 tftpprefix_msg db 'TFTP prefix: ', 0 localboot_msg db 'Booting from local disk...', CR, LF, 0 trying_msg db 'Trying to load: ', 0 fourbs_msg db BS, BS, BS, BS, 0 default_str db 'default', 0 syslinux_banner db CR, LF, 'PXELINUX ', version_str, ' ', date, ' ', 0 cfgprefix db 'pxelinux.cfg/' ; No final null! cfgprefix_len equ ($-cfgprefix) ; ; Command line options we'd like to take a look at ; ; mem= and vga= are handled as normal 32-bit integer values initrd_cmd db 'initrd=' initrd_cmd_len equ $-initrd_cmd ; This one we make ourselves bootif_str db 'BOOTIF=' bootif_str_len equ $-bootif_str ; ; Config file keyword table ; %include "keywords.inc" ; ; Extensions to search for (in *forward* order). ; (.bs and .bss are disabled for PXELINUX, since they are not supported) ; align 4, db 0 exten_table: db '.cbt' ; COMBOOT (specific) db '.0', 0, 0 ; PXE bootstrap program db '.com' ; COMBOOT (same as DOS) db '.c32' ; COM32 exten_table_end: dd 0, 0 ; Need 8 null bytes here ; ; PXE unload sequences ; new_api_unload: db PXENV_UDP_CLOSE db PXENV_UNDI_SHUTDOWN db PXENV_UNLOAD_STACK db PXENV_STOP_UNDI db 0 old_api_unload: db PXENV_UDP_CLOSE db PXENV_UNDI_SHUTDOWN db PXENV_UNLOAD_STACK db PXENV_UNDI_CLEANUP db 0 ; ; PXE query packets partially filled in ; section .bss pxe_bootp_query_pkt: .status: resw 1 ; Status .packettype: resw 1 ; Boot server packet type .buffersize: resw 1 ; Packet size .buffer: resw 2 ; seg:off of buffer .bufferlimit: resw 1 ; Unused section .data pxe_udp_open_pkt: .status: dw 0 ; Status .sip: dd 0 ; Source (our) IP pxe_udp_close_pkt: .status: dw 0 ; Status pxe_udp_write_pkt: .status: dw 0 ; Status .sip: dd 0 ; Server IP .gip: dd 0 ; Gateway IP .lport: dw 0 ; Local port .rport: dw 0 ; Remote port .buffersize: dw 0 ; Size of packet .buffer: dw 0, 0 ; seg:off of buffer pxe_udp_read_pkt: .status: dw 0 ; Status .sip: dd 0 ; Source IP .dip: dd 0 ; Destination (our) IP .rport: dw 0 ; Remote port .lport: dw 0 ; Local port .buffersize: dw 0 ; Max packet size .buffer: dw 0, 0 ; seg:off of buffer ; ; Misc initialized (data) variables ; alignb 4, db 0 BaseStack dd StackBuf ; ESP of base stack dw 0 ; SS of base stack NextSocket dw 49152 ; Counter for allocating socket numbers KeepPXE db 0 ; Should PXE be kept around? ; ; TFTP commands ; tftp_tail db 'octet', 0 ; Octet mode tsize_str db 'tsize' ,0 ; Request size tsize_len equ ($-tsize_str) db '0', 0 blksize_str db 'blksize', 0 ; Request large blocks blksize_len equ ($-blksize_str) asciidec TFTP_LARGEBLK db 0 tftp_tail_len equ ($-tftp_tail) alignb 2, db 0 ; ; Options negotiation parsing table (string pointer, string len, offset ; into socket structure) ; tftp_opt_table: dw tsize_str, tsize_len, tftp_filesize dw blksize_str, blksize_len, tftp_blksize tftp_opts equ ($-tftp_opt_table)/6 ; ; Error packet to return on options negotiation error ; tftp_opt_err dw TFTP_ERROR ; ERROR packet dw TFTP_EOPTNEG ; ERROR 8: bad options db 'tsize option required', 0 ; Error message tftp_opt_err_len equ ($-tftp_opt_err) alignb 4, db 0 ack_packet_buf: dw TFTP_ACK, 0 ; TFTP ACK packet ; ; IP information (initialized to "unknown" values) MyIP dd 0 ; My IP address ServerIP dd 0 ; IP address of boot server Netmask dd 0 ; Netmask of this subnet Gateway dd 0 ; Default router ServerPort dw TFTP_PORT ; TFTP server port ; ; Variables that are uninitialized in SYSLINUX but initialized here ; alignb 4, db 0 BufSafe dw trackbufsize/TFTP_BLOCKSIZE ; Clusters we can load into trackbuf BufSafeBytes dw trackbufsize ; = how many bytes? %ifndef DEPEND %if ( trackbufsize % TFTP_BLOCKSIZE ) != 0 %error trackbufsize must be a multiple of TFTP_BLOCKSIZE %endif %endif

rep options..." info="Options for prep" type=submenu data="prep" item="escue options..." info="Troubleshoot a system" type=submenu data="rescue" helpid=26 item="esting..." info="Options to test hardware" type=submenu data="testing" item="xit to prompt" info="Exit the menu system" type=exitmenu syslinux-legacy-3.63+dfsg/menu/libmenu/0000775000175000017500000000000010777447273016613 5ustar evanevansyslinux-legacy-3.63+dfsg/menu/libmenu/syslnx.h0000664000175000017500000000363610777447273020334 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef __SYSLNX_H__ #define __SYSLNX_H__ #include //Macros which help user not have to remember the structure of register // Data structure #define REG_AH(x) ((x).eax.b[1]) #define REG_AL(x) ((x).eax.b[0]) #define REG_AX(x) ((x).eax.w[0]) #define REG_EAX(x) ((x).eax.l) #define REG_BH(x) ((x).ebx.b[1]) #define REG_BL(x) ((x).ebx.b[0]) #define REG_BX(x) ((x).ebx.w[0]) #define REG_EBX(x) ((x).ebx.l) #define REG_CH(x) ((x).ecx.b[1]) #define REG_CL(x) ((x).ecx.b[0]) #define REG_CX(x) ((x).ecx.w[0]) #define REG_ECX(x) ((x).ecx.l) #define REG_DH(x) ((x).edx.b[1]) #define REG_DL(x) ((x).edx.b[0]) #define REG_DX(x) ((x).edx.w[0]) #define REG_EDX(x) ((x).edx.l) #define REG_DS(x) ((x).ds) #define REG_ES(x) ((x).es) #define REG_FS(x) ((x).fs) #define REG_GS(x) ((x).gs) #define REG_SI(x) ((x).esi.w[0]) #define REG_ESI(x) ((x).esi.l) #define REG_DI(x) ((x).edi.w[0]) #define REG_EDI(x) ((x).edi.l) char issyslinux(void); /* Check if syslinux is running */ void runsyslinuxcmd(const char *cmd); /* Run specified command */ void gototxtmode(void); /* Change mode to text mode */ void syslinux_idle(void); /* Call syslinux idle loop */ /* Run command line with ipappend, returns if kernel image not found If syslinux version too old, then defaults to runsyslinuxcmd */ void runsyslinuximage(const char*cmd, long ipappend); #endif syslinux-legacy-3.63+dfsg/menu/libmenu/help.c0000664000175000017500000001226410777447273017714 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include "help.h" #include #include "string.h" #include "com32io.h" #include // to read entire file into memory char helpbasedir[HELPDIRLEN]; // name of help directory limited to HELPDIRLEN // Find the occurence of the count'th \n in buffer (or NULL) if not found char * findline(char*buffer,int count) { int ctr; char *p= buffer-1; if (count < 1) return buffer; for (ctr=0; ctr < count; ctr++) { p = strchr(p+1,'\n'); if (p==NULL) return NULL; } return p; } // return the number of lines in buffer int countlines(char*buffer) { int ans; const char *p; p = buffer-1; ans = 1; while(p) {p = strchr(p+1,'\n'); ans++; } return ans; } // Print numlines of text starting from buf void printtext(char*buf, int from) { char *p,*f; char right,bot,nlines; // clear window to print right = getnumcols() - HELP_RIGHT_MARGIN; bot = getnumrows() - HELP_BOTTOM_MARGIN; nlines = bot-HELP_BODY_ROW+1; scrollupwindow(HELP_BODY_ROW,HELP_LEFT_MARGIN,bot,right,0x07,nlines); f = findline(buf,from); if (!f) return; // nothing to print if (*f=='\n') f++; // start of from+1st line p = findline(f,nlines); if (p && (*p=='\n')) *p = '\0'; // change to NUL gotoxy(HELP_BODY_ROW,HELP_LEFT_MARGIN,HELPPAGE); cswprint(f,0x07,HELP_LEFT_MARGIN); if (p) *p = '\n'; // set it back } void showhelp(const char *filename) { char nc,nr,ph; char *title,*text; union { char *buffer; void *vbuf; } buf; // This is to avoild type-punning issues char line[512]; size_t size; char scan; int rv,numlines,curr_line; nc = getnumcols(); nr = getnumrows(); ph = nr - HELP_BOTTOM_MARGIN - HELP_BODY_ROW - 1; cls(); drawbox(0,0,nr,nc-1,HELPPAGE,0x07,HELPBOX); drawhorizline(2,0,nc-1,HELPPAGE,0x07,HELPBOX,0); // dumb==0 if (filename == NULL) { // print file contents gotoxy(HELP_BODY_ROW,HELP_LEFT_MARGIN,HELPPAGE); cswprint("Filename not given",0x07,HELP_LEFT_MARGIN); while (1) { inputc(&scan); if (scan == ESCAPE) break; } cls(); return; } rv = loadfile(filename,(void **)&buf.vbuf, &size); // load entire file into memory if (rv < 0) { // Error reading file or no such file sprintf(line, "Error reading file or file not found\n file=%s",filename); gotoxy(HELP_BODY_ROW,HELP_LEFT_MARGIN,HELPPAGE); cswprint(line,0x07,HELP_LEFT_MARGIN); while (1) { inputc(&scan); if (scan == ESCAPE) break; } cls(); return; } title = buf.buffer; text = findline(title,1); // end of first line *text++='\0'; // end the title string and increment text // Now we have a file just print it. gotoxy(1,(nc-strlen(title))/2,HELPPAGE); csprint(title,0x07); numlines = countlines(text); curr_line = 0; scan = ESCAPE+1; // anything except ESCAPE while(scan != ESCAPE) { printtext(text,curr_line); gotoxy(HELP_BODY_ROW-1,nc-HELP_RIGHT_MARGIN,HELPPAGE); if (curr_line > 0) putch(HELP_MORE_ABOVE,0x07,HELPPAGE); else putch(' ',0x07,HELPPAGE); gotoxy(nr-HELP_BOTTOM_MARGIN+1,nc-HELP_RIGHT_MARGIN,HELPPAGE); if (curr_line < numlines - ph) putch(HELP_MORE_BELOW,0x07,HELPPAGE); else putch(' ',0x07,HELPPAGE); inputc(&scan); // wait for user keypress switch(scan) { case HOMEKEY: curr_line = 0; break; case ENDKEY: curr_line = numlines; break; case UPARROW: curr_line--; break; case DNARROW: curr_line++; break; case PAGEUP: curr_line -= ph; break; case PAGEDN: curr_line += ph; break; default: break; } if (curr_line > numlines - ph) curr_line = numlines-ph; if (curr_line < 0) curr_line = 0; } cls(); return; } void runhelp(const char *filename) { char dp; char fullname[HELPDIRLEN+16]; dp = getdisppage(); if (dp != HELPPAGE) setdisppage(HELPPAGE); cursoroff(); if (helpbasedir[0] != 0) { strcpy(fullname,helpbasedir); strcat(fullname,"/"); strcat(fullname,filename); showhelp(fullname); } else showhelp (filename); // Assume filename is absolute if (dp != HELPPAGE) setdisppage(dp); } void runhelpsystem(unsigned int helpid) { char filename[15]; sprintf(filename,"hlp%5d.txt",helpid); runhelp(filename); } void init_help(const char *helpdir) { if (helpdir != NULL) strcpy(helpbasedir,helpdir); else helpbasedir[0] = 0; } void close_help(void) { } syslinux-legacy-3.63+dfsg/menu/libmenu/des.h0000664000175000017500000000015710777447273017542 0ustar evanevan #ifndef _DES_H_ #define _DES_H_ // des crypt extern char *crypt (const char *key, const char *salt); #endif syslinux-legacy-3.63+dfsg/menu/libmenu/passwords.c0000664000175000017500000000771710777447273021020 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Bostom MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include "passwords.h" #include "des.h" #include "string.h" #include #include #include "tui.h" #define MAX_LINE 512 // Max line length in a pwdfile p_pwdentry userdb[MAX_USERS]; // Array of pointers int numusers; // Actual number of users // returns true or false, i.e. 1 or 0 char authenticate_user(const char * username, const char* pwd) { char salt[12]; int i; for (i=0; i< numusers; i++) { if (userdb[i] == NULL) continue; if (strcmp(username,userdb[i]->username)==0) { strcpy(salt, userdb[i]->pwdhash); salt[2] = '\0'; if (strcmp(userdb[i]->pwdhash,crypt(pwd,salt))==0) return 1; } } return 0; } // Does user USERNAME have permission PERM char isallowed(const char *username, const char *perm) { int i; char *dperm; char *tmp; // If no users, then everybody is allowed to do everything if (numusers == 0) return 1; if (strcmp(username,GUEST_USER) == 0) return 0; dperm = (char *) malloc(strlen(perm)+3); strcpy(dperm+1,perm); dperm[0] = ':'; dperm[strlen(perm)+1]=':'; dperm[strlen(perm)+2]=0; // Now dperm = ":perm:" for (i=0; i < numusers; i++) { if (strcmp(userdb[i]->username,username)==0) // Found the user { if (userdb[i]->perms == NULL) return 0; // No permission tmp = strstr(userdb[i]->perms,dperm); // Search for permission free (dperm); // Release memory if (tmp == NULL) return 0; else return 1; } } // User not found return 0 free (dperm); return 0; } // Initialise the list of of user passwords permissions from file void init_passwords(const char *filename) { int i; char line[MAX_LINE], *p,*user,*pwdhash,*perms; FILE *f; for (i=0; i < MAX_USERS; i++) userdb[i] = NULL; numusers = 0; if ( !filename ) return; // No filename specified f = fopen(filename,"r"); if ( !f ) return; // File does not exist // Process each line while ( fgets(line, sizeof line, f) ) { // Replace EOLN with \0 p = strchr(line, '\r'); if ( p ) *p = '\0'; p = strchr(line, '\n'); if ( p ) *p = '\0'; // If comment line or empty ignore line p = line; while (*p==' ') p++; // skip initial spaces if ( (*p == '#') || (*p == '\0')) continue; // Skip comment lines user = p; // This is where username starts p = strchr(user,':'); if (p == NULL) continue; // Malformed line skip *p = '\0'; pwdhash = p+1; if (*pwdhash == 0) continue; // Malformed line (no password specified) p = strchr(pwdhash,':'); if (p == NULL) { // No perms specified perms = NULL; } else { *p = '\0'; perms = p+1; if (*perms == 0) perms = NULL; } // At this point we have user,pwdhash and perms setup userdb[numusers] = (p_pwdentry)malloc(sizeof(pwdentry)); strcpy(userdb[numusers]->username,user); strcpy(userdb[numusers]->pwdhash,pwdhash); if (perms == NULL) userdb[numusers]->perms = NULL; else { userdb[numusers]->perms = (char *)malloc(strlen(perms)+3); (userdb[numusers]->perms)[0] = ':'; strcpy(userdb[numusers]->perms + 1,perms); (userdb[numusers]->perms)[strlen(perms)+1] = ':'; (userdb[numusers]->perms)[strlen(perms)+2] = 0; // Now perms field points to ":perms:" } numusers++; } fclose(f); } void close_passwords() { int i; for (i=0; i < numusers; i++) if (userdb[i] != NULL) free(userdb[i]); numusers = 0; } syslinux-legacy-3.63+dfsg/menu/libmenu/menu.h0000664000175000017500000002455510777447273017743 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* This program can be compiled for DOS with the OpenWatcom compiler * (http://www.openwatcom.org/): * * wcl -3 -osx -mt .c */ #ifndef __MENU_H__ #define __MENU_H__ #include "com32io.h" #include "tui.h" #include "syslnx.h" #include "scancodes.h" #include // TIMEOUT PARAMETERS /* If no key is pressed within TIMEOUTNUMSTEPS * TIMEOUTSTEPSIZE milliseconds and if a timeout handler is registered, then that will be called. The handler should either either take control from there on, or return without producing any change in the current video settings. For e.g. the handler could * Could just quit the menu program * beep and return. TIMEOUTSTEPSIZE is the interval for which the program sleeps without checking for any keystroke. So increasing this will make the response of the system slow. Decreasing this will make a lot of interrupt calls using up your CPU. Default value of TIMEOUTSTEPSIZE of 0.1 seconds should be right in most cases. TIMEOUTNUMSTEPS of 3000 corresponds to a wait time of 300 seconds or 5 minutes */ #define TIMEOUTSTEPSIZE 10 #define TIMEOUTNUMSTEPS 30000L // Attributes #define NORMALATTR 0x17 #define NORMALHLITE 0x1F // Normal Highlight attribute #define REVERSEATTR 0x70 #define REVERSEHLITE 0x78 // Reverse Hightlight attribute #define INACTATTR 0x18 #define INACTHLITE 0x10 // Inactive Highlight attribute #define REVINACTATTR 0x78 #define REVINACTHLITE 0x70 // Reverse Inactive Highlight attr #define STATUSATTR 0x74 #define STATUSHLITE 0x7B // Status highlight #define FILLCHAR 177 #define FILLATTR 0x01 #define SHADOWATTR 0x00 #define SPACECHAR ' ' #define TFILLCHAR ' ' #define TITLEATTR 0x70 #define ENABLEHLITE '<' // Char which turns on highlight #define DISABLEHLITE '>' // Char which turns off highlight #define NOHLITE 0 // The offset into attrib array for non-hilite #define HLITE 1 // The offset for Hlite attrib #define MOREABOVE 24 // char to print when more menu items available above #define MOREBELOW 25 // more items available below #define SCROLLBOX 176 // Filled char to display // Attributes of the menu system #define MAXMENUS 10 // Maximum number of menu's allowed #define MAXMENUSIZE 30 // Default value for max num of entries in each menu #define MAXMENUHEIGHT 14 // Maximum number of entries displayed #define MENUBOXTYPE BOX_SINSIN // Default box type Look at tui.h for other values // Upper bounds on lengths // We copy the given string, so user can reuse the space used to store incoming arguments. #define MENULEN 40 // Each menu entry is atmost MENULEN chars #define STATLEN 80 // Maximum length of status string #define TITLELEN 80 // Maximum length of title string #define ACTIONLEN 255 // Maximum length of an action string // Layout of menu #define MENUROW 3 // Row where menu is displayed (relative to window) #define MENUCOL 4 // Col where menu is displayed (relative to window) #define MENUPAGE 1 // show in display page 1 #define STATLINE 24 // Line number where status line starts (relative to window) // Used for printing debugging messages #define DEBUGLINE 23 // debugging info goes here // Other Chars #define SUBMENUCHAR 175 // This is >> symbol #define RADIOMENUCHAR '>' // > symbol for radio menu? #define EXITMENUCHAR 174 // This is << symbol #define CHECKED 251 // Check mark #define UNCHECKED 250 // Light bullet #define RADIOSEL '.' // Current Radio Selection #define RADIOUNSEL ' ' // Radio option not selected typedef unsigned char uchar; // Types of menu's #define NORMALMENU 1 #define RADIOMENU 2 typedef enum {OPT_INACTIVE, OPT_SUBMENU, OPT_RUN, OPT_EXITMENU, OPT_CHECKBOX, OPT_RADIOMENU, OPT_SEP, OPT_INVISIBLE, OPT_RADIOITEM} t_action; typedef union { uchar submenunum; // For submenu's uchar checked; // For check boxes uchar radiomenunum; // Item mapping to a radio menu } t_itemdata; struct s_menuitem; struct s_menu; struct s_menusystem; typedef struct { unsigned int valid :1; // Is action valid? unsigned int refresh:1; // Should we recompute menu stuff? unsigned int reserved:6; // For future expansion } t_handler_return; t_handler_return ACTION_VALID,ACTION_INVALID; // Specific values typedef t_handler_return (*t_item_handler)(struct s_menusystem *, struct s_menuitem *); typedef void (*t_menusystem_handler)(struct s_menusystem *, struct s_menuitem *); typedef void (*t_keys_handler)(struct s_menusystem *, struct s_menuitem *, unsigned int scancode); // Last parameter = HIGH BYTE = scan code , LOW BYTE = ASCII CODE typedef enum {HDLR_SCREEN, HDLR_KEYS } t_handler; // Types of handlers for menu system // TIMEOUT is the list of possible values which can be returned by the handler // instructing the menusystem what to do. The default is CODE_WAIT typedef enum {CODE_WAIT, CODE_ENTER, CODE_ESCAPE } TIMEOUTCODE; typedef TIMEOUTCODE (*t_timeout_handler)(void); typedef struct s_menuitem { char *item; char *status; char *data; // string containing kernel to run.. but... // for radio menu's this is a pointer to the item selected or NULL (initially) // for submenu's this string could be name of menu void * extra_data; // Any other data user can point to unsigned int helpid; // Used for Context sensitive help t_item_handler handler; // Pointer to function of type menufn t_action action; t_itemdata itemdata; // Data depends on action value uchar shortcut; // one of [A-Za-z0-9] shortcut for this menu item uchar index; // Index within the menu array uchar parindex; // Index of the menu in which this item appears. } t_menuitem; typedef t_menuitem *pt_menuitem; // Pointer to type menuitem typedef struct s_menu { pt_menuitem *items; // pointer to array of pointer to menuitems char *title; // Title string for menu char *name; // menu can be referred to by this string int maxmenusize; // the size of array allocated uchar numitems; // how many items do we actually have uchar menuwidth; uchar row,col; // Position where this menu should be displayed uchar menuheight; // Maximum number of items to be displayed } t_menu; typedef t_menu *pt_menu; // Pointer to type menu typedef struct s_menusystem { pt_menu menus[MAXMENUS]; char *title; t_menusystem_handler handler; // Menu system handler t_keys_handler keys_handler; // Handler for unknown keys t_timeout_handler ontimeout; // Timeout handler unsigned long tm_numsteps; // Time to wait for key press=numsteps * stepsize milliseconds unsigned int tm_stepsize; // Timeout step size (in milliseconds) // Total timeout max time spent idle before we call handler unsigned long tm_total_timeout; // (in milli seconds) unsigned long tm_sofar_timeout; // All accumulated timeout // total timeout handler t_timeout_handler ontotaltimeout; // Total timeout handler int maxmenuheight; uchar nummenus; uchar normalattr[2]; // [0] is non-hlite attr, [1] is hlite attr uchar reverseattr[2]; uchar inactattr[2]; uchar revinactattr[2]; uchar statusattr[2]; uchar fillchar; uchar fillattr; uchar spacechar; uchar tfillchar; uchar titleattr; uchar shadowattr; uchar statline; uchar menupage; uchar maxrow,minrow,numrows; // Number of rows in the window uchar maxcol,mincol,numcols; // Number of columns in the window // Menu box look boxtype menubt; // What type of boxes should be drawn char box_horiz,box_ltrt,box_rtlt; // Some chars of the box, for redrawing portions of the box } t_menusystem; typedef t_menusystem *pt_menusystem; // Pointer to type menusystem pt_menuitem showmenus(uchar startmenu); pt_menusystem init_menusystem(const char *title); void close_menusystem(); // Deallocate memory used void set_normal_attr(uchar normal, uchar selected, uchar inactivenormal, uchar inactiveselected); void set_normal_hlite(uchar normal, uchar selected, uchar inactivenormal, uchar inactiveselected); void set_status_info(uchar statusattr, uchar statushlite, uchar statline); void set_title_info(uchar tfillchar, uchar titleattr); void set_misc_info(uchar fillchar, uchar fillattr,uchar spacechar, uchar shadowattr); void set_box_type(boxtype bt); void set_window_size(uchar top, uchar left, uchar bot, uchar right); // Set the window which menusystem should use void set_menu_options(uchar maxmenuheight); // maximum height of a menu void reg_handler(t_handler htype, void * handler); // Register handler void unreg_handler( t_handler htype); void reg_ontimeout(t_timeout_handler, unsigned int numsteps, unsigned int stepsize); // Set timeout handler, set 0 for default values. // So stepsize=0 means numsteps is measured in centiseconds. void unreg_ontimeout(); void reg_ontotaltimeout(t_timeout_handler, unsigned long numcentiseconds); void unreg_ontotaltimeout(); // Find the number of the menu given the name // Returns -1 if not found uchar find_menu_num(const char *name); // Create a new menu and return its position uchar add_menu(const char *title, int maxmenusize); // Create a named menu and return its position uchar add_named_menu(const char *name, const char *title, int maxmenusize); void set_menu_pos(uchar row,uchar col); // Set the position of this menu. // Add item to the "current" menu pt_menuitem add_item(const char *item, const char *status, t_action action, const char *data, uchar itemdata); // Set shortcut key and help id void set_item_options(uchar shortcut,int helpid); // Set the shortcut key for the current item static inline void set_shortcut(uchar shortcut) { set_item_options(shortcut,0xFFFF); } // Add a separator to the "current" menu pt_menuitem add_sep(); // Generate string based on state of checkboxes and radioitem in given menu // and append string to existing contents of "line" // line must have enough space allocated void gen_append_line(const char *menu_name,char *line); #endif syslinux-legacy-3.63+dfsg/menu/libmenu/syslnx.c0000664000175000017500000000504210777447273020320 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include #include #include "syslnx.h" com32sys_t inreg,outreg; // Global registers for this module char issyslinux(void) { REG_EAX(inreg) = 0x00003000; REG_EBX(inreg) = REG_ECX(inreg) = REG_EDX(inreg) = 0xFFFFFFFF; __intcall(0x21,&inreg,&outreg); return (REG_EAX(outreg) == 0x59530000) && (REG_EBX(outreg) == 0x4c530000) && (REG_ECX(outreg) == 0x4e490000) && (REG_EDX(outreg) == 0x58550000); } void runsyslinuxcmd(const char *cmd) { strcpy(__com32.cs_bounce, cmd); REG_AX(inreg) = 0x0003; // Run command REG_BX(inreg) = OFFS(__com32.cs_bounce); REG_ES(inreg) = SEG(__com32.cs_bounce); __intcall(0x22, &inreg, &outreg); } void gototxtmode(void) { REG_AX(inreg) = 0x0005; __intcall(0x22,&inreg,&outreg); } void syslinux_idle(void) { REG_AX(inreg) = 0x0013; __intcall(0x22,&inreg,&outreg); } unsigned int getversion(char *deriv,unsigned int *numfun) { REG_AX(inreg) = 0x0001; __intcall(0x22,&inreg,&outreg); if (deriv) *deriv= REG_DL(outreg); if (numfun) *numfun = REG_AX(outreg); return REG_CX(outreg); } void runsyslinuximage(const char*cmd, long ipappend) { unsigned int numfun = 0; char *ptr,*cmdline; getversion(NULL,&numfun); // Function 16h not supported Fall back to runcommand if (numfun < 0x16) runsyslinuxcmd(cmd); // Try the Run Kernel Image function // Split command line into strcpy(__com32.cs_bounce,cmd); ptr = __com32.cs_bounce; // serach for first space or end of string while ( (*ptr) && (*ptr != ' ')) ptr++; if (!*ptr) cmdline = ptr; // no command line else { *ptr++='\0'; // terminate kernal name cmdline = ptr+1; while (*cmdline != ' ') cmdline++; // find first non-space } // Now call the interrupt REG_BX(inreg) = OFFS(cmdline); REG_ES(inreg) = SEG(cmdline); REG_SI(inreg) = OFFS(__com32.cs_bounce); REG_DS(inreg) = SEG(__com32.cs_bounce); REG_EDX(inreg) = 0; __intcall(0x22,&inreg,&outreg); // If successful does not return } syslinux-legacy-3.63+dfsg/menu/libmenu/passwords.h0000664000175000017500000000136610777447273021017 0ustar evanevan#ifndef _PASSWORDS_H_ #define _PASSWORDS_H_ char authenticate_user(const char * username, const char* pwd); char isallowed(const char *username, const char * perm); // Initialise the list of of user passwords permissions from file void init_passwords(const char *filename); // Free all space used for internal data structures void close_passwords(); #define MAX_USERS 128 // Maximum number of users #define USERNAME_LENGTH 12 // Max length of user name #define PWDHASH_LENGTH 40 // Max lenght of pwd hash typedef struct { char username[USERNAME_LENGTH+1]; char pwdhash[PWDHASH_LENGTH+1]; char *perms; // pointer to string containing ":" delimited permissions } pwdentry; typedef pwdentry *p_pwdentry; #define GUEST_USER "guest" #endif syslinux-legacy-3.63+dfsg/menu/libmenu/tui.h0000664000175000017500000000476310777447273017577 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef __TUI_H__ #define __TUI_H__ #include #include "syslnx.h" #include "com32io.h" #include "scancodes.h" #ifndef NULL #define NULL ((void *)0) #endif #define BELL 0x07 // CHRELATTR = ^N, CHABSATTR = ^O #define CHABSATTR 15 #define CHRELATTR 14 void clearwindow(char top, char left, char bot, char right, char page, char fillchar, char fillattr); void cls(void); /* Clears the entire current screen page */ // Generic user input, // password = 0 iff chars echoed on screen // showoldvalue <> 0 iff current displayed for editing void getuserinput(char *str, unsigned int size, unsigned int password, unsigned int showoldvalue); static inline void getstring(char *str, unsigned int size) { getuserinput(str,size,0,0); } static inline void editstring(char *str, unsigned int size) { getuserinput(str,size,0,1); } static inline void getpwd(char * str, unsigned int size) { getuserinput(str,size,1,0); } // Box drawing Chars offsets into array #define BOX_TOPLEFT 0x0 #define BOX_BOTLEFT 0x1 #define BOX_TOPRIGHT 0x2 #define BOX_BOTRIGHT 0x3 #define BOX_TOP 0x4 // TOP = BOT = HORIZ #define BOX_BOT 0x4 #define BOX_HORIZ 0x4 #define BOX_LEFT 0x5 #define BOX_RIGHT 0x5 #define BOX_VERT 0x5 // LEFT=RIGHT=VERT #define BOX_LTRT 0x6 #define BOX_RTLT 0x7 #define BOX_TOPBOT 0x8 #define BOX_BOTTOP 0x9 #define BOX_MIDDLE 0xA typedef enum {BOX_SINSIN,BOX_DBLDBL, BOX_SINDBL, BOX_DBLSIN} boxtype; unsigned char * getboxchars(boxtype bt); void drawbox(char top,char left,char bot, char right, char page, char attr,boxtype bt); // Draw a horizontal line // dumb == 1, means just draw the line // dumb == 0 means check the first and last positions and depending on what is // currently on the screen make it a LTRT and/or RTLT appropriately. void drawhorizline(char top, char left, char right, char page, char attr, boxtype bt, char dumb); #endif syslinux-legacy-3.63+dfsg/menu/libmenu/scancodes.h0000664000175000017500000000405210777447273020727 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef __SCANCODES_H__ #define __SCANCODES_H__ // Scancodes of some keys #define ESCAPE 1 #define ENTERA 28 #define ENTERB 224 #define HOMEKEY 71 #define UPARROW 72 #define PAGEUP 73 #define LTARROW 75 #define RTARROW 77 #define ENDKEY 79 #define DNARROW 80 #define PAGEDN 81 #define INSERT 82 #define DELETE 83 #define SPACEKEY 57 // Scan code for SPACE #define CTRLLT 0x73 #define CTRLRT 0x74 #define F1 0x3B #define F2 0x3C #define F3 0x3D #define F4 0x3E #define F5 0x3F #define F6 0x40 #define F7 0x41 #define F8 0x42 #define F9 0x43 #define F10 0x44 #define F11 0x85 #define F12 0x86 #define CTRLF1 0x5E #define CTRLF2 0x5F #define CTRLF3 0x60 #define CTRLF4 0x61 #define CTRLF5 0x62 #define CTRLF6 0x63 #define CTRLF7 0x64 #define CTRLF8 0x65 #define CTRLF9 0x66 #define CTRLF10 0x67 #define CTRLF11 0x89 #define CTRLF12 0x8A #define ALTF1 0x68 #define ALTF2 0x69 #define ALTF3 0x6A #define ALTF4 0x6B #define ALTF5 0x6C #define ALTF6 0x6D #define ALTF7 0x6E #define ALTF8 0x6F #define ALTF9 0x70 #define ALTF10 0x71 #define ALTF11 0x8B #define ALTF12 0x8C /* Bits representing ShiftFlags, See Int16/Function 2 or Mem[0x417] to get this info */ #define INSERT_ON (1<<7) #define CAPSLOCK_ON (1<<6) #define NUMLOCK_ON (1<<5) #define SCRLLOCK_ON (1<<4) #define ALT_PRESSED (1<<3) #define CTRL_PRESSED (1<<2) // actually 1<<1 is Left Shift, 1<<0 is right shift #define SHIFT_PRESSED (1<<1 | 1 <<0) #endif syslinux-legacy-3.63+dfsg/menu/libmenu/des.c0000664000175000017500000006603510777447273017544 0ustar evanevan/* * FreeSec: libcrypt for NetBSD * * Copyright (c) 1994 David Burren * All rights reserved. * * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet * this file should now *only* export crypt(), in order to make * binaries of libcrypt exportable from the USA * * Adapted for FreeBSD-4.0 by Mark R V Murray * this file should now *only* export crypt_des(), in order to make * a module that can be optionally included in libcrypt. * * Adapted for pxelinux menu environment by Th.Gebhardt * removed dependencies of standard C libs * added LOWSPACE option (using common space for different arrays) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of other contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This is an original implementation of the DES and the crypt(3) interfaces * by David Burren . * * An excellent reference on the underlying algorithm (and related * algorithms) is: * * B. Schneier, Applied Cryptography: protocols, algorithms, * and source code in C, John Wiley & Sons, 1994. * * Note that in that book's description of DES the lookups for the initial, * pbox, and final permutations are inverted (this has been brought to the * attention of the author). A list of errata for this book has been * posted to the sci.crypt newsgroup by the author and is available for FTP. * * ARCHITECTURE ASSUMPTIONS: * It is assumed that the 8-byte arrays passed by reference can be * addressed as arrays of u_int32_t's (ie. the CPU is not picky about * alignment). */ #define LOWSPACE #ifndef NULL #define NULL ((void *) 0) #endif typedef unsigned long my_u_int32_t; typedef unsigned char my_u_char_t; /* Re-entrantify me -- all this junk needs to be in * struct crypt_data to make this really reentrant... */ static my_u_char_t inv_key_perm[64]; static my_u_char_t inv_comp_perm[56]; static my_u_char_t u_sbox[8][64]; static my_u_char_t un_pbox[32]; static my_u_int32_t en_keysl[16], en_keysr[16]; static my_u_int32_t de_keysl[16], de_keysr[16]; #ifndef LOWSPACE static my_u_int32_t ip_maskl[8][256], ip_maskr[8][256]; static my_u_int32_t fp_maskl[8][256], fp_maskr[8][256]; static my_u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128]; static my_u_int32_t comp_maskl[8][128], comp_maskr[8][128]; #endif static my_u_int32_t saltbits; static my_u_int32_t old_salt; static my_u_int32_t old_rawkey0, old_rawkey1; #ifdef LOWSPACE static my_u_int32_t common[8][256]; #endif /* Static stuff that stays resident and doesn't change after * being initialized, and therefore doesn't need to be made * reentrant. */ static my_u_char_t init_perm[64], final_perm[64]; static my_u_char_t m_sbox[4][4096]; #ifndef LOWSPACE static my_u_int32_t psbox[4][256]; #endif /* A pile of data */ static const my_u_char_t ascii64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static const my_u_char_t IP[64] = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 }; static const my_u_char_t key_perm[56] = { 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 }; static const my_u_char_t key_shifts[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; static const my_u_char_t comp_perm[48] = { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 }; /* * No E box is used, as it's replaced by some ANDs, shifts, and ORs. */ static const my_u_char_t sbox[8][64] = { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }, { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }, { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }, { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }, { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }, { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }, { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }, { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } }; static const my_u_char_t pbox[32] = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 }; static const my_u_int32_t bits32[32] = { 0x80000000, 0x40000000, 0x20000000, 0x10000000, 0x08000000, 0x04000000, 0x02000000, 0x01000000, 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000, 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080, 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 }; static const my_u_int32_t bits28[28] = { 0x08000000, 0x04000000, 0x02000000, 0x01000000, 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000, 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080, 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 }; static const my_u_int32_t bits24[24] = { 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000, 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080, 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 }; static const my_u_char_t bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; // static const my_u_int32_t *bits28, *bits24; static int ascii_to_bin(char ch) { if (ch > 'z') return(0); if (ch >= 'a') return(ch - 'a' + 38); if (ch > 'Z') return(0); if (ch >= 'A') return(ch - 'A' + 12); if (ch > '9') return(0); if (ch >= '.') return(ch - '.'); return(0); } static void des_init(void) { #ifdef LOWSPACE int i, j, b; #else int i, j, b, k, inbit, obit; my_u_int32_t *p, *il, *ir, *fl, *fr; #endif static int des_initialised = 0; if (des_initialised==1) return; old_rawkey0 = old_rawkey1 = 0L; saltbits = 0L; old_salt = 0L; // bits24 = (bits28 = bits32 + 4) + 4; /* * Invert the S-boxes, reordering the input bits. */ for (i = 0; i < 8; i++) for (j = 0; j < 64; j++) { b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf); u_sbox[i][j] = sbox[i][b]; } /* * Convert the inverted S-boxes into 4 arrays of 8 bits. * Each will handle 12 bits of the S-box input. */ for (b = 0; b < 4; b++) for (i = 0; i < 64; i++) for (j = 0; j < 64; j++) m_sbox[b][(i << 6) | j] = (my_u_char_t)((u_sbox[(b << 1)][i] << 4) | u_sbox[(b << 1) + 1][j]); /* * Set up the initial & final permutations into a useful form, and * initialise the inverted key permutation. */ for (i = 0; i < 64; i++) { init_perm[final_perm[i] = IP[i] - 1] = (my_u_char_t)i; inv_key_perm[i] = 255; } /* * Invert the key permutation and initialise the inverted key * compression permutation. */ for (i = 0; i < 56; i++) { inv_key_perm[key_perm[i] - 1] = (my_u_char_t)i; inv_comp_perm[i] = 255; } /* * Invert the key compression permutation. */ for (i = 0; i < 48; i++) { inv_comp_perm[comp_perm[i] - 1] = (my_u_char_t)i; } /* * Set up the OR-mask arrays for the initial and final permutations, * and for the key initial and compression permutations. */ #ifndef LOWSPACE for (k = 0; k < 8; k++) { for (i = 0; i < 256; i++) { *(il = &ip_maskl[k][i]) = 0L; *(ir = &ip_maskr[k][i]) = 0L; *(fl = &fp_maskl[k][i]) = 0L; *(fr = &fp_maskr[k][i]) = 0L; for (j = 0; j < 8; j++) { inbit = 8 * k + j; if (i & bits8[j]) { if ((obit = init_perm[inbit]) < 32) *il |= bits32[obit]; else *ir |= bits32[obit-32]; if ((obit = final_perm[inbit]) < 32) *fl |= bits32[obit]; else *fr |= bits32[obit - 32]; } } } for (i = 0; i < 128; i++) { *(il = &key_perm_maskl[k][i]) = 0L; *(ir = &key_perm_maskr[k][i]) = 0L; for (j = 0; j < 7; j++) { inbit = 8 * k + j; if (i & bits8[j + 1]) { if ((obit = inv_key_perm[inbit]) == 255) continue; if (obit < 28) *il |= bits28[obit]; else *ir |= bits28[obit - 28]; } } *(il = &comp_maskl[k][i]) = 0L; *(ir = &comp_maskr[k][i]) = 0L; for (j = 0; j < 7; j++) { inbit = 7 * k + j; if (i & bits8[j + 1]) { if ((obit=inv_comp_perm[inbit]) == 255) continue; if (obit < 24) *il |= bits24[obit]; else *ir |= bits24[obit - 24]; } } } } #endif /* * Invert the P-box permutation, and convert into OR-masks for * handling the output of the S-box arrays setup above. */ for (i = 0; i < 32; i++) un_pbox[pbox[i] - 1] = (my_u_char_t)i; #ifndef LOWSPACE for (b = 0; b < 4; b++) for (i = 0; i < 256; i++) { *(p = &psbox[b][i]) = 0L; for (j = 0; j < 8; j++) { if (i & bits8[j]) *p |= bits32[un_pbox[8 * b + j]]; } } #endif des_initialised = 1; } #ifdef LOWSPACE static void setup_ip_maskl(void) { int i, j, k, inbit, obit; my_u_int32_t *il; for (k = 0; k < 8; k++) { for (i = 0; i < 256; i++) { *(il = &common[k][i]) = 0L; for (j = 0; j < 8; j++) { inbit = 8 * k + j; if (i & bits8[j]) { if ((obit = init_perm[inbit]) < 32) *il |= bits32[obit]; } } } } } static void setup_ip_maskr(void) { int i, j, k, inbit, obit; my_u_int32_t *ir; for (k = 0; k < 8; k++) { for (i = 0; i < 256; i++) { *(ir = &common[k][i]) = 0L; for (j = 0; j < 8; j++) { inbit = 8 * k + j; if (i & bits8[j]) { if ((obit = init_perm[inbit]) >= 32) *ir |= bits32[obit-32]; } } } } } static void setup_fp_maskl(void) { int i, j, k, inbit, obit; my_u_int32_t *fl; for (k = 0; k < 8; k++) { for (i = 0; i < 256; i++) { *(fl = &common[k][i]) = 0L; for (j = 0; j < 8; j++) { inbit = 8 * k + j; if (i & bits8[j]) { if ((obit = final_perm[inbit]) < 32) *fl |= bits32[obit]; } } } } } static void setup_fp_maskr(void) { int i, j, k, inbit, obit; my_u_int32_t *fr; for (k = 0; k < 8; k++) { for (i = 0; i < 256; i++) { *(fr = &common[k][i]) = 0L; for (j = 0; j < 8; j++) { inbit = 8 * k + j; if (i & bits8[j]) { if ((obit = final_perm[inbit]) >= 32) *fr |= bits32[obit - 32]; } } } } } static void setup_key_perm_maskl(void) { int i, j, k, inbit, obit; my_u_int32_t *il; for (k = 0; k < 8; k++) { for (i = 0; i < 128; i++) { *(il = &common[k][i]) = 0L; for (j = 0; j < 7; j++) { inbit = 8 * k + j; if (i & bits8[j + 1]) { if ((obit = inv_key_perm[inbit]) == 255) continue; if (obit < 28) *il |= bits28[obit]; } } } } } static void setup_key_perm_maskr(void) { int i, j, k, inbit, obit; my_u_int32_t *ir; for (k = 0; k < 8; k++) { for (i = 0; i < 128; i++) { *(ir = &common[k][i]) = 0L; for (j = 0; j < 7; j++) { inbit = 8 * k + j; if (i & bits8[j + 1]) { if ((obit = inv_key_perm[inbit]) == 255) continue; if (obit >= 28) *ir |= bits28[obit - 28]; } } } } } static void setup_comp_maskl(void) { int i, j, k, inbit, obit; my_u_int32_t *il; for (k = 0; k < 8; k++) { for (i = 0; i < 128; i++) { *(il = &common[k][i]) = 0L; for (j = 0; j < 7; j++) { inbit = 7 * k + j; if (i & bits8[j + 1]) { if ((obit=inv_comp_perm[inbit]) == 255) continue; if (obit < 24) *il |= bits24[obit]; } } } } } static void setup_comp_maskr(void) { int i, j, k, inbit, obit; my_u_int32_t *ir; for (k = 0; k < 8; k++) { for (i = 0; i < 128; i++) { *(ir = &common[k][i]) = 0L; for (j = 0; j < 7; j++) { inbit = 7 * k + j; if (i & bits8[j + 1]) { if ((obit=inv_comp_perm[inbit]) == 255) continue; if (obit >= 24) *ir |= bits24[obit - 24]; } } } } } static void setup_psbox(void) { int i, j, b; my_u_int32_t *p; for (b = 0; b < 4; b++) for (i = 0; i < 256; i++) { *(p = &common[b][i]) = 0L; for (j = 0; j < 8; j++) { if (i & bits8[j]) *p |= bits32[un_pbox[8 * b + j]]; } } } #endif static void setup_salt(my_u_int32_t salt) { my_u_int32_t obit, saltbit; int i; if (salt == old_salt) return; old_salt = salt; saltbits = 0L; saltbit = 1; obit = 0x800000; for (i = 0; i < 24; i++) { if (salt & saltbit) saltbits |= obit; saltbit <<= 1; obit >>= 1; } } static my_u_int32_t char_to_int(const char *key) { my_u_int32_t byte0,byte1,byte2,byte3; byte0 = (my_u_int32_t) (my_u_char_t) key[0]; byte1 = (my_u_int32_t) (my_u_char_t) key[1]; byte2 = (my_u_int32_t) (my_u_char_t) key[2]; byte3 = (my_u_int32_t) (my_u_char_t) key[3]; return byte0 << 24 | byte1 << 16 | byte2 << 8 | byte3 ; } static int des_setkey(const char *key) { my_u_int32_t k0, k1, rawkey0, rawkey1; int shifts, round; des_init(); /* rawkey0 = ntohl(*(const my_u_int32_t *) key); * rawkey1 = ntohl(*(const my_u_int32_t *) (key + 4)); */ rawkey0 = char_to_int(key); rawkey1 = char_to_int(key+4); if ((rawkey0 | rawkey1) && rawkey0 == old_rawkey0 && rawkey1 == old_rawkey1) { /* * Already setup for this key. * This optimisation fails on a zero key (which is weak and * has bad parity anyway) in order to simplify the starting * conditions. */ return(0); } old_rawkey0 = rawkey0; old_rawkey1 = rawkey1; /* * Do key permutation and split into two 28-bit subkeys. */ #ifdef LOWSPACE setup_key_perm_maskl(); k0 = common[0][rawkey0 >> 25] | common[1][(rawkey0 >> 17) & 0x7f] | common[2][(rawkey0 >> 9) & 0x7f] | common[3][(rawkey0 >> 1) & 0x7f] | common[4][rawkey1 >> 25] | common[5][(rawkey1 >> 17) & 0x7f] | common[6][(rawkey1 >> 9) & 0x7f] | common[7][(rawkey1 >> 1) & 0x7f]; setup_key_perm_maskr(); k1 = common[0][rawkey0 >> 25] | common[1][(rawkey0 >> 17) & 0x7f] | common[2][(rawkey0 >> 9) & 0x7f] | common[3][(rawkey0 >> 1) & 0x7f] | common[4][rawkey1 >> 25] | common[5][(rawkey1 >> 17) & 0x7f] | common[6][(rawkey1 >> 9) & 0x7f] | common[7][(rawkey1 >> 1) & 0x7f]; #else k0 = key_perm_maskl[0][rawkey0 >> 25] | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f] | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f] | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f] | key_perm_maskl[4][rawkey1 >> 25] | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f] | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f] | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f]; k1 = key_perm_maskr[0][rawkey0 >> 25] | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f] | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f] | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f] | key_perm_maskr[4][rawkey1 >> 25] | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f] | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f] | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f]; #endif /* * Rotate subkeys and do compression permutation. */ shifts = 0; for (round = 0; round < 16; round++) { my_u_int32_t t0, t1; shifts += key_shifts[round]; t0 = (k0 << shifts) | (k0 >> (28 - shifts)); t1 = (k1 << shifts) | (k1 >> (28 - shifts)); #ifdef LOWSPACE setup_comp_maskl(); de_keysl[15 - round] = en_keysl[round] = common[0][(t0 >> 21) & 0x7f] | common[1][(t0 >> 14) & 0x7f] | common[2][(t0 >> 7) & 0x7f] | common[3][t0 & 0x7f] | common[4][(t1 >> 21) & 0x7f] | common[5][(t1 >> 14) & 0x7f] | common[6][(t1 >> 7) & 0x7f] | common[7][t1 & 0x7f]; setup_comp_maskr(); de_keysr[15 - round] = en_keysr[round] = common[0][(t0 >> 21) & 0x7f] | common[1][(t0 >> 14) & 0x7f] | common[2][(t0 >> 7) & 0x7f] | common[3][t0 & 0x7f] | common[4][(t1 >> 21) & 0x7f] | common[5][(t1 >> 14) & 0x7f] | common[6][(t1 >> 7) & 0x7f] | common[7][t1 & 0x7f]; #else de_keysl[15 - round] = en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f] | comp_maskl[1][(t0 >> 14) & 0x7f] | comp_maskl[2][(t0 >> 7) & 0x7f] | comp_maskl[3][t0 & 0x7f] | comp_maskl[4][(t1 >> 21) & 0x7f] | comp_maskl[5][(t1 >> 14) & 0x7f] | comp_maskl[6][(t1 >> 7) & 0x7f] | comp_maskl[7][t1 & 0x7f]; de_keysr[15 - round] = en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f] | comp_maskr[1][(t0 >> 14) & 0x7f] | comp_maskr[2][(t0 >> 7) & 0x7f] | comp_maskr[3][t0 & 0x7f] | comp_maskr[4][(t1 >> 21) & 0x7f] | comp_maskr[5][(t1 >> 14) & 0x7f] | comp_maskr[6][(t1 >> 7) & 0x7f] | comp_maskr[7][t1 & 0x7f]; #endif } return(0); } static int do_des( my_u_int32_t l_in, my_u_int32_t r_in, my_u_int32_t *l_out, my_u_int32_t *r_out, int count) { /* * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. */ my_u_int32_t l, r, *kl, *kr, *kl1, *kr1; my_u_int32_t f, r48l, r48r; int round; if (count == 0) { return(1); } else if (count > 0) { /* * Encrypting */ kl1 = en_keysl; kr1 = en_keysr; } else { /* * Decrypting */ count = -count; kl1 = de_keysl; kr1 = de_keysr; } /* * Do initial permutation (IP). */ #ifdef LOWSPACE setup_ip_maskl(); l = common[0][l_in >> 24] | common[1][(l_in >> 16) & 0xff] | common[2][(l_in >> 8) & 0xff] | common[3][l_in & 0xff] | common[4][r_in >> 24] | common[5][(r_in >> 16) & 0xff] | common[6][(r_in >> 8) & 0xff] | common[7][r_in & 0xff]; setup_ip_maskr(); r = common[0][l_in >> 24] | common[1][(l_in >> 16) & 0xff] | common[2][(l_in >> 8) & 0xff] | common[3][l_in & 0xff] | common[4][r_in >> 24] | common[5][(r_in >> 16) & 0xff] | common[6][(r_in >> 8) & 0xff] | common[7][r_in & 0xff]; #else l = ip_maskl[0][l_in >> 24] | ip_maskl[1][(l_in >> 16) & 0xff] | ip_maskl[2][(l_in >> 8) & 0xff] | ip_maskl[3][l_in & 0xff] | ip_maskl[4][r_in >> 24] | ip_maskl[5][(r_in >> 16) & 0xff] | ip_maskl[6][(r_in >> 8) & 0xff] | ip_maskl[7][r_in & 0xff]; r = ip_maskr[0][l_in >> 24] | ip_maskr[1][(l_in >> 16) & 0xff] | ip_maskr[2][(l_in >> 8) & 0xff] | ip_maskr[3][l_in & 0xff] | ip_maskr[4][r_in >> 24] | ip_maskr[5][(r_in >> 16) & 0xff] | ip_maskr[6][(r_in >> 8) & 0xff] | ip_maskr[7][r_in & 0xff]; #endif while (count--) { /* * Do each round. */ kl = kl1; kr = kr1; round = 16; while (round--) { /* * Expand R to 48 bits (simulate the E-box). */ r48l = ((r & 0x00000001) << 23) | ((r & 0xf8000000) >> 9) | ((r & 0x1f800000) >> 11) | ((r & 0x01f80000) >> 13) | ((r & 0x001f8000) >> 15); r48r = ((r & 0x0001f800) << 7) | ((r & 0x00001f80) << 5) | ((r & 0x000001f8) << 3) | ((r & 0x0000001f) << 1) | ((r & 0x80000000) >> 31); /* * Do salting for crypt() and friends, and * XOR with the permuted key. */ f = (r48l ^ r48r) & saltbits; r48l ^= f ^ *kl++; r48r ^= f ^ *kr++; /* * Do sbox lookups (which shrink it back to 32 bits) * and do the pbox permutation at the same time. */ #ifdef LOWSPACE setup_psbox(); f = common[0][m_sbox[0][r48l >> 12]] | common[1][m_sbox[1][r48l & 0xfff]] | common[2][m_sbox[2][r48r >> 12]] | common[3][m_sbox[3][r48r & 0xfff]]; #else f = psbox[0][m_sbox[0][r48l >> 12]] | psbox[1][m_sbox[1][r48l & 0xfff]] | psbox[2][m_sbox[2][r48r >> 12]] | psbox[3][m_sbox[3][r48r & 0xfff]]; #endif /* * Now that we've permuted things, complete f(). */ f ^= l; l = r; r = f; } r = l; l = f; } /* * Do final permutation (inverse of IP). */ #ifdef LOWSPACE setup_fp_maskl(); *l_out = common[0][l >> 24] | common[1][(l >> 16) & 0xff] | common[2][(l >> 8) & 0xff] | common[3][l & 0xff] | common[4][r >> 24] | common[5][(r >> 16) & 0xff] | common[6][(r >> 8) & 0xff] | common[7][r & 0xff]; setup_fp_maskr(); *r_out = common[0][l >> 24] | common[1][(l >> 16) & 0xff] | common[2][(l >> 8) & 0xff] | common[3][l & 0xff] | common[4][r >> 24] | common[5][(r >> 16) & 0xff] | common[6][(r >> 8) & 0xff] | common[7][r & 0xff]; #else *l_out = fp_maskl[0][l >> 24] | fp_maskl[1][(l >> 16) & 0xff] | fp_maskl[2][(l >> 8) & 0xff] | fp_maskl[3][l & 0xff] | fp_maskl[4][r >> 24] | fp_maskl[5][(r >> 16) & 0xff] | fp_maskl[6][(r >> 8) & 0xff] | fp_maskl[7][r & 0xff]; *r_out = fp_maskr[0][l >> 24] | fp_maskr[1][(l >> 16) & 0xff] | fp_maskr[2][(l >> 8) & 0xff] | fp_maskr[3][l & 0xff] | fp_maskr[4][r >> 24] | fp_maskr[5][(r >> 16) & 0xff] | fp_maskr[6][(r >> 8) & 0xff] | fp_maskr[7][r & 0xff]; #endif return(0); } #if 0 static int des_cipher(const char *in, char *out, my_u_int32_t salt, int count) { my_u_int32_t l_out, r_out, rawl, rawr; int retval; union { my_u_int32_t *ui32; const char *c; } trans; des_init(); setup_salt(salt); trans.c = in; rawl = ntohl(*trans.ui32++); rawr = ntohl(*trans.ui32); retval = do_des(rawl, rawr, &l_out, &r_out, count); trans.c = out; *trans.ui32++ = htonl(l_out); *trans.ui32 = htonl(r_out); return(retval); } #endif void setkey(const char *key) { int i, j; my_u_int32_t packed_keys[2]; my_u_char_t *p; p = (my_u_char_t *) packed_keys; for (i = 0; i < 8; i++) { p[i] = 0; for (j = 0; j < 8; j++) if (*key++ & 1) p[i] |= bits8[j]; } des_setkey(p); } void encrypt(char *block, int flag) { my_u_int32_t io[2]; my_u_char_t *p; int i, j; des_init(); setup_salt(0L); p = block; for (i = 0; i < 2; i++) { io[i] = 0L; for (j = 0; j < 32; j++) if (*p++ & 1) io[i] |= bits32[j]; } do_des(io[0], io[1], io, io + 1, flag ? -1 : 1); for (i = 0; i < 2; i++) for (j = 0; j < 32; j++) block[(i << 5) | j] = (io[i] & bits32[j]) ? 1 : 0; } char *crypt(const char *key, const char *setting) { my_u_int32_t count, salt, l, r0, r1, keybuf[2]; my_u_char_t *p, *q; static char output[21]; des_init(); /* * Copy the key, shifting each character up by one bit * and padding with zeros. */ q = (my_u_char_t *)keybuf; while (q - (my_u_char_t *)keybuf - 8) { *q++ = *key << 1; if (*(q - 1)) key++; } if (des_setkey((char *)keybuf)) return(NULL); #if 0 if (*setting == _PASSWORD_EFMT1) { int i; /* * "new"-style: * setting - underscore, 4 bytes of count, 4 bytes of salt * key - unlimited characters */ for (i = 1, count = 0L; i < 5; i++) count |= ascii_to_bin(setting[i]) << ((i - 1) * 6); for (i = 5, salt = 0L; i < 9; i++) salt |= ascii_to_bin(setting[i]) << ((i - 5) * 6); while (*key) { /* * Encrypt the key with itself. */ if (des_cipher((char *)keybuf, (char *)keybuf, 0L, 1)) return(NULL); /* * And XOR with the next 8 characters of the key. */ q = (my_u_char_t *)keybuf; while (q - (my_u_char_t *)keybuf - 8 && *key) *q++ ^= *key++ << 1; if (des_setkey((char *)keybuf)) return(NULL); } strncpy(output, setting, 9); /* * Double check that we weren't given a short setting. * If we were, the above code will probably have created * wierd values for count and salt, but we don't really care. * Just make sure the output string doesn't have an extra * NUL in it. */ output[9] = '\0'; p = (my_u_char_t *)output + strlen(output); } else #endif { /* * "old"-style: * setting - 2 bytes of salt * key - up to 8 characters */ count = 25; salt = (ascii_to_bin(setting[1]) << 6) | ascii_to_bin(setting[0]); output[0] = setting[0]; /* * If the encrypted password that the salt was extracted from * is only 1 character long, the salt will be corrupted. We * need to ensure that the output string doesn't have an extra * NUL in it! */ output[1] = setting[1] ? setting[1] : output[0]; p = (my_u_char_t *)output + 2; } setup_salt(salt); /* * Do it. */ if (do_des(0L, 0L, &r0, &r1, (int)count)) return(NULL); /* * Now encode the result... */ l = (r0 >> 8); *p++ = ascii64[(l >> 18) & 0x3f]; *p++ = ascii64[(l >> 12) & 0x3f]; *p++ = ascii64[(l >> 6) & 0x3f]; *p++ = ascii64[l & 0x3f]; l = (r0 << 16) | ((r1 >> 16) & 0xffff); *p++ = ascii64[(l >> 18) & 0x3f]; *p++ = ascii64[(l >> 12) & 0x3f]; *p++ = ascii64[(l >> 6) & 0x3f]; *p++ = ascii64[l & 0x3f]; l = r1 << 2; *p++ = ascii64[(l >> 12) & 0x3f]; *p++ = ascii64[(l >> 6) & 0x3f]; *p++ = ascii64[l & 0x3f]; *p = 0; return(output); } syslinux-legacy-3.63+dfsg/menu/libmenu/menu.c0000664000175000017500000011223210777447273017724 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include "menu.h" #include "com32io.h" #include // Local Variables static pt_menusystem ms; // Pointer to the menusystem char TITLESTR[] = "COMBOOT Menu System for SYSLINUX developed by Murali Krishnan Ganapathy"; char TITLELONG[] = " TITLE too long "; char ITEMLONG[] = " ITEM too long "; char ACTIONLONG[] = " ACTION too long "; char STATUSLONG[] = " STATUS too long "; char EMPTYSTR[] = ""; /* Forward declarations */ int calc_visible(pt_menu menu,int first); int next_visible(pt_menu menu,int index); int prev_visible(pt_menu menu,int index); int next_visible_sep(pt_menu menu,int index); int prev_visible_sep(pt_menu menu,int index); int calc_first_early(pt_menu menu,int curr); int calc_first_late(pt_menu menu,int curr); int isvisible(pt_menu menu,int first, int curr); /* Basic Menu routines */ // This is same as inputc except it honors the ontimeout handler // and calls it when needed. For the callee, there is no difference // as this will not return unless a key has been pressed. char getch(char *scan) { unsigned long i; TIMEOUTCODE c; t_timeout_handler th; // Wait until keypress if no handler specified if ((ms->ontimeout==NULL) && (ms->ontotaltimeout==NULL)) return inputc(scan); th = ms->ontimeout; while (1) // Forever do { for (i=0; i < ms->tm_numsteps; i++) { if (checkkbdbuf()) return inputc(scan); sleep(ms->tm_stepsize); if ( (ms->tm_total_timeout == 0) || (ms->ontotaltimeout==NULL)) continue; // Dont bother with calculations if no handler ms->tm_sofar_timeout += ms->tm_stepsize; if (ms->tm_sofar_timeout >= ms->tm_total_timeout) { th = ms->ontotaltimeout; ms->tm_sofar_timeout = 0; break; // Get out of the for loop } } if (!th) continue; // no handler dont call c = th(); switch(c) { case CODE_ENTER: // Pretend user hit enter *scan = ENTERA; return '\015'; // \015 octal = 13 case CODE_ESCAPE: // Pretend user hit escape *scan = ESCAPE; return '\033'; // \033 octal = 27 default: break; } } return 0; } /* Print a menu item */ /* attr[0] is non-hilite attr, attr[1] is highlight attr */ void printmenuitem(const char *str,uchar* attr) { uchar page = getdisppage(); uchar row,col; int hlite=NOHLITE; // Initially no highlighting getpos(&row,&col,page); while ( *str ) { switch (*str) { case '\b': --col; break; case '\n': ++row; break; case '\r': col=0; break; case BELL: // No Bell Char break; case ENABLEHLITE: // Switch on highlighting hlite = HLITE; break; case DISABLEHLITE: // Turn off highlighting hlite = NOHLITE; break; default: putch(*str, attr[hlite], page); ++col; } if (col > getnumcols()) { ++row; col=0; } if (row > getnumrows()) { scrollup(); row= getnumrows(); } gotoxy(row,col,page); str++; } } int find_shortcut(pt_menu menu,uchar shortcut, int index) // Find the next index with specified shortcut key { int ans; pt_menuitem mi; // Garbage in garbage out if ((index <0) || (index >= menu->numitems)) return index; ans = index+1; // Go till end of menu while (ans < menu->numitems) { mi = menu->items[ans]; if ((mi->action == OPT_INVISIBLE) || (mi->action == OPT_SEP) || (mi->shortcut != shortcut)) ans ++; else return ans; } // Start at the beginning and try again ans = 0; while (ans < index) { mi = menu->items[ans]; if ((mi->action == OPT_INVISIBLE) || (mi->action == OPT_SEP) || (mi->shortcut != shortcut)) ans ++; else return ans; } return index; // Sorry not found } // print the menu starting from FIRST // will print a maximum of menu->menuheight items void printmenu(pt_menu menu, int curr, uchar top, uchar left, uchar first) { int x,row; // x = index, row = position from top int numitems,menuwidth; char fchar[5],lchar[5]; // The first and last char in for each entry const char *str; // and inbetween the item or a seperator is printed uchar *attr; // attribute attr char sep[MENULEN];// and inbetween the item or a seperator is printed pt_menuitem ci; numitems = calc_visible(menu,first); if (numitems > menu->menuheight) numitems = menu->menuheight; menuwidth = menu->menuwidth+3; clearwindow(top,left-2, top+numitems+1, left+menuwidth+1, ms->menupage, ms->fillchar, ms->shadowattr); drawbox(top-1,left-3,top+numitems,left+menuwidth, ms->menupage,ms->normalattr[NOHLITE],ms->menubt); memset(sep,ms->box_horiz,menuwidth); // String containing the seperator string sep[menuwidth-1] = 0; // Menu title x = (menuwidth - strlen(menu->title) - 1) >> 1; gotoxy(top-1,left+x,ms->menupage); printmenuitem(menu->title,ms->normalattr); row = -1; // 1 less than inital value of x for (x=first; x < menu->numitems; x++) { ci = menu->items[x]; if (ci->action == OPT_INVISIBLE) continue; row++; if (row >= numitems) break; // Already have enough number of items // Setup the defaults now lchar[0] = fchar[0] = ' '; lchar[1] = fchar[1] = '\0'; // fchar and lchar are just spaces str = ci->item; // Pointer to item string attr = (x==curr ? ms->reverseattr : ms->normalattr); // Normal attributes switch (ci->action) // set up attr,str,fchar,lchar for everything { case OPT_INACTIVE: attr = (x==curr? ms->revinactattr : ms->inactattr); break; case OPT_SUBMENU: lchar[0] = SUBMENUCHAR; lchar[1] = 0; break; case OPT_RADIOMENU: lchar[0] = RADIOMENUCHAR; lchar[1] = 0; break; case OPT_CHECKBOX: lchar[0] = (ci->itemdata.checked ? CHECKED : UNCHECKED); lchar[1] = 0; break; case OPT_SEP: fchar[0] = '\b'; fchar[1] = ms->box_ltrt; fchar[2] = ms->box_horiz; fchar[3] = ms->box_horiz; fchar[4] = 0; lchar[0] = ms->box_horiz; lchar[1] = ms->box_rtlt; lchar[2] = 0; str = sep; break; case OPT_EXITMENU: fchar[0] = EXITMENUCHAR; fchar[1] = 0; break; default: // Just to keep the compiler happy break; } gotoxy(top+row,left-2,ms->menupage); cprint(ms->spacechar,attr[NOHLITE],menuwidth+2,ms->menupage); // Wipe area with spaces gotoxy(top+row,left-2,ms->menupage); csprint(fchar,attr[NOHLITE]); // Print first part gotoxy(top+row,left,ms->menupage); printmenuitem(str,attr); // Print main part gotoxy(top+row,left+menuwidth-1,ms->menupage); // Last char if any csprint(lchar,attr[NOHLITE]); // Print last part } // Check if we need to MOREABOVE and MOREBELOW to be added // reuse x row = 0; x = next_visible_sep(menu,0); // First item if (! isvisible(menu,first,x)) // There is more above { row = 1; gotoxy(top,left+menuwidth,ms->menupage); cprint(MOREABOVE,ms->normalattr[NOHLITE],1,ms->menupage); } x = prev_visible_sep(menu,menu->numitems); // last item if (! isvisible(menu,first,x)) // There is more above { row = 1; gotoxy(top+numitems-1,left+menuwidth,ms->menupage); cprint(MOREBELOW,ms->normalattr[NOHLITE],1,ms->menupage); } // Add a scroll box x = ((numitems-1)*curr)/(menu->numitems); if ((x>0) && (row==1)) { gotoxy(top+x,left+menuwidth,ms->menupage); cprint(SCROLLBOX,ms->normalattr[NOHLITE],1,ms->menupage); } if (ms->handler) ms->handler(ms,menu->items[curr]); } // Difference between this and regular menu, is that only // OPT_INVISIBLE, OPT_SEP are honoured void printradiomenu(pt_menu menu, int curr, uchar top, uchar left, int first) { int x,row; // x = index, row = position from top int numitems,menuwidth; char fchar[5],lchar[5]; // The first and last char in for each entry const char *str; // and inbetween the item or a seperator is printed uchar *attr; // all in the attribute attr char sep[MENULEN];// and inbetween the item or a seperator is printed pt_menuitem ci; numitems = calc_visible(menu,first); if (numitems > menu->menuheight) numitems = menu->menuheight; menuwidth = menu->menuwidth+3; clearwindow(top,left-2, top+numitems+1, left+menuwidth+1, ms->menupage, ms->fillchar, ms->shadowattr); drawbox(top-1,left-3,top+numitems,left+menuwidth, ms->menupage,ms->normalattr[NOHLITE],ms->menubt); memset(sep,ms->box_horiz,menuwidth); // String containing the seperator string sep[menuwidth-1] = 0; // Menu title x = (menuwidth - strlen(menu->title) - 1) >> 1; gotoxy(top-1,left+x,ms->menupage); printmenuitem(menu->title,ms->normalattr); row = -1; // 1 less than inital value of x for (x=first; x < menu->numitems; x++) { ci = menu->items[x]; if (ci->action == OPT_INVISIBLE) continue; row++; if (row > numitems) break; // Setup the defaults now fchar[0] = RADIOUNSEL; fchar[1]='\0'; // Unselected ( ) lchar[0] = '\0'; // Nothing special after str = ci->item; // Pointer to item string attr = ms->normalattr; // Always same attribute fchar[0] = (x==curr ? RADIOSEL : RADIOUNSEL); switch (ci->action) // set up attr,str,fchar,lchar for everything { case OPT_INACTIVE: attr = ms->inactattr; break; case OPT_SEP: fchar[0] = '\b'; fchar[1] = ms->box_ltrt; fchar[2] = ms->box_horiz; fchar[3] = ms->box_horiz; fchar[4] = 0; lchar[0] = ms->box_horiz; lchar[1] = ms->box_rtlt; lchar[3] = 0; str = sep; break; default: // To keep the compiler happy break; } gotoxy(top+row,left-2,ms->menupage); cprint(ms->spacechar,attr[NOHLITE],menuwidth+2,ms->menupage); // Wipe area with spaces gotoxy(top+row,left-2,ms->menupage); csprint(fchar,attr[NOHLITE]); // Print first part gotoxy(top+row,left,ms->menupage); printmenuitem(str,attr); // Print main part gotoxy(top+row,left+menuwidth-1,ms->menupage); // Last char if any csprint(lchar,attr[NOHLITE]); // Print last part } // Check if we need to MOREABOVE and MOREBELOW to be added // reuse x row = 0; x = next_visible_sep(menu,0); // First item if (! isvisible(menu,first,x)) // There is more above { row = 1; gotoxy(top,left+menuwidth,ms->menupage); cprint(MOREABOVE,ms->normalattr[NOHLITE],1,ms->menupage); } x = prev_visible_sep(menu,menu->numitems); // last item if (! isvisible(menu,first,x)) // There is more above { row = 1; gotoxy(top+numitems-1,left+menuwidth,ms->menupage); cprint(MOREBELOW,ms->normalattr[NOHLITE],1,ms->menupage); } // Add a scroll box x = ((numitems-1)*curr)/(menu->numitems); if ((x > 0) && (row == 1)) { gotoxy(top+x,left+menuwidth,ms->menupage); cprint(SCROLLBOX,ms->normalattr[NOHLITE],1,ms->menupage); } if (ms->handler) ms->handler(ms,menu->items[curr]); } void cleanupmenu(pt_menu menu, uchar top,uchar left,int numitems) { if (numitems > menu->menuheight) numitems = menu->menuheight; clearwindow(top,left-2, top+numitems+1, left+menu->menuwidth+4, ms->menupage, ms->fillchar, ms->fillattr); // Clear the shadow clearwindow(top-1, left-3, top+numitems, left+menu->menuwidth+3, ms->menupage, ms->fillchar, ms->fillattr); // main window } /* Handle a radio menu */ pt_menuitem getradiooption(pt_menu menu, uchar top, uchar left, uchar startopt) // Return item chosen or NULL if ESC was hit. { int curr,i,first,tmp; uchar asc,scan; uchar numitems; pt_menuitem ci; // Current item numitems = calc_visible(menu,0); // Setup status line gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage); cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,ms->menupage); // Initialise current menu item curr = next_visible(menu,startopt); gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage); cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,1); gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage); printmenuitem(menu->items[curr]->status,ms->statusattr); first = calc_first_early(menu,curr); while (1) // Forever { printradiomenu(menu,curr,top,left,first); ci = menu->items[curr]; asc = getch(&scan); switch (scan) { case HOMEKEY: curr = next_visible(menu,0); first = calc_first_early(menu,curr); break; case ENDKEY: curr = prev_visible(menu,numitems-1); first = calc_first_late(menu,curr); break; case PAGEDN: for (i=0; i < 5; i++) curr = next_visible(menu,curr+1); first = calc_first_late(menu,curr); break; case PAGEUP: for (i=0; i < 5; i++) curr = prev_visible(menu,curr-1); first = calc_first_early(menu,curr); break; case UPARROW: curr = prev_visible(menu,curr-1); if (curr < first) first = calc_first_early(menu,curr); break; case DNARROW: curr = next_visible(menu,curr+1); if (! isvisible(menu,first,curr)) first = calc_first_late(menu,curr); break; case LTARROW: case ESCAPE: return NULL; break; case RTARROW: case ENTERA: case ENTERB: if (ci->action == OPT_INACTIVE) break; if (ci->action == OPT_SEP) break; return ci; break; default: // Check if this is a shortcut key if (((asc >= 'A') && (asc <= 'Z')) || ((asc >= 'a') && (asc <= 'z')) || ((asc >= '0') && (asc <= '9'))) { tmp = find_shortcut(menu,asc,curr); if ((tmp > curr) && (! isvisible(menu,first,tmp))) first = calc_first_late(menu,tmp); if (tmp < curr) first = calc_first_early(menu,tmp); curr = tmp; } else { if (ms->keys_handler) // Call extra keys handler ms->keys_handler(ms,menu->items[curr],(scan << 8) | asc); } break; } // Update status line gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage); cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,ms->menupage); printmenuitem(menu->items[curr]->status,ms->statusattr); } return NULL; // Should never come here } /* Handle one menu */ pt_menuitem getmenuoption(pt_menu menu, uchar top, uchar left, uchar startopt) // Return item chosen or NULL if ESC was hit. { int curr,i,first,tmp; uchar asc,scan; uchar numitems; pt_menuitem ci; // Current item t_handler_return hr; // Return value of handler numitems = calc_visible(menu,0); // Setup status line gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage); cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,ms->menupage); // Initialise current menu item curr = next_visible(menu,startopt); gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage); cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,1); gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage); printmenuitem(menu->items[curr]->status,ms->statusattr); first = calc_first_early(menu,curr); while (1) // Forever { printmenu(menu,curr,top,left,first); ci = menu->items[curr]; asc = getch(&scan); switch (scan) { case HOMEKEY: curr = next_visible(menu,0); first = calc_first_early(menu,curr); break; case ENDKEY: curr = prev_visible(menu,numitems-1); first = calc_first_late(menu,curr); break; case PAGEDN: for (i=0; i < 5; i++) curr = next_visible(menu,curr+1); first = calc_first_late(menu,curr); break; case PAGEUP: for (i=0; i < 5; i++) curr = prev_visible(menu,curr-1); first = calc_first_early(menu,curr); break; case UPARROW: curr = prev_visible(menu,curr-1); if (curr < first) first = calc_first_early(menu,curr); break; case DNARROW: curr = next_visible(menu,curr+1); if (! isvisible(menu,first,curr)) first = calc_first_late(menu,curr); break; case LTARROW: case ESCAPE: return NULL; break; case RTARROW: case ENTERA: case ENTERB: if (ci->action == OPT_INACTIVE) break; if (ci->action == OPT_CHECKBOX) break; if (ci->action == OPT_SEP) break; if (ci->action == OPT_EXITMENU) return NULL; // As if we hit Esc // If we are going into a radio menu, dont call handler, return ci if (ci->action == OPT_RADIOMENU) return ci; if (ci->handler != NULL) // Do we have a handler { hr = ci->handler(ms,ci); if (hr.refresh) // Do we need to refresh { // Cleanup menu using old number of items cleanupmenu(menu,top,left,numitems); // Recalculate the number of items numitems = calc_visible(menu,0); // Reprint the menu printmenu(menu,curr,top,left,first); } if (hr.valid) return ci; } else return ci; break; case SPACEKEY: if (ci->action != OPT_CHECKBOX) break; ci->itemdata.checked = !ci->itemdata.checked; if (ci->handler != NULL) // Do we have a handler { hr = ci->handler(ms,ci); if (hr.refresh) // Do we need to refresh { // Cleanup menu using old number of items cleanupmenu(menu,top,left,numitems); // Recalculate the number of items numitems = calc_visible(menu,0); // Reprint the menu printmenu(menu,curr,top,left,first); } } break; default: // Check if this is a shortcut key if (((asc >= 'A') && (asc <= 'Z')) || ((asc >= 'a') && (asc <= 'z')) || ((asc >= '0') && (asc <= '9'))) { tmp = find_shortcut(menu,asc,curr); if ((tmp > curr) && (! isvisible(menu,first,tmp))) first = calc_first_late(menu,tmp); if (tmp < curr) first = calc_first_early(menu,tmp); curr = tmp; } else { if (ms->keys_handler) // Call extra keys handler ms->keys_handler(ms,menu->items[curr],(scan << 8) | asc); } break; } // Update status line gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage); cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,ms->menupage); printmenuitem(menu->items[curr]->status,ms->statusattr); } return NULL; // Should never come here } /* Handle the entire system of menu's. */ pt_menuitem runmenusystem(uchar top, uchar left, pt_menu cmenu, uchar startopt, uchar menutype) /* * cmenu * Which menu should be currently displayed * top,left * What is the position of the top,left corner of the menu * startopt * which menu item do I start with * menutype * NORMALMENU or RADIOMENU * * Return Value: * Returns a pointer to the final item chosen, or NULL if nothing chosen. */ { pt_menuitem opt,choice; uchar startat,mt; uchar row,col; if (cmenu == NULL) return NULL; startover: // Set the menu height cmenu->menuheight = ms->maxrow - top-3; if (cmenu->menuheight > ms->maxmenuheight) cmenu->menuheight = ms->maxmenuheight; if (menutype == NORMALMENU) opt = getmenuoption(cmenu,top,left,startopt); else // menutype == RADIOMENU opt = getradiooption(cmenu,top,left,startopt); if (opt == NULL) { // User hit Esc cleanupmenu(cmenu,top,left,calc_visible(cmenu,0)); return NULL; } // Are we done with the menu system? if ((opt->action != OPT_SUBMENU) && (opt->action != OPT_RADIOMENU)) { cleanupmenu(cmenu,top,left,calc_visible(cmenu,0)); return opt; // parent cleanup other menus } // Either radiomenu or submenu // Do we have a valid menu number? The next hack uses the fact that // itemdata.submenunum = itemdata.radiomenunum (since enum data type) if (opt->itemdata.submenunum >= ms->nummenus) // This is Bad.... { gotoxy(12,12,ms->menupage); // Middle of screen csprint("ERROR: Invalid submenu requested.",0x07); cleanupmenu(cmenu,top,left,calc_visible(cmenu,0)); return NULL; // Pretend user hit esc } // Call recursively for submenu // Position the submenu below the current item, // covering half the current window (horizontally) row = ms->menus[(unsigned int)opt->itemdata.submenunum]->row; col = ms->menus[(unsigned int)opt->itemdata.submenunum]->col; if (row == 0xFF) row = top+opt->index+2; if (col == 0xFF) col = left+3+(cmenu->menuwidth >> 1); mt = (opt->action == OPT_SUBMENU ? NORMALMENU : RADIOMENU ); startat = 0; if ((opt->action == OPT_RADIOMENU) && (opt->data != NULL)) startat = ((t_menuitem *)opt->data)->index; choice = runmenusystem(row, col, ms->menus[(unsigned int)opt->itemdata.submenunum], startat, mt ); if (opt->action == OPT_RADIOMENU) { if (choice != NULL) opt->data = (void *)choice; // store choice in data field if (opt->handler != NULL) opt->handler(ms,opt); choice = NULL; // Pretend user hit esc } if (choice==NULL) // User hit Esc in submenu { // Startover startopt = opt->index; goto startover; } else { cleanupmenu(cmenu,top,left,calc_visible(cmenu,0)); return choice; } } // Finds the indexof the menu with given name uchar find_menu_num(const char *name) { int i; pt_menu m; if (name == NULL) return (uchar)(-1); for (i=0; i < ms->nummenus; i++) { m = ms->menus[i]; if ((m->name) && (strcmp(m->name,name)==0)) return i; } return (uchar)(-1); } // Run through all items and if they are submenus // with a non-trivial "action" and trivial submenunum // replace submenunum with the menu with name "action" void fix_submenus() { int i,j; pt_menu m; pt_menuitem mi; i = 0; for (i=0; i < ms->nummenus; i++) { m = ms->menus[i]; for (j=0; j < m->numitems; j++) { mi = m->items[j]; // if submenu with non-trivial data string // again using hack that itemdata is a union data type if ( mi->data && ((mi->action == OPT_SUBMENU) || (mi->action == OPT_RADIOMENU)) ) mi->itemdata.submenunum = find_menu_num (mi->data); } } } /* User Callable functions */ pt_menuitem showmenus(uchar startmenu) { pt_menuitem rv; uchar oldpage,tpos; fix_submenus(); // Fix submenu numbers incase nick names were used // Setup screen for menusystem oldpage = getdisppage(); setdisppage(ms->menupage); cls(); clearwindow(ms->minrow, ms->mincol, ms->maxrow, ms->maxcol, ms->menupage, ms->fillchar, ms->fillattr); tpos = (ms->numcols - strlen(ms->title) - 1) >> 1; // center it on line gotoxy(ms->minrow,ms->mincol,ms->menupage); cprint(ms->tfillchar,ms->titleattr,ms->numcols,ms->menupage); gotoxy(ms->minrow,ms->mincol+tpos,ms->menupage); csprint(ms->title,ms->titleattr); cursoroff(); // Doesn't seem to work? // Go, main menu cannot be a radio menu rv = runmenusystem(ms->minrow+MENUROW, ms->mincol+MENUCOL, ms->menus[(unsigned int)startmenu], 0, NORMALMENU); // Hide the garbage we left on the screen cursoron(); if (oldpage == ms->menupage) cls(); else setdisppage(oldpage); // Return user choice return rv; } pt_menusystem init_menusystem(const char *title) { int i; ms = NULL; ms = (pt_menusystem) malloc(sizeof(t_menusystem)); if (ms == NULL) return NULL; ms->nummenus = 0; // Initialise all menu pointers for (i=0; i < MAXMENUS; i++) ms->menus[i] = NULL; ms->title = (char *)malloc(TITLELEN+1); if (title == NULL) strcpy(ms->title,TITLESTR); // Copy string else strcpy(ms->title,title); // Timeout settings ms->tm_stepsize = TIMEOUTSTEPSIZE; ms->tm_numsteps = TIMEOUTNUMSTEPS; ms->normalattr[NOHLITE] = NORMALATTR; ms->normalattr[HLITE] = NORMALHLITE; ms->reverseattr[NOHLITE] = REVERSEATTR; ms->reverseattr[HLITE] = REVERSEHLITE; ms->inactattr[NOHLITE] = INACTATTR; ms->inactattr[HLITE] = INACTHLITE; ms->revinactattr[NOHLITE] = REVINACTATTR; ms->revinactattr[HLITE] = REVINACTHLITE; ms->statusattr[NOHLITE] = STATUSATTR; ms->statusattr[HLITE] = STATUSHLITE; ms->statline = STATLINE; ms->tfillchar= TFILLCHAR; ms->titleattr= TITLEATTR; ms->fillchar = FILLCHAR; ms->fillattr = FILLATTR; ms->spacechar= SPACECHAR; ms->shadowattr = SHADOWATTR; ms->menupage = MENUPAGE; // Usually no need to change this at all // Initialise all handlers ms->handler = NULL; ms->keys_handler = NULL; ms->ontimeout=NULL; // No timeout handler ms->tm_total_timeout = 0; ms->tm_sofar_timeout = 0; ms->ontotaltimeout = NULL; // Setup ACTION_{,IN}VALID ACTION_VALID.valid=1; ACTION_VALID.refresh=0; ACTION_INVALID.valid = 0; ACTION_INVALID.refresh = 0; // Figure out the size of the screen we are in now. // By default we use the whole screen for our menu ms->minrow = ms->mincol = 0; ms->numcols = getnumcols(); ms->numrows = getnumrows(); ms->maxcol = ms->numcols - 1; ms->maxrow = ms->numrows - 1; // How many entries per menu can we display at a time ms->maxmenuheight = ms->maxrow - ms->minrow - 3; if (ms->maxmenuheight > MAXMENUHEIGHT) ms->maxmenuheight= MAXMENUHEIGHT; // Set up the look of the box set_box_type(MENUBOXTYPE); return ms; } void set_normal_attr(uchar normal, uchar selected, uchar inactivenormal, uchar inactiveselected) { if (normal != 0xFF) ms->normalattr[0] = normal; if (selected != 0xFF) ms->reverseattr[0] = selected; if (inactivenormal != 0xFF) ms->inactattr[0] = inactivenormal; if (inactiveselected != 0xFF) ms->revinactattr[0] = inactiveselected; } void set_normal_hlite(uchar normal, uchar selected, uchar inactivenormal, uchar inactiveselected) { if (normal != 0xFF) ms->normalattr[1] = normal; if (selected != 0xFF) ms->reverseattr[1] = selected; if (inactivenormal != 0xFF) ms->inactattr[1] = inactivenormal; if (inactiveselected != 0xFF) ms->revinactattr[1] = inactiveselected; } void set_status_info(uchar statusattr, uchar statushlite, uchar statline) { if (statusattr != 0xFF) ms->statusattr[NOHLITE] = statusattr; if (statushlite!= 0xFF) ms->statusattr[HLITE] = statushlite; // statline is relative to minrow if (statline >= ms->numrows) statline = ms->numrows - 1; ms->statline = statline; // relative to ms->minrow, 0 based } void set_title_info(uchar tfillchar, uchar titleattr) { if (tfillchar != 0xFF) ms->tfillchar = tfillchar; if (titleattr != 0xFF) ms->titleattr = titleattr; } void set_misc_info(uchar fillchar, uchar fillattr,uchar spacechar, uchar shadowattr) { if (fillchar != 0xFF) ms->fillchar = fillchar; if (fillattr != 0xFF) ms->fillattr = fillattr; if (spacechar != 0xFF) ms->spacechar = spacechar; if (shadowattr!= 0xFF) ms->shadowattr= shadowattr; } void set_box_type(boxtype bt) { uchar *bxc; ms->menubt = bt; bxc = getboxchars(bt); ms->box_horiz = bxc[BOX_HORIZ]; // The char used to draw top line ms->box_ltrt = bxc[BOX_LTRT]; ms->box_rtlt = bxc[BOX_RTLT]; } void set_menu_options(uchar maxmenuheight) { if (maxmenuheight != 0xFF) ms->maxmenuheight = maxmenuheight; } // Set the window which menusystem should use void set_window_size(uchar top, uchar left, uchar bot, uchar right) { uchar nr,nc; if ((top > bot) || (left > right)) return; // Sorry no change will happen here nr = getnumrows(); nc = getnumcols(); if (bot >= nr) bot = nr-1; if (right >= nc) right = nc-1; ms->minrow = top; ms->mincol = left; ms->maxrow = bot; ms->maxcol = right; ms->numcols = right - left + 1; ms->numrows = bot - top + 1; if (ms->statline >= ms->numrows) ms->statline = ms->numrows - 1; // Clip statline if need be } void reg_handler( t_handler htype, void * handler) { // If bad value set to default screen handler switch(htype) { case HDLR_KEYS: ms->keys_handler = (t_keys_handler) handler; break; default: ms->handler = (t_menusystem_handler) handler; break; } } void unreg_handler(t_handler htype) { switch(htype) { case HDLR_KEYS: ms->keys_handler = NULL; break; default: ms->handler = NULL; break; } } void reg_ontimeout(t_timeout_handler handler, unsigned int numsteps, unsigned int stepsize) { ms->ontimeout = handler; if (numsteps != 0) ms->tm_numsteps = numsteps; if (stepsize != 0) ms->tm_stepsize = stepsize; } void unreg_ontimeout() { ms->ontimeout = NULL; } void reg_ontotaltimeout (t_timeout_handler handler, unsigned long numcentiseconds) { if (numcentiseconds != 0) { ms->ontotaltimeout = handler; ms->tm_total_timeout = numcentiseconds*10; // to convert to milliseconds ms->tm_sofar_timeout = 0; } } void unreg_ontotaltimeout() { ms->ontotaltimeout = NULL; } int next_visible(pt_menu menu, int index) { int ans; if (index < 0) ans = 0 ; else if (index >= menu->numitems) ans = menu->numitems-1; else ans = index; while ((ans < menu->numitems-1) && ((menu->items[ans]->action == OPT_INVISIBLE) || (menu->items[ans]->action == OPT_SEP))) ans++; return ans; } int prev_visible(pt_menu menu, int index) // Return index of prev visible { int ans; if (index < 0) ans = 0; else if (index >= menu->numitems) ans = menu->numitems-1; else ans = index; while ((ans > 0) && ((menu->items[ans]->action == OPT_INVISIBLE) || (menu->items[ans]->action == OPT_SEP))) ans--; return ans; } int next_visible_sep(pt_menu menu, int index) { int ans; if (index < 0) ans = 0 ; else if (index >= menu->numitems) ans = menu->numitems-1; else ans = index; while ((ans < menu->numitems-1) && (menu->items[ans]->action == OPT_INVISIBLE)) ans++; return ans; } int prev_visible_sep(pt_menu menu, int index) // Return index of prev visible { int ans; if (index < 0) ans = 0; else if (index >= menu->numitems) ans = menu->numitems-1; else ans = index; while ((ans > 0) && (menu->items[ans]->action == OPT_INVISIBLE)) ans--; return ans; } int calc_visible(pt_menu menu,int first) { int ans,i; if (menu == NULL) return 0; ans = 0; for (i=first; i < menu->numitems; i++) if (menu->items[i]->action != OPT_INVISIBLE) ans++; return ans; } // is curr visible if first entry is first? int isvisible(pt_menu menu,int first, int curr) { if (curr < first) return 0; return (calc_visible(menu,first)-calc_visible(menu,curr) < menu->menuheight); } // Calculate the first entry to be displayed // so that curr is visible and make curr as late as possible int calc_first_late(pt_menu menu,int curr) { int ans,i,nv; nv = calc_visible(menu,0); if (nv <= menu->menuheight) return 0; // Start with curr and go back menu->menuheight times ans = curr+1; for (i=0; i < menu->menuheight; i++) ans = prev_visible_sep(menu,ans-1); return ans; } // Calculate the first entry to be displayed // so that curr is visible and make curr as early as possible int calc_first_early(pt_menu menu,int curr) { int ans,i,nv; nv = calc_visible(menu,0); if (nv <= menu->menuheight) return 0; // Start with curr and go back till >= menu->menuheight // items are visible nv = calc_visible(menu,curr); // Already nv of them are visible ans = curr; for (i=0; i < menu->menuheight - nv; i++) ans = prev_visible_sep(menu,ans-1); return ans; } // Create a new menu and return its position uchar add_menu(const char *title, int maxmenusize) { int num,i; pt_menu m; num = ms->nummenus; if (num >= MAXMENUS) return -1; m = NULL; m = (pt_menu) malloc(sizeof(t_menu)); if (m == NULL) return -1; ms->menus[num] = m; m->numitems = 0; m->name = NULL; m->row = 0xFF; m->col = 0xFF; if (maxmenusize < 1) m->maxmenusize = MAXMENUSIZE; else m->maxmenusize = maxmenusize; m->items = (pt_menuitem *) malloc(sizeof(pt_menuitem)*(m->maxmenusize)); for (i=0; i < m->maxmenusize; i++) m->items[i] = NULL; m->title = (char *)malloc(MENULEN+1); if (title) { if (strlen(title) > MENULEN - 2) strcpy(m->title,TITLELONG); else strcpy(m->title,title); } else strcpy(m->title,EMPTYSTR); m ->menuwidth = strlen(m->title); ms->nummenus ++; return ms->nummenus - 1; } void set_menu_name(const char *name) // Set the "name" of this menu { pt_menu m; m = ms->menus[ms->nummenus-1]; if (m->name) // Free up previous name { free(m->name); m -> name = NULL; } if (name) { m->name = (char *)malloc(strlen(name)+1); strcpy(m->name,name); } } // Create a new named menu and return its position uchar add_named_menu(const char * name, const char *title, int maxmenusize) { add_menu(title,maxmenusize); set_menu_name(name); return ms->nummenus - 1; } void set_menu_pos(uchar row,uchar col) // Set the position of this menu. { pt_menu m; m = ms->menus[ms->nummenus-1]; m->row = row; m->col = col; } pt_menuitem add_sep() // Add a separator to current menu { pt_menuitem mi; pt_menu m; m = (ms->menus[ms->nummenus-1]); mi = NULL; mi = (pt_menuitem) malloc(sizeof(t_menuitem)); if (mi == NULL) return NULL; m->items[(unsigned int)m->numitems] = mi; mi->handler = NULL; // No handler mi->item = mi->status = mi->data = NULL; mi->action = OPT_SEP; mi->index = m->numitems++; mi->parindex = ms->nummenus-1; mi->shortcut = 0; mi->helpid=0; return mi; } // Add item to the "current" menu pt_menuitem add_item(const char *item, const char *status, t_action action, const char *data, uchar itemdata) { pt_menuitem mi; pt_menu m; const char *str; uchar inhlite=0; // Are we inside hlite area m = (ms->menus[ms->nummenus-1]); mi = NULL; mi = (pt_menuitem) malloc(sizeof(t_menuitem)); if (mi == NULL) return NULL; m->items[(unsigned int) m->numitems] = mi; mi->handler = NULL; // No handler // Allocate space to store stuff mi->item = (char *)malloc(MENULEN+1); mi->status = (char *)malloc(STATLEN+1); mi->data = (char *)malloc(ACTIONLEN+1); if (item) { if (strlen(item) > MENULEN) { strcpy(mi->item,ITEMLONG); } else { strcpy(mi->item,item); } if (strlen(mi->item) > m->menuwidth) m->menuwidth = strlen(mi->item); } else strcpy(mi->item,EMPTYSTR); if (status) { if (strlen(status) > STATLEN) { strcpy(mi->status,STATUSLONG); } else { strcpy(mi->status,status); } } else strcpy(mi->status,EMPTYSTR); mi->action=action; str = mi->item; mi->shortcut = 0; mi->helpid = 0xFFFF; inhlite = 0; // We have not yet seen an ENABLEHLITE char // Find the first char in [A-Za-z0-9] after ENABLEHLITE and not arg to control char while (*str) { if (*str == ENABLEHLITE) { inhlite=1; } if (*str == DISABLEHLITE) { inhlite = 0; } if ( (inhlite == 1) && (((*str >= 'A') && (*str <= 'Z')) || ((*str >= 'a') && (*str <= 'z')) || ((*str >= '0') && (*str <= '9')))) { mi->shortcut=*str; break; } ++str; } if ((mi->shortcut >= 'A') && (mi->shortcut <= 'Z')) // Make lower case mi->shortcut = mi->shortcut -'A'+'a'; if (data) { if (strlen(data) > ACTIONLEN) { strcpy(mi->data,ACTIONLONG); } else { strcpy(mi->data,data); } } else strcpy(mi->data,EMPTYSTR); switch (action) { case OPT_SUBMENU: mi->itemdata.submenunum = itemdata; break; case OPT_CHECKBOX: mi->itemdata.checked = itemdata; break; case OPT_RADIOMENU: mi->itemdata.radiomenunum = itemdata; if (mi->data) free(mi->data); mi->data = NULL; // No selection made break; default: // to keep the compiler happy break; } mi->index = m->numitems++; mi->parindex = ms->nummenus-1; return mi; } // Set the shortcut key for the current item void set_item_options(uchar shortcut,int helpid) { pt_menuitem mi; pt_menu m; m = (ms->menus[ms->nummenus-1]); if (m->numitems <= 0) return; mi = m->items[(unsigned int) m->numitems-1]; if (shortcut != 0xFF) mi->shortcut = shortcut; if (helpid != 0xFFFF) mi->helpid = helpid; } // Free internal datasutructures void close_menusystem(void) { } // append_line_helper(pt_menu menu,char *line) void append_line_helper(int menunum, char *line) { pt_menu menu; pt_menuitem mi,ri; char *app; int ctr; char dp; dp = getdisppage(); menu = ms->menus[menunum]; for (ctr = 0; ctr < (int) menu->numitems; ctr++) { mi = menu->items[ctr]; app = NULL; //What to append switch (mi->action) { case OPT_CHECKBOX: if (mi->itemdata.checked) app = mi->data; break; case OPT_RADIOMENU: if (mi->data) { // Some selection has been made ri = (pt_menuitem) (mi->data); app = ri->data; } break; case OPT_SUBMENU: append_line_helper(mi->itemdata.submenunum,line); break; default: break; } if (app) { strcat(line," "); strcat(line,app); } } } // Generate string based on state of checkboxes and radioitem in given menu // Assume line points to large enough buffer void gen_append_line(const char *menu_name,char *line) { int menunum; menunum = find_menu_num(menu_name); if (menunum < 0) return; // No such menu append_line_helper(menunum,line); } syslinux-legacy-3.63+dfsg/menu/libmenu/com32io.c0000664000175000017500000000675610777447273020250 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include #include #include "com32io.h" #include "syslnx.h" com32sys_t inreg,outreg; // Global register sets for use /* Print character and attribute at cursor */ void cprint(char chr,char attr,unsigned int times,char disppage) { REG_AH(inreg) = 0x09; REG_AL(inreg) = chr; REG_BH(inreg) = disppage; REG_BL(inreg) = attr; REG_CX(inreg) = times; __intcall(0x10,&inreg,&outreg); } void setdisppage(char num) // Set the display page to specified number { REG_AH(inreg) = 0x05; REG_AL(inreg) = num; __intcall(0x10,&inreg,&outreg); } char getdisppage() // Get current display page { REG_AH(inreg) = 0x0f; __intcall(0x10,&inreg,&outreg); return REG_BH(outreg); } void getpos(char * row, char * col, char page) { REG_AH(inreg) = 0x03; REG_BH(inreg) = page; __intcall(0x10,&inreg,&outreg); *row = REG_DH(outreg); *col = REG_DL(outreg); } void gotoxy(char row,char col, char page) { REG_AH(inreg) = 0x02; REG_BH(inreg) = page; REG_DX(inreg) = (row << 8)+col; __intcall(0x10,&inreg,&outreg); } unsigned char sleep(unsigned int msec) { unsigned long micro = 1000*msec; REG_AH(inreg) = 0x86; REG_CX(inreg) = (micro >> 16); REG_DX(inreg) = (micro & 0xFFFF); __intcall(0x15,&inreg,&outreg); return REG_AH(outreg); } void beep() { REG_AH(inreg) = 0x0E; REG_AL(inreg) = 0x07; REG_BH(inreg) = 0; __intcall(0x10,&inreg,&outreg); } void scrollupwindow(char top, char left, char bot, char right, char attr,char numlines) { REG_AH(inreg) = 0x06; REG_AL(inreg) = numlines; REG_BH(inreg) = attr; // Attribute to write blanks lines REG_DX(inreg) = (bot << 8) + right; // BOT RIGHT corner of window REG_CX(inreg) = (top << 8) + left; // TOP LEFT of window __intcall(0x10,&inreg,&outreg); } char inputc(char * scancode) { syslinux_idle(); /* So syslinux can perform periodic activity */ REG_AH(inreg) = 0x10; __intcall(0x16,&inreg,&outreg); if (scancode) *scancode = REG_AH(outreg); return REG_AL(outreg); } void getcursorshape(char *start, char *end) { char page = getdisppage(); REG_AH(inreg) = 0x03; REG_BH(inreg) = page; __intcall(0x10,&inreg,&outreg); *start = REG_CH(outreg); *end = REG_CL(outreg); } void setcursorshape(char start, char end) { REG_AH(inreg) = 0x01; REG_CH(inreg) = start; REG_CL(inreg) = end; __intcall(0x10,&inreg,&outreg); } char getchar(void) { REG_AH(inreg) = 0x08; __intcall(0x21,&inreg,&outreg); return REG_AL(outreg); } void setvideomode(char mode) { REG_AH(inreg) = 0x00; REG_AL(inreg) = mode; __intcall(0x10,&inreg,&outreg); } unsigned char checkkbdbuf() { REG_AH(inreg) = 0x11; __intcall(0x16,&inreg,&outreg); return !(outreg.eflags.l & EFLAGS_ZF); } // Get char displayed at current position unsigned char getcharat(char page) { REG_AH(inreg) = 0x08; REG_BH(inreg) = page; __intcall(0x16,&inreg,&outreg); return REG_AL(outreg); } syslinux-legacy-3.63+dfsg/menu/libmenu/com32io.h0000664000175000017500000000565510777447273020252 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef __COM32IO_H__ #define __COM32IO_H__ #include #ifndef NULL #define NULL ((void *)0) #endif /* BIOS Assisted output routines */ void cswprint(const char *str, char attr, char left); // Print a C str (NUL-terminated) respecting the left edge of window // i.e. \n in str will move cursor to column left // Print a C str (NUL-terminated) static inline void csprint(const char *str, char attr) { cswprint(str,attr,0); } void cprint(char chr,char attr,unsigned int times, char disppage); // Print a char void setdisppage(char num); // Set the display page to specified number char getdisppage(); // Get current display page void gotoxy(char row,char col, char page); void getpos(char * row, char * col, char page); char inputc(char * scancode); // Return ASCII char by val, and scancode by reference static inline void putch(char x, char attr, char page) { cprint(x,attr,1,page); } void setcursorshape(char start,char end); // Set cursor shape void getcursorshape(char *start,char *end); // Get shape for current page // Get char displayed at current position in specified page unsigned char getcharat(char page); static inline void cursoroff(void) /* Turns off cursor */ { setcursorshape(32,33); } static inline void cursoron(void) /* Turns on cursor */ { setcursorshape(6,7); } static inline unsigned char readbiosb(unsigned int ofs) { return *((unsigned char *)MK_PTR(0,ofs)); } static inline char getnumrows() { return readbiosb(0x484); // Actually numrows - 1 } static inline char getnumcols(void) { return readbiosb(0x44a); // Actually numcols } static inline char getshiftflags(void) { return readbiosb(0x417); } void scrollupwindow(char top, char left, char bot,char right,char attr,char numlines); //Scroll up given window static inline void scrollup(void) //Scroll up display screen by one line { scrollupwindow(0,0,getnumrows(),getnumcols(),0x07,1); } void setvideomode(char mode); // Set the video mode. static inline char getvideomode(void) // Get the current video mode { return readbiosb(0x449); } unsigned char sleep(unsigned int msec); // Sleep for specified time void beep(); // A Bell unsigned char checkkbdbuf(); // Check to see if there is kbd buffer is non-empty? static inline void clearkbdbuf() // Clear the kbd buffer (how many chars removed?) { while (checkkbdbuf()) inputc(NULL); } #endif syslinux-legacy-3.63+dfsg/menu/libmenu/tui.c0000664000175000017500000002422010777447273017560 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2006 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include "tui.h" #include #include #include com32sys_t inreg,outreg; // Global register sets for use char bkspstr[] = " \b$"; char eolstr[] = "\n$"; #define GETSTRATTR 0x07 // Reads a line of input from stdin. Replace CR with NUL byte // password <> 0 implies not echoed on screen // showoldvalue <> 0 implies currentvalue displayed first // If showoldvalue <> 0 then caller responsibility to ensure that // str is NULL terminated. void getuserinput(char *stra, unsigned int size, unsigned int password, unsigned int showoldvalue) { unsigned char c,scan; char *p,*q; // p = current char of string, q = tmp char *last; // The current last char of string char *str; // pointer to string which is going to be allocated char page; char row,col; char start,end; // Cursor shape char fudge; // How many chars should be removed from output char insmode; // Are we in insert or overwrite page = getdisppage(); getpos(&row,&col,page); // Get current position getcursorshape(&start,&end); insmode = 1; str = (char *)malloc(size+1); // Allocate memory to store user input memset(str,0,size+1); // Zero it out if (password != 0) showoldvalue = 0; // Password's never displayed if (showoldvalue != 0) strcpy(str,stra); // If show old value copy current value last = str; while (*last) {last++;} // Find the terminating null byte p = str+ strlen(str); if (insmode == 0) setcursorshape(1,7); // Block cursor else setcursorshape(6,7); // Normal cursor // Invariants: p is the current char // col is the corresponding column on the screen if (password == 0) // Not a password, print initial value { gotoxy(row,col,page); csprint(str,GETSTRATTR); } while (1) { // Do forever c = inputc(&scan); if (c == '\r') break; // User hit Enter getout of loop if (scan == ESCAPE) // User hit escape getout and nullify string { *str = 0; break; } fudge = 0; // if scan code is regognized do something // else if char code is recognized do something // else ignore switch(scan) { case HOMEKEY: p = str; break; case ENDKEY: p = last; break; case LTARROW: if (p > str) p--; break; case CTRLLT: if (p==str) break; if (*p == ' ') while ((p > str) && (*p == ' ')) p--; else { if (*(p-1) == ' ') { p--; while ((p > str) && (*p == ' ')) p--; } } while ((p > str) && ((*p == ' ') || (*(p-1) != ' '))) p--; break; case RTARROW: if (p < last) p++; break; case CTRLRT: if (*p==0) break; // At end of string if (*p != ' ') while ((*p!=0) && (*p != ' ')) p++; while ((*p!=0) && ((*p == ' ') && (*(p+1) != ' '))) p++; if (*p==' ') p++; break; case DELETE: q = p; while (*(q+1)) {*q = *(q+1); q++; } if (last > str) last--; fudge = 1; break; case INSERT: insmode = 1-insmode; // Switch mode if (insmode == 0) setcursorshape(1,7); // Block cursor else setcursorshape(6,7); // Normal cursor break; default: // Unrecognized scan code, look at the ascii value switch (c) { case '\b': // Move over by one q=p; while ( q <= last ) { *(q-1)=*q; q++;} if (last > str) last--; if (p > str) p--; fudge = 1; break; case '\x15': /* Ctrl-U: kill input */ fudge = last-str; while ( p > str ) *p--=0; p = str; *p=0; last = str; break; default: // Handle insert and overwrite mode if ((c >= ' ') && (c < 128) && ((unsigned int)(p-str) < size-1) ) { if (insmode == 0) { // Overwrite mode if (p==last) last++; *last = 0; *p++ = c; } else { // Insert mode if (p==last) { // last char last++; *last=0; *p++=c; } else { // Non-last char q=last++; while (q >= p) { *q=*(q-1); q--;} *p++=c; } } } else beep(); } break; } // Now the string has been modified, print it if (password == 0) { gotoxy(row,col,page); csprint(str,GETSTRATTR); if (fudge > 0) cprint(' ',GETSTRATTR,fudge,page); gotoxy(row,col+(p-str),page); } } *p = '\0'; if (password == 0) csprint("\r\n",GETSTRATTR); setcursorshape(start,end); // Block cursor // If user hit ESCAPE so return without any changes if (scan != ESCAPE) strcpy(stra,str); free(str); } /* Print a C string (NUL-terminated) */ void cswprint(const char *str,char attr,char left) { char page = getdisppage(); char newattr=0,cha,chb; char row,col; char nr,nc; nr = getnumrows(); nc = getnumcols(); getpos(&row,&col,page); while ( *str ) { switch (*str) { case '\b': --col; break; case '\n': ++row; col = left; break; case '\r': //col=left; break; case BELL: // Bell Char beep(); break; case CHRELATTR: // change attribute (relatively) case CHABSATTR: // change attribute (absolute) cha = *(str+1); chb = *(str+2); if ((((cha >= '0') && (cha <= '9')) || ((cha >= 'A') && (cha <= 'F'))) && (((chb >= '0') && (chb <= '9')) || ((chb >= 'A') && (chb <= 'F')))) // Next two chars are legal { if ((cha >= 'A') && (cha <= 'F')) cha = cha - 'A'+10; else cha = cha - '0'; if ((chb >= 'A') && (chb <= 'F')) chb = chb - 'A'+10; else chb = chb - '0'; newattr = (cha << 4) + chb; attr = (*str == CHABSATTR ? newattr : attr ^ newattr); str += 2; // Will be incremented again later } break; default: putch(*str, attr, page); ++col; } if (col >= nc) { ++row; col=left; } if (row > nr) { scrollup(); row= nr; } gotoxy(row,col,page); str++; } } void clearwindow(char top, char left, char bot, char right, char page, char fillchar, char fillattr) { char x; for (x=top; x < bot+1; x++) { gotoxy(x,left,page); cprint(fillchar,fillattr,right-left+1,page); } } void cls(void) { unsigned char dp = getdisppage(); gotoxy(0,0,dp); cprint(' ',GETSTRATTR,(1+getnumrows())*getnumcols(),dp); } //////////////////////////////Box Stuff // This order of numbers must match // the values of BOX_TOPLEFT,... in the header file unsigned char SINSIN_CHARS[] = {218,192,191,217, //Corners 196,179, // Horiz and Vertical 195,180,194,193,197}; // Connectors & Middle unsigned char DBLDBL_CHARS[] = {201,200,187,188, // Corners 205,186, // Horiz and Vertical 199,182,203,202,206}; // Connectors & Middle unsigned char SINDBL_CHARS[] = {214,211,183,189, // Corners 196,186, // Horiz & Vert 199,182,210,208,215}; // Connectors & Middle unsigned char DBLSIN_CHARS[] = {213,212,184,190, // Corners 205,179, // Horiz & Vert 198,181,209,207,216}; // Connectors & Middle unsigned char * getboxchars(boxtype bt) { switch (bt) { case BOX_SINSIN: return SINSIN_CHARS; break; case BOX_DBLDBL: return DBLDBL_CHARS; break; case BOX_SINDBL: return SINDBL_CHARS; break; case BOX_DBLSIN: return DBLSIN_CHARS; break; default: return SINSIN_CHARS; break; } return SINSIN_CHARS; } // Draw box and lines void drawbox(char top,char left,char bot, char right, char page, char attr,boxtype bt) { unsigned char *box_chars; // pointer to array of box chars unsigned char x; box_chars = getboxchars(bt); // Top border gotoxy(top,left,page); cprint(box_chars[BOX_TOPLEFT],attr,1,page); gotoxy(top,left+1,page); cprint(box_chars[BOX_TOP],attr,right-left,page); gotoxy(top,right,page); cprint(box_chars[BOX_TOPRIGHT],attr,1,page); // Bottom border gotoxy(bot,left,page); cprint(box_chars[BOX_BOTLEFT],attr,1,page); gotoxy(bot,left+1,page); cprint(box_chars[BOX_BOT],attr,right-left,page); gotoxy(bot,right,page); cprint(box_chars[BOX_BOTRIGHT],attr,1,page); // Left & right borders for (x=top+1; x < bot; x++) { gotoxy(x,left,page); cprint(box_chars[BOX_LEFT],attr,1,page); gotoxy(x,right,page); cprint(box_chars[BOX_RIGHT],attr,1,page); } } void drawhorizline(char top, char left, char right, char page, char attr, boxtype bt, char dumb) { unsigned char start,end; unsigned char *box_chars = getboxchars(bt); if (dumb==0) { start = left+1; end = right-1; } else { start = left; end = right; } gotoxy(top,start,page); cprint(box_chars[BOX_HORIZ],attr,end-start+1,page); if (dumb == 0) { gotoxy(top,left,page); cprint(box_chars[BOX_LTRT],attr,1,page); gotoxy(top,right,page); cprint(box_chars[BOX_RTLT],attr,1,page); } } syslinux-legacy-3.63+dfsg/menu/libmenu/help.h0000664000175000017500000000303210777447273017712 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef __HELP_H_ #define __HELP_H_ #include "menu.h" #include "com32io.h" #include "tui.h" #include // How many rows for the title #define HELP_TITLE_HEIGHT 1 #define HELP_BODY_ROW (HELP_TITLE_HEIGHT+3) #define HELP_LEFT_MARGIN 2 #define HELP_RIGHT_MARGIN 2 // Assume all lines dont cross this #define HELP_BOTTOM_MARGIN 2 // Number of lines not use from bottom of screen #define HELPBOX BOX_SINSIN #define HELPDIRLEN 64 #define HELPPAGE 2 #define HELP_MORE_ABOVE 24 // to print when more is available above #define HELP_MORE_BELOW 25 // same as above but for below // Display one screen of help information void showhelp(const char *filename); // Start the help system using id helpid void runhelpsystem(unsigned int helpid); // Start help system with specified file void runhelp(const char *filename); // Directory where help files are located void init_help(const char *helpdir); // Free internal datastructures void close_help(void); #endif syslinux-legacy-3.63+dfsg/menu/TODO0000664000175000017500000000017210777447273015650 0ustar evanevan* Write COMBOOT code to read .menu files and parse them directly - take the name of menu file to parse from commandline syslinux-legacy-3.63+dfsg/menu/menugen.py0000664000175000017500000002467610777447273017207 0ustar evanevan#!/usr/bin/env python import sys, re, getopt class Menusystem: types = {"run" : "OPT_RUN", "inactive" : "OPT_INACTIVE", "checkbox" : "OPT_CHECKBOX", "radiomenu": "OPT_RADIOMENU", "sep" : "OPT_SEP", "invisible": "OPT_INVISIBLE", "radioitem": "OPT_RADIOITEM", "exitmenu" : "OPT_EXITMENU", "login" : "login", # special type "submenu" : "OPT_SUBMENU"} entry_init = { "item" : "", "info" : "", "data" : "", "ipappend" : 0, # flag to send in case of PXELINUX "helpid" : 65535, # 0xFFFF "shortcut":"-1", "state" : 0, # initial state of checkboxes "argsmenu": "", # name of menu containing arguments "perms" : "", # permission required to execute this entry "_updated" : None, # has this dictionary been updated "type" : "run" } menu_init = { "title" : "", "row" : "0xFF", # let system decide position "col" : "0xFF", "_updated" : None, "name" : "" } system_init ={ "videomode" : "0xFF", "title" : "Menu System", "top" : "1", "left" : "1" , "bot" : "21", "right":"79", "helpdir" : "/isolinux/help", "pwdfile" : "", "pwdrow" : "23", "editrow" : "23", "skipcondn" : "0", "skipcmd" : ".exit", "startfile": "", "onerrorcmd":".repeat", "exitcmd" : ".exit", "exitcmdroot" : "", "timeout" : "600", "timeoutcmd":".beep", "totaltimeout" : "0", "totaltimeoutcmd" : ".wait" } shift_flags = { "alt" : "ALT_PRESSED", "ctrl" : "CTRL_PRESSED", "shift": "SHIFT_PRESSED", "caps" : "CAPSLOCK_ON", "num" : "NUMLOCK_ON", "ins" : "INSERT_ON" } reqd_templates = ["item","login","menu","system"] def __init__(self,template): self.state = "system" self.code_template_filename = template self.menus = [] self.init_entry() self.init_menu() self.init_system() self.vtypes = " OR ".join(self.types.keys()) self.vattrs = " OR ".join(filter(lambda x: x[0] != "_", self.entry.keys())) self.mattrs = " OR ".join(filter(lambda x: x[0] != "_", self.menu.keys())) def init_entry(self): self.entry = self.entry_init.copy() def init_menu(self): self.menu = self.menu_init.copy() def init_system(self): self.system = self.system_init.copy() def add_menu(self,name): self.add_item() self.init_menu() self.menu["name"] = name self.menu["_updated"] = 1 self.menus.append( (self.menu,[]) ) def add_item(self): if self.menu["_updated"]: # menu details have changed self.menus[-1][0].update(self.menu) self.init_menu() if self.entry["_updated"]: if not self.entry["info"]: self.entry["info"] = self.entry["data"] if not self.menus: print "Error before line %d" % self.lineno print "REASON: menu must be declared before a menu item is declared" sys.exit(1) self.menus[-1][1].append(self.entry) self.init_entry() def set_item(self,name,value): if not self.entry.has_key(name): msg = ["Unknown attribute %s in line %d" % (name,self.lineno)] msg.append("REASON: Attribute must be one of %s" % self.vattrs) return "\n".join(msg) if name=="type" and not self.types.has_key(value): msg = [ "Unrecognized type %s in line %d" % (value,self.lineno)] msg.append("REASON: Valid types are %s" % self.vtypes) return "\n".join(msg) if name=="shortcut": if (value <> "-1") and not re.match("^[A-Za-z0-9]$",value): msg = [ "Invalid shortcut char '%s' in line %d" % (value,self.lineno) ] msg.append("REASON: Valid values are [A-Za-z0-9]") return "\n".join(msg) elif value <> "-1": value = "'%s'" % value elif name in ["state","helpid","ipappend"]: try: value = int(value) except: return "Value of %s in line %d must be an integer" % (name,self.lineno) self.entry[name] = value self.entry["_updated"] = 1 return "" def set_menu(self,name,value): if not self.menu.has_key(name): return "Error: Unknown keyword %s" % name self.menu[name] = value self.menu["_updated"] = 1 return "" def set_system(self,name,value): if not self.system.has_key(name): return "Error: Unknown keyword %s" % name if name == "skipcondn": try: # is skipcondn a number? a = int(value) except: # it is a "-" delimited sequence value = value.lower() parts = [ self.shift_flags.get(x.strip(),None) for x in value.split("-") ] self.system["skipcondn"] = " | ".join(filter(None, parts)) else: self.system[name] = value def set(self,name,value): # remove quotes if given if (value[0] == value[-1]) and (value[0] in ['"',"'"]): # remove quotes value = value[1:-1] if self.state == "system": err = self.set_system(name,value) if not err: return if self.state == "menu": err = self.set_menu(name,value) # change state to entry it menu returns error if err: err = None self.state = "item" if self.state == "item": err = self.set_item(name,value) if not err: return # all errors so return item's error message print err sys.exit(1) def print_entry(self,entry,fd): entry["type"] = self.types[entry["type"]] if entry["type"] == "login": #special type fd.write(self.templates["login"] % entry) else: fd.write(self.templates["item"] % entry) def print_menu(self,menu,fd): if menu["name"] == "main": self.foundmain = 1 fd.write(self.templates["menu"] % menu) if (menu["row"] != "0xFF") or (menu["col"] != "0xFF"): fd.write(' set_menu_pos(%(row)s,%(col)s);\n' % menu) def output(self,filename): curr_template = None contents = [] self.templates = {} regbeg = re.compile(r"^--(?P[a-z]+) BEGINS?--\n$") regend = re.compile(r"^--[a-z]+ ENDS?--\n$") ifd = open(self.code_template_filename,"r") for line in ifd.readlines(): b = regbeg.match(line) e = regend.match(line) if e: # end of template if curr_template: self.templates[curr_template] = "".join(contents) curr_template = None continue if b: curr_template = b.group("name") contents = [] continue if not curr_template: continue # lines between templates are ignored contents.append(line) ifd.close() missing = None for x in self.reqd_templates: if not self.templates.has_key(x): missing = x if missing: print "Template %s required but not defined in %s" % (missing,self.code_template_filename) if filename == "-": fd = sys.stdout else: fd = open(filename,"w") self.foundmain = None fd.write(self.templates["header"]) fd.write(self.templates["system"] % self.system) for (menu,items) in self.menus: self.print_menu(menu,fd) for entry in items: self.print_entry(entry,fd) fd.write(self.templates["footer"]) fd.close() if not self.foundmain: print "main menu not found" print self.menus sys.exit(1) def input(self,filename): if filename == "-": fd = sys.stdin else: fd = open(filename,"r") self.lineno = 0 self.state = "system" for line in fd.readlines(): self.lineno = self.lineno + 1 if line and line[-1] in ["\r","\n"]: line = line[:-1] if line and line[-1] in ["\r","\n"]: line = line[:-1] line = line.strip() if line and line[0] in ["#",";"]: continue try: # blank line -> starting a new entry if not line: if self.state == "item": self.add_item() continue # starting a new section? if line[0] == "[" and line[-1] == "]": self.state = "menu" self.add_menu(line[1:-1]) continue # add property of current entry pos = line.find("=") # find the first = in string if pos < 0: print "Syntax error in line %d" % self.lineno print "REASON: non-section lines must be of the form ATTRIBUTE=VALUE" sys.exit(1) attr = line[:pos].strip().lower() value = line[pos+1:].strip() self.set(attr,value) except: print "Error while parsing line %d: %s" % (self.lineno,line) raise fd.close() self.add_item() def usage(): print sys.argv[0]," [options]" print "--input= is the name of the .menu file declaring the menu structure" print "--output= is the name of generated C source" print "--template= is the name of template to be used" print print "input and output default to - (stdin and stdout respectively)" print "template defaults to adv_menu.tpl" sys.exit(1) def main(): tfile = "adv_menu.tpl" ifile = "-" ofile = "-" opts,args = getopt.getopt(sys.argv[1:], "hi:o:t:",["input=","output=","template=","help"]) if args: print "Unknown options %s" % args usage() for o,a in opts: if o in ["-i","--input"]: ifile = a elif o in ["-o", "--output"]: ofile = a elif o in ["-t","--template"]: tfile = a elif o in ["-h","--help"]: usage() inst = Menusystem(tfile) inst.input(ifile) inst.output(ofile) if __name__ == "__main__": main() syslinux-legacy-3.63+dfsg/menu/Makefile0000664000175000017500000000461510777447273016626 0ustar evanevan## ----------------------------------------------------------------------- ## ## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, Inc., 53 Temple Place Ste 330, ## Boston MA 02111-1307, USA; either version 2 of the License, or ## (at your option) any later version; incorporated herein by reference. ## ## ----------------------------------------------------------------------- ## ## samples for syslinux users ## TMPFILE = $(shell mktemp /tmp/gcc_ok.XXXXXX) gcc_ok = $(shell tmpf=$(TMPFILE); if $(CC) $(1) -c -x c /dev/null -o $$tmpf 2>/dev/null; \ then echo $(1); else echo $(2); fi; rm -f $$tmpf) M32 := $(call gcc_ok,-m32,) $(call gcc_ok,-fno-stack-protector,) CC = gcc LD = ld -m elf_i386 AR = ar NASM = nasm NASMOPT = -O9999 RANLIB = ranlib COM32DIR = ../com32 LUDIR = $(COM32DIR)/libutil LDIR = $(COM32DIR)/lib CFLAGS = $(M32) -mregparm=3 -DREGPARM=3 -W -Wall -march=i386 -Os -fomit-frame-pointer -I$(LUDIR)/include -I$(COM32DIR)/include -Ilibmenu -D__COM32__ SFLAGS = -D__COM32__ -march=i386 LDFLAGS = -T $(LDIR)/com32.ld OBJCOPY = objcopy LIBGCC := $(shell $(CC) --print-libgcc) LIBS = libmenu/libmenu.a $(LUDIR)/libutil_com.a $(LDIR)/libcom32.a $(LIBGCC) LIBMENU = libmenu/syslnx.o libmenu/com32io.o libmenu/tui.o \ libmenu/menu.o libmenu/passwords.o libmenu/des.o libmenu/help.o CMENUS = $(patsubst %.c,%.c32,$(wildcard *.c)) IMENUS = $(patsubst %.menu,%.c32,$(wildcard *.menu)) MENUS = $(CMENUS) $(IMENUS) .SUFFIXES: .S .c .o .elf .c32 .menu .PRECIOUS: %.c %.c: %.menu adv_menu.tpl python menugen.py --input=$< --output=$@ --template=adv_menu.tpl .PRECIOUS: %.o %.o: %.S $(CC) $(SFLAGS) -c -o $@ $< .PRECIOUS: %.o %.o: %.c %.h $(CC) $(CFLAGS) -c -o $@ $< .PRECIOUS: %.elf %.elf: %.o $(LIBS) $(LD) $(LDFLAGS) -o $@ $^ %.c32: %.elf $(OBJCOPY) -O binary $< $@ all: menus libmenu/libmenu.a: $(LIBMENU) -rm -f $@ $(AR) cq $@ $^ $(RANLIB) $@ tidy: rm -f *.o *.lo *.a *.lst *.elf libclean: rm -f libmenu/*.o libmenu/*.a clean: tidy menuclean rm -f *.lss *.c32 *.com menuclean: rm -f $(patsubst %.menu,%.c,$(wildcard *.menu)) spotless: clean libclean menuclean rm -f *~ \#* menus: $(MENUS) install: # Don't install samples syslinux-legacy-3.63+dfsg/menu/adv_menu.tpl0000664000175000017500000003300310777447273017476 0ustar evanevanAll the lines in this file not in between --something BEGINS-- and --something ENDS-- is ignored completely and will not make it into the generated C file This file has sections of C code each section delimited by --secname BEGINS-- and --secname ENDS--. In the generated C code certain section may be used multiple times. Currently the different section which must be defined are header, system, item, login and footer Any additional sections you define will be processed but will probably not make it to the C code if you do not modify menugen.py to use it. header and footer go through unmolested. The remaining are % substituted using python rules. Basically it means %(var)s gets replaced by the value of the variable "var" which is a processed form of what is read from the .menu file NOTE: There is absolutely no C code in the python script, so you are free to modify this template to suit your needs --header BEGINS-- /* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2006 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef NULL #define NULL ((void *) 0) #endif #include "menu.h" #include "help.h" #include "passwords.h" #include "com32io.h" #include #include #define MAX_CMD_LINE_LENGTH 514 typedef struct s_xtra { long ipappend; // Stores the ipappend flag to send (useful for PXELINUX only) char *argsmenu; // Stores the name of menu which contains options for the given RUN item char *perms; // stores the permissions required to activate the item } t_xtra; typedef t_xtra *pt_xtra; // Pointer to extra datastructure // Types of dot commands for which caller takes responsibility of handling // In some case some commands may not make sense, it is up to the caller // to handle cases which do not make sense typedef enum {QUIT_CMD, REPEAT_CMD, ENTER_CMD, ESCAPE_CMD} t_dotcmd; /*----------------- Global Variables */ // default user #define GUEST_USER "guest" // for local commands. return value of execdotcmd #define QUIT_CMD 0 #define RPT_CMD 1 char username[12]; // Name of user currently using the system int PWD_ROW; // Line number where user authentication happens int EDIT_ROW; // row where User Tab char loginstr[] = "ogin "; char logoutstr[30]; int vmode; // The video mode we want to be in char timeoutcmd[MAX_CMD_LINE_LENGTH]; // Command to execute on timeout char totaltimeoutcmd[MAX_CMD_LINE_LENGTH]; // Command to execute on totaltimeout char QUITSTR[] = ".quit"; // same as exit char IGNORESTR[]=".ignore"; // same as repeat, wait /*---------------- End globals */ // returns pointer to first non-space char // and advances end of str by removing trailing spaces char * strip(char *str) { char *p,*s,*e; if (!str) return NULL; p = str; s = NULL; e = NULL; while (*p) { if (*p != ' ') { // mark start of string or record the last visited non-space char if (!s) s=p; else e=p; } p++; } *(++e)='\0'; // kill string earlier return s; } // executes a list of % separated commands // non-dot commands are assumed to be syslinux commands // All syslinux commands are appended with the contents of kerargs // If it fails (kernel not found) then the next one is tried in the // list // returns QUIT_CMD or RPT_CMD t_dotcmd execdotcmd(const char *cmd, char *defcmd, const char *kerargs) { char cmdline[MAX_CMD_LINE_LENGTH]; char dotcmd[MAX_CMD_LINE_LENGTH]; char *curr,*next,*p,*args; char ctr; strcpy(dotcmd,cmd); next = dotcmd; cmdline[0] = '\0'; while (*next) { // if something to do curr = next; p = strchr(next,'%'); if (p) { *p--='\0'; next=p+2; while (*p == ' ') p--; *(++p)='\0'; // remove trailing spaces } else { if (*defcmd) { // execute defcmd next next=defcmd; defcmd=NULL; // exec def cmd only once } else next=NULL; } // now we just need to execute the command "curr" curr = strip(curr); if (curr[0] != '.') { // just run the kernel strcpy(cmdline,curr); if (kerargs) strcat(cmdline,kerargs); runsyslinuximage(cmdline,0); // No IPAppend } else { // We have a DOT command // split command into command and args (may be empty) args = curr; while ( (*args != ' ') && (*args != '\0') ) args++; if (*args) { // found a space *args++ = '\0'; while (*args == ' ') args++; // skip over spaces } if ( (strcmp(curr,".exit")==0) || (strcmp(curr,".quit")==0) ) return QUIT_CMD; if ( (strcmp(curr,".repeat")==0) || (strcmp(curr,".ignore")==0) || (strcmp(curr,".wait")==0) ) return RPT_CMD; if (strcmp(curr,".beep")==0) { if ((args) && ('0' <= args[0]) && (args[0] <= '9')) ctr = args[0]-'0'; else ctr=1; for (;ctr>0; ctr--) beep(); } if (strcmp(curr,".help")==0) runhelp(args); } } return RPT_CMD; // by default we do not quit } TIMEOUTCODE timeout(const char *cmd) { t_dotcmd c; c = execdotcmd(cmd,".wait",NULL); switch(c) { case ENTER_CMD: return CODE_ENTER; case ESCAPE_CMD: return CODE_ESCAPE; default: return CODE_WAIT; } } TIMEOUTCODE ontimeout() { return timeout(timeoutcmd); } TIMEOUTCODE ontotaltimeout() { return timeout(totaltimeoutcmd); } void keys_handler(t_menusystem *ms, t_menuitem *mi,unsigned int scancode) { char nc; if ( ((scancode >> 8) == F1) && (mi->helpid != 0xFFFF) ) { // If scancode of F1 and non-trivial helpid runhelpsystem(mi->helpid); } // If user hit TAB, and item is an "executable" item // and user has privileges to edit it, edit it in place. if (((scancode & 0xFF) == 0x09) && (mi->action == OPT_RUN) && (EDIT_ROW < getnumrows()) && (EDIT_ROW > 0) && (isallowed(username,"editcmd") || isallowed(username,"root"))) { nc = getnumcols(); // User typed TAB and has permissions to edit command line gotoxy(EDIT_ROW,1,ms->menupage); csprint("Command line:",0x07); editstring(mi->data,ACTIONLEN); gotoxy(EDIT_ROW,1,ms->menupage); cprint(' ',0x07,nc-1,ms->menupage); } } t_handler_return login_handler(t_menusystem *ms, t_menuitem *mi) { (void)mi; // Unused char pwd[40]; char login[40]; char nc; t_handler_return rv; rv = ACTION_INVALID; if (PWD_ROW < 0) return rv; // No need to authenticate if (mi->item == loginstr) { /* User wants to login */ nc = getnumcols(); gotoxy(PWD_ROW,1,ms->menupage); csprint("Enter Username: ",0x07); getstring(login, sizeof username); gotoxy(PWD_ROW,1,ms->menupage); cprint(' ',0x07,nc,ms->menupage); csprint("Enter Password: ",0x07); getpwd(pwd, sizeof pwd); gotoxy(PWD_ROW,1,ms->menupage); cprint(' ',0x07,nc,ms->menupage); if (authenticate_user(login,pwd)) { strcpy(username,login); strcpy(logoutstr,"ogout "); strcat(logoutstr,username); mi->item = logoutstr; // Change item to read "Logout" rv.refresh = 1; // refresh the screen (as item contents changed) } else strcpy(username,GUEST_USER); } else // User needs to logout { strcpy(username,GUEST_USER); strcpy(logoutstr,""); mi->item = loginstr; } return rv; } t_handler_return check_perms(t_menusystem *ms, t_menuitem *mi) { char *perms; pt_xtra x; (void) ms; // To keep compiler happy x = (pt_xtra) mi->extra_data; perms = ( x ? x->perms : NULL); if (!perms) return ACTION_VALID; if (isallowed(username,"root") || isallowed(username,perms)) // If allowed return ACTION_VALID; else return ACTION_INVALID; } // Compute the full command line to add and if non-trivial // prepend the string prepend to final command line // Assume cmdline points to buffer long enough to hold answer void gencommand(pt_menuitem mi, char *cmdline) { pt_xtra x; cmdline[0] = '\0'; strcat(cmdline,mi->data); x = (pt_xtra) mi->extra_data; if ( (x) && (x->argsmenu)) gen_append_line(x->argsmenu,cmdline); } // run the given command together with additional options which may need passing void runcommand(pt_menuitem mi) { char *line; pt_xtra x; long ipappend; line = (char *)malloc(sizeof(char)*MAX_CMD_LINE_LENGTH); gencommand(mi,line); x = (pt_xtra) mi->extra_data; ipappend = (x ? x->ipappend : 0); runsyslinuximage(line,x->ipappend); free(line); } // set the extra info for the specified menu item. void set_xtra(pt_menuitem mi, const char *argsmenu, const char *perms, unsigned int helpid, long ipappend) { pt_xtra xtra; int bad_argsmenu, bad_perms, bad_ipappend; mi->extra_data = NULL; // initalize mi->helpid = helpid; // set help id if (mi->action != OPT_RUN) return; bad_argsmenu = bad_perms = bad_ipappend = 0; if ( (argsmenu==NULL) || (strlen(argsmenu)==0)) bad_argsmenu = 1; if ( (perms==NULL) || (strlen(perms)==0)) bad_perms = 1; if ( ipappend==0) bad_ipappend = 1; if (bad_argsmenu && bad_perms && bad_ipappend) return; xtra = (pt_xtra) malloc(sizeof(t_xtra)); mi->extra_data = (void *) xtra; xtra->argsmenu = xtra->perms = NULL; xtra->ipappend = ipappend; if (!bad_argsmenu) { xtra->argsmenu = (char *) malloc(sizeof(char)*(strlen(argsmenu)+1)); strcpy(xtra->argsmenu,argsmenu); } if (!bad_perms) { xtra->perms = (char *) malloc(sizeof(char)*(strlen(perms)+1)); strcpy(xtra->perms,perms); mi->handler = &check_perms; } } int main(void) { pt_menuitem curr; char quit; char exitcmd[MAX_CMD_LINE_LENGTH]; char exitcmdroot[MAX_CMD_LINE_LENGTH]; char onerrcmd[MAX_CMD_LINE_LENGTH]; char startfile[MAX_CMD_LINE_LENGTH]; char *ecmd; // effective exit command or onerrorcmd char skipbits; char skipcmd[MAX_CMD_LINE_LENGTH]; int timeout; // time in multiples of 0.1 seconds int totaltimeout; // time in multiples of 0.1 seconds t_dotcmd dotrv; // to store the return value of execdotcmd int temp; strcpy(username,GUEST_USER); --header ENDS-- --system BEGINS-- /* ---- Initializing menu system parameters --- */ vmode = %(videomode)s; skipbits = %(skipcondn)s; PWD_ROW = %(pwdrow)s; EDIT_ROW = %(editrow)s; strcpy(onerrcmd,"%(onerrorcmd)s"); strcpy(exitcmd,"%(exitcmd)s"); strcpy(exitcmdroot,"%(exitcmdroot)s"); // If not specified exitcmdroot = exitcmd if (exitcmdroot[0] == '\0') strcpy(exitcmdroot,exitcmd); // Timeout stuff timeout = %(timeout)s; strcpy(timeoutcmd,"%(timeoutcmd)s"); totaltimeout = %(totaltimeout)s; strcpy(totaltimeoutcmd,"%(totaltimeoutcmd)s"); strcpy(startfile,"%(startfile)s"); init_help("%(helpdir)s"); init_passwords("%(pwdfile)s"); init_menusystem("%(title)s"); set_window_size(%(top)s,%(left)s,%(bot)s,%(right)s); // Register the ontimeout handler, with a time out of 10 seconds reg_ontimeout(ontimeout,timeout*10,0); reg_ontotaltimeout(ontotaltimeout,totaltimeout*10); // Register menusystem handlers reg_handler(HDLR_KEYS,&keys_handler); /* ---- End of initialization --- */ --system ENDS-- --item BEGINS-- curr = add_item("%(item)s","%(info)s",%(type)s,"%(data)s",%(state)d); set_xtra(curr,"%(argsmenu)s","%(perms)s",%(helpid)d,%(ipappend)d); // Set associated extra info set_shortcut(%(shortcut)s); --item ENDS-- --login BEGINS-- curr = add_item(loginstr,"Login/Logout of authentication system",OPT_RUN,NULL,0); curr->helpid = %(helpid)d; curr->handler = &login_handler; --login ENDS-- --menu BEGINS-- /* ------- MENU %(name)s ----- */ add_named_menu("%(name)s","%(title)s",-1); --menu ENDS-- --footer BEGINS-- /* ------- END OF MENU declarations ----- */ // Check if we should skip the menu altogether quit = 0; // Dont skip the menu if (getshiftflags() & skipbits) { // we must skip the menu altogther and execute skipcmd dotrv = execdotcmd(skipcmd,".beep%.exit",NULL); // Worst case we beep and exit if (dotrv == QUIT_CMD) quit = 1; } // Switch vide mode if required if (vmode != 0xFF) setvideomode(vmode); // Do we have a startfile to display? if (startfile[0] != '\0') runhelp(startfile); // The main loop while (quit == 0) { // As long as quit is zero repeat curr = showmenus(find_menu_num("main")); // Initial menu is the one called "main" if (curr) { if (curr->action == OPT_RUN) { ecmd = (char *)malloc(sizeof(char)*MAX_CMD_LINE_LENGTH); gencommand(curr,ecmd); temp = (curr->extra_data ? ((pt_xtra)curr->extra_data)->ipappend : 0); runsyslinuximage(ecmd,temp); // kernel not found so execute the appropriate dot command dotrv = execdotcmd(onerrcmd,".quit",ecmd); // pass bad cmdline as arg if (dotrv== QUIT_CMD) quit = 1; free(ecmd); ecmd = NULL; } else csprint("Error in programming!",0x07); } else { // find effective exit command ecmd = ( isallowed(username,"root") ? exitcmdroot : exitcmd); dotrv = execdotcmd(ecmd,".repeat",NULL); quit = (dotrv == QUIT_CMD ? 1 : 0); // should we exit now } } // Deallocate space used and quit close_passwords(); close_help(); close_menusystem(); return 0; } --footer ENDS-- syslinux-legacy-3.63+dfsg/menu/CHANGES0000664000175000017500000000263110777447273016155 0ustar evanevanChanges in v1.2 --------------- * Allowed menu's to have names. Submenu's can be referred to by names instead of their index in the menu system. This allows user to refer to submenus which are not yet part of the menusystem. * help pages can be longer than one screen * menugen.py: Python script for converting .menu files to C source code .menu files can be used to descibe most static uses of menu system, including SubMenus, Checkboxes, RadioButtons, User Authentication and Context sensitive help. You can also restrict use of certain items to users with certain credentials. See MENU_FORMAT for the format of .menu files * display.c32: Takes the name of the text file to display and displays it allowing user to scroll through the text. USAGE: display.c32 must be an absolute filename (including the /isolinux part) Changes in v1.1 --------------- * Additional handler type: Keys handler * Menuitem handlers now have a return value of type t_handler_return. For all simple cases, you just return ACTION_VALID or ACTION_INVALID (For some types of menu items, handlers are ignored, and for others the return value is ignored) * add_menu takes an extra argument (to better control memory footprint) You can just set it to -1 to choose the default value * Now the menu system support long menu's using scroll bars. * Support for passwords and context sensitive help is added. syslinux-legacy-3.63+dfsg/menu/complex.c0000664000175000017500000003256010777447273017001 0ustar evanevan/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef NULL #define NULL ((void *) 0) #endif #include "menu.h" #include "com32io.h" #include "help.h" #include "passwords.h" #include "des.h" #include #include /* Global variables */ char infoline[160]; char buffer[80]; // Different network options static char nonet[] = "etwork [none]"; static char dhcpnet[]="etwork [dhcp]"; static char statnet[]="etwork [static]"; static char loginstr[] = "ogin "; static char logoutstr[]= "ogout "; struct { unsigned int baseurl : 1; // Do we need to specify by url unsigned int mountcd : 1; // Should we mount the cd unsigned int winrep : 1; // Want to repair windows? unsigned int linrep : 1; // Want to repair linux? } flags; // Some menu options t_menuitem *baseurl,*mountcd,*network,*runprep,*winrep,*linrep; t_menuitem * stat,*dhcp,*none,*prepopt,*secret; // all the menus we are going to declare unsigned char TESTING,RESCUE,MAIN,PREPMENU,NETMENU,LONGMENU,SECRETMENU; char username[12]; // Name of user currently using the system /* End globals */ TIMEOUTCODE ontimeout() { beep(); return CODE_WAIT; } #define INFLINE 22 #define PWDLINE 3 #define PWDPROMPT 21 #define PWDCOLUMN 60 #define PWDATTR 0x74 #define EDITPROMPT 21 void keys_handler(t_menusystem *ms, t_menuitem *mi,unsigned int scancode) { char nc; if ((scancode >> 8) == F1) { // If scancode of F1 runhelpsystem(mi->helpid); } // If user hit TAB, and item is an "executable" item // and user has privileges to edit it, edit it in place. if (((scancode & 0xFF) == 0x09) && (mi->action == OPT_RUN) && (isallowed(username,"editcmd") || isallowed(username,"root"))) { nc = getnumcols(); // User typed TAB and has permissions to edit command line gotoxy(EDITPROMPT,1,ms->menupage); csprint("Command line:",0x07); editstring(mi->data,ACTIONLEN); gotoxy(EDITPROMPT,1,ms->menupage); cprint(' ',0x07,nc-1,ms->menupage); } } t_handler_return login_handler(t_menusystem *ms, t_menuitem *mi) { (void)mi; // Unused char pwd[40]; char login[40]; char nc; t_handler_return rv; if (mi->item == loginstr) { /* User wants to login */ nc = getnumcols(); gotoxy(PWDPROMPT,1,ms->menupage); csprint("Enter Username: ",0x07); getstring(login, sizeof username); gotoxy(PWDPROMPT,1,ms->menupage); cprint(' ',0x07,nc,ms->menupage); csprint("Enter Password: ",0x07); getpwd(pwd, sizeof pwd); gotoxy(PWDPROMPT,1,ms->menupage); cprint(' ',0x07,nc,ms->menupage); if (authenticate_user(login,pwd)) { strcpy(username,login); mi->item = logoutstr; // Change item to read "Logout" } else strcpy(username,GUEST_USER); } else // User needs to logout { strcpy(username,GUEST_USER); mi->item = loginstr; } if (strcmp(username,GUEST_USER)==0) { prepopt->action = OPT_INACTIVE; secret->action = OPT_INVISIBLE; } else { prepopt->action = OPT_SUBMENU; prepopt->itemdata.radiomenunum = PREPMENU; secret->action = OPT_SUBMENU; secret->itemdata.submenunum = SECRETMENU; } rv.valid = 0; rv.refresh = 1; return rv; } void msys_handler(t_menusystem *ms, t_menuitem *mi) { char nc; void *v; nc = getnumcols(); // Get number of columns gotoxy(PWDLINE,PWDCOLUMN,ms->menupage); csprint("User: ",PWDATTR); cprint(ms->fillchar,ms->fillattr,sizeof username,ms->menupage); gotoxy(PWDLINE,PWDCOLUMN +6,ms->menupage); csprint(username,PWDATTR); if (mi->parindex != PREPMENU) // If we are not in the PREP MENU { gotoxy(INFLINE,0,ms->menupage); cprint(' ',0x07,nc,ms->menupage); gotoxy(INFLINE+1,0,ms->menupage); cprint(' ',0x07,nc,ms->menupage); return; } strcpy (infoline," "); if (flags.baseurl) strcat(infoline,"baseurl=http://192.168.11.12/gui "); if (flags.mountcd) strcat(infoline,"mountcd=yes "); v = (void *)network->data; if (v!=NULL) // Some network option specified { strcat(infoline,"network="); strcat(infoline,(char *)(((t_menuitem *)v)->data)); } if (flags.winrep) strcat(infoline,"repair=win "); if (flags.linrep) strcat(infoline,"repair=lin "); gotoxy(INFLINE,0,ms->menupage); cprint(' ',0x07,nc,ms->menupage); gotoxy(INFLINE+1,0,ms->menupage); cprint(' ',0x07,nc,ms->menupage); gotoxy(INFLINE,0,ms->menupage); csprint("Kernel Arguments:",0x07); gotoxy(INFLINE,17,ms->menupage); csprint(infoline,0x07); } t_handler_return network_handler(t_menusystem *ms, t_menuitem *mi) { // mi=network since this is handler only for that. (void)ms; // Unused if (mi->data == (void *)none) mi->item = nonet; if (mi->data == (void *)stat) mi->item = statnet; if (mi->data == (void *)dhcp) mi->item = dhcpnet; return ACTION_INVALID; // VALID or INVALID does not matter } t_handler_return checkbox_handler(t_menusystem *ms, t_menuitem *mi) { (void)ms; /* Unused */ if (mi->action != OPT_CHECKBOX) return ACTION_INVALID; if (strcmp(mi->data,"baseurl") == 0) flags.baseurl = (mi->itemdata.checked ? 1 : 0); if (strcmp(mi->data,"winrepair") == 0) { if (mi->itemdata.checked) { flags.winrep = 1; linrep->action = OPT_INACTIVE; } else { flags.winrep = 0; linrep->action = OPT_CHECKBOX; } } if (strcmp(mi->data,"linrepair") == 0) { if (mi->itemdata.checked) { flags.linrep = 1; winrep->action = OPT_INACTIVE; } else { flags.winrep = 0; winrep->action = OPT_CHECKBOX; } } if (strcmp(mi->data,"mountcd") == 0) flags.mountcd = (mi->itemdata.checked ? 1 : 0); return ACTION_VALID; } /* Clears keyboard buffer and then wait for stepsize*numsteps milliseconds for user to press any key checks for keypress every stepsize milliseconds. Returns: 1 if user pressed a key (not read from the buffer), 0 if time elapsed */ int checkkeypress(int stepsize, int numsteps) { int i; clearkbdbuf(); for (i=0; i < numsteps; i++) { if (checkkbdbuf()) return 1; sleep(stepsize); } return 0; } int main() { t_menuitem * curr; char cmd[160]; char ip[30]; // Set default username as guest strcpy(username,GUEST_USER); // Switch video mode here // setvideomode(0x18); // or whatever mode you want // Choose the default title and setup default values for all attributes.... init_passwords("/isolinux/password"); init_help("/isolinux/help"); init_menusystem(NULL); set_window_size(1,1,20,78); // Leave some space around // Choose the default values for all attributes and char's // -1 means choose defaults (Actually the next 4 lines are not needed) //set_normal_attr (-1,-1,-1,-1); //set_status_info (-1,-1); // Display status on the last line //set_title_info (-1,-1); //set_misc_info(-1,-1,-1,-1); // Register the menusystem handler reg_handler(HDLR_SCREEN,&msys_handler); reg_handler(HDLR_KEYS,&keys_handler); // Register the ontimeout handler, with a time out of 10 seconds reg_ontimeout(ontimeout,1000,0); NETMENU = add_menu(" Init Network ",-1); none = add_item("one","Dont start network",OPT_RADIOITEM,"no ",0); dhcp = add_item("hcp","Use DHCP",OPT_RADIOITEM,"dhcp ",0); stat = add_item("tatic","Use static IP I will specify later",OPT_RADIOITEM,"static ",0); TESTING = add_menu(" Testing ",-1); set_menu_pos(5,55); add_item("emory Test","Perform extensive memory testing",OPT_RUN, "memtest",0); add_item("nvisible","You dont see this",OPT_INVISIBLE,"junk",0); add_item("xit this menu","Go one level up",OPT_EXITMENU,"exit",0); RESCUE = add_menu(" Rescue Options ",-1); add_item("inux Rescue","linresc",OPT_RUN,"linresc",0); add_item("os Rescue","dosresc",OPT_RUN,"dosresc",0); add_item("indows Rescue","winresc",OPT_RUN,"winresc",0); add_item("xit this menu","Go one level up",OPT_EXITMENU,"exit",0); PREPMENU = add_menu(" Prep options ",-1); baseurl = add_item("aseurl by IP?","Specify gui baseurl by IP address",OPT_CHECKBOX,"baseurl",0); mountcd = add_item("ountcd?","Mount the cdrom drive?",OPT_CHECKBOX,"mountcd",0); network = add_item(dhcpnet,"How to initialise network device?",OPT_RADIOMENU,NULL,NETMENU); add_sep(); winrep = add_item("Reinstall indows","Re-install the windows side of a dual boot setup",OPT_CHECKBOX,"winrepair",0); linrep = add_item("Reinstall inux","Re-install the linux side of a dual boot setup",OPT_CHECKBOX,"linrepair",0); add_sep(); runprep = add_item("un prep now","Execute prep with the above options",OPT_RUN,"prep",0); add_item("xit this menu","Go up one level",OPT_EXITMENU,"exitmenu",0); baseurl->handler = &checkbox_handler; mountcd->handler = &checkbox_handler; winrep->handler = &checkbox_handler; linrep->handler = &checkbox_handler; network->handler = &network_handler; flags.baseurl = 0; flags.mountcd = 0; flags.winrep = 0; flags.linrep = 0; SECRETMENU = add_menu(" Secret Menu ",-1); add_item("secret 1","Secret",OPT_RUN,"A",0); add_item("secret 2","Secret",OPT_RUN,"A",0); LONGMENU = add_menu(" Long Menu ",40); // Override default here add_item("a","Aa",OPT_RUN,"A",0); add_item("b","Ab",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("","A",OPT_RUN,"A",0); add_item("