1
0
Fork 0
sattools/src/jpgstack.c

204 lines
4.4 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
#include <math.h>
#include <cpgplot.h>
#define NMAX 1024
struct image
{
int nx, ny, nz;
float *z;
};
struct image read_jpg (char *filename);
void write_jpg (char *filename, struct image img);
int
main (int argc, char *argv[])
{
int i, j, flag, n;
struct image avg, max, raw;
for (flag = 0, i = 1, n = 0; i < argc; i++, n++)
{
printf ("%d %s\n", i, argv[i]);
// Read image
raw = read_jpg (argv[i]);
// If first image, initialize
if (flag == 0)
{
avg.nx = raw.nx;
avg.ny = raw.ny;
avg.nz = raw.nz;
avg.z =
(float *) malloc (sizeof (float) * avg.nx * avg.ny * avg.nz);
for (j = 0; j < avg.nx * avg.ny * avg.nz; j++)
avg.z[j] = 0.0;
max.nx = raw.nx;
max.ny = raw.ny;
max.nz = raw.nz;
max.z =
(float *) malloc (sizeof (float) * max.nx * max.ny * max.nz);
for (j = 0; j < max.nx * max.ny * max.nz; j++)
max.z[j] = 0.0;
flag = 1;
}
// Add values
for (j = 0; j < avg.nx * avg.ny * avg.nz; j++)
avg.z[j] += raw.z[j];
// Add values
for (j = 0; j < avg.nx * avg.ny * avg.nz; j++)
if (raw.z[j] > max.z[j])
max.z[j] = raw.z[j];
// Free
free (raw.z);
}
// Average;
for (j = 0; j < avg.nx * avg.ny * avg.nz; j++)
avg.z[j] /= (float) n;
// Write
write_jpg ("average.jpg", avg);
write_jpg ("maximum.jpg", max);
// Free
free (avg.z);
free (max.z);
return 0;
}
struct image
read_jpg (char *filename)
{
int i = 0, j, k, l, m;
unsigned long location = 0;
struct image img;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
unsigned char *raw_image = NULL;
FILE *file;
// Open file
file = fopen (filename, "rb");
if (!file)
perror ("Error opening file");
// Get header info, decompress
cinfo.err = jpeg_std_error (&jerr);
jpeg_create_decompress (&cinfo);
jpeg_stdio_src (&cinfo, file);
jpeg_read_header (&cinfo, TRUE);
jpeg_start_decompress (&cinfo);
// Allocate memory
raw_image =
(unsigned char *) malloc (cinfo.output_width * cinfo.output_height *
cinfo.num_components);
// Read image, one scan at a time
row_pointer[0] =
(unsigned char *) malloc (cinfo.output_width * cinfo.num_components);
while (cinfo.output_scanline < cinfo.image_height)
{
jpeg_read_scanlines (&cinfo, row_pointer, 1);
for (i = 0; i < cinfo.image_width * cinfo.num_components; i++)
raw_image[location++] = row_pointer[0][i];
}
// wrap up decompression, destroy objects, free pointers and close open files
jpeg_finish_decompress (&cinfo);
jpeg_destroy_decompress (&cinfo);
// Copy image to image struct
img.nx = cinfo.image_width;
img.ny = cinfo.image_height;
img.nz = cinfo.num_components;
img.z = (float *) malloc (sizeof (float) * img.nx * img.ny * img.nz);
// Fill image
for (i = 0; i < img.nx; i++)
{
for (j = 0; j < img.ny; j++)
{
for (k = 0; k < img.nz; k++)
{
l = img.nz * (i + img.nx * j) + k;
img.z[l] = (float) raw_image[l];
}
}
}
// Free allocated memory
free (row_pointer[0]);
free (raw_image);
// Close file
fclose (file);
return img;
}
// Write jpg
void
write_jpg (char *filename, struct image img)
{
int i, j, k, l, m;
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
FILE *outfile;
unsigned char *raw_image = NULL;
outfile = fopen (filename, "wb");
cinfo.err = jpeg_std_error (&jerr);
jpeg_create_compress (&cinfo);
jpeg_stdio_dest (&cinfo, outfile);
cinfo.image_width = img.nx;
cinfo.image_height = img.ny;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults (&cinfo);
jpeg_start_compress (&cinfo, TRUE);
// Allocate memory
raw_image =
(unsigned char *) malloc (cinfo.image_width * cinfo.image_height *
cinfo.input_components);
// Fill image
for (i = 0; i < img.nx; i++)
{
for (j = 0; j < img.ny; j++)
{
for (k = 0; k < img.nz; k++)
{
l = img.nz * (i + img.nx * j) + k;
raw_image[l] = (unsigned char) img.z[l];
}
}
}
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] =
&raw_image[cinfo.next_scanline * cinfo.image_width *
cinfo.input_components];
jpeg_write_scanlines (&cinfo, row_pointer, 1);
}
jpeg_finish_compress (&cinfo);
jpeg_destroy_compress (&cinfo);
fclose (outfile);
return;
}