Current issue

Vol.26 No.4

Vol.26 No.4

Volumes

© 1984-2024
British APL Association
All rights reserved.

Archive articles posted online on request: ask the archivist.

archive/17/2

Volume 17, No.2

This article might contain pre-Unicode character-mapped APL code.
See here for details.

Hacker’s Corner – How Big is that Doggie in the Window?

original from William Parke (wrp@parkenet.org), notes by Adrian Smith

Introduction

Being kind to web browsers is always a good idea, but particularly so when it comes to images. For readers who have been asleep for the last 5 years, you include a picture in a web page with an HTML fragment like:

<img src="trad/v172/"mydog.jpg">This"  is my dog!

... and when the browser hits the tag, it beetles off back to the server and asks for the image file. In fact if you have lots of pictures, sensible browsers start a whole series of threads running to get the pictures in parallel. Of course the whole of the text has usually been loaded long before the last image arrives, which leaves the browser with a big problem – how can it lay out the page until it knows how big all the images are?

There are two possible solutions here:

  1. wait for the last picture to come, compute the wraparounds and gaps, then lay out the text
  2. slam the text down as soon as you can and rewrite it as many times as you have to, as information about the pictures trickles in.

Option 1 is good if you have ADSL or are working on a LAN, option 2 is actually not as bad as it sounds on a slow modem. However, you can tell the browser exactly what to expect by including some extra information in the tag:

<img src="trad/v172/"mydog.jpg""  height=240 width=128>This is my dog!

Now the page can be rendered correctly and immediately, and the pictures will slot neatly into the gaps. Everyone deeply content, all pigs fed and ready to fly etc. But .... how does your APL web-site builder find out how big a picture is so it can include the information in the HTML stream that it writes out?

This was an issue I had been quietly ignoring for some time, as my HelpStuf workspace only does Webpages as a by-product, being much more focussed on Help files and manuals. However it is rapidly becoming essential to do good web-based documentation too, so I was delighted when Bill Parke took up the challenge, took on the research and came up with a serious piece of APL+Win code which will find the size of more or less any file you care to name.

SizeofIMG in APL+Win

Bill keeps up-to-date copies of his code on his own website, and the original is a shade over 300 lines long, so it would be pointless to list it here. However the references are (very sensibly) included in the leading comments:

©’([fileformat width height depth hres vres units] or [attributestring])„[returnformat] SizeofIMG filename -- find size information in BMP, JPG, GIF and PNG image files
©’ver 2000.06.09 wrp <wrp@parkenet.org>
©’ file „… [path\]imagefilename
©’ rf   „… 0 = return raw data (default)
©’         1 = return string formatted for HTML <IMG> tag
©’ z    „… raw data: fileformat width height depth Hresolution Vresolution resolutionunits
©’      or format string: 'width="xxx" height="yyy"'

©’ JPEG information adapted from:
©’  the Independent JPEG Group's JPEG software, release 6b
©’  Copyright (C) 1991-1998, Thomas G. Lane.
©’   specifically jdmarker.c
©’  ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz
©’  ftp.simtel.net/pub/simtelnet/msdos/graphics/jpegsr6b.zip
©’
©’ BMP, GIF and PNG information from:
©’  Miano, John. "Compressed Image File Formats"
©’  Copyright (C) 1999, ACM Press (Addison-Wesley)
©’  ISBN 0201604434 

He returns the size information, and quite a lot of other interesting stuff about the file. Calling it is as simple as it looks:

     1 SizeOf 'd:\digipix\cars\mazda.jpg'
width=1852 height=1239

Here is my translation into Dyalog APL, much reduced in size as I only needed the file-size information and could ignore bitmap format as these are never used in my webpages. I have cut the leading comments, which just repeat Bill’s notes.

     ’ size„SizeOf file;fileformat;units;height;width;nsize;ntie;
            byte;nread;length;data;ŒIO
[1]   © Get size info (GIF,JPG,PNG) and return in HTML format
 ...........
