diff options
| -rw-r--r-- | image.c | 91 | 
1 files changed, 91 insertions, 0 deletions
| @@ -625,6 +625,91 @@ getImage(Image * image, ParsedURL *current, int flag)      return cache;  } +static int +parseImageHeader(char *path, u_int *width, u_int *height) +{ +    char *suffix; + +    suffix = path + strlen(path); +    if (strcasecmp(suffix - 5, ".jpeg") == 0 || strcasecmp(suffix - 4 , ".jpg") == 0) { +	FILE *fp = fopen(path, "r"); +	if (fp) { +	    u_char buf[2]; +	    if (fread(buf, 1, 2, fp) != 2 || memcmp(buf, "\xff\xd8", 2) != 0 || +	        fseek(fp, 2, SEEK_CUR) < 0)	/* 0xffe0 */ +		goto  jpg_error; + +	    while (fread(buf, 1, 2, fp) == 2) { +		size_t len = ((buf[0] << 8) | buf[1]) - 2; +		if (fseek(fp, len, SEEK_CUR) < 0) goto jpg_error; +	        if (fread(buf, 1, 2, fp) == 2 && memcmp(buf, "\xff\xc0", 2) == 0) { +		    fseek(fp, 3, SEEK_CUR); +		    if (fread(buf, 1, 2, fp) == 2) { +			*height = (buf[0] << 8) | buf[1]; +			if (fread(buf, 1, 2, fp) == 2) { +			    *width = (buf[0] << 8) | buf[1]; +			    fclose(fp); +			    return TRUE; +			} +		    } +		    break; +		} +	    } + +	jpg_error: +	    fclose(fp); +	    return FALSE; +	} +    } +    else if (strcasecmp(suffix - 4,  ".png") == 0) { +	FILE *fp = fopen(path, "r"); +	if (fp) { +	    u_char buf[8]; +	    if (fread(buf, 1, 8, fp) != 8 || +	        memcmp(buf, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8) != 0 || +		fseek(fp, 8, SEEK_CUR) < 0) +		goto  png_error; + +	    if (fread(buf, 1, 4, fp) == 4) { +	        *width = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; +		if (fread(buf, 1, 4, fp) == 4) { +		    *height = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; +		    fclose(fp); +		    return TRUE; +		} +	    } + +	png_error: +	    fclose(fp); +	    return FALSE; +	} +    } +    else if (strcasecmp(suffix - 4, ".gif") == 0) { +	FILE *fp = fopen(path, "r"); +	if (fp) { +	    u_char buf[3]; +	    if (fread(buf, 1, 3, fp) != 3 || memcmp(buf, "GIF", 3) != 0 || +	        fseek(fp, 3, SEEK_CUR) < 0) { +		goto  png_error; +	    } +	    if (fread(buf, 1, 2, fp) == 2) { +		*width = (buf[1] << 8) | buf[0]; +		if (fread(buf, 1, 2, fp) == 2) { +		    *height = (buf[1] << 8) | buf[0]; +		    fclose(fp); +		    return TRUE; +		} +	    } +	} + +	gif_error: +	    fclose(fp); +	    return FALSE; +    } + +    return FALSE; +} +  int  getImageSize(ImageCache * cache)  { @@ -637,6 +722,10 @@ getImageSize(ImageCache * cache)      if (!cache || !(cache->loaded & IMG_FLAG_LOADED) ||  	(cache->width > 0 && cache->height > 0))  	return FALSE; + +    if (parseImageHeader(cache->file, &w, &h)) +	goto got_image_size; +      tmp = Strnew();      if (!strchr(Imgdisplay, '/'))  	Strcat_m_charp(tmp, w3m_auxbin_dir(), "/", NULL); @@ -652,6 +741,8 @@ getImageSize(ImageCache * cache)      if (!(w > 0 && h > 0))  	return FALSE; + +got_image_size:      w = (int)(w * image_scale / 100 + 0.5);      if (w == 0)  	w = 1; | 
