Exemple #1
0
uint32_t progressive_render(int quality, int bytes_read) {
    printf("%i bytes read, rendering at quality=%.2f%%\n",bytes_read, 0.01*quality);
    FLIF_IMAGE* image = flif_decoder_get_image(d, 0);
    if (!image) { printf("Error: No decoded image found\n"); return 1; }
    uint32_t w = flif_image_get_width(image);
    uint32_t h = flif_image_get_height(image);
    if (!window) window = SDL_CreateWindow("FLIF Viewer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, 0);
    if (!window) { printf("Error: Could not create window\n"); return 2; }
    char title[100];
    sprintf(title,"%ix%i FLIF image [read %i bytes, quality=%.2f%%]",w,h,bytes_read, 0.01*quality);
    SDL_SetWindowTitle(window,title);
    SDL_Surface *canvas = SDL_GetWindowSurface(window);
    if (!canvas) { printf("Error: Could not get canvas\n"); return 2; }
    if (!surf) surf = SDL_CreateRGBSurface(0,w,h,32,0x000000FF,0x0000FF00,0x00FF0000,0xFF000000);
    if (!surf) { printf("Error: Could not create surface\n"); return 2; }
    char* pp =(char*) surf->pixels;
    for (uint32_t r=0; r<h; r++) {
        flif_image_read_row_RGBA8(image, r, pp, w * sizeof(RGBA));
        pp += surf->pitch;
    }
    if (flif_image_get_nb_channels(image) > 3) {
      // SDL_FillRect(canvas,NULL,0);
      // Draw checkerboard background for image with alpha channel
      SDL_Rect sq; sq.w=20; sq.h=20;
      for (sq.y=0; sq.y<h; sq.y+=sq.h) for (sq.x=0; sq.x<w; sq.x+=sq.w)
          SDL_FillRect(canvas,&sq,((sq.y/sq.h + sq.x/sq.w)&1 ? 0xFF606060 : 0xFFA0A0A0));
    }
    SDL_BlitSurface(surf,NULL,canvas,NULL);
    SDL_UpdateWindowSurface(window);
    SDL_Event e;
    while (SDL_PollEvent(&e)) {if (!do_event(e)) return 0;} // stop decoding
    //SDL_Delay(500);
    return quality + 500; // call me back when you have at least 5% better quality
}
Exemple #2
0
uint32_t progressive_render(int32_t quality, int64_t bytes_read) {
    while (drawing) {SDL_Delay(50);}
    drawing = 1;
    printf("%lli bytes read, rendering at quality=%.2f%%\n",(unsigned long long int) bytes_read, 0.01*quality);
    animation = (flif_decoder_num_images(d) > 1);
    FLIF_IMAGE* image = flif_decoder_get_image(d, 0);
    if (!image) { printf("Error: No decoded image found\n"); return 1; }
    uint32_t w = flif_image_get_width(image);
    uint32_t h = flif_image_get_height(image);
    if (!window) { printf("Error: Could not create window\n"); return 2; }
    SDL_SetWindowSize(window,w,h);
    char title[100];
    sprintf(title,"%ix%i FLIF image [read %lli bytes, quality=%.2f%%]",w,h,(unsigned long long int) bytes_read, 0.01*quality);
    SDL_SetWindowTitle(window,title);
    for (int f = 0; f< flif_decoder_num_images(d); f++) {
        FLIF_IMAGE* image = flif_decoder_get_image(d, f);
        if (!image) { printf("Error: No decoded image found\n"); return 1; }
        uint32_t w = flif_image_get_width(image);
        uint32_t h = flif_image_get_height(image);
        frame_delay[f] = flif_image_get_frame_delay(image);
        if (!surf[f]) surf[f] = SDL_CreateRGBSurface(0,w,h,32,0x000000FF,0x0000FF00,0x00FF0000,0xFF000000);
        if (!surf[f]) { printf("Error: Could not create surface\n"); return 1; }
        if (!tmpsurf) tmpsurf = SDL_CreateRGBSurface(0,w,h,32,0x000000FF,0x0000FF00,0x00FF0000,0xFF000000);
        if (!tmpsurf) { printf("Error: Could not create surface\n"); return 1; }
        char* pp =(char*) tmpsurf->pixels;
        for (uint32_t r=0; r<h; r++) {
            flif_image_read_row_RGBA8(image, r, pp, w * sizeof(RGBA));
            pp += tmpsurf->pitch;
        }
        if (flif_image_get_nb_channels(image) > 3) {
          if (!bgsurf) {
            bgsurf = SDL_CreateRGBSurface(0,w,h,32,0x000000FF,0x0000FF00,0x00FF0000,0xFF000000);
            // Draw checkerboard background for image with alpha channel
            SDL_Rect sq; sq.w=20; sq.h=20;
            for (sq.y=0; sq.y<h; sq.y+=sq.h) for (sq.x=0; sq.x<w; sq.x+=sq.w)
              SDL_FillRect(bgsurf,&sq,((sq.y/sq.h + sq.x/sq.w)&1 ? 0xFF606060 : 0xFFA0A0A0));
          }
          SDL_BlitSurface(bgsurf,NULL,surf[f],NULL);
        }
        SDL_BlitSurface(tmpsurf,NULL,surf[f],NULL);
    }
    drawing = 0;
    draw_image();
//    SDL_Delay(1000);
    if (quit) return 0; // stop decoding
    return quality + 1000; // call me back when you have at least 10.00% better quality
}
Exemple #3
0
int compare_images(FLIF_IMAGE* image1, FLIF_IMAGE* image2)
{
    int result = 0;

    uint32_t w1 = flif_image_get_width(image1);
    uint32_t h1 = flif_image_get_height(image1);

    uint32_t w2 = flif_image_get_width(image2);
    uint32_t h2 = flif_image_get_height(image2);

    if(w1 != w2 || h1 != h2)
    {
        printf("Error: Images have different width/height\n");
        result = 1;
    }

    RGBA* row1 = (RGBA*)malloc(w1 * sizeof(RGBA));
    if(row1 == 0)
    {
        printf("Error: Out of memory\n");
        result = 1;
    }
    else
    {
        RGBA* row2 = (RGBA*)malloc(w1 * sizeof(RGBA));
        if(row2 == 0)
        {
            printf("Error: Out of memory\n");
            result = 1;
        }
        else
        {
            int difference = 0;
            uint32_t y;
            for(y = 0; y < h1; ++y)
            {
                flif_image_read_row_RGBA8(image1, y, row1, w1 * sizeof(RGBA));
                flif_image_read_row_RGBA8(image2, y, row2, w2 * sizeof(RGBA));
                uint32_t x;
                for(x = 0; x < w1; ++x)
                {
                    if( row1[x].r != row2[x].r ||
                        row1[x].g != row2[x].g ||
                        row1[x].b != row2[x].b ||
                        row1[x].a != row2[x].a)
                    {
                        // stop flooding the log if the image has many differences
                        if(difference < 100)
                        {
                            printf("Error: Color difference at %u,%u: %02X%02X%02X%02X -> %02X%02X%02X%02X\n", x, y, row1[x].r, row1[x].g, row1[x].b, row1[x].a, row2[x].r, row2[x].g, row2[x].b, row2[x].a);
                            result = 1;
                        }
                        difference++;
                    }
                }
            }

            free(row2);
        }

        free(row1);
    }

    return result;
}
// Callback function: converts (partially) decoded image/animation to a/several SDL_Texture(s),
//                    resizes the viewer window if needed, and calls draw_image()
// Input arguments are: quality (0..10000), current position in the .flif file
// Output is the desired minimal quality before doing the next callback
uint32_t progressive_render(int32_t quality, int64_t bytes_read) {
    loading = 1;
    while (drawing) {SDL_Delay(50);} // don't touch the textures until we're done drawing
    printf("%lli bytes read, rendering at quality=%.2f%%\n",(long long int) bytes_read, 0.01*quality);
    FLIF_IMAGE* image = flif_decoder_get_image(d, 0);
    if (!image) { printf("Error: No decoded image found\n"); return 1; }
    uint32_t w = flif_image_get_width(image);
    uint32_t h = flif_image_get_height(image);

    // set the window title and size
    if (!window) { printf("Error: Could not create window\n"); return 2; }
    char title[100];
    sprintf(title,"FLIF image decoded at %ix%i [read %lli bytes, quality=%.2f%%]",w,h,(long long int) bytes_read, 0.01*quality);
    SDL_SetWindowTitle(window,title);
    if (!window_size_set) {
      int ww = (w > dm.w ? dm.w : w);
      int wh = (h > dm.h ? dm.h : h);
      if (ww > w * wh / h) ww = wh * w / h;
      else if (ww < w * wh / h) wh = ww * h / w;
      if (w > dm.w*8/10 && h > dm.h*8/10) { ww = ww*8/10; wh = wh*8/10; }
      SDL_SetWindowSize(window,ww,wh);
      SDL_SetWindowPosition(window,SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED);
      if (w > dm.w*8/10 && h > dm.h*8/10) { SDL_MaximizeWindow(window); }
      window_size_set = 1;
    }

    // allocate enough room for the texture pointers and frame delays
    if (!image_frame) image_frame = calloc(flif_decoder_num_images(d), sizeof(FLIF_IMAGE*));
    if (!frame_delay) frame_delay = calloc(flif_decoder_num_images(d), sizeof(int));

    // produce one SDL_Texture per frame
    for (int f = 0; f < flif_decoder_num_images(d); f++) {
        if (quit) return 0;
        FLIF_IMAGE* image = flif_decoder_get_image(d, f);
        if (!image) { printf("Error: No decoded image found\n"); return 1; }
        frame_delay[f] = flif_image_get_frame_delay(image);
        // Copy the decoded pixels to a temporary surface
        if (!tmpsurf) tmpsurf = SDL_CreateRGBSurface(0,w,h,32,0x000000FF,0x0000FF00,0x00FF0000,0xFF000000);
        if (!tmpsurf) { printf("Error: Could not create surface\n"); return 1; }
        char* pp =(char*) tmpsurf->pixels;
        for (uint32_t r=0; r<h; r++) {
            flif_image_read_row_RGBA8(image, r, pp, w * sizeof(RGBA));
            pp += tmpsurf->pitch;
        }
        // Draw checkerboard background for image/animation with alpha channel
        if (flif_image_get_nb_channels(image) > 3) {
          if (!bgsurf) bgsurf = SDL_CreateRGBSurface(0,w,h,32,0x000000FF,0x0000FF00,0x00FF0000,0xFF000000);
          if (!bgsurf) { printf("Error: Could not create surface\n"); return 1; }
          SDL_Rect sq; sq.w=20; sq.h=20;
          for (sq.y=0; sq.y<h; sq.y+=sq.h) for (sq.x=0; sq.x<w; sq.x+=sq.w)
              SDL_FillRect(bgsurf,&sq,((sq.y/sq.h + sq.x/sq.w)&1 ? 0xFF606060 : 0xFFA0A0A0));
          // Alpha-blend decoded frame on top of checkerboard background
          SDL_BlitSurface(tmpsurf,NULL,bgsurf,NULL);
          SDL_FreeSurface(tmpsurf); tmpsurf = bgsurf; bgsurf = NULL;
        }
        if (!renderer) { printf("Error: Could not get renderer\n"); return 1; }
        if (image_frame[f]) SDL_DestroyTexture(image_frame[f]);
        // Convert the surface to a texture (for accelerated blitting)
        image_frame[f] = SDL_CreateTextureFromSurface(renderer, tmpsurf);
        if (!image_frame[f]) { printf("Could not create texture!\n"); quit=1; return 0; }
        SDL_SetTextureBlendMode(image_frame[f],SDL_BLENDMODE_NONE);
    }
    SDL_FreeSurface(tmpsurf); tmpsurf=NULL;
    loading = 0;
    draw_image();
    // setting nb_frames to a value > 1 will make sure the main thread keeps calling draw_image()
    nb_frames = flif_decoder_num_images(d);
    if (quit) return 0; // stop decoding
    return quality + 1000; // call me back when you have at least 10.00% better quality
}