2019-03-03 16:22:55 +01:00
|
|
|
/*
|
|
|
|
* fimg-core.c
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
2019-08-07 17:30:16 +02:00
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
2019-03-03 16:22:55 +01:00
|
|
|
|
|
|
|
#include "../floatimg.h"
|
|
|
|
|
|
|
|
extern int verbosity; /* must be declared around main() */
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------- */
|
|
|
|
float fimg_get_maxvalue(FloatImg *head)
|
|
|
|
{
|
|
|
|
float maxval;
|
|
|
|
int foo;
|
|
|
|
|
2019-08-26 02:35:17 +02:00
|
|
|
if (head->type != FIMG_TYPE_RGB && head->type != FIMG_TYPE_GRAY) {
|
2019-08-07 17:30:16 +02:00
|
|
|
fprintf(stderr, "%s : type %d invalide\n",
|
|
|
|
__func__, head->type);
|
|
|
|
return nanf("wtf ?");
|
|
|
|
}
|
|
|
|
|
2019-03-03 16:22:55 +01:00
|
|
|
maxval = 0.0; /* no negative values allowed */
|
|
|
|
|
2019-08-26 02:35:17 +02:00
|
|
|
switch (head->type) {
|
|
|
|
case FIMG_TYPE_RGB:
|
|
|
|
for (foo=0; foo<(head->width*head->height); foo++) {
|
|
|
|
if (head->R[foo] > maxval) maxval = head->R[foo];
|
|
|
|
if (head->G[foo] > maxval) maxval = head->G[foo];
|
|
|
|
if (head->B[foo] > maxval) maxval = head->B[foo];
|
|
|
|
}
|
|
|
|
case FIMG_TYPE_GRAY:
|
|
|
|
for (foo=0; foo<(head->width*head->height); foo++) {
|
|
|
|
if (head->R[foo] > maxval) maxval = head->R[foo];
|
|
|
|
}
|
2019-03-03 16:22:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return maxval;
|
|
|
|
}
|
|
|
|
/* ---------------------------------------------------------------- */
|
|
|
|
int fimg_meanvalues(FloatImg *head, float means[4])
|
|
|
|
{
|
|
|
|
int idx, surface;
|
2019-09-28 23:45:51 +02:00
|
|
|
double accus[4];
|
2019-03-03 16:22:55 +01:00
|
|
|
|
|
|
|
surface = head->width * head->height;
|
|
|
|
if (surface < 1) return -1;
|
|
|
|
|
2019-09-28 23:45:51 +02:00
|
|
|
memset(accus, 0, 4*sizeof(double));
|
2019-03-03 16:22:55 +01:00
|
|
|
|
|
|
|
for (idx=0; idx<surface; idx++) {
|
2019-09-28 23:45:51 +02:00
|
|
|
accus[0] += head->R[idx];
|
2019-03-03 16:22:55 +01:00
|
|
|
if (head->type > 2) {
|
2019-09-28 23:45:51 +02:00
|
|
|
accus[1] += head->G[idx];
|
|
|
|
accus[2] += head->B[idx];
|
2019-03-03 16:22:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-28 23:45:51 +02:00
|
|
|
for (idx=0; idx<4; idx++) {
|
|
|
|
means[idx] = (float)(accus[idx]/(double)surface);
|
|
|
|
}
|
2019-03-03 16:22:55 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* ---------------------------------------------------------------- */
|
2019-08-27 09:19:25 +02:00
|
|
|
/*
|
|
|
|
* more elaborate functions are in fimg-2gray.c
|
|
|
|
*/
|
2019-03-03 16:22:55 +01:00
|
|
|
int fimg_to_gray(FloatImg *head)
|
|
|
|
{
|
|
|
|
float add;
|
|
|
|
int foo;
|
|
|
|
|
2019-08-07 17:30:16 +02:00
|
|
|
if (head->type != FIMG_TYPE_RGB) {
|
|
|
|
fprintf(stderr, "%s : type %d invalide\n",
|
|
|
|
__func__, head->type);
|
|
|
|
return -3;
|
|
|
|
}
|
|
|
|
|
2019-03-03 16:22:55 +01:00
|
|
|
for (foo=0; foo<(head->width*head->height); foo++) {
|
|
|
|
add = head->R[foo];
|
|
|
|
add += head->G[foo];
|
|
|
|
add += head->B[foo];
|
2019-09-17 13:14:33 +02:00
|
|
|
head->R[foo] = head->G[foo] = head->B[foo] = add / 3.0;
|
2019-03-03 16:22:55 +01:00
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* ---------------------------------------------------------------- */
|
|
|
|
void fimg_add_cste(FloatImg *fi, float value)
|
|
|
|
{
|
|
|
|
int nbre, idx;
|
|
|
|
|
2019-08-07 17:30:16 +02:00
|
|
|
if (fi->type != FIMG_TYPE_RGB) {
|
|
|
|
fprintf(stderr, "%s : type %d invalide\n",
|
|
|
|
__func__, fi->type);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-03 16:22:55 +01:00
|
|
|
nbre = fi->width * fi->height * fi->type;
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "%s, nbre is %d\n", __func__, nbre);
|
|
|
|
#endif
|
2019-09-10 01:31:48 +02:00
|
|
|
for (idx=0; idx<nbre; idx++) {
|
2019-03-03 16:22:55 +01:00
|
|
|
fi->R[idx] += value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* ---------------------------------------------------------------- */
|
2019-09-25 09:21:00 +02:00
|
|
|
int fimg_count_negativ(FloatImg *fi)
|
|
|
|
{
|
|
|
|
int nbre, idx;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
if (fi->type != FIMG_TYPE_RGB) {
|
|
|
|
fprintf(stderr, "%s : type %d invalide\n",
|
|
|
|
__func__, fi->type);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
nbre = fi->width * fi->height * fi->type;
|
|
|
|
|
|
|
|
count = 0;
|
|
|
|
for (idx=0; idx<nbre; idx++) {
|
|
|
|
if (fi->R[idx] < 0.0) count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
/* ---------------------------------------------------------------- */
|
2019-09-10 01:31:48 +02:00
|
|
|
void fimg_mul_cste(FloatImg *fi, float value)
|
|
|
|
{
|
|
|
|
int nbre, idx;
|
|
|
|
|
|
|
|
if (fi->type != FIMG_TYPE_RGB) {
|
|
|
|
fprintf(stderr, "%s : type %d invalide\n",
|
|
|
|
__func__, fi->type);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nbre = fi->width * fi->height * fi->type;
|
|
|
|
// #if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "%s, nbre is %d\n", __func__, nbre);
|
|
|
|
// #endif
|
|
|
|
for (idx=0; idx<nbre; idx++) {
|
|
|
|
fi->R[idx] *= value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* ---------------------------------------------------------------- */
|
2019-03-03 16:22:55 +01:00
|
|
|
/* Warning: this function is _very_ slow */
|
|
|
|
void fimg_drand48(FloatImg *fi, float kmul)
|
|
|
|
{
|
|
|
|
int nbre, idx;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, ">>> %s ( %p %g )\n", __func__, fi, kmul);
|
|
|
|
#endif
|
|
|
|
|
2019-09-02 10:07:56 +02:00
|
|
|
if (fi->type != FIMG_TYPE_RGB) {
|
|
|
|
fprintf(stderr, "%s : type %d invalide\n",
|
|
|
|
__func__, fi->type);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
nbre = fi->width * fi->height;
|
2019-03-03 16:22:55 +01:00
|
|
|
for (idx=0; idx<nbre; idx++) {
|
|
|
|
fi->R[idx] = drand48() * kmul;
|
2019-09-02 10:07:56 +02:00
|
|
|
fi->G[idx] = drand48() * kmul;
|
|
|
|
fi->B[idx] = drand48() * kmul;
|
2019-03-03 16:22:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
/* ---------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|