home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
NETWORK
/
netpbm_src.lzh
/
NETPBM
/
PGM
/
spottopgm.c
< prev
Wrap
C/C++ Source or Header
|
1996-11-18
|
8KB
|
240 lines
/* Spottopgm: Convert a SPOT satellite image to Portable Greymap format.
*
* Usage: spottopgm [-1|2|3] [Firstcol Firstline Lastcol Lastline] inputfile
*
* Author: Warren Toomey, 1992.
*/
#include <stdio.h>
#include "pgm.h"
/* prototypes */
int get_image ARGS((long length));
int get_imghdr ARGS((int length));
int usage ARGS((void));
/* Global variables */
FILE *spotfile; /* The input file */
#if defined (atarist) && defined (__MBASE__)
char *linebuf;
#else
char linebuf[12000]; /* The line buffer */
#endif
long Firstline = 0, /* The rectangle the user wants */
Lastline = 3000, /* cut out of the image */
Firstcol = 0,
Lastcol = 0;
long Diff = 0; /* Firstcol - Lastcol */
char *Bufptr; /* Pointer into the input image */
int Color = 1; /* Either 1, 2 or 3 */
int Colbool = 0; /* 1 if colour */
/* Get_image extracts the pixel data from one line
* (i.e one record) in the SPOT input file. A SPOT image
* record has a header, data and trailer. The data lengths
* are fixed at 3960, 5400, 8640 or 10980 bytes.
*
* When we arrive here we have read in 12 bytes of the record.
* We then read in the rest of the record. We find the trailer
* and from that determine the number of pixels on the line.
*
* If the image is really color i.e interleaved 3 colors, we
* convert a line if its spectral sequence is the same as the one
* requested by the user (i.e 1, 2 or 3). I could create a ppm file
* but I couldn't be bothered with the rearranging of the data.
*/
int
get_image(length)
long length;
{
int cnt;
struct Linehdr /* Each line begins with the 12 bytes */
{ /* we have already, plus these 20 bytes */
long linenum; /* The line number of the record */
short recseq; /* The record sequence number */
short spectseq; /* The spectral number of the line */
long linetime; /* Time it was recorded (in ms). */
long leftpixmar; /* The pixel number of the 1st pixel */
long rightpixmar; /* The pixel number of the last pixel */
} linehdr;
long numpixels; /* Number of pixels on the line */
/* Get the details of this line */
if (pm_readbiglong (spotfile, &linehdr.linenum) == -1
|| pm_readbigshort (spotfile, &linehdr.recseq) == -1
|| pm_readbigshort (spotfile, &linehdr.spectseq) == -1
|| pm_readbiglong (spotfile, &linehdr.linetime) == -1
|| pm_readbiglong (spotfile, &linehdr.leftpixmar) == -1
| pm_readbiglong (spotfile, &linehdr.rightpixmar) == -1)
pm_error ("EOF / read error reading line header");
/* Now read in the line data */
cnt = length - 20 - 88;
cnt = fread(linebuf, 1, cnt, spotfile);
if (!Diff)
{
cnt += 28;
if (fseek (spotfile, 24, 1) == EOF)
pm_error ("seek error");
if (pm_readbiglong (spotfile, &numpixels) == -1)
pm_error ("EOF / read error reading line ender");
/* Determine the picture size */
Bufptr = &linebuf[Firstcol];
if (Lastcol == 0 || Lastcol > numpixels)
Lastcol = numpixels;
Diff = Lastcol - Firstcol;
/* Print out the header */
printf("P5\n%d %d\n255\n", Diff, Lastline - Firstline);
/* Inform about the image size */
if (Colbool) fprintf(stderr, "Color image, ");
fprintf(stderr, "%d pixels wide\n", numpixels);
}
/* Output the line */
if (linehdr.linenum >= Firstline && linehdr.linenum <= Lastline
&& linehdr.spectseq == Color)
fwrite(Bufptr, 1, Diff, stdout);
if (linehdr.linenum > Lastline) exit(0);
#ifdef DEBUG
fprintf(stderr,
"Line %4d, %3d, %3d, time %4d, l/r pixmar %4d %4d len %d pixnum %d\n",
linehdr.linenum, linehdr.recseq, linehdr.spectseq, linehdr.linetime,
linehdr.leftpixmar, linehdr.rightpixmar, length, numpixels);
#endif
/* And return the amount to seek */
return (length - 20 - cnt);
}
/* The image header tells us if the image is in monochrome or color, and
* if the latter, if the input colors are interleaved. If interleaved
* color, lines are interleaved R, G, B, R, G, B etc. Technically, some
* interleaving of infra-red, visible and ultra-violet.
*
* In the description field below,
* element 0 == P --> monochrome
* element 0 == X --> color
* element 9 == S --> sequential (i.e only one color here)
* element 9 == I --> interleaved (1 or more colors)
*/
int
get_imghdr(length)
int length;
{
struct Imghdr
{
long linewidth;
char dummy1[36];
char description[16]; /* Type of image */
} header;
if (pm_readbiglong (spotfile, &header.linewidth) == -1)
pm_error ("EOF / read error reading header");
#ifdef DEBUG
if (fread (header.dummy1, 1, 36, spotfile) != 36)
pm_error ("EOF / read error reading header");
#else
if (fseek (spotfile, 36, 1) == EOF)
pm_error ("seek error");
#endif
if (fread (header.description, 1, 16, spotfile) != 16)
pm_error ("EOF / read error reading header");
/* Determine mono or colour */
if (header.description[0] == 'X' && header.description[9] == 'S')
Colbool = 1;
else Colbool = 0;
#ifdef DEBUG
fprintf(stderr, "Dummy str is >%s<\n", header.dummy1);
fprintf(stderr, "Imghdr str is >%s<, col %d\n", header.description, Colbool);
#endif
/* Return the amount to fseek */
return (length - 56);
}
usage()
{
fprintf(stderr,
"Usage: spottopgm [-1|2|3] [Firstcol Firstline Lastcol Lastline] input_file\n");
exit(1);
}
int
main(argc, argv)
int argc;
char *argv[];
{
struct Record /* A SPOT image is broken up into */
{ /* records with the following fields */
long record; /* The record number (1, 2, 3...) */
unsigned char sub1; /* Record sub type 1 */
unsigned char type; /* The record type */
unsigned char sub2; /* Record sub type 2 */
unsigned char sub3; /* Record sub type 3 */
long length; /* Record length in bytes */
} arecord;
pgm_init( &argc, argv );
switch (argc)
{
case 7:
Color= -(atoi(argv[1])); /* Get the color to extract */
argv++;
case 6:
Firstcol = atoi(argv[1]); /* Get the rectangle to extract */
Firstline = atoi(argv[2]);
Lastcol = atoi(argv[3]);
Lastline = atoi(argv[4]);
argv += 4;
goto openfile; /* Yuk, a goto! */
case 3:
Color= -(atoi(argv[1])); /* Get the color to extract */
argv++;
case 2:
openfile:
spotfile = fopen(argv[1], "r"); /* Open the input file */
if (spotfile == NULL) { perror("fopen"); exit(1); }
break;
default:
usage();
}
#if defined (atarist) && defined (__MBASE__)
linebuf = (char *) pm_allocrow (12000, sizeof (char));
#endif
while (1) /* Get a record */
{
if (pm_readbiglong (spotfile, &arecord.record) == -1)
break;
arecord.sub1 = fgetc (spotfile);
arecord.type = fgetc (spotfile);
arecord.sub2 = fgetc (spotfile);
arecord.sub3 = fgetc (spotfile);
if (pm_readbiglong (spotfile, &arecord.length) == -1)
pm_error ("EOF / read error reading a record");
arecord.length -= 12; /* Subtract header size as well */
if (arecord.type == 0355 && arecord.sub1 == 0355)
arecord.length = get_image(arecord.length);
else if (arecord.type == 0300 && arecord.sub1 == 077)
arecord.length = get_imghdr(arecord.length);
#ifdef DEBUG
else
fprintf(stderr, "Rcrd %3d, type %03o, stype %03o %03o %03o, length %d\n",
arecord.record, arecord.type, arecord.sub1, arecord.sub2,
(int) arecord.sub3 & 0xff, arecord.length);
#endif
/* Seek to next record */
fseek(spotfile, arecord.length, 1);
}
exit (0);
}