FloatImg/lib/fimg-core.c

370 lines
8.5 KiB
C
Raw Normal View History

2019-03-03 16:22:55 +01:00
/*
* fimg-core.c
*
*
*/
#include <stdio.h>
#include <stdlib.h>
2021-05-20 09:31:28 +02:00
#include <stdint.h>
2019-03-03 16:22:55 +01:00
#include <unistd.h>
#include "string.h"
#include "../floatimg.h"
extern int verbosity; /* must be declared around main() */
/* ---------------------------------------------------------------- */
2020-02-19 22:36:58 +01:00
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:
case FIMG_TYPE_RGBZ: 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";
case FIMG_TYPE_RGBZ: return "rgbz";
2019-08-07 11:55:29 +02:00
}
return "???";
}
/* --------------------------------------------------------------------- */
2019-03-03 16:22:55 +01:00
int fimg_print_version(int k)
{
2022-04-12 14:54:07 +02:00
fprintf(stderr, "*** FloatImg library, v%d '%s' (%s, %s)\n",
FIMG_VERSION, RELEASE_NAME, __DATE__, __TIME__);
2019-03-03 16:22:55 +01:00
if (51 == k) {
2021-03-17 18:32:51 +01:00
puts("+------------------------+");
puts("| Pastis is coming soon |");
puts("+------------------------+");
2019-03-03 16:22:55 +01:00
}
return 0;
}
/* --------------------------------------------------------------------- */
2020-06-11 15:57:12 +02:00
void fimg_print_sizeof(void)
{
fprintf(stderr, " sz FloatImg = %lu\n", sizeof(FloatImg));
fprintf(stderr, " sz filehead = %lu\n", sizeof(FimgFileHead));
2022-04-09 23:18:14 +02:00
fprintf(stderr, " sz metadata = %lu\n", sizeof(FimgMetaData));
fprintf(stderr, " sz filter = %lu\n", sizeof(FimgFilter3x3));
2020-06-11 15:57:12 +02:00
}
/* --------------------------------------------------------------------- */
2021-03-30 19:48:55 +02:00
void fimg_printdims(char *txt, FloatImg *pi)
{
fprintf(stderr, "# %s %dx%d\n", txt, pi->width, pi->height);
}
/* --------------------------------------------------------------------- */
2019-03-03 16:22:55 +01:00
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));
2021-04-03 05:21:17 +02:00
printf(" dims %d x %d\n", 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;
}
/* ---------------------------------------------------------------- */
static float *plane_alloc(int size)
{
float *fptr;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %d )\n", __func__, size);
#endif
fptr = calloc(size, sizeof(float));
if (NULL==fptr) {
fprintf(stderr, "no more memory available, ABEND\n");
abort();
}
return fptr;
}
/* ---------------------------------------------------------------- */
2019-11-12 13:57:32 +01:00
/*
* values for the parameter 'type' are defined in 'floatimg.h'
2019-11-12 13:57:32 +01:00
*/
int fimg_create(FloatImg *fimg, int w, int h, int type)
2019-03-03 16:22:55 +01:00
{
int size;
2019-03-03 16:22:55 +01:00
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d %d %d )\n", __func__, fimg, w, h, type);
2019-03-03 16:22:55 +01:00
#endif
if ( ! fimg_type_is_valid(type) ) {
fprintf(stderr, "%s: type %d invalid\n", __func__, type);
2019-03-03 16:22:55 +01:00
return -2;
}
2019-08-03 14:27:21 +02:00
2020-01-10 12:01:12 +01:00
/*
* what to do if we've got a descriptor for an image
2021-03-17 18:32:51 +01:00
* already allocated ? and how to check that ?
2020-01-10 12:01:12 +01:00
*/
2019-03-03 16:22:55 +01:00
memset(fimg, 0, sizeof(FloatImg));
size = w * h;
fimg->width = w; fimg->height = h;
fimg->type = type;
2019-03-03 16:22:55 +01:00
/* the red channel is allway allocated */
fimg->R = (float *)plane_alloc(size);
2019-03-03 16:22:55 +01:00
if (FIMG_TYPE_RGB == type) {
fimg->G = (float *)plane_alloc(size);
fimg->B = (float *)plane_alloc(size);
}
2019-03-03 16:22:55 +01:00
if (FIMG_TYPE_RGBA == type) {
2021-03-17 18:32:51 +01:00
fimg->G = (float *)plane_alloc(size);
fimg->B = (float *)plane_alloc(size);
fimg->A = (float *)plane_alloc(size);
2019-03-03 16:22:55 +01:00
}
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) {
2024-03-27 12:20:28 +01:00
fprintf(stderr, "%s : descriptor address is null\n", __func__);
2019-03-03 18:07:20 +01:00
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-12-27 12:25:33 +01: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);
2021-03-17 18:32:51 +01:00
if (FIMG_TYPE_RGB == fimg->type) {
2021-03-10 05:51:48 +01:00
free(fimg->G);
free(fimg->B);
}
2019-03-03 16:22:55 +01:00
memset(fimg, 0, sizeof(FloatImg));
2019-11-12 13:57:32 +01:00
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_clone(FloatImg *old, FloatImg *new, int flags)
{
2021-03-17 18:32:51 +01:00
int foo, size;
2019-11-12 13:57:32 +01:00
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p 0x%x )\n", __func__, old, new, flags);
2019-11-12 13:57:32 +01:00
#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;
}
2021-03-17 18:32:51 +01:00
if (flags & 0x01) { /* copy pixels values */
size = old->width * old->height * sizeof(float);
memcpy(new->R, old->R, size);
memcpy(new->G, old->G, size);
memcpy(new->B, old->B, size);
2019-11-12 13:57:32 +01:00
}
2019-12-27 12:25:33 +01:00
return 0;
}
/* --------------------------------------------------------------------- */
int fimg_copy_data(FloatImg *from, FloatImg *to)
{
int size;
int foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p )\n", __func__, from, to);
2019-12-27 12:25:33 +01:00
#endif
2020-04-06 20:09:11 +02:00
foo = fimg_images_not_compatible(from, to);
2019-12-27 12:25:33 +01:00
if (foo) {
fprintf(stderr, "%s: pics not compatible (%d)\n", __func__, foo);
return foo;
}
size = from->width * from->height * sizeof(float);
2019-12-27 12:25:33 +01:00
memcpy(to->R, from->R, size);
memcpy(to->G, from->G, size);
memcpy(to->B, from->B, size);
2019-12-27 12:25:33 +01:00
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;
}
2021-03-17 18:32:51 +01:00
size = fimg->width * fimg->height * sizeof(float);
2019-03-03 16:22:55 +01:00
memset(fimg->R, 0, size);
2021-04-03 05:21:17 +02:00
memset(fimg->G, 0, size);
memset(fimg->B, 0, size);
2019-03-03 16:22:55 +01:00
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;
2019-12-27 12:25:33 +01:00
#if DEBUG_LEVEL
2019-09-28 23:54:14 +02:00
fprintf(stderr, ">>> %-25s ( %p %f %f %f )\n", __func__, head,
r, g, b);
2019-12-27 12:25:33 +01:00
#endif
2019-09-28 23:54:14 +02:00
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;
}
/* --------------------------------------------------------------------- */
2020-02-13 20:44:22 +01:00
/* nouveau 12 fevrier 2020 */
int fimg_get_rgb(FloatImg *head, int x, int y, float *prgb)
{
int offset;
2019-03-03 16:22:55 +01:00
2020-02-13 20:44:22 +01: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
2020-02-13 20:44:22 +01:00
offset = x + (y * head->width);
prgb[0] = head->R[offset];
prgb[1] = head->G[offset];
prgb[2] = head->B[offset];
2019-03-03 16:22:55 +01:00
2020-02-13 20:44:22 +01:00
return 0;
}
/* --------------------------------------------------------------------- */
2020-03-24 10:41:57 +01:00
/* nouveau 24 mars 2020 - coronacoding */
int fimg_put_rgb(FloatImg *head, int x, int y, float *prgb)
{
int offset;
if (head->type != FIMG_TYPE_RGB) {
#if DEBUG_LEVEL > 1
fprintf(stderr, "%s : type %d is bad.\n", __func__, head->type);
#endif
return -1;
}
offset = x + (y * head->width);
head->R[offset] = prgb[0];
head->G[offset] = prgb[1];
head->B[offset] = prgb[2];
return 0;
}
/* --------------------------------------------------------------------- */