#ifndef HALIDEHELPERS_H #define HALIDEHELPERS_H #include #include #include #include #include #include Halide::Buffer* qt2halide(QImage& qtimage); int profile(int argc, char *argv[], Halide::Func profilee(Halide::ImageParam input, QSize outputSize), QSize calculateOutputSize(QSize input) = NULL, QPoint calculateOutputOffset() = NULL, Halide::Func profilee_with_overlay(Halide::ImageParam input, Halide::ImageParam overlay, QSize outputSize) = NULL) { QCoreApplication application(argc, argv); QCommandLineParser parser; QCommandLineOption imageOption("image-file", "Image to process", "file", "ref1.jpg"); QCommandLineOption overlayOption("overlay-file", "Overlay image", "file", "over.png"); QCommandLineOption outputOption("output-file", "Resulting image", "file", "output.jpg"); parser.addHelpOption(); parser.addOption(imageOption); parser.addOption(overlayOption); parser.addOption(outputOption); parser.process(application); QString input_file = parser.value("image-file"); QString output_file = parser.value("output-file"); QString overlay_file = parser.value("overlay-file"); QImage qt_input_image(input_file); Halide::Buffer* input_image = qt2halide(qt_input_image); QImage qtoverlay(overlay_file); Halide::Buffer* overlay_image = qt2halide(qtoverlay); QSize outputSize; if (calculateOutputSize) outputSize = calculateOutputSize(qt_input_image.size()); else outputSize = qt_input_image.size(); int channels = 4; QImage qt_output_image(outputSize, qt_input_image.format()); buffer_t output_buf = {0}; output_buf.host = qt_output_image.bits(); output_buf.elem_size = 1; output_buf.extent[0] = qt_output_image.width(); output_buf.extent[1] = qt_output_image.height(); output_buf.extent[2] = channels; output_buf.stride[0] = channels; output_buf.stride[1] = qt_output_image.width() * channels; output_buf.stride[2] = 1; Halide::Buffer output_image(Halide::type_of(), &output_buf); Halide::ImageParam imageParam(Halide::type_of(), 3); Halide::ImageParam overlayParam(Halide::type_of(), 3); Halide::Func function; if (profilee_with_overlay) { function = profilee_with_overlay(imageParam, overlayParam, outputSize); } else { function = profilee(imageParam, outputSize); } overlayParam.set_stride(0, channels); overlayParam.set_stride(2, 1); overlayParam.set_extent(2, channels); imageParam.set_stride(0, channels); imageParam.set_stride(2, 1); imageParam.set_extent(2, channels); function.output_buffer().set_stride(0, channels); function.output_buffer().set_stride(2, 1); function.output_buffer().set_extent(2, channels); function.compile_jit(); // Realize once to force creation of OpenGL context imageParam.set(output_image); // FIXME: Makes Halide on CPU much faster //function.realize(output_image); QPoint offset; if (calculateOutputOffset) { offset = calculateOutputOffset(); } QElapsedTimer timer; timer.start(); if (!offset.isNull()) { output_image.set_min(offset.x(), offset.y()); } if (profilee_with_overlay) { overlayParam.set(*overlay_image); } imageParam.set(*input_image); function.realize(output_image); qDebug() << "Time elapsed:" << timer.elapsed() << "ms"; qDebug() << "Writing resulting image to" << output_file; output_image.copy_to_host(); qt_output_image.save(output_file); return 0; } Halide::Buffer* qt2halide(QImage& qtimage) { qtimage = qtimage.convertToFormat(QImage::Format_ARGB32); if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { // FIXME } int channels = 4; // setting up buffers buffer_t buft = {0}; buft.host = qtimage.bits(); buft.elem_size = 1; buft.extent[0] = qtimage.width(); buft.extent[1] = qtimage.height(); buft.extent[2] = channels; buft.stride[0] = channels; buft.stride[1] = qtimage.width() * channels; buft.stride[2] = 1; buft.host_dirty = true; Halide::Buffer* buffer = new Halide::Buffer(Halide::type_of(), &buft); return buffer; } #endif // HALIDEHELPERS_H