2019-03-03 16:22:55 +01:00
|
|
|
/*
|
|
|
|
* fimg-core.c
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include "string.h"
|
|
|
|
|
|
|
|
#include "../floatimg.h"
|
|
|
|
|
|
|
|
extern int verbosity; /* must be declared around main() */
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------- */
|
2019-08-07 11:55:29 +02:00
|
|
|
static int fimg_type_is_valid(int type)
|
2019-03-03 16:22:55 +01:00
|
|
|
{
|
2019-08-07 11:55:29 +02:00
|
|
|
switch (type) {
|
|
|
|
case FIMG_TYPE_GRAY:
|
|
|
|
case FIMG_TYPE_RGB:
|
|
|
|
case FIMG_TYPE_RGBA: return 1;
|
2019-03-03 16:22:55 +01:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
2019-09-10 12:18:02 +02:00
|
|
|
char *fimg_str_type(int type)
|
2019-08-07 11:55:29 +02:00
|
|
|
{
|
|
|
|
switch (type) {
|
|
|
|
case FIMG_TYPE_GRAY: return "gray";
|
|
|
|
case FIMG_TYPE_RGB: return "rgb";
|
|
|
|
case FIMG_TYPE_RGBA: return "rgba";
|
|
|
|
}
|
|
|
|
return "???";
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
2019-03-03 16:22:55 +01:00
|
|
|
int fimg_print_version(int k)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "*** FloatImg library, alpha v%d (%s, %s)\n",
|
|
|
|
FIMG_VERSION, __DATE__, __TIME__);
|
|
|
|
|
|
|
|
if (51 == k) {
|
|
|
|
puts("+--------------------+");
|
|
|
|
puts("| Pastis is coming. |");
|
|
|
|
puts("+--------------------+");
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
void fimg_printhead(FloatImg *h)
|
|
|
|
{
|
|
|
|
printf("%5d %5d %2d %p %p %p %p\n", h->width, h->height, h->type,
|
|
|
|
h->R, h->G, h->B, h->A);
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
int fimg_describe(FloatImg *head, char *txt)
|
|
|
|
{
|
|
|
|
printf("----- '%s' at %p -----\n", txt, head);
|
|
|
|
|
|
|
|
if( ! fimg_type_is_valid(head->type) ) {
|
|
|
|
fprintf(stderr, "*** %s *** type %d invalid *** %s ***\n",
|
|
|
|
__func__, head->type, txt);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-09-09 17:58:10 +02:00
|
|
|
printf(" type %d %s\n", head->type, fimg_str_type(head->type));
|
|
|
|
printf(" dims %d x %d\n",
|
2019-08-07 11:55:29 +02:00
|
|
|
head->width, head->height);
|
2019-09-09 17:58:10 +02:00
|
|
|
printf(" fval/count %f %d\n", head->fval, head->count);
|
2019-08-07 11:55:29 +02:00
|
|
|
|
2019-09-09 17:58:10 +02:00
|
|
|
printf(" pixels@ %p %p %p %p\n",
|
2019-03-03 16:22:55 +01:00
|
|
|
head->R, head->G, head->B, head->A);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* ---------------------------------------------------------------- */
|
2019-11-12 13:57:32 +01:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
*/
|
2019-03-03 16:22:55 +01:00
|
|
|
int fimg_create(FloatImg *fimg, int w, int h, int t)
|
|
|
|
{
|
|
|
|
int surface, size;
|
|
|
|
float *fptr;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, ">>> %-25s ( %p %d %d %d )\n", __func__, fimg, w, h, t);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if ( ! fimg_type_is_valid(t) ) {
|
|
|
|
return -2;
|
|
|
|
}
|
2019-08-03 14:27:21 +02:00
|
|
|
|
2019-03-03 16:22:55 +01:00
|
|
|
memset(fimg, 0, sizeof(FloatImg));
|
|
|
|
|
|
|
|
surface = w * h;
|
2019-08-07 11:55:29 +02:00
|
|
|
size = surface * t * sizeof(float);
|
2019-03-03 16:22:55 +01:00
|
|
|
#if DEBUG_LEVEL > 1
|
|
|
|
fprintf(stderr, "surface is %d pixels, need %d bytes\n", surface, size);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
fptr = (float *)malloc(size);
|
|
|
|
if (NULL==fptr) {
|
2019-03-03 18:03:50 +01:00
|
|
|
fprintf(stderr, "%s : no mem, exiting.\n", __func__);
|
2019-03-03 16:22:55 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL > 1
|
|
|
|
fprintf(stderr, " got %d bytes at %p\n", size, fptr);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
fimg->width = w; fimg->height = h;
|
|
|
|
fimg->type = t;
|
|
|
|
|
|
|
|
fimg->R = fptr;
|
2019-08-07 11:55:29 +02:00
|
|
|
if ( (t==FIMG_TYPE_RGB) || (t==FIMG_TYPE_RGBA) ) {
|
2019-03-03 16:22:55 +01:00
|
|
|
fimg->G = fptr + surface;
|
|
|
|
fimg->B = fptr + surface + surface;
|
|
|
|
}
|
2019-08-07 11:55:29 +02:00
|
|
|
if ( t==FIMG_TYPE_RGBA ) fimg->A = fptr + (3 * surface);
|
|
|
|
/* ok this a really WTF fragment of code */
|
2019-03-03 16:22:55 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
int fimg_destroy(FloatImg *fimg)
|
|
|
|
{
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, ">>> %-25s ( %p )\n", __func__, fimg);
|
|
|
|
#endif
|
|
|
|
|
2019-03-03 18:07:20 +01:00
|
|
|
if (NULL == fimg) {
|
|
|
|
fprintf(stderr, "%s : parameter is null\n", __func__);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-03-03 16:22:55 +01:00
|
|
|
if ( ! fimg_type_is_valid(fimg->type) ) {
|
2019-08-07 11:55:29 +02:00
|
|
|
fprintf(stderr, "%s : type %d invalid\n", __func__,
|
|
|
|
fimg->type);
|
2019-03-03 16:22:55 +01:00
|
|
|
return -2;
|
|
|
|
}
|
2019-03-03 18:07:20 +01:00
|
|
|
if (NULL == fimg->R) {
|
2019-08-07 11:55:29 +02:00
|
|
|
fprintf(stderr, "%s : %p already freed\n", __func__, fimg);
|
2019-03-03 18:07:20 +01:00
|
|
|
return -3;
|
|
|
|
}
|
2019-03-03 16:22:55 +01:00
|
|
|
free(fimg->R);
|
|
|
|
memset(fimg, 0, sizeof(FloatImg));
|
|
|
|
|
2019-11-12 13:57:32 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
int fimg_clone(FloatImg *old, FloatImg *new, int flags)
|
|
|
|
{
|
|
|
|
int foo;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, ">>> %-25s ( %p %p 0x%x)\n", __func__, old, new, flags);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if ( ! fimg_type_is_valid(old->type) ) {
|
|
|
|
fprintf(stderr, "invalid type %d in %s\n", old->type, __func__);
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(new, 0, sizeof(FloatImg));
|
|
|
|
|
|
|
|
foo = fimg_create(new, old->width, old->height, old->type);
|
|
|
|
if (foo) {
|
|
|
|
fprintf(stderr, "error %d in %s\n", foo, __func__);
|
|
|
|
return -3;
|
|
|
|
}
|
|
|
|
|
2019-11-12 14:10:45 +01:00
|
|
|
if (flags & 0x01) {
|
2019-11-12 13:57:32 +01:00
|
|
|
/* XXX copy all the pixels's datas */
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-03-03 16:22:55 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
int fimg_clear(FloatImg *fimg)
|
|
|
|
{
|
|
|
|
int size;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, ">>> %-25s ( %p )\n", __func__, fimg);
|
|
|
|
#endif
|
|
|
|
if ( ! fimg_type_is_valid(fimg->type) ) {
|
|
|
|
fprintf(stderr, "invalid type %d in %s\n", fimg->type, __func__);
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
2019-08-10 21:26:39 +02:00
|
|
|
size = fimg->width * fimg->height * fimg->type * sizeof(float);
|
2019-03-03 16:22:55 +01:00
|
|
|
memset(fimg->R, 0, size);
|
|
|
|
|
2019-09-28 23:54:14 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
int fimg_rgb_constant(FloatImg *head, float r, float g, float b)
|
|
|
|
{
|
|
|
|
int idx, size;
|
|
|
|
|
|
|
|
fprintf(stderr, ">>> %-25s ( %p %f %f %f )\n", __func__, head,
|
|
|
|
r, g, b);
|
|
|
|
|
|
|
|
if (head->type != FIMG_TYPE_RGB) {
|
|
|
|
return -21;
|
|
|
|
}
|
|
|
|
|
|
|
|
size = head->width * head->height;
|
|
|
|
|
|
|
|
for (idx=0; idx<size; idx++) {
|
|
|
|
head->R[idx] = r;
|
|
|
|
head->G[idx] = g;
|
|
|
|
head->B[idx] = b;
|
|
|
|
}
|
|
|
|
|
2019-08-07 11:55:29 +02:00
|
|
|
return 0;
|
2019-03-03 16:22:55 +01:00
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
int fimg_plot_rgb (FloatImg *head, int x, int y,
|
|
|
|
float r, float g, float b)
|
|
|
|
{
|
|
|
|
int offset;
|
|
|
|
|
|
|
|
if (head->type < 3) {
|
|
|
|
#if DEBUG_LEVEL > 1
|
|
|
|
fprintf(stderr, "%s : type %d is bad.\n", __func__, head->type);
|
|
|
|
#endif
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
offset = x + (y * head->width);
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL > 1
|
|
|
|
fprintf(stderr, ">>> %s ( %p %d %d %f )\n", __func__, head, x, y, gray);
|
|
|
|
fprintf(stderr, " offset %d\n", offset);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
head->R[offset] = r;
|
|
|
|
head->G[offset] = g;
|
|
|
|
head->B[offset] = b;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* ---------------------------------------------------------------- */
|
|
|
|
int fimg_add_rgb(FloatImg *head, int x, int y, float r, float g, float b)
|
|
|
|
{
|
|
|
|
int offset;
|
2019-09-03 19:35:45 +02:00
|
|
|
|
|
|
|
if (head->type != FIMG_TYPE_RGB) {
|
|
|
|
#if DEBUG_LEVEL > 1
|
|
|
|
fprintf(stderr, "%s : type %d is bad.\n", __func__, head->type);
|
|
|
|
#endif
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-03-03 16:22:55 +01:00
|
|
|
offset = x + (y * head->width);
|
|
|
|
head->R[offset] += r;
|
|
|
|
head->G[offset] += g;
|
|
|
|
head->B[offset] += b;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|