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. Trying to gamma adjust a QImage
Forum Updated to NodeBB v4.3 + New Features

Trying to gamma adjust a QImage

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 4 Posters 475 Views 1 Watching
  • 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.
  • PerdrixP Offline
    PerdrixP Offline
    Perdrix
    wrote on last edited by Perdrix
    #1

    I've got code to apply a gamma adjustment to a QImage that works fine for QImage::Format_RGB32 images, but the code path for handling QImage::Format_RGBX64 doesn't work right giving results like this:

    68ca45e9-c848-4bad-96ff-9a43270d9ddd-image.png

    The code is quite short the template class T in this case is ushort and fMultiplier is 1.0:

    else        // Must be RGB64
    {
    	for (int j = 0; j < height; j++)
    	{
    		QRgba64* pOutPixel = reinterpret_cast<QRgba64*>(pImageData + (j * bytes_per_line));
    		if constexpr (std::is_same_v<BitmapClass<T>, CColorBitmapT<T>>)
    		{
    			// Init iterators
    			T* pRed = pInBitmap->GetRedPixel(0, j);
    			T* pGreen = pInBitmap->GetGreenPixel(0, j);
    			T* pBlue = pInBitmap->GetBluePixel(0, j);
    
    			for (int i = 0; i < width; i++)
    			{
    				*pOutPixel++ = QRgba64::fromRgba64(gammatrans.getTransformation16(*pRed / fMultiplier),
    					gammatrans.getTransformation16(*pGreen / fMultiplier),
    					gammatrans.getTransformation16(*pBlue / fMultiplier),
    					std::numeric_limits<uint16_t>::max());
    				pRed++;
    				pGreen++;
    				pBlue++;
    			}
    		}
    		if constexpr (std::is_same_v<BitmapClass<T>, CGrayBitmapT<T>>)
    		{
    			// Init iterators
    			T* pGray = pInBitmap->GetGrayPixel(0, j);
    			unsigned char value = 0;
    
    			for (int i = 0; i < width; i++)
    			{
    				value = gammatrans.getTransformation16(*pGray / fMultiplier);
    				*pOutPixel++ = qRgba64(value, value, value, std::numeric_limits<uint16_t>::max());
    				pGray++;
    			}
    		}
    	}
    	bResult = true;
    }
    

    Clearly it's not right but so far I've failed to spot the howler!

    Can anyone spot my error?

    Thank you
    David

    W 1 Reply Last reply
    0
    • PerdrixP Perdrix

      I've got code to apply a gamma adjustment to a QImage that works fine for QImage::Format_RGB32 images, but the code path for handling QImage::Format_RGBX64 doesn't work right giving results like this:

      68ca45e9-c848-4bad-96ff-9a43270d9ddd-image.png

      The code is quite short the template class T in this case is ushort and fMultiplier is 1.0:

      else        // Must be RGB64
      {
      	for (int j = 0; j < height; j++)
      	{
      		QRgba64* pOutPixel = reinterpret_cast<QRgba64*>(pImageData + (j * bytes_per_line));
      		if constexpr (std::is_same_v<BitmapClass<T>, CColorBitmapT<T>>)
      		{
      			// Init iterators
      			T* pRed = pInBitmap->GetRedPixel(0, j);
      			T* pGreen = pInBitmap->GetGreenPixel(0, j);
      			T* pBlue = pInBitmap->GetBluePixel(0, j);
      
      			for (int i = 0; i < width; i++)
      			{
      				*pOutPixel++ = QRgba64::fromRgba64(gammatrans.getTransformation16(*pRed / fMultiplier),
      					gammatrans.getTransformation16(*pGreen / fMultiplier),
      					gammatrans.getTransformation16(*pBlue / fMultiplier),
      					std::numeric_limits<uint16_t>::max());
      				pRed++;
      				pGreen++;
      				pBlue++;
      			}
      		}
      		if constexpr (std::is_same_v<BitmapClass<T>, CGrayBitmapT<T>>)
      		{
      			// Init iterators
      			T* pGray = pInBitmap->GetGrayPixel(0, j);
      			unsigned char value = 0;
      
      			for (int i = 0; i < width; i++)
      			{
      				value = gammatrans.getTransformation16(*pGray / fMultiplier);
      				*pOutPixel++ = qRgba64(value, value, value, std::numeric_limits<uint16_t>::max());
      				pGray++;
      			}
      		}
      	}
      	bResult = true;
      }
      

      Clearly it's not right but so far I've failed to spot the howler!

      Can anyone spot my error?

      Thank you
      David

      W Offline
      W Offline
      wrosecrans
      wrote on last edited by
      #2

      You get the input value outside of the loop that iterates width pixels across the scanline. So every output pixel in the scanline has the same input.

      @Perdrix said in Trying to gamma adjust a QImage:

      T* pRed = pInBitmap->GetRedPixel(0, j);

      JonBJ 1 Reply Last reply
      0
      • W wrosecrans

        You get the input value outside of the loop that iterates width pixels across the scanline. So every output pixel in the scanline has the same input.

        @Perdrix said in Trying to gamma adjust a QImage:

        T* pRed = pInBitmap->GetRedPixel(0, j);

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #3

        @wrosecrans said in Trying to gamma adjust a QImage:

        You get the input value outside of the loop that iterates width pixels across the scanline.

        But code has pRed++; pGreen++; pBlue++; inside the loop?

        Christian EhrlicherC W 2 Replies Last reply
        0
        • JonBJ JonB

          @wrosecrans said in Trying to gamma adjust a QImage:

          You get the input value outside of the loop that iterates width pixels across the scanline.

          But code has pRed++; pGreen++; pBlue++; inside the loop?

          Christian EhrlicherC Online
          Christian EhrlicherC Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @JonB said in Trying to gamma adjust a QImage:

          But code has pRed++; pGreen++; pBlue++; inside the loop?

          Which is very strange - this means that the image data is grouped per color per line:

          RRR...RRRGGG...GGGBBB....BBB
          RRR...RRRGGG...GGGBBB....BBB
          RRR...RRRGGG...GGGBBB....BBB

          Which I doubt is the case. I knew that e.g. tiff is storing the single planes as separate images but this arrangement looks weird.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          1 Reply Last reply
          1
          • JonBJ JonB

            @wrosecrans said in Trying to gamma adjust a QImage:

            You get the input value outside of the loop that iterates width pixels across the scanline.

            But code has pRed++; pGreen++; pBlue++; inside the loop?

            W Offline
            W Offline
            wrosecrans
            wrote on last edited by
            #5

            @JonB said in Trying to gamma adjust a QImage:

            But code has pRed++; pGreen++; pBlue++; inside the loop?

            Ah, good point. But even that isn't correct, because if T* points to a 16 bit channel value, incrementing it won't increment it by the stride of a pixel. Though I'm not entirely sure what's really happening there because I don't see what type T is in the snippet. There may just not be enough information to properly answer the question because the types are unclear.

            @Christian-Ehrlicher said in Trying to gamma adjust a QImage:

            Which I doubt is the case. I knew that e.g. tiff is storing the single planes as separate images but this arrangement looks weird.

            It's possible for TIFF to be planar, but it's not guaranteed because it's one of those formats with a zillion modes and sub-formats. TIFF can also be a container for something like JPEG, where the YUV data is planar, but by the time you have it decompressed into RGB in a QImage you would normally have it as chunky RGBRGBRGB rather than RRRGGGBBB.

            My advice to OP is to step through the code in a debugger and look at exactly what's actually happening with a test input image. It's probably something unexpected.

            JonBJ 1 Reply Last reply
            0
            • W wrosecrans

              @JonB said in Trying to gamma adjust a QImage:

              But code has pRed++; pGreen++; pBlue++; inside the loop?

              Ah, good point. But even that isn't correct, because if T* points to a 16 bit channel value, incrementing it won't increment it by the stride of a pixel. Though I'm not entirely sure what's really happening there because I don't see what type T is in the snippet. There may just not be enough information to properly answer the question because the types are unclear.

              @Christian-Ehrlicher said in Trying to gamma adjust a QImage:

              Which I doubt is the case. I knew that e.g. tiff is storing the single planes as separate images but this arrangement looks weird.

              It's possible for TIFF to be planar, but it's not guaranteed because it's one of those formats with a zillion modes and sub-formats. TIFF can also be a container for something like JPEG, where the YUV data is planar, but by the time you have it decompressed into RGB in a QImage you would normally have it as chunky RGBRGBRGB rather than RRRGGGBBB.

              My advice to OP is to step through the code in a debugger and look at exactly what's actually happening with a test input image. It's probably something unexpected.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @wrosecrans said in Trying to gamma adjust a QImage:

              because if T* points to a 16 bit channel value, incrementing it won't increment it by the stride of a pixel. Though I'm not entirely sure what's really happening there because I don't see what type T is in the snippet.

              @Perdrix said in Trying to gamma adjust a QImage:

              the template class T in this case is ushort

              :)

              Presumably depends on whatever format QImage::Format_RGBX64 is. https://stackoverflow.com/a/57090489/489865 says

              The image is stored using a 64-bit halfword-ordered RGB(x) format (16-16-16-16). This is the same as the Format_RGBX64 [I think he means Format_RGBA64] except alpha must always be 65535. (added in Qt 5.12)

              if that helps....

              PerdrixP 1 Reply Last reply
              0
              • JonBJ JonB

                @wrosecrans said in Trying to gamma adjust a QImage:

                because if T* points to a 16 bit channel value, incrementing it won't increment it by the stride of a pixel. Though I'm not entirely sure what's really happening there because I don't see what type T is in the snippet.

                @Perdrix said in Trying to gamma adjust a QImage:

                the template class T in this case is ushort

                :)

                Presumably depends on whatever format QImage::Format_RGBX64 is. https://stackoverflow.com/a/57090489/489865 says

                The image is stored using a 64-bit halfword-ordered RGB(x) format (16-16-16-16). This is the same as the Format_RGBX64 [I think he means Format_RGBA64] except alpha must always be 65535. (added in Qt 5.12)

                if that helps....

                PerdrixP Offline
                PerdrixP Offline
                Perdrix
                wrote on last edited by Perdrix
                #7

                @JonB The input bitmap is my own format which contains (effectively) three vectors of type <T> in this case uint16_t, so incrementing pRed will move to the next uint16_t in the red channel. At least that's the theory!

                In practice it turns out there was a problem when converting a 16 bit QImage into the local representation that resulted in the local bitmap being corrupt!

                So the code I posted may even be correct!!!

                David

                1 Reply Last reply
                0

                • Login

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