tif: add tiff decoder
This commit is contained in:
parent
82ccf5b26a
commit
043c8e4453
6 changed files with 2068 additions and 8 deletions
|
@ -1,6 +1,6 @@
|
||||||
.TH JPG 1
|
.TH JPG 1
|
||||||
.SH NAME
|
.SH NAME
|
||||||
jpg, gif, png, ppm, bmp, v210, yuv, ico, tga, tojpg, togeordi, togif, toppm, topng, toico \- view and convert pictures
|
jpg, gif, png, tif, ppm, bmp, v210, yuv, ico, tga, tojpg, togeordi, togif, toppm, topng, toico \- view and convert pictures
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B jpg
|
.B jpg
|
||||||
[
|
[
|
||||||
|
@ -23,6 +23,13 @@ jpg, gif, png, ppm, bmp, v210, yuv, ico, tga, tojpg, togeordi, togif, toppm, top
|
||||||
.I file ...
|
.I file ...
|
||||||
]
|
]
|
||||||
.br
|
.br
|
||||||
|
.B tif
|
||||||
|
[
|
||||||
|
.B -39cdektv
|
||||||
|
] [
|
||||||
|
.I file ...
|
||||||
|
]
|
||||||
|
.br
|
||||||
.B ppm
|
.B ppm
|
||||||
[
|
[
|
||||||
.B -39cdektv
|
.B -39cdektv
|
||||||
|
@ -137,6 +144,7 @@ These programs read, display, and write image files in public formats.
|
||||||
.IR Jpg ,
|
.IR Jpg ,
|
||||||
.IR gif ,
|
.IR gif ,
|
||||||
.IR png ,
|
.IR png ,
|
||||||
|
.IR tif ,
|
||||||
.IR ppm ,
|
.IR ppm ,
|
||||||
.IR bmp ,
|
.IR bmp ,
|
||||||
.IR tga ,
|
.IR tga ,
|
||||||
|
@ -156,8 +164,14 @@ read Plan 9 images files, convert them to JPEG, GIF, PPM, or PNG, and write them
|
||||||
The default behavior of
|
The default behavior of
|
||||||
.IR jpg ,
|
.IR jpg ,
|
||||||
.IR gif ,
|
.IR gif ,
|
||||||
|
.IR png ,
|
||||||
|
.IR tif ,
|
||||||
|
.IR ppm ,
|
||||||
|
.IR bmp ,
|
||||||
|
.IR tga ,
|
||||||
|
.IR v210 ,
|
||||||
and
|
and
|
||||||
.IR ppm
|
.IR yuv
|
||||||
is to display the
|
is to display the
|
||||||
.IR file ,
|
.IR file ,
|
||||||
or standard input if no file is named.
|
or standard input if no file is named.
|
||||||
|
@ -227,11 +241,12 @@ The input is a motion JPEG file, with multiple images representing frames of the
|
||||||
.PP
|
.PP
|
||||||
The
|
The
|
||||||
.IR tojpg ,
|
.IR tojpg ,
|
||||||
.IR togif
|
.IR togif ,
|
||||||
and
|
|
||||||
.IR toppm
|
.IR toppm
|
||||||
programs go the other way: they convert from Plan 9 images to JPEG, GIF and PPM,
|
and
|
||||||
and have no display capability.
|
.IR topng
|
||||||
|
programs go the other way: they convert from Plan 9 images to JPEG, GIF,
|
||||||
|
PPM and PNG and have no display capability.
|
||||||
They all accept an option
|
They all accept an option
|
||||||
.B -c
|
.B -c
|
||||||
to set the comment field of the resulting file.
|
to set the comment field of the resulting file.
|
||||||
|
@ -323,6 +338,8 @@ space in the image. The icon file is written to standard output.
|
||||||
.br
|
.br
|
||||||
.B http://www.w3.org/TR/2003/REC-PNG-20031110
|
.B http://www.w3.org/TR/2003/REC-PNG-20031110
|
||||||
.br
|
.br
|
||||||
|
.B http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
|
||||||
|
.br
|
||||||
.B http://netpbm.sourceforge.net/doc/ppm.html
|
.B http://netpbm.sourceforge.net/doc/ppm.html
|
||||||
.br
|
.br
|
||||||
.B http://en.wikipedia.org/wiki/Windows_bitmap
|
.B http://en.wikipedia.org/wiki/Windows_bitmap
|
||||||
|
|
|
@ -50,9 +50,11 @@ typedef struct ImageInfo {
|
||||||
|
|
||||||
|
|
||||||
Rawimage** readjpg(int, int);
|
Rawimage** readjpg(int, int);
|
||||||
Rawimage** Breadjpg(Biobuf *b, int);
|
Rawimage** Breadjpg(Biobuf*, int);
|
||||||
Rawimage** readpng(int, int);
|
Rawimage** readpng(int, int);
|
||||||
Rawimage** Breadpng(Biobuf *b, int);
|
Rawimage** Breadpng(Biobuf*, int);
|
||||||
|
Rawimage** readtif(int);
|
||||||
|
Rawimage** Breadtif(Biobuf*);
|
||||||
Rawimage** readgif(int, int);
|
Rawimage** readgif(int, int);
|
||||||
Rawimage** readpixmap(int, int);
|
Rawimage** readpixmap(int, int);
|
||||||
Rawimage* torgbv(Rawimage*, int);
|
Rawimage* torgbv(Rawimage*, int);
|
||||||
|
|
|
@ -9,6 +9,7 @@ TARG=\
|
||||||
toppm\
|
toppm\
|
||||||
png\
|
png\
|
||||||
topng\
|
topng\
|
||||||
|
tif\
|
||||||
yuv\
|
yuv\
|
||||||
ico\
|
ico\
|
||||||
toico\
|
toico\
|
||||||
|
@ -55,6 +56,7 @@ $O.ppm: $IMFILES readppm.$O ppm.$O
|
||||||
$O.toppm: writeppm.$O multichan.$O toppm.$O
|
$O.toppm: writeppm.$O multichan.$O toppm.$O
|
||||||
$O.png: $IMFILES readpng.$O png.$O
|
$O.png: $IMFILES readpng.$O png.$O
|
||||||
$O.topng: writepng.$O topng.$O
|
$O.topng: writepng.$O topng.$O
|
||||||
|
$O.tif: $IMFILES readtif.$O tif.$O
|
||||||
$O.yuv: $IMFILES readyuv.$O yuv.$O
|
$O.yuv: $IMFILES readyuv.$O yuv.$O
|
||||||
$O.bmp: $IMFILES readbmp.$O bmp.$O
|
$O.bmp: $IMFILES readbmp.$O bmp.$O
|
||||||
$O.v210: $IMFILES readv210.$O v210.$O
|
$O.v210: $IMFILES readv210.$O v210.$O
|
||||||
|
|
1787
sys/src/cmd/jpg/readtif.c
Normal file
1787
sys/src/cmd/jpg/readtif.c
Normal file
File diff suppressed because it is too large
Load diff
251
sys/src/cmd/jpg/tif.c
Normal file
251
sys/src/cmd/jpg/tif.c
Normal file
|
@ -0,0 +1,251 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <bio.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <event.h>
|
||||||
|
#include "imagefile.h"
|
||||||
|
|
||||||
|
int cflag = 0;
|
||||||
|
int dflag = 0;
|
||||||
|
int eflag = 0;
|
||||||
|
int nineflag = 0;
|
||||||
|
int threeflag = 0;
|
||||||
|
int output = 0;
|
||||||
|
Image *image;
|
||||||
|
int defaultcolor = 1;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Border = 2,
|
||||||
|
Edge = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
int init(void);
|
||||||
|
char *show(int, char *, int);
|
||||||
|
|
||||||
|
void
|
||||||
|
eresized(int new)
|
||||||
|
{
|
||||||
|
Rectangle r;
|
||||||
|
|
||||||
|
if(new && getwindow(display, Refnone) < 0)
|
||||||
|
sysfatal("getwindow: %r");
|
||||||
|
if(image == nil)
|
||||||
|
return;
|
||||||
|
r = insetrect(screen->clipr, Edge+Border);
|
||||||
|
r.max.x = r.min.x + Dx(image->r);
|
||||||
|
r.max.y = r.min.y + Dy(image->r);
|
||||||
|
border(screen, r, -Border, nil, ZP);
|
||||||
|
drawop(screen, r, image, nil, image->r.min, S);
|
||||||
|
flushimage(display, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
fprint(2, "usage: %s [-39cdektv] [file.tif ...]\n", argv0);
|
||||||
|
exits("usage");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int fd, i;
|
||||||
|
char *err;
|
||||||
|
ulong outchan;
|
||||||
|
|
||||||
|
outchan = CMAP8;
|
||||||
|
ARGBEGIN {
|
||||||
|
/*
|
||||||
|
* produce encoded, compressed, bitmap file;
|
||||||
|
* no display by default
|
||||||
|
*/
|
||||||
|
case 'c':
|
||||||
|
cflag++;
|
||||||
|
dflag++;
|
||||||
|
output++;
|
||||||
|
if(defaultcolor)
|
||||||
|
outchan = CMAP8;
|
||||||
|
break;
|
||||||
|
/* suppress display of image */
|
||||||
|
case 'd':
|
||||||
|
dflag++;
|
||||||
|
break;
|
||||||
|
/* disable floyd-steinberg error diffusion */
|
||||||
|
case 'e':
|
||||||
|
eflag++;
|
||||||
|
break;
|
||||||
|
/* force black and white */
|
||||||
|
case 'k':
|
||||||
|
defaultcolor = 0;
|
||||||
|
outchan = GREY8;
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
* produce encoded, compressed, three-color
|
||||||
|
* bitmap file; no display by default
|
||||||
|
*/
|
||||||
|
case '3':
|
||||||
|
threeflag++;
|
||||||
|
/* fall through */
|
||||||
|
/*
|
||||||
|
* produce encoded, compressed, true-color
|
||||||
|
* bitmap file; no display by default
|
||||||
|
*/
|
||||||
|
case 't':
|
||||||
|
cflag++;
|
||||||
|
dflag++;
|
||||||
|
output++;
|
||||||
|
defaultcolor = 0;
|
||||||
|
outchan = RGB24;
|
||||||
|
break;
|
||||||
|
/* force RGBV */
|
||||||
|
case 'v':
|
||||||
|
defaultcolor = 0;
|
||||||
|
outchan = CMAP8;
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
* produce plan 9, uncompressed, bitmap file;
|
||||||
|
* no display by default
|
||||||
|
*/
|
||||||
|
case '9':
|
||||||
|
nineflag++;
|
||||||
|
dflag++;
|
||||||
|
output++;
|
||||||
|
if(defaultcolor)
|
||||||
|
outchan = CMAP8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
} ARGEND
|
||||||
|
|
||||||
|
if(argc <= 0)
|
||||||
|
exits(show(0, "<stdin>", outchan));
|
||||||
|
err = nil;
|
||||||
|
for(i = 0; i < argc; i++) {
|
||||||
|
if((fd = open(argv[i], OREAD)) < 0) {
|
||||||
|
fprint(2, "%s: open %s: %r\n",
|
||||||
|
argv0, argv[i]);
|
||||||
|
err = "open";
|
||||||
|
} else {
|
||||||
|
err = show(fd, argv[i], outchan);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
if((nineflag || cflag) && argc > 1 && err == nil) {
|
||||||
|
fprint(2, "%s: exiting after one file\n",
|
||||||
|
argv0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exits(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
init(void)
|
||||||
|
{
|
||||||
|
static int inited = 0;
|
||||||
|
|
||||||
|
if(!inited) {
|
||||||
|
if(initdraw(0, 0, 0) < 0) {
|
||||||
|
fprint(2, "%s: initdraw: %r", argv0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
einit(Ekeyboard|Emouse);
|
||||||
|
inited++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
show(int fd, char *name, int outchan)
|
||||||
|
{
|
||||||
|
Rawimage **array, *r, *c;
|
||||||
|
Image *i;
|
||||||
|
int j, ch;
|
||||||
|
Biobuf b;
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
if(Binit(&b, fd, OREAD) < 0)
|
||||||
|
return nil;
|
||||||
|
array = Breadtif(&b);
|
||||||
|
if(array == nil || array[0] == nil) {
|
||||||
|
if(array != nil)
|
||||||
|
free(array);
|
||||||
|
fprint(2, "%s: decode %s failed: %r\n", argv0,
|
||||||
|
name);
|
||||||
|
return "decode";
|
||||||
|
}
|
||||||
|
Bterm(&b);
|
||||||
|
if(!dflag) {
|
||||||
|
if(init() < 0)
|
||||||
|
return "initdraw";
|
||||||
|
/* fixme: ppm doesn't check for outchan==CMAP8 */
|
||||||
|
if(defaultcolor && screen->depth > 8 &&
|
||||||
|
outchan == CMAP8)
|
||||||
|
outchan = RGB24;
|
||||||
|
}
|
||||||
|
r = array[0];
|
||||||
|
if(outchan != CMAP8) {
|
||||||
|
switch(r->chandesc) {
|
||||||
|
case CY:
|
||||||
|
outchan = GREY8;
|
||||||
|
break;
|
||||||
|
case CRGB24:
|
||||||
|
outchan = RGB24;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c = r;
|
||||||
|
} else if((c = torgbv(r, !eflag)) == nil) {
|
||||||
|
fprint(2, "%s: conversion of %s failed: %r\n",
|
||||||
|
argv0, name);
|
||||||
|
return "torgbv";
|
||||||
|
}
|
||||||
|
if(!dflag) {
|
||||||
|
i = allocimage(display, c->r, outchan, 0, 0);
|
||||||
|
if(i == nil) {
|
||||||
|
fprint(2, "%s: allocimage %s: %r\n",
|
||||||
|
argv0, name);
|
||||||
|
return "allocimage";
|
||||||
|
}
|
||||||
|
if(loadimage(i, i->r, c->chans[0],
|
||||||
|
c->chanlen) < 0) {
|
||||||
|
fprint(2, "%s: loadimage %s: %r\n",
|
||||||
|
argv0, name);
|
||||||
|
return "loadimage";
|
||||||
|
}
|
||||||
|
image = i;
|
||||||
|
eresized(0);
|
||||||
|
ch = ekbd();
|
||||||
|
if(ch == 'q' || ch == 0x7f || ch == 0x04)
|
||||||
|
exits(nil);
|
||||||
|
draw(screen, screen->clipr, display->white,
|
||||||
|
nil, ZP);
|
||||||
|
image = nil;
|
||||||
|
freeimage(i);
|
||||||
|
}
|
||||||
|
if(nineflag) {
|
||||||
|
chantostr(buf, outchan);
|
||||||
|
print("%11s %11d %11d %11d %11d ", buf,
|
||||||
|
c->r.min.x, c->r.min.y,
|
||||||
|
c->r.max.x, c->r.max.y);
|
||||||
|
if(write(1, c->chans[0], c->chanlen) !=
|
||||||
|
c->chanlen) {
|
||||||
|
fprint(2, "%s: %s: write error: %r\n",
|
||||||
|
argv0, name);
|
||||||
|
return "write";
|
||||||
|
}
|
||||||
|
} else if(cflag) {
|
||||||
|
if(writerawimage(1, c) < 0) {
|
||||||
|
fprint(2, "%s: %s: write error: %r\n",
|
||||||
|
argv0, name);
|
||||||
|
return "write";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(c != nil && c != r) {
|
||||||
|
free(c->chans[0]);
|
||||||
|
free(c);
|
||||||
|
}
|
||||||
|
for(j = 0; j < r->nchans; j++)
|
||||||
|
free(r->chans[j]);
|
||||||
|
free(r);
|
||||||
|
free(array);
|
||||||
|
return nil;
|
||||||
|
}
|
|
@ -680,6 +680,7 @@ popenfile(Page *p)
|
||||||
"image/gif", popenimg, "gif",
|
"image/gif", popenimg, "gif",
|
||||||
"image/jpeg", popenimg, "jpg",
|
"image/jpeg", popenimg, "jpg",
|
||||||
"image/png", popenimg, "png",
|
"image/png", popenimg, "png",
|
||||||
|
"image/tiff", popenimg, "tif",
|
||||||
"image/ppm", popenimg, "ppm",
|
"image/ppm", popenimg, "ppm",
|
||||||
"image/bmp", popenimg, "bmp",
|
"image/bmp", popenimg, "bmp",
|
||||||
"image/tga", popenimg, "tga",
|
"image/tga", popenimg, "tga",
|
||||||
|
|
Loading…
Reference in a new issue