home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: Graphics
/
Graphics.zip
/
gif_info.zip
/
gif_info.cmd
next >
Wrap
OS/2 REXX Batch file
|
1998-02-03
|
14KB
|
457 lines
/**********************/
/* GIF_INFO is called as:
stuff=GIF_INFO(gif_file,infotype,imgnum,idmess)
Parameters:
GIF_FILE: A fully qualified file name. If no extension, a .GIF is added.
OR
The contents of a gif_file (say, as read with a
gif_file=charin(afile,1,chars(afile))
infotype: Type of output
imgnum: modifies the type of output (typically, selects nth image)
idmess: If specified, then GIF_FILE contains the contents of a gif_File
with a name of idmess. If not specified, GIF_FILE is a file name.
In the former case, idmess should have no embedded spaces.
For details, see GIF_INFO.TXT.
Technical info: For gif89a specs, please see
http://member.aol.com/royalef/gif89a.txt
Author: Daniel Hellerstein danielh@econ.ag.gov
*/
gif_info:
parse arg afile,atype,aval,idmess
atype=translate(atype)
call init1
idmess=translate(idmess,'_',' ')
atype=strip(atype)
dodisp=0
delay=-1
atype=left(atype,1)
if atype='' | atype='S' then dodisp=1
if idmess<>'' then do /* afile contains the actual gif file */
ain=afile
fqn=idmess
filesize=length(ain)
end /* do */
else do /* afile is the name of the gif file */
fqn=stream(afile,'c','query exists')
if fqn='' then do
if dodisp=1 then say bold 'No Such File:' normal fqn
return ''
end
filesize=chars(afile)
ain=charin(fqn,1,filesize)
oo=stream(afile,'c','close')
end
gifver=left(ain,6)
if abbrev(translate(gifver),'GIF8')=0 then do
if dodisp=1 then
say reverse " Error. ' normal afile bold ' is not a GIF file (" normal gifver ')'
return fqn' -1'
end /* do */
if dodisp=1 then
say " " cy_ye " Examining:" normal bold||fqn||normal ,
'(size=' filesize ' bytes), version: 'gifver
l1=substr(ain,7,2)
g_width=c2d(reverse(l1))
l2=substr(ain,9,2)
g_height=c2d(reverse(l2))
l3=substr(ain,11,1)
ctable0=x2b(c2x(l3))
global_color_flag=left(ctable0,1)
ct1=right(ctable0,3)
ct1=right(ct1,8,0)
ct1=x2d(b2x(ct1))
numcolors=2**(ct1+1)
if dodisp=1 then say ">>"bold" Header information." normal
if dodisp=1 then
say " Global color table: existence flag, #colors " global_color_flag ',' numcolors
if dodisp=1 then
say " Global width x height " g_width ' x ' g_height
iat=13 /* 11 bytes used for intro info */
gcolortable=''
if global_color_flag=1 then do
gcolortable=substr(ain,iat+1,3*numcolors)
iat=iat+(3*numcolors) /* iat is the Last byte used */
end
desc.1='2c'x ; desc.1.!val='image'
desc.2='21'x ; desc.2.!val='extension'
desc.3='3b'x ; desc.3.!val='trailer'
ext.1='f9'x ; ext.1.!val='graphic control'
ext.2='fe'x ; ext.2.!val='comment'
ext.3='01'x ; ext.3.!val='plain text'
ext.4='ff'x ; ext.4.!val='application'
nimgs=0
ngcs=0
ncmts=0
napps=0
nptxts=0
do forever /* scan the gif file */
if (atype='B' | atype='I' | atype='T') & nimgs=aval then leave /* got the nth image */
if atype='C' & ncmts=aval then leave
if atype='P' & nptxts=aval then leave
if atype='A' & napps=aval then leave
/* continue processing */
iat=iat+1
blockid=substr(ain,iat,1) /* get next block type */
select
when blockid='00'x then do
if dodisp=1 then say reverse " Warning: null block id, skipping " normal
ares=0
end /* do */
when blockid=desc.1 then do /* it's an image */
nimgs=nimgs+1
call do_image
ares=result
end /* do */
when blockid=desc.2 then do /* extension */
iat=iat+1 /* get extention type */
extype=substr(ain,iat,1)
select
when extype=ext.1 then do /*graphics control */
ngcs=ngcs+1
call graphics_control
ares=result
end
when extype=ext.3 then do /*plain text */
nptxts=nptxts+1
call plain_text
ares=result
end /* do */
when extype=ext.2 then do /*comment */
ncmts=ncmts+1
call is_comment
ares=result
end
when extype=ext.4 then do /* application */
napps=napps+1
call application_block
ares=result
end /* do */
otherwise do
if dodisp=1 then say reverse " Bad Extension label: " c2x(extype) normal
RETURN 'ERROR -1'
end
end /* extype select */
end /* extention descriptor */
when blockid=desc.3 then do
if dodisp=1 then say " GIF file terminator found. "
leave /* terminator */
end
otherwise do
if dodisp=1 then
say reverse "Error in GIF file -- bad descriptor id " normal '('c2x(blockid)'x)'
return 'ERROR -2'
end
end /* select */
if ares<0 then return 'ERROR 'ares
end /* forever */
/* ------------- package output for return */
select
when atype='' | atype='S' then return 1 /* a display option, noting special to return */
/* basic image-file info */
when atype='B' & (aval=''|aval=0) then do
nn=global_color_flag*numcolors
oo=fqn' 'nimgs' 'ncmts' 'napps' 'nptxts' 'g_width' 'g_height' 'nn
return oo
end /* do */
when atype='B' then do /* other "basic */
if nimgs<>aval then return fqn' -2'
if datatype(aval)<>'NUM' then return fqn' -2'
tci=-1
if ngcs=nimgs then tci=tc_index
lct=lcl_ct_flag*lcl_ct_size
oo=fqn' 'lcl_width' 'lcl_height' 'tci' 'delay' 'lcl_interlace' 'lct
return oo
end
when atype='I' then do /* other "basic */
if datatype(aval)<>'NUM' then return fqn' -2'
if nimgs<>aval | aval=0 then return fqn' -2'
tci=-1
if ngcs=nimgs then tci=tc_index
lct=lcl_ct_flag*lcl_ct_size
oo=fqn' 'lcl_width' 'lcl_height' 'tci' 'delay' 'lcl_interlace' 'lct' 'imgsize||','||amess
return oo
end
when atype='T' & (aval=0 | aval='') then do /* other "basic */
n3=numcolors*3
oo=fqn' 'n3||','||gcolortable
return oo
end
when atype='T' then do /* other "basic */
if datatype(aval)<>'NUM' then return fqn' -2'
if nimgs<>aval | aval=0 then return fqn' -2'
lct=lcl_ct_flag*lcl_ct_size
oo=fqn' 'lct||','||acolortable
return oo
end
when atype='C' then do /* other "basic */
if datatype(aval)<>'NUM' then return fqn' -2'
if ncmts<>aval | aval=0 then return fqn' -2'
oo=fqn||' '||csize||','||amess
return oo
end
when atype='A' then do /* other "basic */
if datatype(aval)<>'NUM' then return fqn' -2'
if napps<>aval | aval=0 then return fqn' -2'
oo=fqn' 'app_id','app_auth','appsize','amess
return oo
end
when atype='P' then do /* other "basic */
if datatype(aval)<>'NUM' then return fqn' -2'
if nptxts<>aval | aval=0 then return fqn' -2'
oo=fqn' 'pt_left' 'pt_top' 'pt_width' 'pt_height' 'pt_size||','||amess
return oo
end
otherwise return 'ERROR 0'
end
return ''
/************/
do_image:
if dodisp=1 then say (1+iat)">> " bold " IMAGE DESCRIPTOR # " nimgs normal
l1=substr(ain,iat+1,2)
lcl_left=c2d(reverse(l1))
l2=substr(ain,iat+3,2)
lcl_top=c2d(reverse(l2))
l1=substr(ain,iat+5,2)
lcl_width=c2d(reverse(l1))
l2=substr(ain,iat+7,2)
lcl_height=c2d(reverse(l2))
l3=substr(ain,iat+9,1)
ctable0=x2b(c2x(l3))
lcl_ct_flag=left(ctable0,1)
lcl_interlace=substr(ctable0,2,1)
t1=right(ctable0,3) ; t1=right(t1,8,0)
lcl_ct_size=x2d(b2x(t1)) ; lcl_ct_size=2**(lcl_ct_size+1)
if dodisp=1 then say " Image: top,left :" lcl_top ', 'lcl_left
if dodisp=1 then say " Image: width x height: " lcl_width 'x' lcl_height
if dodisp=1 then
say " Interlace flag, local color table flag, local color table size: " ,
lcl_interlace', 'lcl_ct_flag', 'lcl_ct_size
skip=lcl_ct_flag*lcl_ct_size*3
acolortable=''
if skip>0 then
acolortable=substr(ain,iat+10,skip)
iat=iat+9+skip /* iat is now just before the table based image */
/* chew up the data block */
iat=iat+1 /* skip the lzw bits variable */
imgsize=chew_data()
if imgsize<0 then return -6
if dodisp=1 then if dodisp=1 then say " Image size: " imgsize ' (bytes)'
return 1
/*********/
graphics_control:
if dodisp=1 then say (1+iat)">>" bold " GRAPHICS CONTROL Block # " ngcs normal
iat=iat+2
pk=substr(ain,iat,1) ; pk=x2b(c2x(pk))
tc_flag=right(pk,1)
iat=iat+1
tmp=reverse(substr(ain,iat,2))
delay=x2d(c2x(tmp))
iat=iat+2
tc_index=x2d(c2x(substr(ain,iat,1)))
iat=iat+1
term=x2d(c2x(substr(ain,iat,1)))
if dodisp=1 then
say " Transparent flag, transparent index : " tc_flag ', ' tc_index
if dodisp=1 then
say " Delay (0.01 seconds) : " delay
if term<>0 then return -8
return 1
/*********/
application_block:
if dodisp=1 then say (1+iat)">>" bold " APPLICATION Extension # " napps normal
iat=iat+1
app_blocksize=x2d(c2x(substr(ain,iat,1)))
if app_blocksize<>11 then do
if dodisp=1 then
say reverse "Error. Bad block application block size: "app_blocksize normal
return -3
end /* do */
iat=iat+1
app_id=substr(ain,iat,8)
iat=iat+8
app_auth=substr(ain,iat,3)
iat=iat+2
appsize=chew_data()
if appsize<0 then return -33
if dodisp=1 then say " Application ID: " app_id
if dodisp=1 then say " Application authorization:" app_auth
if dodisp=1 then say " # bytes in application block: " appsize
return 1
/***********/
plain_text:
if dodisp=1 then say (1+iat)">> " bold " PLAIN TEXT Extension # " nptxts normal
iat=iat+1
app_blocksize=x2d(c2x(substr(ain,iat,1)))
if ptextblocksize<>12 then do
if dodisp=1 then say reverse "Error. Bad plain text block size: "ptext_blocksize normal
return -4
end /* do */
l1=substr(ain,iat+1,2)
pt_left=c2d(reverse(l1))
l2=substr(ain,iat+3,2)
pt_top=c2d(reverse(l2))
l1=substr(ain,iat+5,2)
pt_width=c2d(reverse(l1))
l2=substr(ain,iat+7,2)
pt_height=c2d(reverse(l2))
if dodisp=1 then say " Text location; Left , top : " pt_left ', 'pt_top
if dodisp=1 then say " Text size; Width x Height in pixels: " pt_width ' x ' pt_height
iat=iat+4
pt_size=chew_data(1)
if pt_size<0 then return -44
if dodisp=1 then say "# bytes in plain text: " pt_size
if dodisp=1 then say bold " Plain text message: " normal amess
return 1
/*********/
is_comment:
if dodisp=1 then say (iat+1)">>" bold " COMMENT Extension # " ncmts normal
csize=chew_data(1)
if csize<0 then return -7
if dodisp=1 then say "Size of comment: " csize
if dodisp=1 then say bold "Comment text: " normal amess
return 1
/*********/
chew_data:procedure expose iat ain amess filesize
parse arg keep
totsize=0
amess=''
do forever /* data blocks */
if iat>filesize then do
if dodisp=1 then say "Error. Data overrun (no terminator) "
return -5
end /* do */
iat=iat+1 /* size of block */
ii=substr(ain,iat,1) ; ii=c2d(ii)
if ii=0 then do
leave
end /* do */
iat=iat+1
if keep<>0 then amess=amess||substr(ain,iat,ii)
totsize=totsize+ii
iat=iat+ii-1
end /* do */
return totsize
/*************/
init1:
ansion=checkansi()
if ansion=1 then do
aesc='1B'x
cy_ye=aesc||'[37;46;m'
normal=aesc||'[0;m'
bold=aesc||'[1;m'
re_wh=aesc||'[31;47;m'
reverse=aesc||'[7;m'
end
else do
if dodisp=1 then say " Warning: Could not detect ANSI.... output will look ugly ! "
cy_ye="" ; normal="" ; bold="" ;re_wh="" ;
reverse=""
end /* Do */
return 1
/* ------------------------------------------------------------------ */
/* function: Check if ANSI is activated */
/* */
/* call: CheckAnsi */
/* */
/* where: - */
/* */
/* returns: 1 - ANSI support detected */
/* 0 - no ANSI support available */
/* -1 - error detecting ansi */
/* */
/* note: Tested with the German and the US version of OS/2 3.0 */
/* */
/* */
CheckAnsi: PROCEDURE
thisRC = -1
trace off
/* install a local error handler */
SIGNAL ON ERROR Name InitAnsiEnd
"@ANSI 2>NUL | rxqueue 2>NUL"
thisRC = 0
do while queued() <> 0
queueLine = lineIN( "QUEUE:" )
if pos( " on.", queueLine ) <> 0 | , /* USA */
pos( " (ON).", queueLine ) <> 0 then /* GER */
thisRC = 1
end /* do while queued() <> 0 */
InitAnsiEnd:
signal off error
RETURN thisRC