134 строки
3.2 KiB
Plaintext
Исполняемый файл
134 строки
3.2 KiB
Plaintext
Исполняемый файл
#!/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 ();
|