JPC-RR r11.7
[jpcrr.git] / streamtools / testresizer.cpp
blob000d2be45afe3106791bfd1ffb283dd6ec078f96
1 #include "SDL_image.h"
2 #include "SDL.h"
3 #include "resize.hpp"
4 #include <sys/time.h>
5 #include "rescalers/public.hpp"
6 #include <zlib.h>
7 #include <cstdlib>
8 #include <stdint.h>
9 #include <string>
10 #include <iostream>
11 #include <vector>
12 #include "newpacket.hpp"
13 #include <stdexcept>
15 namespace
17 bool do_quit_on(SDL_Event* e)
19 if(e->type == SDL_QUIT)
20 return true;
21 if(e->type == SDL_KEYUP && e->key.keysym.sym == 'q')
22 return true;
23 return false;
27 int real_main(int argc, char** argv)
29 if(argc < 5) {
30 std::cerr << "Syntax: testresizer.exe <picture> <algo> <width> <height>" << std::endl;
31 exit(1);
34 char* ptr1;
35 char* ptr2;
36 unsigned twidth = strtoul(argv[3], &ptr1, 10);
37 unsigned theight = strtoul(argv[4], &ptr2, 10);
38 if(!twidth || !theight || *ptr1 || *ptr2) {
39 std::cerr << "Error: Bad target size." << std::endl;
40 exit(1);
44 //Load the image.
45 SDL_Surface* img = IMG_Load(argv[1]);
46 if(!img) {
47 std::cerr << "Can't load image '" << argv[1] << "':" << IMG_GetError() << std::endl;
48 exit(2);
51 //Convert the SDL surface into raw image.
52 unsigned width = img->w;
53 unsigned height = img->h;
54 image_frame_rgbx src(width, height);
55 unsigned char* pixels = src.get_pixels();
56 SDL_LockSurface(img);
57 for(uint32_t y = 0; y < height; y++)
58 for(uint32_t x = 0; x < width; x++) {
59 Uint8 r, g, b;
60 size_t addr = y * img->pitch + x * img->format->BytesPerPixel;
61 if(img->format->BytesPerPixel == 4)
62 SDL_GetRGB(*(Uint32*)((unsigned char*)img->pixels + addr), img->format, &r, &g, &b);
63 else if(img->format->BytesPerPixel == 3)
64 SDL_GetRGB(*(Uint32*)((unsigned char*)img->pixels + addr) & 0xFFFFFF, img->format,
65 &r, &g, &b);
66 else if(img->format->BytesPerPixel == 2)
67 SDL_GetRGB(*(Uint16*)((unsigned char*)img->pixels + addr), img->format, &r, &g, &b);
68 else
69 SDL_GetRGB(*(Uint8*)((unsigned char*)img->pixels + addr), img->format, &r, &g, &b);
70 pixels[4 * width * y + 4 * x + 0] = r;
71 pixels[4 * width * y + 4 * x + 1] = g;
72 pixels[4 * width * y + 4 * x + 2] = b;
73 pixels[4 * width * y + 4 * x + 3] = 0;
75 SDL_UnlockSurface(img);
76 SDL_FreeSurface(img);
78 rescaler_group grp(*(parse_rescaler_expression(argv[2]).use_rescaler));
79 image_frame_rgbx& dest = src.resize(twidth, theight, grp);
81 //Now, display the image.
82 SDL_Surface* swsurf = NULL;
83 SDL_Surface* hwsurf = NULL;
85 if(SDL_Init(SDL_INIT_VIDEO) < 0) {
86 std::cerr << "Can't Initialize SDL." << std::endl;
87 exit(2);
90 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
91 uint32_t rmask = 0xFF000000;
92 uint32_t gmask = 0x00FF0000;
93 uint32_t bmask = 0x0000FF00;
94 #else
95 uint32_t rmask = 0x000000FF;
96 uint32_t gmask = 0x0000FF00;
97 uint32_t bmask = 0x00FF0000;
98 #endif
100 hwsurf = SDL_SetVideoMode(dest.get_width(), dest.get_height(), 0, SDL_SWSURFACE |
101 SDL_DOUBLEBUF | SDL_ANYFORMAT);
102 swsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, dest.get_width(), dest.get_height(), 32,
103 rmask, gmask, bmask, 0);
104 if(!swsurf || !hwsurf) {
105 std::cerr << "Can't Set video mode." << std::endl;
106 exit(2);
109 //Copy the picture to surface.
110 SDL_LockSurface(swsurf);
111 memcpy((unsigned char*)swsurf->pixels, dest.get_pixels(), 4 * twidth * theight);
112 SDL_UnlockSurface(swsurf);
114 //Render and wait.
115 SDL_BlitSurface(swsurf, NULL, hwsurf, NULL);
116 SDL_Flip(hwsurf);
117 SDL_Event e;
118 while(SDL_PollEvent(&e) != 1 || !do_quit_on(&e));
120 if(&dest != &src)
121 delete &dest;
123 struct timeval tva;
124 struct timeval tvb;
125 gettimeofday(&tva, NULL);
126 int frames = 0;
127 while(1) {
128 image_frame_rgbx& dest = src.resize(twidth, theight, grp);
129 if(&dest != &src)
130 delete &dest;
131 frames++;
132 gettimeofday(&tvb, NULL);
133 if(tvb.tv_sec > tva.tv_sec + 5 || (tvb.tv_sec == tva.tv_sec + 5 && tvb.tv_usec > tva.tv_usec))
134 break;
136 std::cerr << "Scaled " << frames << " in " << (tvb.tv_sec - tva.tv_sec) * 1000000 +
137 (tvb.tv_usec - tva.tv_usec) << " microseconds." << std::endl;
139 return 0;