kornelski / dssim

Image similarity comparison simulating human perception (multiscale SSIM in Rust)
https://kornel.ski/dssim
GNU Affero General Public License v3.0
1.07k stars 69 forks source link

error in c #150

Closed tados000 closed 8 months ago

tados000 commented 8 months ago

Hello,

Here is my code `#include

include

include

include </home/seb/dssim/dssim-core/dssim.h>

int main(int argc, char** argv) {

char chemin_image1[1024];
snprintf(chemin_image1, 1024, "/home/seb/color_cjpeg2.jpg");
char chemin_image2[1024];
snprintf(chemin_image2, 1024, "/home/seb/color_image.jpeg");

// Ouverture des fichiers d'image
FILE *fichier_image1 = fopen(chemin_image1, "rb");
if (!fichier_image1) {
    printf("Impossible d'ouvrir l'image 1\n");
    return 1;
}
FILE *fichier_image2 = fopen(chemin_image2, "rb");
if (!fichier_image2) {
    printf("Impossible d'ouvrir l'image 2\n");
    fclose(fichier_image1);
    return 1;
}

// Lecture des images en mémoire (c'est juste un exemple, pas une utilisation réelle de DSSIM)
fseek(fichier_image1, 0, SEEK_END);
size_t taille_image1 = ftell(fichier_image1);
fseek(fichier_image1, 0, SEEK_SET);
uint8_t *pixels_image1 = malloc(taille_image1);
fread(pixels_image1, 1, taille_image1, fichier_image1);
fclose(fichier_image1);

fseek(fichier_image2, 0, SEEK_END);
size_t taille_image2 = ftell(fichier_image2);
fseek(fichier_image2, 0, SEEK_SET);
uint8_t *pixels_image2 = malloc(taille_image2);
fread(pixels_image2, 1, taille_image2, fichier_image2);
fclose(fichier_image2);

// Initialisation du contexte DSSIM
struct Dssim *dssim = dssim_new();

// Création des images à partir des pixels chargés
DssimImage *img1 = dssim_create_image_rgb(dssim, pixels_image1, 1920, 1080);
DssimImage *img2 = dssim_create_image_rgb(dssim, pixels_image2, 1920, 1080);

// Comparaison des images
double resultat_dssim = dssim_compare(dssim, img1, img2);
printf("Valeur DSSIM entre les images : %f\n", resultat_dssim);

// Libération de la mémoire et des ressources
dssim_free_image(img1);
dssim_free_image(img2);
dssim_free(dssim);
free(pixels_image1);
free(pixels_image2);

return 0;

} I use GCC like this : gcc -o testdssim testdssim.c -L/usr/lib/lib -l:libdssim.a`

It give to me : /usr/bin/ld : /usr/lib/lib/libdssim.a(dssim.dssim.6a49f9df07a6a3a0-cgu.13.rcgu.o) : dans la fonction « rayon::iter::plumbing::bridge_producer_consumer::helper » : dssim.6a49f9df07a6a3a0-cgu.13:(.text._ZN5rayon4iter8plumbing24bridge_producer_consumer6helper17h3ee5fc810108da07E+0x14b) : référence indéfinie vers « fmaf » /usr/bin/ld : dssim.6a49f9df07a6a3a0-cgu.13:(.text._ZN5rayon4iter8plumbing24bridge_producer_consumer6helper17h3ee5fc810108da07E+0x297) : référence indéfinie vers « cbrtf » /usr/bin/ld : dssim.6a49f9df07a6a3a0-cgu.13:(.text._ZN5rayon4iter8plumbing24bridge_producer_consumer6helper17h3ee5fc810108da07E+0x474) : référence indéfinie vers « cbrtf » /usr/bin/ld : dssim.6a49f9df07a6a3a0-cgu.13:(.text._ZN5rayon4iter8plumbing24bridge_producer_consumer6helper17h3ee5fc810108da07E+0x4e0) : référence indéfinie vers « cbrtf » /usr/bin/ld : /usr/lib/lib/libdssim.a(dssim.dssim.6a49f9df07a6a3a0-cgu.13.rcgu.o) : dans la fonction « rayon::iter::plumbing::bridge_producer_consumer::helper » : dssim.6a49f9df07a6a3a0-cgu.13:(.text._ZN5rayon4iter8plumbing24bridge_producer_consumer6helper17h6093feaeefd6c344E+0x156) : référence indéfinie vers « fmaf » /usr/bin/ld : dssim.6a49f9df07a6a3a0-cgu.13:(.text._ZN5rayon4iter8plumbing24bridge_producer_consumer6helper17h6093feaeefd6c344E+0x297) : référence indéfinie vers « cbrtf » /usr/bin/ld : dssim.6a49f9df07a6a3a0-cgu.13:(.text._ZN5rayon4iter8plumbing24bridge_producer_consumer6helper17h6093feaeefd6c344E+0x3e5) : référence indéfinie vers « cbrtf » /usr/bin/ld : dssim.6a49f9df07a6a3a0-cgu.13:(.text._ZN5rayon4iter8plumbing24bridge_producer_consumer6helper17h6093feaeefd6c344E+0x450) : référence indéfinie vers « cbrtf » /usr/bin/ld : /usr/lib/lib/libdssim.a(dssim.dssim.6a49f9df07a6a3a0-cgu.13.rcgu.o) : dans la fonction « core::ops::function::impls::<impl core::ops::function::FnMut<A> for &F>::call_mut » : dssim.6a49f9df07a6a3a0-cgu.13:(.text._ZN4core3ops8function5impls71_$LT$impl$u20$core..ops..function..FnMut$LT$A$GT$$u20$for$u20$$RF$F$GT$8call_mut17h5d1fe4a57825663aE+0x3b1) : référence indéfinie vers « exp2 » /usr/bin/ld : dssim.6a49f9df07a6a3a0-cgu.13:(.text._ZN4core3ops8function5impls71_$LT$impl$u20$core..ops..function..FnMut$LT$A$GT$$u20$for$u20$$RF$F$GT$8call_mut17h5d1fe4a57825663aE+0x3c1) : référence indéfinie vers « pow » /usr/bin/ld : /usr/lib/lib/libdssim.a(dssim.dssim.6a49f9df07a6a3a0-cgu.13.rcgu.o) : dans la fonction « dssim_create_image_rgba » : dssim.6a49f9df07a6a3a0-cgu.13:(.text.dssim_create_image_rgba+0x54) : référence indéfinie vers « powf » /usr/bin/ld : /usr/lib/lib/libdssim.a(dssim.dssim.6a49f9df07a6a3a0-cgu.13.rcgu.o) : dans la fonction « dssim_create_image_rgb » : dssim.6a49f9df07a6a3a0-cgu.13:(.text.dssim_create_image_rgb+0x54) : référence indéfinie vers « powf » collect2: error: ld returned 1 exit status /usr/lib/lib$ ls libdssim.a libdssim.so libdssim.so.3 libdssim.so.3.0.0 pkgconfig

