Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Save QImage from BYTE buffer segfaults ?

Save QImage from BYTE buffer segfaults ?

Scheduled Pinned Locked Moved Solved General and Desktop
qimagebmpbytes
43 Posts 8 Posters 11.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Jarek B
    9 Jul 2020, 11:51

    @R-P-H

    Just round up space that you need for one line

    280 / 32 = 8.75
    9 * 32 = 288

    R Offline
    R Offline
    R-P-H
    wrote on 9 Jul 2020, 15:37 last edited by
    #30

    @Jarek-B said in Save QImage from BYTE buffer segfaults ?:

    @R-P-H

    Just round up space that you need for one line

    280 / 32 = 8.75
    9 * 32 = 288

    I tried: BYTE *buf = new BYTE(288 * 300); Result is exactly the same. Still crashes on occasion.

    1 Reply Last reply
    0
    • S SGaist
      9 Jul 2020, 11:15

      Then are you sure their BYTE type is not something custom ? Do they also show how to access the data ?

      Is it the Windows BYTE type ?

      R Offline
      R Offline
      R-P-H
      wrote on 9 Jul 2020, 15:40 last edited by
      #31

      @SGaist said in Save QImage from BYTE buffer segfaults ?:

      Then are you sure their BYTE type is not something custom ? Do they also show how to access the data ?

      Is it the Windows BYTE type ?

      They do not show how to access the data afterwards.

      It's defined as typedef unsigned char BYTE; from windows.h.

      1 Reply Last reply
      0
      • M mranger90
        8 Jul 2020, 17:00

        @R-P-H Of course it's black, the data never gets initialized.
        Also, the reason why it doesn't crash is because:
        BYTE *buf = new BYTE(x * y); // allocates a single byte, initialized to the value of (x * y)
        BYTE *buf = new BYTE[x * y]; // allocates an array of bytes whose size is x * y

        R Offline
        R Offline
        R-P-H
        wrote on 9 Jul 2020, 15:41 last edited by
        #32

        @mranger90 said in Save QImage from BYTE buffer segfaults ?:

        @R-P-H Of course it's black, the data never gets initialized.
        Also, the reason why it doesn't crash is because:
        BYTE *buf = new BYTE(x * y); // allocates a single byte, initialized to the value of (x * y)
        BYTE *buf = new BYTE[x * y]; // allocates an array of bytes whose size is x * y

        The image is always black and it's not supposed to be, so this doesn't work.

        1 Reply Last reply
        0
        • H Offline
          H Offline
          hskoglund
          wrote on 9 Jul 2020, 15:44 last edited by hskoglund 7 Sept 2020, 15:51
          #33

          Hi, you could try explicitly specify the number of bytes per line:
          Edit: also, it could be that your deleting the buffer before the QImage is deleted:

          BYTE *buf = new BYTE(imWidth * imHeight);
          //Populate buf with data using API call here (not shown)
          {
              QImage img(buf, imWidth, imHeight, imWidth, QImage::Format_Grayscale8);
              img.save("image.bmp", "BMP");
          }
          delete [] buf;
          
          R 1 Reply Last reply 9 Jul 2020, 16:20
          0
          • H hskoglund
            9 Jul 2020, 15:44

            Hi, you could try explicitly specify the number of bytes per line:
            Edit: also, it could be that your deleting the buffer before the QImage is deleted:

            BYTE *buf = new BYTE(imWidth * imHeight);
            //Populate buf with data using API call here (not shown)
            {
                QImage img(buf, imWidth, imHeight, imWidth, QImage::Format_Grayscale8);
                img.save("image.bmp", "BMP");
            }
            delete [] buf;
            
            R Offline
            R Offline
            R-P-H
            wrote on 9 Jul 2020, 16:20 last edited by
            #34

            @hskoglund said in Save QImage from BYTE buffer segfaults ?:

            Hi, you could try explicitly specify the number of bytes per line:
            Edit: also, it could be that your deleting the buffer before the QImage is deleted:

            BYTE *buf = new BYTE(imWidth * imHeight);
            //Populate buf with data using API call here (not shown)
            {
                QImage img(buf, imWidth, imHeight, imWidth, QImage::Format_Grayscale8);
                img.save("image.bmp", "BMP");
            }
            delete [] buf;
            

            Hi, thanks for the suggestion. I tried it and result is the same...still crashes on occasion.

            I also tried with removing the delete [] buf line and still the same.

            B 1 Reply Last reply 9 Jul 2020, 16:35
            0
            • R R-P-H
              9 Jul 2020, 16:20

              @hskoglund said in Save QImage from BYTE buffer segfaults ?:

              Hi, you could try explicitly specify the number of bytes per line:
              Edit: also, it could be that your deleting the buffer before the QImage is deleted:

              BYTE *buf = new BYTE(imWidth * imHeight);
              //Populate buf with data using API call here (not shown)
              {
                  QImage img(buf, imWidth, imHeight, imWidth, QImage::Format_Grayscale8);
                  img.save("image.bmp", "BMP");
              }
              delete [] buf;
              

              Hi, thanks for the suggestion. I tried it and result is the same...still crashes on occasion.

              I also tried with removing the delete [] buf line and still the same.

              B Offline
              B Offline
              Bonnie
              wrote on 9 Jul 2020, 16:35 last edited by
              #35

              @R-P-H
              If your BYTE means unsigned char, then the expression of new BYTE(imWidth * imHeight) is definitely wrong.
              As @mranger90 says, that really means you allocate a buf of only one byte size, whose value is (imWidth * imHeight).
              So I won't be surprised that it crashes.

              R 1 Reply Last reply 9 Jul 2020, 16:48
              0
              • B Bonnie
                9 Jul 2020, 16:35

                @R-P-H
                If your BYTE means unsigned char, then the expression of new BYTE(imWidth * imHeight) is definitely wrong.
                As @mranger90 says, that really means you allocate a buf of only one byte size, whose value is (imWidth * imHeight).
                So I won't be surprised that it crashes.

                R Offline
                R Offline
                R-P-H
                wrote on 9 Jul 2020, 16:48 last edited by
                #36

                @Bonnie said in Save QImage from BYTE buffer segfaults ?:

                @R-P-H
                If your BYTE means unsigned char, then the expression of new BYTE(imWidth * imHeight) is definitely wrong.
                As @mranger90 says, that really means you allocate a buf of only one byte size, whose value is (imWidth * imHeight).
                So I won't be surprised that it crashes.

                I tried with new BYTE[imWidth * imHeight] as well but the image is always black.

                B 1 Reply Last reply 9 Jul 2020, 16:59
                0
                • R R-P-H
                  9 Jul 2020, 16:48

                  @Bonnie said in Save QImage from BYTE buffer segfaults ?:

                  @R-P-H
                  If your BYTE means unsigned char, then the expression of new BYTE(imWidth * imHeight) is definitely wrong.
                  As @mranger90 says, that really means you allocate a buf of only one byte size, whose value is (imWidth * imHeight).
                  So I won't be surprised that it crashes.

                  I tried with new BYTE[imWidth * imHeight] as well but the image is always black.

                  B Offline
                  B Offline
                  Bonnie
                  wrote on 9 Jul 2020, 16:59 last edited by Bonnie 7 Sept 2020, 17:12
                  #37

                  @R-P-H
                  Right, this is another problem.
                  How can you be sure your populated data is not all black?
                  I will suggest you do some tests without Qt classes.

                  BYTE *buf = new BYTE[imWidth * imHeight];
                  //Populate buf with data using API call here (not shown)
                  bool AllZero = true;
                  for(int i = 0; i < imWidth * imHeight; i++) {
                      if(buf[i] != 0)
                          AllZero = false;
                  }
                  qDebug() << "AllZero :" << AllZero;
                  delete [] buf;
                  

                  Or you can just print all of the data to see whether it is all zero(black).

                  R 1 Reply Last reply 9 Jul 2020, 21:09
                  0
                  • B Bonnie
                    9 Jul 2020, 16:59

                    @R-P-H
                    Right, this is another problem.
                    How can you be sure your populated data is not all black?
                    I will suggest you do some tests without Qt classes.

                    BYTE *buf = new BYTE[imWidth * imHeight];
                    //Populate buf with data using API call here (not shown)
                    bool AllZero = true;
                    for(int i = 0; i < imWidth * imHeight; i++) {
                        if(buf[i] != 0)
                            AllZero = false;
                    }
                    qDebug() << "AllZero :" << AllZero;
                    delete [] buf;
                    

                    Or you can just print all of the data to see whether it is all zero(black).

                    R Offline
                    R Offline
                    R-P-H
                    wrote on 9 Jul 2020, 21:09 last edited by R-P-H 7 Sept 2020, 22:38
                    #38

                    @Bonnie said in Save QImage from BYTE buffer segfaults ?:

                    @R-P-H
                    Right, this is another problem.
                    How can you be sure your populated data is not all black?
                    I will suggest you do some tests without Qt classes.

                    BYTE *buf = new BYTE[imWidth * imHeight];
                    //Populate buf with data using API call here (not shown)
                    bool AllZero = true;
                    for(int i = 0; i < imWidth * imHeight; i++) {
                        if(buf[i] != 0)
                            AllZero = false;
                    }
                    qDebug() << "AllZero :" << AllZero;
                    delete [] buf;
                    

                    Or you can just print all of the data to see whether it is all zero(black).

                    Yes it's all black everytime.

                    1 Reply Last reply
                    0
                    • R Offline
                      R Offline
                      R-P-H
                      wrote on 9 Jul 2020, 23:09 last edited by
                      #39

                      I would like to try save the buffer to a
                      BMP image using only standard C++ just to check that it's not a problem with using QImage. But I haven't been able to get that working yet...

                      1 Reply Last reply
                      0
                      • H Offline
                        H Offline
                        hskoglund
                        wrote on 9 Jul 2020, 23:49 last edited by
                        #40

                        QImage is quite reliable, for example if I add just 2 for loops to change the pixels to something not black:

                        int imWidth = 260;
                        int imHeight = 300;
                        
                        typedef unsigned char BYTE;
                        BYTE *buf = new BYTE[imWidth * imHeight];
                        
                        for (int y = 0; (y < imHeight); ++y)
                            for (int x = 0; (x < imWidth); ++x)
                                buf[x + y * imWidth] = x*x + y*y;
                        
                        QImage img(buf, imWidth, imHeight, QImage::Format_Grayscale8);
                        
                        img.save("image.bmp", "BMP");
                        delete [] buf;
                        

                        I get:
                        Screenshot 2020-07-10 at 01.49.14.png

                        R 1 Reply Last reply 10 Jul 2020, 08:33
                        1
                        • H Offline
                          H Offline
                          hskoglund
                          wrote on 10 Jul 2020, 03:39 last edited by
                          #41

                          Hi again, dug around in my old projects (turn-of-the-century old :-) and I found this function to write grey BMP files the hard way:

                          void save_bitmap_grey8(char* file_name, int width, int height, BYTE* pixel_data)
                          {
                              #pragma pack(push, 1)
                              struct bitmap_file_header
                              {
                                  short bitmap_type;
                                  int   file_size;
                                  short reserved1;
                                  short reserved2;
                                  int   offset_bits;
                              } bfh;
                              #pragma pack(pop)
                          
                              struct bitmap_image_header
                              {
                                  int   size_header;
                                  int   width;
                                  int   height;
                                  short planes;
                                  short bit_count;
                                  int   compression;
                                  int   image_size;
                                  int   ppm_x;
                                  int   ppm_y;
                                  int   clr_used;
                                  int   clr_important;
                              } bih;
                          
                              struct grey_palette { BYTE r; BYTE g; BYTE b; BYTE a; } gp[256];
                              for (int i = 0; (i < 256); ++i)
                              {
                                   gp[i].r = gp[i].g = gp[i].b = i;
                                   gp[i].a = 0;
                              }
                          
                              int imagesize = height * (((width * 8 + 31) & ~31) / 8);
                          
                              memcpy(&bfh.bitmap_type, "BM", 2);
                              bfh.file_size   = sizeof(bfh) + sizeof(bih) + sizeof(gp) + imagesize;
                              bfh.reserved1   = 0;
                              bfh.reserved2   = 0;
                              bfh.offset_bits = sizeof(bfh) + sizeof(bih) + sizeof(gp);
                          
                              bih.size_header   = sizeof(bih);
                              bih.width         = width;
                              bih.height        = height;
                              bih.planes        = 1;
                              bih.bit_count     = 8;
                              bih.compression   = 0;
                              bih.image_size    = imagesize;
                              bih.ppm_x         = 3780; // meter->inch->96 ppi
                              bih.ppm_y         = 3780; // same here
                              bih.clr_used      = 256;
                              bih.clr_important = 256;
                          
                              FILE* image = fopen(file_name, "wb");
                              fwrite(&bfh, 1, sizeof(bfh), image);
                              fwrite(&bih, 1, sizeof(bih), image);
                              fwrite(&gp, 1, sizeof(gp), image);
                              fwrite(pixel_data, 1, width * height, image);
                          
                              fclose(image);
                          }
                          

                          So just swap out QImage with the above function, like this:

                          int imWidth = 260;
                          int imHeight = 300;
                          
                          BYTE *buf = new BYTE[imWidth * imHeight];
                          
                          for (int y = 0; (y < imHeight); ++y)
                              for (int x = 0; (x < imWidth); ++x)
                                  buf[x + y * imWidth] = x*x + y*y;
                          
                          save_bitmap_grey8("image.bmp",imWidth,imHeight,buf);
                          
                          delete [] buf;
                          

                          Looks exactly the same, except....
                          Screenshot 2020-07-10 at 05.35.30.png it's upside down! That's a relic of OS/2's spec. for bitmaps, they wanted (x =0 , y = 0) to be in lower left corner instead of top left corner. QImage fixes this but my code has that vintage upside/down bug :-)

                          1 Reply Last reply
                          1
                          • H hskoglund
                            9 Jul 2020, 23:49

                            QImage is quite reliable, for example if I add just 2 for loops to change the pixels to something not black:

                            int imWidth = 260;
                            int imHeight = 300;
                            
                            typedef unsigned char BYTE;
                            BYTE *buf = new BYTE[imWidth * imHeight];
                            
                            for (int y = 0; (y < imHeight); ++y)
                                for (int x = 0; (x < imWidth); ++x)
                                    buf[x + y * imWidth] = x*x + y*y;
                            
                            QImage img(buf, imWidth, imHeight, QImage::Format_Grayscale8);
                            
                            img.save("image.bmp", "BMP");
                            delete [] buf;
                            

                            I get:
                            Screenshot 2020-07-10 at 01.49.14.png

                            R Offline
                            R Offline
                            R-P-H
                            wrote on 10 Jul 2020, 08:33 last edited by
                            #42

                            @hskoglund Thanks for the info ! Looks to me like the API is not populating the buffer hence why it is all black.

                            1 Reply Last reply
                            0
                            • R Offline
                              R Offline
                              R-P-H
                              wrote on 6 Aug 2020, 11:28 last edited by
                              #43

                              @mranger90 said in Save QImage from BYTE buffer segfaults ?:

                              try:
                              BYTE *buf = new BYTE[imWidth * imHeight];

                              So the issue turned out to be with the device itself. Changing the code as above and replacing the device solved the issue. Thanks.

                              1 Reply Last reply
                              1

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved