	include zlib.i
	include exec/exec.i
	include exec/exec_lib.i
	include dos/dos.i
	include dos/dos_lib.i
	include intuition/intuition.i
	include intuition/intuition_lib.i
	include intuition/pointerclass.i
	include graphics/gfx.i
	include graphics/graphics_lib.i

INBUF	equ 16384
OUTBUF	equ 65536

	section TEXT,code
vPNG
	lea _LinkerDB,a4
	move.l 4.w,_SysBase
	moveq #36,d0
	lea DosName,a1
	move.l _SysBase,a6
	jsr _LVOOpenLibrary(a6)
	move.l d0,_DOSBase
	beq no_dos

	moveq #39,d0
	lea GfxName,a1
	jsr _LVOOpenLibrary(a6)
	move.l d0,_GfxBase
	beq no_gfx

	moveq #39,d0
	lea IntuitionName,a1
	jsr _LVOOpenLibrary(a6)
	move.l d0,_IntuitionBase
	beq no_int

;do ReadArgs
	lea vPNG_template,a0
	move.l a0,d1
	lea vPNG_array,a2
	move.l a2,d2
	clr.l d3
	move.l _DOSBase,a6
	jsr _LVOReadArgs(a6)
	move.l d0,_RDArgs
	beq rdargs_failed
;open png file
	move.l vPNG_name,d1
	beq no_file
	move.l #MODE_OLDFILE,d2
	jsr _LVOOpen(a6)
	move.l d0,PNG_fh
	beq no_file
;check signature
	move.l d0,d1
	lea temp,a2
	move.l a2,d2
	moveq #8,d3
	jsr _LVORead(a6)
	cmp.l d0,d3
	bne not_PNG
	cmp.l #$89504e47,(a2)
	bne not_PNG
	cmp.l #$0d0a1a0a,4(a2)
	bne not_PNG
;file is PNG

	move.l PNG_fh,d0
	moveq #0,d1
	bsr @OpenFFR
	move.l d0,PNG_fh_async
	beq cant_open_async

	move.l #MEMF_ANY|MEMF_CLEAR,d0
	move.l #32768,d1
	move.l d1,d2
	move.l _SysBase,a6
	jsr _LVOCreatePool(a6)
	move.l d0,vPNG_pool
	beq no_pool

	move.l vPNG_pool,a0
	move.l #INBUF,d0
	move.l _SysBase,a6
	jsr _LVOAllocPooled(a6)
	move.l d0,in
	beq no_memory

process_hunks
	move.l PNG_fh_async,a0
	lea temp,a2
	moveq #8,d0
	move.l a2,a1
	bsr @FFRRead
	moveq #8,d1
	cmp.l d0,d1
	bne PNG_error1

	move.l (a2),d6		;hunk's length
	move.l 4(a2),d5
	cmp.l #'IHDR',d5
	beq handle_IHDR
	cmp.l #'PLTE',d5
	beq handle_PLTE
	cmp.l #'IDAT',d5
	beq handle_IDAT
	cmp.l #'IEND',d5
	beq handle_IEND

; else hunk isn't supported

	move.l PNG_fh_async,a0
	move.l in,a1
	move.l d6,d0
	addq.l #4,d0
	bsr @FFRRead
	subq.l #4,d0
	cmp.l d0,d6
	bne PNG_error1
	bra process_hunks

handle_IHDR
	moveq #13,d0
	cmp.l d0,d6
	bne PNG_error1

	move.l PNG_fh_async,a0
	lea PNG_info,a1
	moveq #17,d0
	bsr @FFRRead
	moveq #17,d1
	cmp.l d0,d1
	bne PNG_error1

BPNG_HAVE_IHDR equ 0
PNG_HAVE_IHDR equ (1<<BPNG_HAVE_IHDR)
	ori.b #PNG_HAVE_IHDR,flags

	move.l width,d2
	ble PNG_error1
	move.l height,d3
	ble PNG_error1

	tst.b compression_type
	bne PNG_error1
	tst.b filter_type
	bne PNG_error1
	tst.b interlace_type
	bne PNG_error1

	moveq #0,d1
	move.b bit_depth,d1
	cmp.b #1,d1
	beq bit_depth_ok
	cmp.b #2,d1
	beq bit_depth_ok
	cmp.b #4,d1
	beq bit_depth_ok
	cmp.b #8,d1
	beq bit_depth_ok
	cmp.b #16,d1
	bne PNG_error1
	moveq #8,d1
bit_depth_ok
	move.l d1,scr_depth

	move.b color_type,d0

	tst.b d0
	beq init_gray_image
	cmp.b #2,d0
	beq init_color_image
	cmp.b #3,d0
	beq init_color_image_pal
	cmp.b #4,d0
	beq init_alpha_gray_image
	cmp.b #6,d0
	bne PNG_error1

init_alpha_color_image
	bra PNG_error1

init_color_image_pal
	cmp.b #8,bit_depth
	bgt PNG_error1
	bra process_hunks

init_alpha_gray_image
	bra PNG_error1
init_color_image
	cmp.b #8,bit_depth
	blt PNG_error1
	
init_gray_image
	cmp.b #16,bit_depth
	beq PNG_error1
	moveq #1,d0
	move.l d1,d4
	lsl.l d1,d0
	move.l d0,d3
	mulu.w #12,d0
	addq.l #4+4,d0
	move.l vPNG_pool,a0
	move.l _SysBase,a6
	jsr _LVOAllocPooled(a6)
	move.l d0,palette
	beq PNG_error1
	move.l d0,a0
	move.w d3,(a0)+
	clr.w (a0)+
	subq.w #1,d3
	move.l (gray_add,d4.l*4),d1
	moveq #0,d0
exp_gray_pal
	move.l d0,(a0)+
	move.l d0,(a0)+
	move.l d0,(a0)+
	add.l d1,d0
	dbf d3,exp_gray_pal
	clr.l (a0)
	bra process_hunks

handle_PLTE
	btst #BPNG_HAVE_IHDR,flags
	beq PNG_error1
BPNG_HAVE_PLTE equ 1
PNG_HAVE_PLTE equ (1<<BPNG_HAVE_PLTE)
	ori.b #PNG_HAVE_PLTE,flags

	move.l d6,d0
	beq PNG_error1
	divs.w #3,d0
	swap d0
	tst.w d0
	bne PNG_error1
	move.l d0,d5
	swap d0
	mulu.w #12,d0
	addq.l #4+4,d0
	move.l d0,d4
	move.l vPNG_pool,a0
	move.l _SysBase,a6
	jsr _LVOAllocPooled(a6)
	move.l d0,palette
	beq PNG_error1

	move.l PNG_fh_async,a0
	move.l d0,a1
	move.l d6,d0
	move.l a1,d2
	addq.l #4,d0
	bsr @FFRRead
	subq.l #4,d0
	cmp.l d0,d6
	bne PNG_error1

	move.l d2,a0
	add.l d4,a0
	move.l d2,a1
	clr.l -(a0)
	add.l d6,a1
	move.l #$01010101,d0
expand_palette
	moveq #0,d1
	move.b -(a1),d1
	mulu.l d0,d1
	move.l d1,-(a0)
	moveq #0,d1
	move.b -(a1),d1
	mulu.l d0,d1
	move.l d1,-(a0)
	moveq #0,d1
	move.b -(a1),d1
	mulu.l d0,d1
	move.l d1,-(a0)
	cmp.l a1,d2
	blt expand_palette

	move.l d5,-(a0)

	bra process_hunks

handle_IDAT
	btst #BPNG_HAVE_IHDR,flags
	beq PNG_error1
	cmp.b #3,color_type
	bne _l5
	btst #BPNG_HAVE_PLTE,flags
	beq PNG_error1
_l5

;init_display
	tst.l vPNG_rtg
	beq _l51
	or.l #DIPF_IS_FOREIGN,id_haveflags
_l51	move.l vPNG_modeid,d0
	beq no_modeid_specified
	move.l d0,a0
	move.l (a0),d2
	move.l d2,mode_id
	move.l #DTAG_DISP,d1
	move.l #dis_SIZEOF,d0
	sub.l a0,a0
	lea dis_info,a1
	move.l _GfxBase,a6
	jsr _LVOGetDisplayInfoData(a6)
	tst.l d0
	beq no_modeid_specified
	move.l dis_info+dis_PropertyFlags,d0
	and.l #DIPF_IS_FOREIGN,d0
	beq id_is_inv
	moveq #-1,d0
	move.l d0,vPNG_rtg
	bra id_is_inv

no_modeid_specified
	clr.l -(a7)
	move.l id_haveflags,-(a7)
	move.l #BIDTAG_DIPFMustHave,-(a7)
	move.l scr_depth,-(a7)
	move.l #BIDTAG_Depth,-(a7)
	move.l height,-(a7)
	move.l #BIDTAG_NominalHeight,-(a7)
	move.l width,-(a7)
	move.l #BIDTAG_NominalWidth,-(a7)
	move.l a7,a0
	move.l _GfxBase,a6
	jsr _LVOBestModeIDA(a6)
	add.l #9*4,a7
	cmp.l #INVALID_ID,d0
	beq id_is_inv
	move.l d0,mode_id

id_is_inv
	moveq #0,d1
	moveq #0,d0
	move.b color_type,d1
	move.b (components,d1.w),d0
	move.b bit_depth,d1
	mulu.w d1,d0
	move.l d0,pixel_depth
	move.l width,d2
	mulu.l d2,d0
	addq.l #7,d0
	lsr.l #3,d0
	addq.l #1,d0
	move.l d0,rrow_width

	move.l #OUTBUF,d1
	divu.l d0,d1
	tst.l d1
	bne _l41
	moveq #1,d1
	bra _l4
_l41	cmp.l height,d1
	ble _l4
	move.l height,d1
_l4	move.l d1,rows_num
	mulu.l d1,d0
	move.l d0,outbuf

	move.l height,d1
	move.l d2,scr_width
	move.l d1,scr_height
	move.l d2,d0
	add.l #31,d0
	and.b #$e0,d0
	move.l d0,aligned_width

	tst.l vPNG_rtg
	beq planar_display
	move.l #TAG_SKIP,tag_bitmap
	bra no_tout
	
planar_display
	move.l scr_depth,d2
	moveq #BMF_CLEAR|BMF_INTERLEAVED|BMF_DISPLAYABLE,d3
	sub.l a0,a0
	move.l _GfxBase,a6
	jsr _LVOAllocBitMap(a6)
	move.l d0,bitmap_base
	beq PNG_error1
	subq.l #1,d2
	beq _1bit_bitmap
	move.l d0,a0
	move.l #BMA_FLAGS,d1
	jsr _LVOGetBitMapAttr(a6)
	move.l #BMF_INTERLEAVED,d1
	and.l d0,d1
	beq PNG_error1
	move.l #BMF_STANDARD,d1
	and.l d0,d1
	beq PNG_error1
_1bit_bitmap
	move.l aligned_width,d4
	mulu.l scr_depth,d4
	lsr.l #3,d4
	move.l d4,trow_width

	moveq #8,d2
	cmp.l scr_depth,d2
	bne no_tout

	move.l d4,d0
	mulu.l rows_num,d0
	move.l vPNG_pool,a0
	move.l _SysBase,a6
	jsr _LVOAllocPooled(a6)
	move.l d0,tout
	beq PNG_error1

no_tout	move.l outbuf,d0
	add.l rrow_width,d0
	move.l vPNG_pool,a0
	move.l _SysBase,a6
	jsr _LVOAllocPooled(a6)
	move.l d0,out
	beq PNG_error1

	tst.l vPNG_preload
	beq no_preload
	moveq #1,d0
	clr.l activate_flag
	move.l d0,behind_flag
no_preload

	sub.l a0,a0
	lea vPNG_scr_tags,a1
	move.l _IntuitionBase,a6
	jsr _LVOOpenScreenTagList(a6)
	move.l d0,vPNG_scr_base
	beq PNG_error1

;alloc temp bitmap and rastport for WPL8, temp memory for line buffer
	tst.l vPNG_rtg
	beq no_rtg_init

	move.l d0,a0	
	move.l sc_RastPort+rp_BitMap(a0),a0
	move.l aligned_width,d0
	move.l #1,d1
	move.l scr_depth,d2
	move.l #BMF_CLEAR,d3
	move.l _GfxBase,a6
	jsr _LVOAllocBitMap(a6)
	move.l d0,bitmap_base
	beq PNG_error1
	move.l vPNG_pool,a0
	move.l aligned_width,d0
	move.l _SysBase,a6
	jsr _LVOAllocPooled(a6)
	move.l d0,tline
	beq PNG_error1
	move.l vPNG_pool,a0
	move.l #rp_SIZEOF,d0
	jsr _LVOAllocPooled(a6)
	move.l d0,trp
	beq PNG_error1
	move.l d0,a1
	move.l _GfxBase,a6
	jsr _LVOInitRastPort(a6)
	move.l trp,a0
	move.l bitmap_base,rp_BitMap(a0)

no_rtg_init
	sub.l a0,a0
	lea vPNG_win_tags,a1
	move.l _IntuitionBase,a6
	jsr _LVOOpenWindowTagList(a6)
	move.l d0,vPNG_win_base
	beq PNG_error1

	move.l d0,a0
	moveq #-1,d0
	clr.l -(a7)
	move.l d0,-(a7)
	move.l #WA_PointerDelay,-(a7)
	move.l d0,-(a7)
	move.l #WA_BusyPointer,-(a7)
	move.l a7,a1
	jsr _LVOSetWindowPointerA(a6)
	add.l #5*4,a7
;end init display

	lea z,a5
	move.l a5,a0
	bsr @inflateInit_
	tst.l d0
	bne PNG_error1

	move.l d6,d5
	move.l in,next_in(a5)
	clr.l avail_in(a5)

	move.l out,next_out(a5)
	move.l outbuf,avail_out(a5)

z_process
	tst.l avail_in(a5)
	bne _l2
	tst.l d5
	bne _l31

	move.l PNG_fh_async,a0
	lea temp,a1
	moveq #12,d0
	bsr @FFRRead
	moveq #12,d1
	cmp.l d0,d1
	bne quit_handle_IDAT

	move.l temp+4,d5
	cmp.l #'IDAT',temp+8
	bne quit_handle_IDAT
	
_l31	move.l d5,d3
	cmp.l #INBUF,d3
	blt _l3
	move.l #INBUF,d3
_l3
	sub.l d3,d5
	move.l PNG_fh_async,a0
	move.l in,a1
	move.l d3,d0
	bsr @FFRRead
	cmp.l d0,d3
	bne.s PNG_error1
	move.l in,next_in(a5)
	move.l d3,avail_in(a5)

_l2	tst.l avail_out(a5)
	bne z_infl

	bsr show_buffer

	move.l out,next_out(a5)
	move.l outbuf,avail_out(a5)
z_infl
	move.l #Z_PARTIAL_FLUSH,d0
	move.l a5,a0
	bsr @inflate
	tst.l d0
	beq z_process
z_end	
	bsr show_buffer

	moveq #16,d0
	moveq #16,d1
	moveq #2,d2
	moveq #BMF_CLEAR,d3
	sub.l a0,a0
	move.l _GfxBase,a6
	jsr _LVOAllocBitMap(a6)
	move.l d0,pointer_bm
	beq cant_alloc_pointer

	sub.l a0,a0
	lea pointerclass_str,a1
	lea pointerobj_tags,a2
	move.l _IntuitionBase,a6
	jsr _LVONewObjectA(a6)
	move.l d0,pointer_object
	lea pointer_tags,a1
	bne pointer_ok
cant_alloc_pointer
	lea empty_tags,a1
pointer_ok
	move.l vPNG_win_base,a2
	move.l a2,a0
	move.l _IntuitionBase,a6
	jsr _LVOSetWindowPointerA(a6)

	tst.l vPNG_preload
	beq no_scr2front
	move.l vPNG_scr_base,a0
	jsr _LVOScreenToFront(a6)
	move.l a2,a0
	jsr _LVOActivateWindow(a6)
no_scr2front


	move.l _SysBase,a6
wait_loop
	tst.l quit_wait_loop
	bne aa
	move.l wd_UserPort(a2),a0
	moveq #1,d0
	move.b MP_SIGBIT(a0),d1
	lsl.l d1,d0
	jsr _LVOWait(a6)
	move.l wd_UserPort(a2),a0
	jsr _LVOGetMsg(a6)
	tst.l d0
	beq wait_loop
handle_msg
	move.l d0,a1
	move.l im_Class(a1),d2
	move.w im_Code(a1),d3
	jsr _LVOReplyMsg(a6)
	cmp.l #IDCMP_MOUSEBUTTONS,d2
	beq handle_idcmp_mb
	cmp.l #IDCMP_VANILLAKEY,d2
	bne wait_loop
handle_idcmp_vk
	cmp.w #27,d3
	beq wl1
	bra wait_loop
handle_idcmp_mb
	cmp.w #IECODE_LBUTTON,d3
	beq wl1
	cmp.w #IECODE_RBUTTON,d3
	bne wl2	
wl1	seq quit_wait_loop
wl2	bra wait_loop

aa
	move.l a2,a0
	lea empty_tags,a1
	move.l _IntuitionBase,a6
	jsr _LVOSetWindowPointerA(a6)

	move.l pointer_object,d0
	beq no_pointer_object
	move.l d0,a0
	jsr _LVODisposeObject(a6)
	
no_pointer_object
	move.l pointer_bm,d0
	beq no_pointer_bm
	move.l d0,a0
	move.l _GfxBase,a6
	jsr _LVOFreeBitMap(a6)
no_pointer_bm

quit_handle_IDAT
	lea z,a0
	bsr @inflateEnd

handle_IEND

process_hunks_end

PNG_error1
	move.l vPNG_win_base,d0
	beq no_vPNG_window
	move.l d0,a0
	move.l _IntuitionBase,a6
	jsr _LVOCloseWindow(a6)
no_vPNG_window
	move.l vPNG_scr_base,d0
	beq no_vPNG_screen
	move.l d0,a0
	move.l _IntuitionBase,a6
	jsr _LVOCloseScreen(a6)
no_vPNG_screen
	move.l bitmap_base,d0
	beq no_bitmap
	move.l d0,a0
	move.l _GfxBase,a6
	jsr _LVOFreeBitMap(a6)
no_bitmap
no_memory
	move.l vPNG_pool,a0
	move.l _SysBase,a6
	jsr _LVODeletePool(a6)
no_pool
	move.l PNG_fh_async,a0
	bsr @CloseFFR
not_PNG
cant_open_async
	move.l PNG_fh,d1
	move.l _DOSBase,a6
	jsr _LVOClose(a6)
no_file
	move.l _RDArgs,d1
	jsr _LVOFreeArgs(a6)
rdargs_failed
	move.l _IntuitionBase,a1
	move.l _SysBase,a6
	jsr _LVOCloseLibrary(a6)
no_int
	move.l _GfxBase,a1
	jsr _LVOCloseLibrary(a6)
no_gfx
	move.l _DOSBase,a1
	jsr _LVOCloseLibrary(a6)
no_dos
	moveq #0,d0
	rts

;flush buffer to screen
show_buffer
	movem.l d2-d7/a2/a3/a5/a6,-(a7)
	move.l out,a1
	move.l prev_row,a0
	move.l pixel_depth,d0
	addq.l #7,d0
	lsr.l #3,d0
	move.l rows_num,d3
	cmp.l height,d3
	ble _fo1
	move.l height,d3
_fo1
	move.l rrow_width,d1
	subq.l #1,d1