I don't userstand why

kornelski commented 8 months ago

You need to link to libm -lm

tados000 commented 8 months ago

Thanks for such a quick response.I now have a segmentation error:

seb@dell:~/c$ ./testdssim
Erreur de segmentation
seb@dell:~/c$` gdb ./testdssim
GNU gdb (Debian 13.1-3) 13.1
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./testdssim...
(gdb) run
Starting program: /home/seb/c/testdssim
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x0000555555575c6e in dssim_create_image_rgb ()
(gdb)
kornelski commented 8 months ago

You've passed incorrect pointer to dssim_create_image_rgb. Make sure it's a valid allocation and has the right size.

tados000 commented 8 months ago

Exact! It works now

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include </home/seb/dssim/dssim-core/dssim.h>

// compile avec:  gcc -o testdssim testdssim.c -L/usr/lib/lib -l:libdssim.a -lm

void load_ppm_data(unsigned char *ppmData,const char *filename) 
    {
        FILE *file = fopen(filename, "rb");
        if (!file) {
            perror("Error opening file");
            free(ppmData);
            exit(1);
        }
        long fileSize = 1920 * 1080 * 3; // Assuming 24-bit PPM
        fseek(file, 17, SEEK_SET); // placement du curseur après l'entête du fichier PPM
        size_t bytesRead = fread(ppmData, 1, fileSize, file);
        if (bytesRead != fileSize) {
            perror("Error reading file");
            free(ppmData);
            fclose(file);
            exit(1);
        } 
        fclose(file);
    }

// Function to allocate memory for PPM data
unsigned char* allocate_ppm_memory() 
    {
        long fileSize = 1920 * 1080 * 3; // Assuming 24-bit PPM
        unsigned char *ppmData = (unsigned char *)malloc(fileSize);
        if (!ppmData) {
            perror("Memory allocation failed");
            exit(1);
        }
        return ppmData;
    } 

int main(int argc, char** argv)
{
    int width = 1920;
    int height = 1080;
    char filename[1024];

    // Allocate memory for PPM data
    unsigned char *ppmData1 = allocate_ppm_memory();
    unsigned char *ppmData2 = allocate_ppm_memory();

    // Load PPM data into memory   
    snprintf(filename, 1024, "/tmp/1.ppm");
    load_ppm_data(ppmData1, filename);
    snprintf(filename, 1024, "/tmp/2.ppm");
    load_ppm_data(ppmData2, filename);
    // Initialisation du contexte DSSIM
    struct Dssim *dssim = dssim_new();

    // Création des images à partir des pixels chargés
    DssimImage *img1 = dssim_create_image_rgb(dssim, ppmData1, width, height);
    DssimImage *img2 = dssim_create_image_rgb(dssim, ppmData2, width, height);

    // Comparaison des images
    double resultat_dssim = dssim_compare(dssim, img1, img2);
    printf("Valeur DSSIM entre les images : %f\n", resultat_dssim);

    // Libération de la mémoire et des ressources
    dssim_free_image(img1);
    dssim_free_image(img2);
    dssim_free(dssim);
    free(ppmData1);
    free(ppmData2);

    return 0;
}