d1f314 | 2013-07-08 | Henrik Grubbström (Grubba) | | #charset utf-8
|
370919 | 2002-03-20 | Martin Nilsson | | #pike __REAL_VERSION__
|
a59c9e | 2002-01-17 | Martin Nilsson | |
|
cbf778 | 2006-09-13 | Tor Edvardsson | |
|
a59c9e | 2002-01-17 | Martin Nilsson | |
|
039e25 | 2002-09-29 | Manual system | |
|
a59c9e | 2002-01-17 | Martin Nilsson | |
#define M_SOF0 0xC0 /* Start Of Frame N */
#define M_SOF1 0xC1 /* N indicates which compression process */
#define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */
#define M_SOF3 0xC3
#define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */
#define M_SOF6 0xC6
#define M_SOF7 0xC7
#define M_SOF9 0xC9
#define M_SOF10 0xCA
#define M_SOF11 0xCB
#define M_SOF13 0xCD
#define M_SOF14 0xCE
#define M_SOF15 0xCF
#define M_SOI 0xD8 /* Start Of Image (beginning of datastream) */
#define M_EOI 0xD9 /* End Of Image (end of datastream) */
#define M_SOS 0xDA /* Start Of Scan (begins compressed data) */
#define M_COM 0xFE /* COMment */
|
3bdcd0 | 2015-08-26 | Martin Nilsson | | #define M_APP1 0xE1
|
a59c9e | 2002-01-17 | Martin Nilsson | |
|
9eaf1d | 2008-06-28 | Martin Nilsson | | protected int(0..255) read_1_byte(Stdio.File f)
|
a59c9e | 2002-01-17 | Martin Nilsson | | {
return f->read(1)[0];
}
|
9eaf1d | 2008-06-28 | Martin Nilsson | | protected int(0..65535) read_2_bytes(Stdio.File f)
|
a59c9e | 2002-01-17 | Martin Nilsson | | {
int c;
sscanf( f->read(2), "%2c", c );
return c;
}
|
9eaf1d | 2008-06-28 | Martin Nilsson | | protected int first_marker(Stdio.File f)
|
a59c9e | 2002-01-17 | Martin Nilsson | | {
int c1, c2;
|
352471 | 2015-05-26 | Martin Nilsson | |
|
58eee3 | 2004-05-23 | Martin Nilsson | | sscanf(f->read(2), "%c%c", c1, c2);
|
e567fd | 2004-05-23 | Martin Nilsson | | if (c1==0xFF||c2==M_SOI) return 1;
return 0;
|
a59c9e | 2002-01-17 | Martin Nilsson | | }
|
9eaf1d | 2008-06-28 | Martin Nilsson | | protected int next_marker(Stdio.File f)
|
a59c9e | 2002-01-17 | Martin Nilsson | | {
|
32cd2b | 2005-10-05 | Martin Nilsson | |
int c = read_1_byte(f);
while (c != 0xFF)
|
a59c9e | 2002-01-17 | Martin Nilsson | | c = read_1_byte(f);
|
32cd2b | 2005-10-05 | Martin Nilsson | |
|
a59c9e | 2002-01-17 | Martin Nilsson | | do {
c = read_1_byte(f);
} while (c == 0xFF);
return c;
}
|
9eaf1d | 2008-06-28 | Martin Nilsson | | protected int skip_variable(Stdio.File f)
|
a59c9e | 2002-01-17 | Martin Nilsson | | {
int length = read_2_bytes(f);
|
58eee3 | 2004-05-23 | Martin Nilsson | | if (length < 2) return 0;
|
a59c9e | 2002-01-17 | Martin Nilsson | | length -= 2;
f->seek(f->tell()+length);
return 1;
}
|
039e25 | 2002-09-29 | Manual system | |
|
a59c9e | 2002-01-17 | Martin Nilsson | | array(int) get_JPEG(Stdio.File f)
{
|
58eee3 | 2004-05-23 | Martin Nilsson | | if (!first_marker(f))
|
a59c9e | 2002-01-17 | Martin Nilsson | | return 0;
|
352471 | 2015-05-26 | Martin Nilsson | |
|
3bdcd0 | 2015-08-26 | Martin Nilsson | | mapping exif;
|
a59c9e | 2002-01-17 | Martin Nilsson | |
for (;;)
{
|
32cd2b | 2005-10-05 | Martin Nilsson | | switch (next_marker(f)) {
|
a59c9e | 2002-01-17 | Martin Nilsson | | case M_SOF0:
case M_SOF1:
case M_SOF2:
case M_SOF3:
case M_SOF5:
case M_SOF6:
case M_SOF7:
case M_SOF9:
case M_SOF10:
case M_SOF11:
case M_SOF13:
case M_SOF14:
case M_SOF15:
|
58eee3 | 2004-05-23 | Martin Nilsson | | int image_height, image_width;
|
743897 | 2004-05-23 | Martin Nilsson | | sscanf(f->read(7), "%*3s%2c%2c", image_height, image_width);
|
3bdcd0 | 2015-08-26 | Martin Nilsson | | if( exif && has_value(exif, "Orientation") &&
(< "5", "6", "7", "8" >)[exif->Orientation] )
|
a142c2 | 2013-02-07 | Leif Stensson | | {
|
3bdcd0 | 2015-08-26 | Martin Nilsson | |
int tmp = image_height;
image_height = image_width;
image_width = tmp;
|
a142c2 | 2013-02-07 | Leif Stensson | | }
|
a59c9e | 2002-01-17 | Martin Nilsson | | return ({ image_width,image_height });
break;
|
352471 | 2015-05-26 | Martin Nilsson | |
|
3bdcd0 | 2015-08-26 | Martin Nilsson | | case M_APP1:
int pos = f->tell();
f->seek(pos-2);
catch {
exif = Standards.EXIF.get_properties(f, ([ 0x0112 :
({ "Orientation" }) ]));
};
f->seek(pos);
if(!skip_variable(f)) return 0;
break;
|
a59c9e | 2002-01-17 | Martin Nilsson | | case M_SOS:
return 0;
case M_EOI:
return 0;
|
352471 | 2015-05-26 | Martin Nilsson | |
|
a59c9e | 2002-01-17 | Martin Nilsson | | default:
|
58eee3 | 2004-05-23 | Martin Nilsson | | if(!skip_variable(f)) return 0;
|
a59c9e | 2002-01-17 | Martin Nilsson | | break;
}
}
}
|
039e25 | 2002-09-29 | Manual system | |
|
a59c9e | 2002-01-17 | Martin Nilsson | | array(int) get_GIF(Stdio.File f)
{
int offs=f->tell();
if(f->read(3)!="GIF") return 0;
f->seek(offs+6);
|
743897 | 2004-05-23 | Martin Nilsson | | return array_sscanf(f->read(4), "%-2c%-2c");
|
a59c9e | 2002-01-17 | Martin Nilsson | | }
|
039e25 | 2002-09-29 | Manual system | |
|
a59c9e | 2002-01-17 | Martin Nilsson | | array(int) get_PNG(Stdio.File f)
{
int offs=f->tell();
f->seek(offs+1);
if(f->read(3)!="PNG") return 0;
f->seek(offs+12);
if(f->read(4)!="IHDR") return 0;
|
743897 | 2004-05-23 | Martin Nilsson | | return array_sscanf(f->read(8), "%4c%4c");
|
a59c9e | 2002-01-17 | Martin Nilsson | | }
|
cbf778 | 2006-09-13 | Tor Edvardsson | |
array(int) get_TIFF(Stdio.File f)
{
int|string buf;
int entries;
int val = 0;
string bo2b;
string bo4b;
|
352471 | 2015-05-26 | Martin Nilsson | |
|
cbf778 | 2006-09-13 | Tor Edvardsson | | buf = f->read(2);
|
352471 | 2015-05-26 | Martin Nilsson | | if(buf == "II")
|
cbf778 | 2006-09-13 | Tor Edvardsson | | {
bo2b = "%2-c";
bo4b = "%4-c";
}
else if(buf == "MM")
{
bo2b = "%2c";
bo4b = "%4c";
}
|
352471 | 2015-05-26 | Martin Nilsson | | else
|
cbf778 | 2006-09-13 | Tor Edvardsson | | {
return 0;
}
|
352471 | 2015-05-26 | Martin Nilsson | |
|
cbf778 | 2006-09-13 | Tor Edvardsson | | sscanf(f->read(2), bo2b, buf);
if(buf != 42)
{
return 0;
}
|
352471 | 2015-05-26 | Martin Nilsson | |
|
cbf778 | 2006-09-13 | Tor Edvardsson | |
sscanf(f->read(4), bo4b, buf);
f->seek(buf);
|
352471 | 2015-05-26 | Martin Nilsson | |
|
cbf778 | 2006-09-13 | Tor Edvardsson | |
sscanf(f->read(2), bo2b, entries);
|
352471 | 2015-05-26 | Martin Nilsson | |
for(int i = 0; i < entries; i++)
|
cbf778 | 2006-09-13 | Tor Edvardsson | | {
sscanf(f->read(2), bo2b, int tag);
|
352471 | 2015-05-26 | Martin Nilsson | | if(tag == 256 || tag == 257)
|
cbf778 | 2006-09-13 | Tor Edvardsson | | {
sscanf(f->read(2), bo2b, buf);
sscanf(f->read(4), bo4b, int count);
|
352471 | 2015-05-26 | Martin Nilsson | | if(count == 1)
|
cbf778 | 2006-09-13 | Tor Edvardsson | | {
|
352471 | 2015-05-26 | Martin Nilsson | | if(buf == 3)
|
cbf778 | 2006-09-13 | Tor Edvardsson | | {
sscanf(f->read(2), bo2b, buf);
f->seek(f->tell() + 2);
}
else if(buf == 4)
{
sscanf(f->read(4), bo4b, buf);
}
else
{
return 0;
|
352471 | 2015-05-26 | Martin Nilsson | | }
|
cbf778 | 2006-09-13 | Tor Edvardsson | | if(tag == 256)
{
if(val == 0)
val = buf;
else
return ({buf, val});
}
else
{
if(val == 0)
val = buf;
else
return ({val, buf});
}
}
else
{
return 0;
}
}
|
352471 | 2015-05-26 | Martin Nilsson | | else
|
cbf778 | 2006-09-13 | Tor Edvardsson | | {
f->seek(f->tell() + 10);
}
}
return 0;
}
|
b503be | 2010-06-02 | Jonas Wallden | |
array(int) get_PSD(Stdio.File f)
{
if (f->read(6) != "8BPS\0\1") return 0;
|
352471 | 2015-05-26 | Martin Nilsson | |
|
b503be | 2010-06-02 | Jonas Wallden | |
f->read(8);
|
352471 | 2015-05-26 | Martin Nilsson | |
|
b503be | 2010-06-02 | Jonas Wallden | |
return reverse(array_sscanf(f->read(8), "%4c%4c"));
}
|
0770cf | 2015-08-08 | Martin Nilsson | |
array(int) get_WebP(Stdio.File f)
{
if (f->read(4) != "RIFF") return 0;
f->read(4);
if (f->read(4) != "WEBP") return 0;
switch(f->read(4))
{
case "VP8 ":
f->read(4);
f->read(3);
if(f->read(3)!="\x9d\x01\x2a") return 0;
return array_sscanf(f->read(4), "%-2c%-2c")[*] & 0x3fff;
break;
case "VP8L":
f->read(4);
if( f->read(1) != "/" ) return 0;
string data = f->read(4);
int width = (data[0] | (data[1] & 0x3f)<<8) + 1;
int height = (data[1]>>6 | data[2]<<2 | (data[3] & 0x0f)<<10) + 1;
return ({ width, height });
break;
case "VP8X":
|
589212 | 2015-08-08 | Martin Nilsson | | f->read(4);
|
0770cf | 2015-08-08 | Martin Nilsson | | f->read(4);
|
589212 | 2015-08-08 | Martin Nilsson | | return array_sscanf(f->read(6), "%-3c%-3c")[*]+1;
|
0770cf | 2015-08-08 | Martin Nilsson | | break;
}
return 0;
}
|
2ef602 | 2004-08-26 | Martin Nilsson | |
|
e567fd | 2004-05-23 | Martin Nilsson | |
|
b503be | 2010-06-02 | Jonas Wallden | |
|
0770cf | 2015-08-08 | Martin Nilsson | |
|
e567fd | 2004-05-23 | Martin Nilsson | |
|
78a9fc | 2015-08-27 | Martin Nilsson | | array(int|string) get(string|Stdio.File file) {
|
c0e097 | 2015-08-08 | Martin Nilsson | |
if(stringp(file))
|
2ef602 | 2004-08-26 | Martin Nilsson | | file = Stdio.FakeFile(file);
|
58eee3 | 2004-05-23 | Martin Nilsson | |
|
2905ba | 2015-08-08 | Martin Nilsson | | array ret;
switch(file->read(2))
{
case "GI":
if( (< "F87a", "F89a" >)[file->read(4)] )
return array_sscanf(file->read(4), "%-2c%-2c") + ({ "gif" });
break;
case "\x89P":
if(file->read(4)=="NG\r\n")
{
file->read(6+4);
return array_sscanf(file->read(8), "%4c%4c") + ({ "png" });
}
break;
|
352471 | 2015-05-26 | Martin Nilsson | |
|
2905ba | 2015-08-08 | Martin Nilsson | | case "8B":
if(file->read(4)=="PS\0\1")
{
file->read(6+2);
return reverse(array_sscanf(file->read(8), "%4c%4c")) + ({ "psd" });
}
break;
case "II":
case "MM":
file->seek(file->tell()-2);
ret = get_TIFF(file);
if(ret) return ret+({ "tiff" });
break;
case "\xff\xd8":
file->seek(file->tell()-2);
ret = get_JPEG(file);
if(ret) return ret+({ "jpeg" });
break;
|
0770cf | 2015-08-08 | Martin Nilsson | |
case "RI":
file->seek(file->tell()-2);
ret = get_WebP(file);
if(ret) return ret+({ "webp" });
break;
|
58eee3 | 2004-05-23 | Martin Nilsson | | }
|
2905ba | 2015-08-08 | Martin Nilsson | |
|
0770cf | 2015-08-08 | Martin Nilsson | | return 0;
|
a59c9e | 2002-01-17 | Martin Nilsson | | }
|