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