1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
#!/usr/bin/env slsh
% This script prints the width and height of one or more jpeg image files.
if (__argc < 2)
{
() = fprintf (stderr, "Usage: %s files....\n", path_basename (__argv[0]));
exit (1);
}
private variable M_SOF0 = 0xC0; %/* Start Of Frame N */
private variable M_SOF1 = 0xC1; %/* N indicates which compression process */
private variable M_SOF2 = 0xC2; %/* Only SOF0-SOF2 are now in common use */
private variable M_SOF3 = 0xC3; %
private variable M_SOF5 = 0xC5; %/* NB: codes C4 and CC are NOT SOF markers */
private variable M_SOF6 = 0xC6; %
private variable M_SOF7 = 0xC7; %
private variable M_SOF9 = 0xC9; %
private variable M_SOF10 = 0xCA; %
private variable M_SOF11 = 0xCB; %
private variable M_SOF13 = 0xCD; %
private variable M_SOF14 = 0xCE; %
private variable M_SOF15 = 0xCF; %
private variable M_SOI = 0xD8; %/* Start Of Image (beginning of datastream) */
private variable M_EOI = 0xD9; %/* End Of Image (end of datastream) */
private variable M_SOI = 0xD8; % Start Of Image (beginning of datastream)
private define read_nbytes (fp, n)
{
variable b;
if (n != fread_bytes (&b, n, fp))
throw ReadError, "Failed to read $n bytes"$;
return b;
}
private define read_ushort (fp)
{
return unpack (">H", read_nbytes (fp, 2));
}
private define open_jpg_file_for_read (file)
{
variable fp = fopen (file, "rb");
variable b = read_nbytes (fp, 2);
if ((b[0] != 0xFF) or (b[1] != M_SOI))
return NULL;
return fp;
}
private define next_marker (fp)
{
variable c = read_nbytes (fp, 1);
while (c != 0xFF)
c = read_nbytes (fp, 1);
% Remove pad bytes
do
c = read_nbytes (fp, 1);
while (c == 0xFF);
return c;
}
private define skip_variable (fp)
{
variable len = read_ushort (fp);
if (len < 2)
throw DataError, "Erroneous JPEG marker length";
len -= 2;
while (len > 512)
{
() = read_nbytes (fp, 512);
len -= 512;
}
() = read_nbytes (fp, len);
}
public define jpeg_size (file, width, height)
{
variable fp = open_jpg_file_for_read (file);
if (fp == NULL)
return -1;
variable is_sof = UChar_Type[256];
is_sof[M_SOF0] = 1;
is_sof[M_SOF1] = 1;
is_sof[M_SOF2] = 1;
is_sof[M_SOF3] = 1;
is_sof[M_SOF5] = 1;
is_sof[M_SOF6] = 1;
is_sof[M_SOF7] = 1;
is_sof[M_SOF9] = 1;
is_sof[M_SOF10] = 1;
is_sof[M_SOF11] = 1;
is_sof[M_SOF13] = 1;
is_sof[M_SOF15] = 1;
while (0 == is_sof[next_marker(fp)])
{
skip_variable (fp);
}
variable len = read_ushort (fp);
variable data_precision = read_nbytes (fp, 1);
variable h = read_ushort (fp);
variable w = read_ushort (fp);
@width = w;
@height = h;
return 0;
}
private define main ()
{
variable file;
foreach file (__argv[[1:]])
{
try
{
variable width, height;
if (-1 == jpeg_size (file, &width, &height))
{
() = fprintf (stderr, "%s is not a jpeg file\n", file);
continue;
}
() = fprintf (stdout, "%s: %ux%u\n", file, width, height);
}
catch ReadError, DataError:
() = fprintf (stderr, "Caught error processing %s ...skipped\n", file);
}
exit (0);
}
main ();
|