Hacks.
[j2kbench.git] / j2kbench.cc
1 #include <dcp/j2k.h>
2 #include <dcp/openjpeg_image.h>
3 #include <boost/thread.hpp>
4 #include <boost/foreach.hpp>
5 #include <list>
6 #include <iostream>
7
8 using std::list;
9 using std::cout;
10 using boost::shared_ptr;
11
12 void
13 thread (int iterations, shared_ptr<const dcp::OpenJPEGImage> image)
14 {
15         int const width = 1998;
16         int const height = 1080;
17
18         for (int i = 0; i < iterations; ++i) {
19                 dcp::compress_j2k (image, 100000000, 24, false, false);
20         }
21 }
22
23 shared_ptr<const dcp::OpenJPEGImage>
24 load_frame (boost::filesystem::path file)
25 {
26         boost::uintmax_t const size = boost::filesystem::file_size (file);
27         FILE* f = fopen_boost (path, "rb");
28         if (!f) {
29                 cerr << "Could not open " << file.string() << "\n";
30                 exit (EXIT_FAILURE);
31         }
32
33         uint8_t* data = new uint8_t[size];
34         if (fread (data, 1, size, f) != size) {
35                 delete[] data;
36                 cerr << "Could not read " << file.string() << "\n";
37                 exit (EXIT_FAILURE);
38         }
39
40         fclose (f);
41         Magick::Blob blob;
42         blob.update (data, size);
43         delete[] data;
44
45         Magick::Image* magick_image = new Magick::Image (blob);
46         dcp::Size size (magick_image->columns(), magick_image->rows());
47         int const stride = size.width() * 6;
48
49         uint8_t* rgb = new uint8_t[size.width() * size.height() * 6];
50
51         /* Write line-by-line here as _image must be aligned, and write() cannot be told about strides */
52         uint8_t* p = data;
53         for (int i = 0; i < size.height; ++i) {
54                 using namespace MagickCore;
55                 magick_image->write (0, i, size.width, 1, "RGB", ShortPixel, p);
56                 p += stride;
57         }
58
59         delete magick_image;
60
61         return dcp::rgb_to_xyz (rgb, size, stride, dcp::ColourConversion::rec709_to_xyz(), optional<dcp::NoteHandler> ());
62 }
63
64
65 int
66 main (int argc, char* argv[])
67 {
68         if (argc < 4) {
69                 cout << "Syntax: " << argv[0] << " <threads> <iterations> <frame file>\n";
70                 exit (EXIT_FAILURE);
71         }
72
73         int const num_threads = atoi (argv[1]);
74         int const num_iterations = atoi (argv[2]);
75         boost::filesystem::path frame_file = argv[3];
76         cout << num_threads << " threads, " << num_iterations << " iterations, frame file " << frame_file.string() << ".\n";
77
78         shared_ptr<const dcp::OpenJPEGImage> image = load_frame (frame_file);
79
80         struct timeval start;
81         gettimeofday (&start, 0);
82
83         list<boost::thread*> threads;
84         for (int i = 0; i < num_threads; ++i) {
85                 threads.push_back (new boost::thread (boost::bind (&thread, num_iterations, image)));
86         }
87
88         BOOST_FOREACH (boost::thread* i, threads) {
89                 i->join ();
90         }
91
92         struct timeval stop;
93         gettimeofday (&stop, 0);
94
95         cout << ((stop.tv_sec + double(stop.tv_usec) / 1000000) - (start.tv_sec + double(start.tv_usec) / 1000000)) << "s\n";
96 }