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.
  • 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