filter_row_loop
	move.b (a1)+,d2
	move.l a0,a2			;current prev row
	move.l a1,a0			;next prev row
	beq filter_value_none
	subq.b #1,d2
	beq filter_value_sub
	subq.b #1,d2
	beq filter_value_up
	subq.b #1,d2
	beq filter_value_avg
	subq.b #1,d2
	beq filter_value_paeth
	bra filter_value_none

filter_value_sub
	move.l d1,d4
	moveq #7,d2
	sub.l d0,d4
	and.l d4,d2
	move.l a1,a2
	add.l d0,a1
	bra _fvs1
filter_value_up
	moveq #7,d2
	move.l d1,d4
	and.l d1,d2
_fvs1
	lsr.l #3,d4
	neg.l d2
	jmp (_fvus2,pc,d2.l*4)
_fvus1	
	rept 8
	 move.b (a2)+,d5
	 add.b d5,(a1)+
	endr
_fvus2
	dbf d4,_fvus1
	bra end_filter_row_loop

filter_value_paeth
	move.l a1,a3		;lp
	move.l a2,a5		;cp
	move.l d0,d4
	subq.l #1,d4
_fvp1	move.b (a2)+,d5
	add.b d5,(a1)+
	dbf d4,_fvp1
	move.l d1,d6
	moveq #0,d2
	sub.l d0,d6
	moveq #0,d4
	subq.l #1,d6
_fvp3
	moveq #0,d5
	move.b (a3)+,d2		;a
	move.b (a2)+,d4		;b
	move.b (a5)+,d5		;c

	sub.l d5,d4		;pa
	sub.l d5,d2		;pb
	move.l d4,d5		;pc
	bge.s _no_neg_pa
	neg.l d4
_no_neg_pa
	add.l d2,d5		;d5
	bge.s _no_neg_pc
	neg.l d5
_no_neg_pc
	tst.l d2
	bge.s _no_neg_pb
	neg.l d2
_no_neg_pb
	cmp.l d4,d2
	blt _pb_lower_pa
	cmp.l d4,d5
	blt _pc_min
_pa_min	move.b -1(a3),d2
	add.b d2,(a1)+		;pa - minimum
	dbf d6,_fvp3
	bra end_filter_row_loop
_pb_lower_pa
	cmp.l d2,d5
	blt _pc_min
_pb_min	move.b -1(a2),d4	;pb - minimum
	add.b d4,(a1)+
	dbf d6,_fvp3
	bra end_filter_row_loop
_pc_min	move.b -1(a5),d5	;pc - minimum
	add.b d5,(a1)+
_fvp2	dbf d6,_fvp3
	bra end_filter_row_loop

filter_value_avg
	move.l a1,a3		;lp
	move.l d0,d4
	subq.l #1,d4
_fva1	move.b (a2)+,d5
	lsr.b #1,d5
	add.b d5,(a1)+
	dbf d4,_fva1
	move.l d1,d4
	sub.l d0,d4
	subq.l #1,d4
_fva2	move.b (a2)+,d5
	add.b (a3)+,d5
	roxr.b #1,d5
	add.b d5,(a1)+
	dbf d4,_fva2
	bra end_filter_row_loop
filter_value_none
	add.l d1,a1
end_filter_row_loop
	subq.l #1,d3
	bgt filter_row_loop

;copy prev row
	move.l a1,prev_row
	move.l d1,d0
	move.l _SysBase,a6
	jsr _LVOCopyMem(a6)

	moveq #0,d0
	moveq #1,d1
	move.b color_type,d0
	move.b bit_depth,d1
	move.l (show_proc,d0.l*4),a0
	jmp (a0)

gray_image
	cmp.b #16,d1
	beq flush_end
	bra pal_image

gray_alpha_image
	bra flush_end

rgb_image
	tst.l vPNG_rtg
	bne flush_end
	move.l out,a1
	move.l rows_num,d7
	cmp.l height,d7
	ble _rgb1
	move.l height,d7
_rgb1	subq.l #1,d7

	move.l #$7f7f7f7f,d3
	move.l #$3f3f3f3f,d4
	move.l #$1f1f1f1f,d5
_rgb3
	addq.l #1,a1
	move.l a1,a0
	move.l width,d6
	lsr.l #2,d6
	subq.l #1,d6
	beq _rgb21
_rgb31
	move.w (a1)+,d0
	move.w (a1)+,d1
	move.b d0,d2
	swap d2
	move.b d1,d0
	move.w (a1)+,d2
	swap d0
	move.b d2,d1
	move.w (a1)+,d0
	swap d1
	move.b d0,d2
	move.w (a1)+,d1
	lsl.l #8,d2
	move.b d1,d0
	move.b (a1)+,d2
	move.b (a1)+,d1

	lsr.l #1,d2
	lsr.l #2,d0
	and.l d3,d2
	and.l d4,d0
	lsr.l #3,d1
	add.l d0,d2
	and.l d5,d1
	lsr.l #1,d0
	add.l d1,d2
	and.l d5,d0
	add.l d0,d2

	move.l d2,(a0)+
	dbf d6,_rgb31
_rgb21
	move.l width,d6
	and.w #$3,d6
	subq.w #1,d6
	blt _rgb22
_rgb2	move.b (a1)+,d0
	move.b (a1)+,d1
	lsr.b #2,d0
	lsr.b #1,d1
	move.b (a1)+,d2
	add.b d0,d1
	lsr.b #3,d2
	lsr.b #1,d0
	add.b d0,d1
	add.b d2,d1
	move.b d1,(a0)+
	dbf d6,_rgb2
_rgb22	dbf d7,_rgb3
	bra pal_image

rgb_alpha_image
	bra flush_end

pal_image
	tst.l vPNG_rtg
	beq do_planar
	move.l scr_depth,d0
	cmp.b #8,d0
	bne flush_end

	move.l tline,a2
	move.l out,a3
	move.l rows_num,d7
	cmp.l height,d7
	blt p2c_1
	move.l height,d7
p2c_1	sub.l d7,height
	subq.l #1,d7
y_loop
	move.l a3,a0
	move.l rrow_width,d0
	move.l a2,a1
	add.l d0,a3
	addq.l #1,a0
	subq.l #1,d0
	move.l _SysBase,a6
	jsr _LVOCopyMem(a6)
	move.l vPNG_scr_base,a0
	lea sc_RastPort(a0),a0
	move.l trp,a1
	move.l width,d2
	moveq #0,d0
	move.l line_y,d1
	move.l _GfxBase,a6
	jsr _LVOWritePixelLine8(a6)
	addq.l #1,line_y
	dbf d7,y_loop

	bra flush_end
do_planar
	move.l rrow_width,d1
	sub.l trow_width,d1
	move.l d1,c2p_mod
	move.l scr_depth,d0
	move.l (c2p_proc,d0.l*4),d0
	beq flush_end
do_c2p
	move.l d0,a2
	move.l vPNG_scr_base,a0
	move.l out,a1
	move.l rows_num,d0
	move.l trow_width,d1
	jsr (a2)
flush_end
	movem.l (a7)+,d2-d7/a2/a3/a5/a6
	rts

version_string dc.b '$VER: vPNG 0.03 (01.09.99)',0

	xref c2p_1
	xref c2p_2
	xref c2p_4
	xref c2p_8

	xref @inflate
	xref @inflateInit_
	xref @inflateEnd

	xref @OpenFFR
	xref @CloseFFR
	xref @FFRRead

	xref _LinkerDB

	xdef _SysBase
	xdef height
	xdef c2p_mod
	xdef tout


	section __MERGED,data

vPNG_template	 dc.b 'FROM/A,PRELOAD/S,GRAY/S,MODEID/N,RTG/S',0
		 even
pointerclass_str dc.b 'pointerclass',0
		 even
DosName 	 DOSNAME
		 even
IntuitionName	 INTNAME
		 even
GfxName		 GRAFNAME

		 cnop 0,4
vPNG_scr_tags
		 dc.l SA_Width
scr_width	 dc.l 0
		 dc.l SA_Height
scr_height	 dc.l 0
		 dc.l SA_Depth
