Results 1 to 7 of 7

Thread: Can't use libturbojpeg to load image files

  1. #1
    Join Date
    Jul 2015
    Posts
    22
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Can't use libturbojpeg to load image files

    Dear all,

    I am trying to speed up the loading of a JPEG image by replacing the decode step during the loading with some libturbojpeg functions.
    So I put together a minimal working example from several pieces which I found in forums etc:


    .pro file:
    Qt Code:
    1. QT += core gui
    2.  
    3. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    4.  
    5. TARGET = Application
    6. TEMPLATE = app
    7.  
    8.  
    9. SOURCES += main.cpp\
    10. mainwindow.cpp\
    11. JpegEncoderDecoder/JpegEncoderDecoder.cpp
    12.  
    13. HEADERS += mainwindow.h\
    14. JpegEncoderDecoder/JpegEncoderDecoder.h
    15.  
    16. FORMS += mainwindow.ui
    17.  
    18.  
    19. LIBS += -L$$PWD/usr/lib/ -ljpeg -lturbojpeg
    20.  
    21. INCLUDEPATH += $$PWD/usr/include
    22. DEPENDPATH += $$PWD/usr/include
    To copy to clipboard, switch view to plain text mode 


    main.cpp:
    Qt Code:
    1. #include "mainwindow.h"
    2. #include <QApplication>
    3. #include <QImageReader>
    4. #include <QByteArray>
    5. #include <QFile>
    6. #include <QBuffer>
    7. #include <QString>
    8.  
    9. #include <jpeglib.h>
    10.  
    11. #include <iostream>
    12. #include <fstream>
    13. #include <string>
    14.  
    15. #include <JpegEncoderDecoder/JpegEncoderDecoder.h>
    16.  
    17.  
    18. int read_jpeg_file(unsigned char *pInputDataStream, std::string file_name)
    19. {
    20. std::ifstream imageStream;
    21. imageStream.open(file_name.c_str(), std::ios_base::binary);
    22.  
    23. imageStream.seekg (0, std::ios::end);
    24. int n = imageStream.tellg();
    25. imageStream.seekg (0, std::ios::beg);
    26.  
    27. pInputDataStream = new unsigned char[n];
    28.  
    29.  
    30. if (!imageStream.is_open())
    31. {
    32. std::cout << stderr << "Can't open input file !\n";
    33. exit(1);
    34. }
    35. else
    36. {
    37. imageStream.read((char *)pInputDataStream, n);
    38. }
    39. return 0;
    40. }
    41.  
    42.  
    43.  
    44. int main(int argc, char *argv[])
    45. {
    46. QApplication a(argc, argv);
    47.  
    48. QString qPath("jpeg-100.jpg");
    49.  
    50. unsigned char *pInputDataStream;
    51. int width = 320;
    52. int height= 240;
    53. int JPEG_QUALITY=75;
    54. int COLOR_COMPONENTS=3;
    55. int in_len = width*height*COLOR_COMPONENTS;
    56. std::string strFileName=qPath.toStdString();
    57.  
    58. //Step 1: Load .jpeg in memory filebuffer
    59. int iRead = read_jpeg_file(pInputDataStream, strFileName);
    60.  
    61. //Step 2: Use turbojpeglib to decompress filebuffer to uncompressedbuffer
    62. JpegEncoderDecoder bla(width, height, JPEG_QUALITY, COLOR_COMPONENTS);
    63. unsigned char*buffer = bla.decodeJpeg(pInputDataStream);
    64.  
    65. //Step 3: Convert to QImage
    66. QImage myDecodedJPEGimage(buffer, width, height, QImage::Format_RGB888) ;
    67.  
    68. //Step 4: Show in main window
    69. MainWindow w(myDecodedJPEGimage);
    70. w.show();
    71.  
    72. return a.exec();
    73. }
    To copy to clipboard, switch view to plain text mode 



    JpegEncoderDecoder.h:
    Qt Code:
    1. #ifndef JPEGENCODERDECODER_H
    2. #define JPEGENCODERDECODER_H
    3.  
    4. class JpegEncoderDecoder
    5. {
    6. public:
    7. JpegEncoderDecoder(int width=1920, int height=1080, int JPEG_QUALITY=75, int COLOR_COMPONENTS=3);
    8.  
    9. void encodeJpeg(unsigned char * pBuffer);
    10. unsigned char * decodeJpeg(unsigned char * pcompressedImage);
    11.  
    12. private:
    13. int m_width;
    14. int m_height;
    15. const int m_JPEG_QUALITY ;
    16. const int m_COLOR_COMPONENTS;
    17. };
    18.  
    19. #endif // JPEGENCODERDECODER_H
    To copy to clipboard, switch view to plain text mode 


    Qt Code:
    1. // some includes....
    2.  
    3. JpegEncoderDecoder::JpegEncoderDecoder(int width, int height, int JPEG_QUALITY, int COLOR_COMPONENTS) :
    4. m_width (width)
    5. , m_height(height)
    6. , m_JPEG_QUALITY(JPEG_QUALITY)
    7. , m_COLOR_COMPONENTS(COLOR_COMPONENTS)
    8. {
    9. }
    10.  
    11. unsigned char * JpegEncoderDecoder::decodeJpeg(unsigned char *pcompressedImage)
    12. {
    13. long unsigned int _jpegSize; //!< _jpegSize from above
    14.  
    15.  
    16. int jpegSubsamp;
    17. unsigned char buffer[m_width*m_height*m_COLOR_COMPONENTS]; //!< will contain the decompressed image
    18.  
    19. tjhandle _jpegDecompressor = tjInitDecompress();
    20.  
    21. tjDecompressHeader2(_jpegDecompressor, pcompressedImage, _jpegSize, &m_width, &m_height, &jpegSubsamp);
    22.  
    23. tjDecompress2(_jpegDecompressor, pcompressedImage, _jpegSize, buffer, m_width, 0/*pitch*/, m_height, TJPF_RGB, TJFLAG_FASTDCT);
    24.  
    25. tjDestroy(_jpegDecompressor);
    26.  
    27. return buffer;
    28. }
    To copy to clipboard, switch view to plain text mode 

    I am omitting the definition of JpegEncoderDecoder::encodeJpeg, as well as mainwindow.h and mainwindow.cpp here.


    This is compiling and also running fine, but unfortunately it does not show the image as expected. Instead I just see a black rectangle with some colored pixels in it. What am I doing wrong?

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,017
    Thanks
    280
    Thanked 816 Times in 805 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: Can't use libturbojpeg to load image files

    I am omitting the definition of JpegEncoderDecoder::encodeJpeg, as well as mainwindow.h and mainwindow.cpp here.
    Qt Code:
    1. MainWindow w(myDecodedJPEGimage);
    To copy to clipboard, switch view to plain text mode 

    Well, since all the magic associated with actually displaying the image you might have loaded is occurring inside this constructor, don't you think it would be helpful to someone trying to figure out what might be wrong to post that code as well?

    Nah, I guess not. We'll just make something up.

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,546 Times in 1,496 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Can't use libturbojpeg to load image files

    Have you tried saving the QImage to file and see if it is correct there?
    I.e. see if displaying the image is the problem or if the image is corrupted already.

    A guess could be that the image format passed to the QImage constructor is not actually the format of the data.

    Cheers,
    _

  4. #4
    Join Date
    Oct 2012
    Posts
    132
    Thanks
    10
    Thanked 21 Times in 21 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Can't use libturbojpeg to load image files

    The data buffer points to is freed when your decodeJpeg function returns. Hence the data can not be used outside the function.

    Why not using QImage directly? It can decode JPEG with the image format plugin for JPEG.

  5. #5
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,734
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Can't use libturbojpeg to load image files

    JpegEncoderDecoder() also seems to be using _jpegSize unitialised.

  6. #6
    Join Date
    Jul 2015
    Posts
    22
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Can't use libturbojpeg to load image files

    Well, since all the magic associated with actually displaying the image you might have loaded is occurring inside this constructor, don't you think it would be helpful to someone trying to figure out what might be wrong to post that code as well?
    No big deal: it's just
    Qt Code:
    1. MainWindow::MainWindow(QImage qIma, QWidget *parent) :
    2. QMainWindow(parent),
    3. ui(new Ui::MainWindow)
    4. {
    5. ui->setupUi(this);
    6.  
    7. m_scene.addPixmap(QPixmap::fromImage(qIma));
    8. ui->graphicsView->setScene(&m_scene);
    9. ui->graphicsView->show();
    10.  
    11. }
    To copy to clipboard, switch view to plain text mode 


    The QImage I pass into the ctor of MainWindow must already be broken, i guess...

    Well, since all the magic associated with actually displaying the image you might have loaded is occurring inside this constructor, don't you think it would be helpful to someone trying to figure out what might be wrong to post that code as well?
    No big deal: it's just
    Qt Code:
    1. MainWindow::MainWindow(QImage qIma, QWidget *parent) :
    2. QMainWindow(parent),
    3. ui(new Ui::MainWindow)
    4. {
    5. ui->setupUi(this);
    6.  
    7. m_scene.addPixmap(QPixmap::fromImage(qIma));
    8. ui->graphicsView->setScene(&m_scene);
    9. ui->graphicsView->show();
    10.  
    11. }
    To copy to clipboard, switch view to plain text mode 


    The QImage I pass into the ctor of MainWindow must already be broken, i guess...


    Added after 7 minutes:


    Why not using QImage directly? It can decode JPEG with the image format plugin for JPEG.
    I know that this is possible. However, I am trying to speed up the loading of images like it is described here: http://stackoverflow.com/questions/2...n-to-a-qwidget
    Apparently this method offers "at least 3x speedup compared to QImage::loadFromData()"
    Last edited by donelron; 1st October 2015 at 01:11.

  7. #7
    Join Date
    Oct 2012
    Posts
    132
    Thanks
    10
    Thanked 21 Times in 21 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Can't use libturbojpeg to load image files

    The imageformats plugin for JPEG (libqjpeg.so) links against libjpeg.so.8 which is provided by the libjpeg-turbo package of my GNU/Linux distribution. There are also mingw-w64 cross-compiler packages I use to build Windows binaries. These also link against libjpeg-turbo.
    So using QImage::loadFromData() with libjpeg-turbo is possible. Hence I think manual usage of libjpeg-turbo is not necessary to speedup decoding.
    Last edited by Infinity; 1st October 2015 at 13:14.

Similar Threads

  1. Replies: 2
    Last Post: 20th May 2014, 13:53
  2. Replies: 5
    Last Post: 30th October 2012, 08:52
  3. how to load image from one ui to another
    By trupti in forum Newbie
    Replies: 4
    Last Post: 3rd January 2011, 12:03
  4. how do load image
    By yuvaraj.yadav in forum Qt Programming
    Replies: 5
    Last Post: 21st April 2009, 05:31
  5. best way to load image from db
    By C167 in forum Qt Programming
    Replies: 2
    Last Post: 10th April 2008, 18:24

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.