[14]  © Translated from Bill Parke's APL+Win code by ACDS - July 2000
[15]  © See http://parkenet.org/wrp/apl/SizeofIMG.html for his notes
[16]
[17]   size„'' ª ŒIO„0
[18]
[19]  © Initialize data variables
[20]   fileformat„units„'' ª height„width„0 ª ntie„¯1+˜/0,ŒNNUMS
[21]
[22]   :Trap 0 © Open file with error trapping
[23]     file ŒNTIE ntie 0
[24]   :Else
[25]     Log'Could not open ',file,' no size information will be included'
[26]     :Return
[27]   :End
[28]
[29]   nsize„ŒNSIZE ntie
[30]
[31]   :If 255 216¦256|ŒNREAD ntie,83,(nread„2),0   © is JPEG file
[32]     fileformat„'JPEG'
[33]     :While nread<nsize   © read byte-by-byte, look for FF (255) markers
[34]       :Repeat    © read until marker found or end of file
[35]         byte„256|ŒNREAD ntie,83 1
[36]         …(nsize=nread„1+nread)†END
[37]       :Until 255=byte  © marker found, look for marker code
[38]
[39]       :Repeat  © read marker code, skip any FF padding
[40]         byte„256|ŒNREAD ntie,83 1
[41]         …(nsize=nread„1+nread)†END
[42]       :Until 255¬byte  © length includes itself, so subtract here
[43]
[44]       length„¯2+256 256ƒ256|ŒNREAD ntie,83 2 ª nread„2+nread
[45]
[46]       :Select œbyte
[47]       :CaseList (192+¼16)~196 200 204
[48]         data„256|ŒNREAD ntie,83,length
[49]         nread„nread+length
[50]        © image size is contained in next 4 bytes
[51]         height„256 256ƒdata[1 2] ª width„256 256ƒdata[3 4]
[52]         …END
[53]
[54]       :Else   © not interested -- skip this parameter segment
[55]         :If 0<length
[56]           byte„ŒNREAD ntie,83,length
[57]           nread„nread+length
[58]         :End
[59]
[60]       :EndSelect
[61]
[62]     :EndWhile    © -- end JPEG section -------------------
[63]
[64]   :ElseIf 'GIF'¦ŒNREAD ntie,82 3 0
[65]     fileformat„'GIF',ŒNREAD ntie,82 3   © GIF subtype ('87a' or '89a')
[66]     (width height)„ŒNREAD ntie,163 2
[67]
[68]   © -- end GIF section ----------------------------------------
[69]
[70]   :ElseIf 137 80 78 71 13 10 26 10¦256|ŒNREAD ntie,83 8 0
[71]     length„323 ŒDR²ŒNREAD ntie,82 4
[72]     :If (13=length)^'IHDR'¦ŒNREAD ntie,82 4
[73]       fileformat„'PNG'
[74]       width„323 ŒDR²ŒNREAD ntie,82 4
[75]       height„323 ŒDR²ŒNREAD ntie,82 4
[76]     :End
[77]   © -- end PNG section ----------------------------------------
[78]
[79]   :End
[80]
[81]  END:
[82]
[83]   :If ^/0<width,height  © only supply valid values
[84]     size„' width=',(•width),' height=',(•height)
[85]   :End
[86]
[87]   ŒNUNTIE ntie
     ’

Notice the trailing 0 on the call to ŒNTIE on line[23] – this is something I almost always forget (including the above function until I pasted it into Vector 5 minutes ago) and it is essential if you are accessing a read-only network drive. Notice the effect of correcting the problem ...

      SizeOf '\\della\d\pix\berlin\bbgate.jpg'
Could not open \\della\d\pix\berlin\bbgate.jpg no size information will be included

      SizeOf '\\della\d\pix\berlin\bbgate.jpg'
 width=523 height=360

I think APL+Win defaults to opening the file read-only (option=0) but Dyalog defaults to read-write mode which is a very silly idea if you keep your pictures on a network drive, a CD ROM or a read-only ZIP drive.

Summary

If you are using APL to build web-pages, go and get Bill’s code and just use it. If you really want to know about the details, follow up his excellent references. Either way, he has made a really useful contribution to the corpus of publicly available APL code, and deserves all our thanks.


script began 0:22:41
caching off
debug mode off
cache time 3600 sec
indmtime not found in cache
cached index is fresh
recompiling index.xml
index compiled in 0.2167 secs
read index
read issues/index.xml
identified 26 volumes, 101 issues
array (
  'id' => '10006300',
)
regenerated static HTML
article source is 'HTML'
source file encoding is ''
read as 'Windows-1252'
URL: "mydog.jpg">this => trad/v172/"mydog.jpg">This
URL: "mydog.jpg" => trad/v172/"mydog.jpg"
completed in 0.2436 secs