scr_depth	 dc.l 0
		 dc.l SA_DisplayID
mode_id		 dc.l 0
tag_palette	 dc.l SA_Colors32
palette		 dc.l 0
tag_bitmap	 dc.l SA_BitMap
bitmap_base	 dc.l 0
		 dc.l SA_Quiet
		 dc.l 1
		 dc.l SA_AutoScroll
		 dc.l 1
		 dc.l SA_Overscan
		 dc.l OSCAN_TEXT
		 dc.l SA_BackFill
		 dc.l LAYERS_NOBACKFILL
		 dc.l SA_Behind
behind_flag	 dc.l 0
		 dc.l TAG_DONE
vPNG_win_tags
		 dc.l WA_CustomScreen
vPNG_scr_base	 dc.l 0
		 dc.l WA_Flags
		 dc.l WFLG_BACKDROP|WFLG_BORDERLESS|WFLG_SIMPLE_REFRESH|WFLG_RMBTRAP
		 dc.l WA_IDCMP
		 dc.l IDCMP_MOUSEBUTTONS|IDCMP_VANILLAKEY
		 dc.l WA_Activate
activate_flag	 dc.l 1
		 dc.l TAG_DONE

gray_add	 dc.l 0
		 dc.l $ffffffff
		 dc.l $55555555
		 dc.l 0
		 dc.l $11111111
		 dc.l 0
		 dc.l 0
		 dc.l 0
		 dc.l $01010101

show_proc	 dc.l gray_image
		 dc.l 0
		 dc.l rgb_image
		 dc.l pal_image
		 dc.l gray_alpha_image
		 dc.l 0
		 dc.l rgb_alpha_image

c2p_proc	 dc.l 0
		 dc.l c2p_1
		 dc.l c2p_2
		 dc.l 0
		 dc.l c2p_4
		 dc.l 0
		 dc.l 0
		 dc.l 0
		 dc.l c2p_8

pointerobj_tags	 dc.l POINTERA_BitMap
pointer_bm	 dc.l 0
		 dc.l TAG_DONE

pointer_tags	 dc.l WA_Pointer
pointer_object	 dc.l 0
		 dc.l TAG_DONE

empty_tags	 dc.l TAG_DONE


components	 dc.b 1
		 dc.b 0
		 dc.b 3
		 dc.b 1
		 dc.b 2
		 dc.b 4

	section __MERGED,bss

PNG_fh		 ds.l 1
PNG_fh_async	 ds.l 1

_SysBase	 ds.l 1
_DOSBase	 ds.l 1
_IntuitionBase	 ds.l 1
_GfxBase	 ds.l 1
z		 ds.b z_SIZEOF
temp		 ds.l 3
;quit		 ds.l 1
quit_wait_loop	 ds.l 1

vPNG_pool	 ds.l 1
tout		 ds.l 1
in		 ds.l 1
out		 ds.l 1
outbuf		 ds.l 1
tline		 ds.l 1
line_y		 ds.l 1
trp		 ds.l 1

;PNG image info
PNG_info
width		 ds.l 1
height		 ds.l 1
bit_depth	 ds.b 1
color_type	 ds.b 1
compression_type ds.b 1
filter_type	 ds.b 1
interlace_type	 ds.b 1
crc		 ds.b 4

		 cnop 0,4
aligned_width	 ds.l 1
rows_num	 ds.l 1
flags		 ds.l 1
id_haveflags	 ds.l 1
id_havenotflags	 ds.l 1

trow_width	 ds.l 1
rrow_width	 ds.l 1
c2p_mod		 ds.l 1
pixel_depth	 ds.l 1
prev_row	 ds.l 1

; ReadArgs...
vPNG_array	 ds.l 5

vPNG_name	 equ vPNG_array+0
vPNG_preload	 equ vPNG_array+4
vPNG_gray	 equ vPNG_array+8
vPNG_modeid	 equ vPNG_array+12
vPNG_rtg	 equ vPNG_array+16

_RDArgs		 ds.l 1

vPNG_win_base	 ds.l 1

dis_info	 ds.b dis_SIZEOF

