updates
This commit is contained in:
293
src/amscimglib4/amscimglib4_bitmap.c
Normal file
293
src/amscimglib4/amscimglib4_bitmap.c
Normal file
@ -0,0 +1,293 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <amscimglib4/amscimglib4.h>
|
||||
#include <amscimglib4/amscimglib4_intl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct amscimglib4_bitmapfileheader
|
||||
{
|
||||
unsigned char magic[2]; //2 bytes 'BM', 'BA', 'CI', 'CP', 'IC', or 'PT'
|
||||
unsigned int bmpsize; //4 bytes (32 bit)
|
||||
unsigned short res1, res2; //2 and 2 bytes
|
||||
unsigned int pixeloff; //4 bytes - starting address where pixel array can be found
|
||||
} amscimglib4_bitmapfileheader;
|
||||
|
||||
typedef struct amscimglib4_bitmapinfoheader
|
||||
{
|
||||
//conventional NT version windows bitmap info header
|
||||
unsigned int headersize; //4 bytes, offset 14 (40 bytes for NT BITMAPINFOHEADER)
|
||||
int width; //4. offset 18 - (signed! can be negative)
|
||||
int height; //4 offset 22
|
||||
unsigned short colorplanes; //2 bytes = must be 1
|
||||
unsigned short bitsperpixel; //2 bytes {1, 4, 8, 16, 24, and 32}
|
||||
unsigned int compressionmethod; //4 bytes
|
||||
//0 - BI_RGB - the only one I'll be supporting...
|
||||
//1 - BI_RLE8
|
||||
//2 - BI_RLE4
|
||||
//3 - BI_BITFIELDS
|
||||
//4 - BI_JPEG
|
||||
//5 - BI_PNG
|
||||
//6 - BI_ALPHABITFIELDS
|
||||
//7 - BI_CMYK
|
||||
//8 - BI_CMYKRLE8
|
||||
//9 - BI_CMYKRLE4
|
||||
unsigned int imsz; //4 - image size. dummy of 0 given for BI_RGB bitmaps
|
||||
int hrez; //4 - horizontal resolution (pixel per meter) [I'll use a default of 3780 for each]
|
||||
int vrez; //4 - vertical resolution of image (pixel per meter, signed int)
|
||||
unsigned int colpallette; //4 - 0, or default to 2^N
|
||||
unsigned int ignore; //4 not really used
|
||||
} amscimglib4_bitmapinfoheader;
|
||||
|
||||
//bits for bitmap pixels are stored in packed rows. The size of each row is rounded up to a multiple of 4 bytes.
|
||||
//rowsize in bytes: rowsize = floor((bitsperpixel*imagewidth+31)/32)*4;
|
||||
|
||||
void amscimglib4_printheader(amscimglib4_bitmapfileheader *filehead, amscimglib4_bitmapinfoheader *infohead)
|
||||
{
|
||||
printf("magic: %c%c\n", filehead->magic[0],filehead->magic[1]);
|
||||
printf("bmpsize: %d\n", filehead->bmpsize);
|
||||
printf("res1: %d\n", filehead->res1);
|
||||
printf("res2: %d\n", filehead->res2);
|
||||
printf("pixel offset: %d\n", filehead->pixeloff);
|
||||
printf("\n");
|
||||
printf("header size: %d\n", infohead->headersize);
|
||||
printf("width: %d\n", infohead->width);
|
||||
printf("height: %d\n", infohead->height);
|
||||
printf("colorplanes: %d\n", infohead->colorplanes);
|
||||
printf("bitsperpixel: %d\n", infohead->bitsperpixel);
|
||||
printf("compressionmethod: %d\n", infohead->compressionmethod);
|
||||
printf("imsz: %d\n", infohead->imsz);
|
||||
printf("horizontal rez: %d\n",infohead->hrez);
|
||||
printf("vertical rez: %d\n",infohead->vrez);
|
||||
printf("color pallette: %d\n",infohead->colpallette);
|
||||
printf("ignore: %d\n", infohead->ignore);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void amscimglib4_readimage_bmp(const char *fname, amscimglib4_image *img)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
int I,J;
|
||||
unsigned int sz;
|
||||
|
||||
amscimglib4_bitmapfileheader bmpfilehead;
|
||||
amscimglib4_bitmapinfoheader bmpinfohead;
|
||||
|
||||
fp = fopen(fname,"rb");
|
||||
sz = amscimglib4_filesize(fp);
|
||||
if(fp==NULL)
|
||||
{
|
||||
printf("amscimglib4_readimage_bmp: %s cannot be opened!\n",fname);
|
||||
}
|
||||
else
|
||||
{
|
||||
fread(bmpfilehead.magic, 2, 1, fp);
|
||||
if(!(bmpfilehead.magic[0]=='B' && bmpfilehead.magic[1]=='M') || sz<54)
|
||||
{
|
||||
printf("amscimglib4_readimage_bmp: %s has file-signature %c%c. Not a bitmap (BM)...\n",fname,bmpfilehead.magic[0],bmpfilehead.magic[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fread(&(bmpfilehead.bmpsize),4,1,fp);
|
||||
fread(&(bmpfilehead.res1),2,1,fp);
|
||||
fread(&(bmpfilehead.res2),2,1,fp);
|
||||
fread(&(bmpfilehead.pixeloff),4,1,fp);
|
||||
|
||||
fread(&(bmpinfohead.headersize),4,1,fp);
|
||||
fread(&(bmpinfohead.width),4,1,fp);
|
||||
fread(&(bmpinfohead.height),4,1,fp);
|
||||
fread(&(bmpinfohead.colorplanes),2,1,fp);
|
||||
fread(&(bmpinfohead.bitsperpixel),2,1,fp);
|
||||
fread(&(bmpinfohead.compressionmethod),4,1,fp);
|
||||
fread(&(bmpinfohead.imsz),4,1,fp);
|
||||
fread(&(bmpinfohead.hrez),4,1,fp);
|
||||
fread(&(bmpinfohead.vrez),4,1,fp);
|
||||
fread(&(bmpinfohead.colpallette),4,1,fp);
|
||||
fread(&(bmpinfohead.ignore),4,1,fp);
|
||||
|
||||
//_DEBUG
|
||||
//amscimglib4_printheader(&bmpfilehead,&bmpinfohead); //show bitmap information
|
||||
|
||||
if(bmpinfohead.colorplanes!=1)
|
||||
{
|
||||
printf("amscimglib4_readimage_bmp: error! non-standard colorplane number %d\n",bmpinfohead.colorplanes);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(bmpinfohead.compressionmethod != 0)
|
||||
{
|
||||
printf("amscimglib4_readimage_bmp: %s is not an RGB bitmap. amsimglib currently only handles RGB bitmaps...\n",fname);
|
||||
}
|
||||
else
|
||||
{
|
||||
//begin loading the image
|
||||
unsigned char *buffer = NULL;
|
||||
|
||||
int rowsize;
|
||||
unsigned int bpp = bmpinfohead.bitsperpixel;
|
||||
unsigned char R,G,B,A;
|
||||
fseek(fp,bmpfilehead.pixeloff,SEEK_SET);
|
||||
amscimglib4_image_resize(img,abs(bmpinfohead.width),abs(bmpinfohead.height));
|
||||
|
||||
rowsize = (bpp*abs(bmpinfohead.width)+31)/32;
|
||||
rowsize = rowsize*4;
|
||||
|
||||
//printf("rowsize = %d, width = %d\n", rowsize, bmpinfohead.width);
|
||||
|
||||
buffer = (unsigned char *) malloc(rowsize);
|
||||
for(I=0;I<img->sizey;I++)
|
||||
{
|
||||
fread(buffer,rowsize,1,fp);
|
||||
//handle the buffer:
|
||||
for(J=0;J<img->sizex;J++)
|
||||
{
|
||||
if(bpp==8)
|
||||
{
|
||||
R = buffer[J*bpp/8+0];
|
||||
G = buffer[J*bpp/8+0];
|
||||
B = buffer[J*bpp/8+0];
|
||||
A = 255;
|
||||
}
|
||||
else if(bpp==24)
|
||||
{ //BGR order
|
||||
R = buffer[J*bpp/8+2];
|
||||
G = buffer[J*bpp/8+1];
|
||||
B = buffer[J*bpp/8+0];
|
||||
A = 255;
|
||||
}
|
||||
else if(bpp==32)
|
||||
{ //BGRA order? I've never seen one of these in the wild, so I don't know...
|
||||
R = buffer[J*bpp/8+2];
|
||||
G = buffer[J*bpp/8+1];
|
||||
B = buffer[J*bpp/8+0];
|
||||
A = buffer[J*bpp/8+3];
|
||||
}
|
||||
else
|
||||
{
|
||||
R = 0; G = 0; B = 0; A = 0;
|
||||
}
|
||||
amscimglib4_set_pixel_RGBA(img,J,I,R,G,B,A);
|
||||
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
|
||||
if(bmpinfohead.width*bmpinfohead.hrez < 0)
|
||||
amscimglib4_image_flipx(img);
|
||||
if(bmpinfohead.height*bmpinfohead.vrez > 0)
|
||||
amscimglib4_image_flipy(img);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void amscimglib4_writeimage_bmp(const char *fname, amscimglib4_image *img)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
|
||||
// if(img->sizex>0&&img->sizey>0) //do not write zero size images
|
||||
// {
|
||||
|
||||
fp = fopen(fname,"wb");
|
||||
if(fp==NULL)
|
||||
{
|
||||
printf("amscimglib4_writeimage_bmp: %s could not be opened!\n",fname);
|
||||
}
|
||||
else
|
||||
{
|
||||
int I,J;
|
||||
amscimglib4_bitmapfileheader bmpfilehead;
|
||||
amscimglib4_bitmapinfoheader bmpinfohead;
|
||||
int bpp = 24;
|
||||
int rowsize;
|
||||
unsigned char R,B,G,A;
|
||||
|
||||
unsigned char *buffer;
|
||||
|
||||
rowsize = (bpp*img->sizex+31)/32;
|
||||
rowsize = rowsize*4;
|
||||
|
||||
if(img->sizex>0&&img->sizey>0)
|
||||
{
|
||||
bmpfilehead.magic[0] = 'B';
|
||||
bmpfilehead.magic[1] = 'M';
|
||||
bmpfilehead.bmpsize = 54+rowsize*img->sizey;
|
||||
bmpfilehead.res1 = 0;
|
||||
bmpfilehead.res2 = 0;
|
||||
bmpfilehead.pixeloff = 54;
|
||||
|
||||
fwrite(bmpfilehead.magic,2,1,fp);
|
||||
fwrite(&(bmpfilehead.bmpsize),4,1,fp);
|
||||
fwrite(&(bmpfilehead.res1),2,1,fp);
|
||||
fwrite(&(bmpfilehead.res2),2,1,fp);
|
||||
fwrite(&(bmpfilehead.pixeloff),4,1,fp);
|
||||
|
||||
bmpinfohead.headersize = 40;
|
||||
fwrite(&(bmpinfohead.headersize),4,1,fp);
|
||||
bmpinfohead.width = img->sizex;
|
||||
fwrite(&(bmpinfohead.width),4,1,fp);
|
||||
bmpinfohead.height = img->sizey;
|
||||
fwrite(&(bmpinfohead.height),4,1,fp);
|
||||
bmpinfohead.colorplanes = 1;
|
||||
fwrite(&(bmpinfohead.colorplanes),2,1,fp);
|
||||
bmpinfohead.bitsperpixel = 24;
|
||||
fwrite(&(bmpinfohead.bitsperpixel),2,1,fp);
|
||||
bmpinfohead.compressionmethod = 0;
|
||||
fwrite(&(bmpinfohead.compressionmethod),4,1,fp);
|
||||
bmpinfohead.imsz = 0;
|
||||
fwrite(&(bmpinfohead.imsz),4,1,fp);
|
||||
bmpinfohead.hrez = 3780;
|
||||
fwrite(&(bmpinfohead.hrez),4,1,fp);
|
||||
bmpinfohead.vrez = 3780;
|
||||
fwrite(&(bmpinfohead.vrez),4,1,fp);
|
||||
bmpinfohead.colpallette = 0;
|
||||
fwrite(&(bmpinfohead.colpallette),4,1,fp);
|
||||
bmpinfohead.ignore = 0;
|
||||
fwrite(&(bmpinfohead.ignore),4,1,fp);
|
||||
|
||||
buffer = (unsigned char *) malloc(rowsize);
|
||||
for(I=0;I<rowsize;I++) buffer[I] = 0;
|
||||
|
||||
//begin writing out the image file
|
||||
for(I=0;I<img->sizey;I++)
|
||||
{
|
||||
for(J=0;J<img->sizex;J++)
|
||||
{
|
||||
//amscimglib4_get_pixel_RGBA(img,J,img->sizey-I-1,&R,&G,&B,&A); //go from bottom to top
|
||||
R = img->data[4*(J + img->sizex*(img->sizey-I-1)) + 0];
|
||||
G = img->data[4*(J + img->sizex*(img->sizey-I-1)) + 1];
|
||||
B = img->data[4*(J + img->sizex*(img->sizey-I-1)) + 2];
|
||||
|
||||
buffer[J*bpp/8+0] = B;
|
||||
buffer[J*bpp/8+1] = G;
|
||||
buffer[J*bpp/8+2] = R;
|
||||
}
|
||||
|
||||
fwrite(buffer,rowsize,1,fp);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
// } //do not write zero size images
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; //end extern "C"
|
||||
#endif
|
320
src/amscimglib4/amscimglib4_image.c
Normal file
320
src/amscimglib4/amscimglib4_image.c
Normal file
@ -0,0 +1,320 @@
|
||||
#include <amscimglib4/amscimglib4.h>
|
||||
#include <amscimglib4/amscimglib4_intl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
AMSCIMGLIB4_API int amscimglib4_image_new(amscimglib4_image **imgptr, int _sizex, int _sizey)
|
||||
{
|
||||
int ret = amscimglib4_success;
|
||||
int res;
|
||||
|
||||
if(imgptr==NULL)
|
||||
{
|
||||
ret = amscimglib4_failure;
|
||||
return ret;
|
||||
}
|
||||
if(*imgptr!=NULL)
|
||||
{
|
||||
res = amscimglib4_image_delete(imgptr);
|
||||
if(*imgptr!=NULL || res==amscimglib4_failure)
|
||||
{
|
||||
ret = amscimglib4_failure;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
*imgptr = (amscimglib4_image*) malloc(sizeof(amscimglib4_image));
|
||||
if(*imgptr==NULL)
|
||||
{
|
||||
ret = amscimglib4_failure;
|
||||
return ret;
|
||||
}
|
||||
(*imgptr)->sizex = 0;
|
||||
(*imgptr)->sizey = 0;
|
||||
(*imgptr)->data = NULL;
|
||||
|
||||
res = amscimglib4_image_resize(*imgptr,_sizex,_sizey);
|
||||
if(res==amscimglib4_failure)
|
||||
{
|
||||
ret = amscimglib4_failure;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
AMSCIMGLIB4_API int amscimglib4_image_delete(amscimglib4_image **imgptr)
|
||||
{
|
||||
int ret = amscimglib4_success;
|
||||
amscimglib4_image* lptr;
|
||||
|
||||
if(imgptr==NULL)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if(*imgptr==NULL)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
lptr = *imgptr;
|
||||
|
||||
if(lptr->data!=NULL)
|
||||
{
|
||||
free(lptr->data);
|
||||
lptr->data=NULL;
|
||||
}
|
||||
|
||||
lptr->sizex = 0;
|
||||
lptr->sizey = 0;
|
||||
|
||||
free(*imgptr);
|
||||
*imgptr = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
AMSCIMGLIB4_API int amscimglib4_image_resize(amscimglib4_image *imgptr, int _sizex, int _sizey)
|
||||
{
|
||||
int ret = amscimglib4_success;
|
||||
unsigned char *newdata = NULL;
|
||||
int I,J,K;
|
||||
|
||||
if(imgptr==NULL)
|
||||
{
|
||||
return amscimglib4_failure;
|
||||
}
|
||||
|
||||
newdata = (unsigned char*) malloc(sizeof(char)*4*_sizex*_sizey);
|
||||
if(newdata==NULL)
|
||||
{
|
||||
return amscimglib4_failure;
|
||||
}
|
||||
|
||||
for(K=0;K<4;K++)
|
||||
for(I=0;I<_sizex;I++)
|
||||
for(J=0;J<_sizey;J++)
|
||||
newdata[4*(I+_sizex*J)+K] = 0;
|
||||
|
||||
if(imgptr->data!=NULL)
|
||||
{
|
||||
for(K=0;K<4;K++)
|
||||
for(I=0;I<_sizex && I<imgptr->sizex;I++)
|
||||
for(J=0;J<_sizey && J<imgptr->sizey;J++)
|
||||
newdata[4*(I+_sizex*J)+K] = imgptr->data[4*(I+_sizex*J)+K];
|
||||
}
|
||||
|
||||
free(imgptr->data);
|
||||
imgptr->data = newdata;
|
||||
imgptr->sizex = _sizex;
|
||||
imgptr->sizey = _sizey;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//sets all pixels in the image to (0,0,0,0)
|
||||
AMSCIMGLIB4_API void amscimglib4_image_clear(amscimglib4_image *imgptr)
|
||||
{
|
||||
int I,J,K;
|
||||
|
||||
if(imgptr == NULL) return;
|
||||
|
||||
if(imgptr->data!=NULL)
|
||||
{
|
||||
for(K=0;K<4;K++)
|
||||
for(I=0;I<imgptr->sizex;I++)
|
||||
for(J=0;J<imgptr->sizey;J++)
|
||||
imgptr->data[4*(I+imgptr->sizex*J)+K] = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//copies an image from one image struct to another
|
||||
//resizes imgto
|
||||
AMSCIMGLIB4_API int amscimglib4_image_copy(amscimglib4_image *imgto, const amscimglib4_image *imgfrom)
|
||||
{
|
||||
int ret = amscimglib4_success;
|
||||
int res;
|
||||
int I,J,K;
|
||||
|
||||
res = amscimglib4_image_resize(imgto,imgfrom->sizex,imgfrom->sizey);
|
||||
if(res==amscimglib4_failure)
|
||||
{
|
||||
ret = amscimglib4_failure;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(imgfrom->data!=NULL && imgto->data!=NULL)
|
||||
{
|
||||
for(K=0;K<4;K++)
|
||||
for(I=0;I<imgto->sizex;I++)
|
||||
for(J=0;J<imgto->sizey;J++)
|
||||
imgto->data[4*(I+imgto->sizex*J)+K] = imgfrom->data[4*(I+imgfrom->sizex*J)+K];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//transposes an image
|
||||
AMSCIMGLIB4_API int amscimglib4_transpose_image(amscimglib4_image *img)
|
||||
{
|
||||
int ret = amscimglib4_success;
|
||||
int res;
|
||||
amscimglib4_image *img2 = NULL;
|
||||
int I,J,K;
|
||||
|
||||
if(img==NULL)
|
||||
{
|
||||
ret = amscimglib4_failure;
|
||||
return ret;
|
||||
}
|
||||
|
||||
res = amscimglib4_image_new(&img2,img->sizex,img->sizey);
|
||||
if(res==amscimglib4_failure)
|
||||
{
|
||||
ret = amscimglib4_failure;
|
||||
return ret;
|
||||
}
|
||||
|
||||
amscimglib4_image_copy(img2,img);
|
||||
res = amscimglib4_image_resize(img,img2->sizey,img2->sizex);
|
||||
if(res==amscimglib4_failure || img->sizex != img2->sizey || img->sizey != img2->sizex)
|
||||
{
|
||||
ret = amscimglib4_failure;
|
||||
amscimglib4_image_delete(&img2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for(K=0;K<4;K++)
|
||||
for(I=0;I<img->sizex;I++)
|
||||
for(J=0;J<img->sizey;J++)
|
||||
img->data[4*(I+img->sizex*J)+K] = img2->data[4*(J+img2->sizex*I)+K];
|
||||
|
||||
amscimglib4_image_delete(&img2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AMSCIMGLIB4_API int amscimglib4_set_pixel_RGBA(amscimglib4_image *img, int x, int y,
|
||||
unsigned char R, unsigned char G, unsigned char B, unsigned char A)
|
||||
{
|
||||
int ret = amscimglib4_success;
|
||||
if(img==NULL)
|
||||
{
|
||||
ret = amscimglib4_failure;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(x<0 || y<0 || x>=img->sizex || y>=img->sizey)
|
||||
{
|
||||
ret = amscimglib4_failure;
|
||||
return ret;
|
||||
}
|
||||
|
||||
img->data[4*(x+img->sizex*y)+0] = R;
|
||||
img->data[4*(x+img->sizex*y)+1] = G;
|
||||
img->data[4*(x+img->sizex*y)+2] = B;
|
||||
img->data[4*(x+img->sizex*y)+3] = A;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AMSCIMGLIB4_API int amscimglib4_get_pixel_RGBA(amscimglib4_image *img, int x, int y,
|
||||
unsigned char *R, unsigned char *G, unsigned char *B, unsigned char *A)
|
||||
{
|
||||
int ret = amscimglib4_success;
|
||||
|
||||
if(img==NULL)
|
||||
{
|
||||
ret = amscimglib4_failure;
|
||||
if(R!=NULL) *R = 0;
|
||||
if(G!=NULL) *G = 0;
|
||||
if(B!=NULL) *B = 0;
|
||||
if(A!=NULL) *A = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(x<0 || y<0 || x>=img->sizex || y>=img->sizey)
|
||||
{
|
||||
ret = amscimglib4_failure;
|
||||
if(R!=NULL) *R = 0;
|
||||
if(G!=NULL) *G = 0;
|
||||
if(B!=NULL) *B = 0;
|
||||
if(A!=NULL) *A = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(R!=NULL) *R = img->data[4*(x+img->sizex*y)+0];
|
||||
if(G!=NULL) *G = img->data[4*(x+img->sizex*y)+1];
|
||||
if(B!=NULL) *B = img->data[4*(x+img->sizex*y)+2];
|
||||
if(A!=NULL) *A = img->data[4*(x+img->sizex*y)+3];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AMSCIMGLIB4_API int amscimglib4_set_pixel(amscimglib4_image *img, int x, int y,
|
||||
const amscimglib4_pixel px)
|
||||
{
|
||||
int ret = amscimglib4_set_pixel_RGBA(img,x,y,px.R,px.G,px.B,px.A);
|
||||
return ret;
|
||||
}
|
||||
|
||||
AMSCIMGLIB4_API int amscimglib4_get_pixel(amscimglib4_image *img, int x, int y,
|
||||
amscimglib4_pixel *px)
|
||||
{
|
||||
int ret;
|
||||
if(px==NULL) return amscimglib4_failure;
|
||||
ret = amscimglib4_get_pixel_RGBA(img,x,y,&(px->R),&(px->G),&(px->B),&(px->A));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
AMSCIMGLIB4_API void amscimglib4_image_flipx(amscimglib4_image *img)
|
||||
{
|
||||
amscimglib4_image *img2 = NULL;
|
||||
if(img==NULL) return;
|
||||
int I,J,K;
|
||||
|
||||
amscimglib4_image_new(&img2,img->sizex,img->sizey);
|
||||
amscimglib4_image_copy(img2,img);
|
||||
|
||||
for(K=0;K<4;K++)
|
||||
for(I=0;I<img->sizex;I++)
|
||||
for(J=0;J<img->sizey;J++)
|
||||
img->data[4*(I+img->sizex*J)+K] = img2->data[4*((img2->sizex-I-1)+img2->sizex*J)+K];
|
||||
|
||||
amscimglib4_image_delete(&img2);
|
||||
return;
|
||||
}
|
||||
|
||||
AMSCIMGLIB4_API void amscimglib4_image_flipy(amscimglib4_image *img)
|
||||
{
|
||||
amscimglib4_image *img2 = NULL;
|
||||
if(img==NULL) return;
|
||||
int I,J,K;
|
||||
|
||||
amscimglib4_image_new(&img2,img->sizex,img->sizey);
|
||||
amscimglib4_image_copy(img2,img);
|
||||
|
||||
for(K=0;K<4;K++)
|
||||
for(I=0;I<img->sizex;I++)
|
||||
for(J=0;J<img->sizey;J++)
|
||||
img->data[4*(I+img->sizex*J)+K] = img2->data[4*(I+img2->sizex*(img2->sizey-J-1))+K];
|
||||
|
||||
amscimglib4_image_delete(&img2);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; //end extern "C"
|
||||
#endif
|
223
src/amscimglib4/amscimglib4_jpeg.c
Normal file
223
src/amscimglib4/amscimglib4_jpeg.c
Normal file
@ -0,0 +1,223 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <jpeglib.h>
|
||||
#include <jerror.h>
|
||||
|
||||
#include <amscimglib4/amscimglib4.h>
|
||||
#include <amscimglib4/amscimglib4_intl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void amscimglib4_readimage_jpeg(const char *fname, amscimglib4_image *img)
|
||||
{
|
||||
|
||||
int rc, i, j;
|
||||
|
||||
FILE *fp = NULL; //the file pointer
|
||||
|
||||
//variables for the decompressor
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
|
||||
int row_stride, X, Y, pixsz;
|
||||
unsigned char *jpg_buffer;
|
||||
unsigned char *rowptr[1];
|
||||
|
||||
amscimglib4_pixel px;
|
||||
|
||||
int I,J;
|
||||
|
||||
//load the jpeg data from a file into a memory buffer
|
||||
fp = fopen(fname,"rb");
|
||||
if(fp!=NULL)
|
||||
{
|
||||
|
||||
|
||||
//begin processing the jpeg
|
||||
|
||||
//allocate a decompress struct with the default error handler
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
//configure this decompressor to read data from the file stream
|
||||
jpeg_stdio_src(&cinfo,fp);
|
||||
|
||||
rc = jpeg_read_header(&cinfo, TRUE);
|
||||
if(rc!=1)
|
||||
{
|
||||
printf("amscimglib4_readimg_jpg: Error! %s not a normal JPEG.\n", fname);
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
X = cinfo.output_width;
|
||||
Y = cinfo.output_height;
|
||||
pixsz = cinfo.output_components;
|
||||
row_stride = X*pixsz;
|
||||
|
||||
|
||||
|
||||
amscimglib4_image_resize(img,X,Y);
|
||||
//amscimglib4_delete_image(img);
|
||||
//amscimglib4_new_image(img,X,Y);
|
||||
|
||||
//allocate buffer
|
||||
jpg_buffer = (unsigned char *) malloc(sizeof(unsigned char)*X*Y*pixsz);
|
||||
|
||||
//read the jpeg
|
||||
while(cinfo.output_scanline < cinfo.output_height)
|
||||
{
|
||||
rowptr[0] = jpg_buffer + cinfo.output_scanline*row_stride; //pointer to pointer to row
|
||||
jpeg_read_scanlines(&cinfo, rowptr, 1);
|
||||
}
|
||||
|
||||
//translate into my image format
|
||||
for(I=0;I<X;I++)
|
||||
{
|
||||
for(J=0;J<Y;J++)
|
||||
{
|
||||
if(pixsz == 1)
|
||||
{
|
||||
//greyscale
|
||||
px.R = jpg_buffer[(I+X*J)*pixsz+0];
|
||||
px.G = jpg_buffer[(I+X*J)*pixsz+0];
|
||||
px.B = jpg_buffer[(I+X*J)*pixsz+0];
|
||||
px.A = 255;
|
||||
amscimglib4_set_pixel(img,I,J,px);
|
||||
}
|
||||
else if(pixsz == 3)
|
||||
{
|
||||
//RGB - what I imagine most jpegs actually are
|
||||
|
||||
px.R = jpg_buffer[(I+X*J)*pixsz+0];
|
||||
px.G = jpg_buffer[(I+X*J)*pixsz+1];
|
||||
px.B = jpg_buffer[(I+X*J)*pixsz+2];
|
||||
px.A = 255;
|
||||
amscimglib4_set_pixel(img,I,J,px);
|
||||
}
|
||||
else if(pixsz == 4)
|
||||
{
|
||||
//RGBA? careful - might be CYMK?
|
||||
px.R = jpg_buffer[(I+X*J)*pixsz+0];
|
||||
px.G = jpg_buffer[(I+X*J)*pixsz+1];
|
||||
px.B = jpg_buffer[(I+X*J)*pixsz+2];
|
||||
px.A = jpg_buffer[(I+X*J)*pixsz+3];
|
||||
amscimglib4_set_pixel(img,I,J,px);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("amscimglib4_read_jpeg: Doesn't know how to handle pixel size of %d\n.",pixsz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//free the buffer
|
||||
free(jpg_buffer);
|
||||
|
||||
jpeg_finish_decompress(&cinfo); //cleans things up. lets you reuse the cinfo object
|
||||
jpeg_destroy_decompress(&cinfo); //free everything
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("amscimglib4_readimage_jpeg: Error! %s could not be opened!\n",fname);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void amscimglib4_writeimage_jpeg(const char *fname, amscimglib4_image *img, int quality)
|
||||
{
|
||||
int I,J;
|
||||
unsigned char *jpg_buffer; //points to a large array of RGBRGBRGB data
|
||||
int height = img->sizey;
|
||||
int width = img->sizex;
|
||||
FILE *fp = NULL;
|
||||
|
||||
unsigned char *row_pointer[1];
|
||||
int row_stride;
|
||||
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
|
||||
amscimglib4_pixel px;
|
||||
|
||||
//step 1 - allocate and initialize a JPEG compression object
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
//initialize the JPEG compression object
|
||||
jpeg_create_compress(&cinfo);
|
||||
//specify data destination (a file)
|
||||
fp = fopen(fname,"wb");
|
||||
if(fp==NULL)
|
||||
{
|
||||
printf("amscimglib4_writeimage_jpeg: Error! %s could not be opened!\n",fname);
|
||||
}
|
||||
else
|
||||
{
|
||||
jpeg_stdio_dest(&cinfo,fp);
|
||||
|
||||
//set up the input image description
|
||||
cinfo.image_width = width; //image width and height
|
||||
cinfo.image_height = height;
|
||||
cinfo.input_components = 3; //color components per pixel
|
||||
cinfo.in_color_space = JCS_RGB;
|
||||
|
||||
jpeg_set_defaults(&cinfo);
|
||||
jpeg_set_quality(&cinfo,quality,TRUE); //limit to baseline-JPEG values
|
||||
//quality ranges from 1 to 100
|
||||
jpeg_start_compress(&cinfo,TRUE); //true ensures we will write a complete JPEG file.
|
||||
|
||||
row_stride = width*3;
|
||||
|
||||
//allocate and translate the image buffer to an RGB bytebuffer
|
||||
jpg_buffer = (unsigned char *)malloc(sizeof(unsigned char)*width*height*3);
|
||||
for(I=0;I<img->sizex;I++)
|
||||
{
|
||||
for(J=0;J<img->sizey;J++)
|
||||
{
|
||||
amscimglib4_get_pixel(img,I,J,&px);
|
||||
|
||||
jpg_buffer[(I+J*img->sizex)*3+0] = px.R;
|
||||
jpg_buffer[(I+J*img->sizex)*3+1] = px.G;
|
||||
jpg_buffer[(I+J*img->sizex)*3+2] = px.B;
|
||||
}
|
||||
}
|
||||
|
||||
while(cinfo.next_scanline <cinfo.image_height)
|
||||
{
|
||||
//jpeg_write_scanlines expects an array of pointers to scanlines.
|
||||
row_pointer[0] = & jpg_buffer[cinfo.next_scanline*row_stride];
|
||||
//how can any of these jpeglib authors miss the fact they are passing a pointer? Why allocate one element when passing this pointer?
|
||||
jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
||||
}
|
||||
|
||||
//finish compression
|
||||
jpeg_finish_compress(&cinfo);
|
||||
//I think this concludes writing the file
|
||||
|
||||
free(jpg_buffer);
|
||||
fclose(fp);
|
||||
|
||||
//cleanup steps - frees memory
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; //end extern "C"
|
||||
#endif
|
141
src/amscimglib4/amscimglib4_png.c
Normal file
141
src/amscimglib4/amscimglib4_png.c
Normal file
@ -0,0 +1,141 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h> //includes memset?
|
||||
#include <png.h>
|
||||
|
||||
#include <amscimglib4/amscimglib4.h>
|
||||
#include <amscimglib4/amscimglib4_intl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* 1) Declare a 'png_image' structure (see below) on the stack, set the
|
||||
* version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL
|
||||
* (this is REQUIRED, your program may crash if you don't do it.)
|
||||
* 2) Call the appropriate png_image_begin_read... function.
|
||||
* 3) Set the png_image 'format' member to the required sample format.
|
||||
* 4) Allocate a buffer for the image and, if required, the color-map.
|
||||
* 5) Call png_image_finish_read to read the image and, if required, the
|
||||
* color-map into your buffers.
|
||||
|
||||
* To write a PNG file using the simplified API:
|
||||
*
|
||||
* 1) Declare a 'png_image' structure on the stack and memset() it to all zero.
|
||||
* 2) Initialize the members of the structure that describe the image, setting
|
||||
* the 'format' member to the format of the image samples.
|
||||
* 3) Call the appropriate png_image_write... function with a pointer to the
|
||||
* image and, if necessary, the color-map to write the PNG data.
|
||||
|
||||
*/
|
||||
|
||||
/* Initialize to NULL, free with png_image_free */
|
||||
|
||||
|
||||
|
||||
void amscimglib4_readimage_png(const char *fname, amscimglib4_image *img)
|
||||
{
|
||||
int I,J;
|
||||
//FILE *fp;
|
||||
png_image image; //the control structure used by libpng
|
||||
//png_image has height, width, format, flags...
|
||||
//
|
||||
//format = PNG_FORMAT_RGBA
|
||||
// PNG_FORMAT_
|
||||
memset(&image,0,sizeof(image)); //fills memory with zeros
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
|
||||
if(png_image_begin_read_from_file(&image, fname) != 0)
|
||||
{
|
||||
png_bytep buffer; //presumably this is a pointer to bytes
|
||||
unsigned char *bf2;
|
||||
int z;
|
||||
unsigned char R,G,B,A;
|
||||
//set the format in which to read the PNG file: This code chooses RGBA
|
||||
image.format = PNG_FORMAT_RGBA;
|
||||
buffer = (png_bytep) malloc(PNG_IMAGE_SIZE(image));
|
||||
if(buffer!=NULL &&
|
||||
png_image_finish_read(&image,
|
||||
NULL /*background*/,
|
||||
buffer,
|
||||
0 /*row stride*/,
|
||||
NULL /*colormap*/) != 0
|
||||
);
|
||||
{
|
||||
// the example code now uses a writing function to write it to another file
|
||||
//png_image_write_to_file(&image, fname, 0 /*convert_to_8bit*/, buffer, 0/*row_stride*/,NULL/*colormap*/)
|
||||
//I want to convert and translate the image into my struct
|
||||
|
||||
//this function must make some sort of assumption about the contents of the buffer? I might have to try to blit output to see what?
|
||||
// fp = fopen("testbufferoutput.csv","w+");
|
||||
// //assuming RGBARGBARGBA
|
||||
// for(I=0;I<image.width;I++)
|
||||
// {
|
||||
// for(J=0;J<image.height;J++)
|
||||
// {
|
||||
// bf2 = (unsigned char *)buffer;
|
||||
// z = (I+J*image.width)*4;
|
||||
// fprintf(fp,"%d,%d,%d,%d,",bf2[z+0],bf2[z+1],bf2[z+2],bf2[z+3]);
|
||||
// }
|
||||
// fprintf(fp,"\n");
|
||||
// }
|
||||
// fclose(fp);
|
||||
amscimglib4_image_resize(img,image.width,image.height);
|
||||
bf2 = (unsigned char *) buffer;
|
||||
for(I=0;I<image.width;I++)
|
||||
{
|
||||
for(J=0;J<image.height;J++)
|
||||
{
|
||||
z = (I+J*image.width)*4;
|
||||
R = bf2[z+0];
|
||||
G = bf2[z+1];
|
||||
B = bf2[z+2];
|
||||
A = bf2[z+3];
|
||||
amscimglib4_set_pixel_RGBA(img,I,J,R,G,B,A);
|
||||
}
|
||||
}
|
||||
|
||||
//clean up
|
||||
png_image_free(&image);
|
||||
free(buffer);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//something went wrong?
|
||||
printf("readimage_png: error: %s\n", image.message);
|
||||
amscimglib4_image_resize(img,0,0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void amscimglib4_writeimage_png(const char *fname, amscimglib4_image *img)
|
||||
{
|
||||
png_image image;
|
||||
|
||||
unsigned char *bb2 = NULL;
|
||||
bb2 = (unsigned char*)malloc(img->sizex*img->sizey*4*sizeof(unsigned char));
|
||||
memcpy(bb2,img->data,img->sizex*img->sizey*4*sizeof(unsigned char));
|
||||
|
||||
memset(&image,0,sizeof(image)); //fills memory with zeros
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
image.format = PNG_FORMAT_RGBA;
|
||||
image.width = img->sizex;
|
||||
image.height = img->sizey;
|
||||
|
||||
png_image_write_to_file(&image, fname, 0 /*convert_to_8bit*/, (png_bytep) bb2, 0/*row_stride*/,NULL/*colormap*/);
|
||||
|
||||
free(bb2); //weird - png-writer causes memory leaks if {I operate directly on img->bytebuf
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; //end extern "C"
|
||||
#endif
|
@ -1,12 +0,0 @@
|
||||
#include <amscimglib4/amscimglib4.h>
|
||||
#include <amscimglib4/amscimglib4_intl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; //end extern "C"
|
||||
#endif
|
20
src/amscimglib4/amscimglib4_util.c
Normal file
20
src/amscimglib4/amscimglib4_util.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include <amscimglib4/amscimglib4.h>
|
||||
#include <amscimglib4/amscimglib4_intl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//returns the size of a file using ANSI C
|
||||
unsigned int amscimglib4_filesize(FILE *fp)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
fseek(fp,0L,SEEK_END);
|
||||
ret = ftell(fp); //find the size of the file
|
||||
fseek(fp,0L,SEEK_SET);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; //end extern "C"
|
||||
#endif
|
@ -1,12 +0,0 @@
|
||||
#include <amscimglib4/amscimglib4.h>
|
||||
#include <amscimglib4/amscimglib4_intl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; //end extern "C"
|
||||
#endif
|
Reference in New Issue
Block a user