⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdcmpixelreadconvert.cxx

📁 DTMK软件开发包,此为开源软件,是一款很好的医学图像开发资源.
💻 CXX
📖 第 1 页 / 共 4 页
字号:
      a16 = (uint16_t*)LutRGBA + 0 + debR;
      for( i=0; i < lengthR; ++i )
      {
         *a16 = ((uint16_t*)LutRedData)[i];
         a16 += 4;
      }
                                                                              
      a16 = (uint16_t*)LutRGBA + 1 + debG;
      for( i=0; i < lengthG; ++i)
      {
         *a16 = ((uint16_t*)LutGreenData)[i];
         a16 += 4;
      }
                                                                                
      a16 = (uint16_t*)LutRGBA + 2 + debB;
      for(i=0; i < lengthB; ++i)
      {
         *a16 = ((uint16_t*)LutBlueData)[i];
         a16 += 4;
      }
                                                                             
      a16 = (uint16_t*)LutRGBA + 3 ;
      for(i=0; i < 65536; ++i)
      {
         *a16 = 1; // Alpha component
         a16 += 4;
      }
/* Just to 'see' the LUT, at debug time
// Don't remove this commented out code.

      a16=(uint16_t*)LutRGBA;
      for (int j=0;j<65536;j++)
      {
         std::cout << *a16     << " " << *(a16+1) << " "
                   << *(a16+2) << " " << *(a16+3) << std::endl;
         a16+=4;
      }
*/
   }
}

/**
 * \brief Swap the bytes, according to \ref SwapCode.
 */
void PixelReadConvert::ConvertSwapZone()
{
   unsigned int i;

   // If this file is 'ImplicitVR BigEndian PrivateGE Transfer Syntax', 
   // then the header is in little endian format and the pixel data is in 
   // big endian format.  When reading the header, GDCM has already established
   // a byte swapping code suitable for this machine to read the
   // header. In TS::ImplicitVRBigEndianPrivateGE, this code will need
   // to be switched in order to read the pixel data.  This must be
   // done REGARDLESS of the processor endianess!
   //
   // Example:  Assume we are on a little endian machine.  When
   // GDCM reads the header, the header will match the machine
   // endianess and the swap code will be established as a no-op.
   // When GDCM reaches the pixel data, it will need to switch the
   // swap code to do big endian to little endian conversion.
   //
   // Now, assume we are on a big endian machine.  When GDCM reads the
   // header, the header will be recognized as a different endianess
   // than the machine endianess, and a swap code will be established
   // to convert from little endian to big endian.  When GDCM readers
   // the pixel data, the pixel data endianess will now match the
   // machine endianess.  But we currently have a swap code that
   // converts from little endian to big endian.  In this case, we
   // need to switch the swap code to a no-op.
   //
   // Therefore, in either case, if the file is in
   // 'ImplicitVR BigEndian PrivateGE Transfer Syntax', then GDCM needs to switch
   // the byte swapping code when entering the pixel data.
   
   int tempSwapCode = SwapCode;
   if ( IsPrivateGETransferSyntax )
   {
      gdcmWarningMacro(" IsPrivateGETransferSyntax found; turn the SwapCode"); 
      // PrivateGETransferSyntax only exists for 'true' Dicom images
      // we assume there is no 'exotic' 32 bits endianess!
      if (SwapCode == 1234) 
      {
         tempSwapCode = 4321;
      }
      else if (SwapCode == 4321)
      {
         tempSwapCode = 1234;
      }
   }
    
   if ( BitsAllocated == 16 )
   {
      uint16_t *im16 = (uint16_t*)Raw;
      switch( tempSwapCode )
      {
         case 1234:
            break;
         case 3412:
         case 2143:
         case 4321:
            for( i = 0; i < RawSize / 2; i++ )
            {
               im16[i]= (im16[i] >> 8) | (im16[i] << 8 );
            }
            break;
         default:
            gdcmWarningMacro("SwapCode value (16 bits) not allowed." 
                        << tempSwapCode);
      }
   }
   else if ( BitsAllocated == 32 )
   {
      uint32_t s32;
      uint16_t high;
      uint16_t low;
      uint32_t *im32 = (uint32_t*)Raw;
      switch ( tempSwapCode )
      {
         case 1234:
            break;
         case 4321:
            for( i = 0; i < RawSize / 4; i++ )
            {
               low     = im32[i] & 0x0000ffff;  // 4321
               high    = im32[i] >> 16;
               high    = ( high >> 8 ) | ( high << 8 );
               low     = ( low  >> 8 ) | ( low  << 8 );
               s32     = low;
               im32[i] = ( s32 << 16 ) | high;
            }
            break;
         case 2143:
            for( i = 0; i < RawSize / 4; i++ )
            {
               low     = im32[i] & 0x0000ffff;   // 2143
               high    = im32[i] >> 16;
               high    = ( high >> 8 ) | ( high << 8 );
               low     = ( low  >> 8 ) | ( low  << 8 );
               s32     = high;
               im32[i] = ( s32 << 16 ) | low;
            }
            break;
         case 3412:
            for( i = 0; i < RawSize / 4; i++ )
            {
               low     = im32[i] & 0x0000ffff; // 3412
               high    = im32[i] >> 16;
               s32     = low;
               im32[i] = ( s32 << 16 ) | high;
            }
            break;
         default:
            gdcmWarningMacro("SwapCode value (32 bits) not allowed." << tempSwapCode );
      }
   }
}

/**
 * \brief Deal with endianness i.e. re-arange bytes inside the integer
 */
void PixelReadConvert::ConvertReorderEndianity()
{
   if ( BitsAllocated != 8 )
   {
      ConvertSwapZone();
   }

   // Special kludge in order to deal with xmedcon broken images:
   if ( BitsAllocated == 16
     && BitsStored < BitsAllocated
     && !PixelSign )
   {
      int l = (int)( RawSize / ( BitsAllocated / 8 ) );
      uint16_t *deb = (uint16_t *)Raw;
      for(int i = 0; i<l; i++)
      {
         if ( *deb == 0xffff )
         {
           *deb = 0;
         }
         deb++;
      }
   }
}

/**
 * \brief Deal with Grey levels i.e. re-arange them
 *        to have low values = dark, high values = bright
 */
void PixelReadConvert::ConvertFixGreyLevels()
{
   if (!IsMonochrome1)
      return;

   uint32_t i; // to please M$VC6
   int16_t j;

   if (!PixelSign)
   {
      if ( BitsAllocated == 8 )
      {
         uint8_t *deb = (uint8_t *)Raw;
         for (i=0; i<RawSize; i++)      
         {
            *deb = 255 - *deb;
            deb++;
         }
         return;
      }

      if ( BitsAllocated == 16 )
      {
         uint16_t mask =1;
         for (j=0; j<BitsStored-1; j++)
         {
            mask = (mask << 1) +1; // will be fff when BitsStored=12
         }

         uint16_t *deb = (uint16_t *)Raw;
         for (i=0; i<RawSize/2; i++)      
         {
            *deb = mask - *deb;
            deb++;
         }
         return;
       }
   }
   else
   {
      if ( BitsAllocated == 8 )
      {
         uint8_t smask8 = 255;
         uint8_t *deb = (uint8_t *)Raw;
         for (i=0; i<RawSize; i++)      
         {
            *deb = smask8 - *deb;
            deb++;
         }
         return;
      }
      if ( BitsAllocated == 16 )
      {
         uint16_t smask16 = 65535;
         uint16_t *deb = (uint16_t *)Raw;
         for (i=0; i<RawSize/2; i++)      
         {
            *deb = smask16 - *deb;
            deb++;
         }
         return;
      }
   }
}

/**
 * \brief  Re-arrange the bits within the bytes.
 * @return Boolean always true
 */
bool PixelReadConvert::ConvertReArrangeBits() throw ( FormatError )
{

   if ( BitsStored != BitsAllocated )
   {
      int l = (int)( RawSize / ( BitsAllocated / 8 ) );
      if ( BitsAllocated == 16 )
      {
         // pmask : to mask the 'unused bits' (may contain overlays)
         uint16_t pmask = 0xffff;
         pmask = pmask >> ( BitsAllocated - BitsStored );

         uint16_t *deb = (uint16_t*)Raw;

         if ( !PixelSign )  // Pixels are unsigned
         {
            for(int i = 0; i<l; i++)
            {   
               *deb = (*deb >> (BitsStored - HighBitPosition - 1)) & pmask;
               deb++;
            }
         }
         else // Pixels are signed
         {
            // smask : to check the 'sign' when BitsStored != BitsAllocated
            uint16_t smask = 0x0001;
            smask = smask << ( 16 - (BitsAllocated - BitsStored + 1) );
            // nmask : to propagate sign bit on negative values
            int16_t nmask = (int16_t)0x8000;  
            nmask = nmask >> ( BitsAllocated - BitsStored - 1 );

            for(int i = 0; i<l; i++)
            {
               *deb = *deb >> (BitsStored - HighBitPosition - 1);
               if ( *deb & smask )
               {
                  *deb = *deb | nmask;
               }
               else
               {
                  *deb = *deb & pmask;
               }
               deb++;
            }
         }
      }
      else if ( BitsAllocated == 32 )
      {
         // pmask : to mask the 'unused bits' (may contain overlays)
         uint32_t pmask = 0xffffffff;
         pmask = pmask >> ( BitsAllocated - BitsStored );

         uint32_t *deb = (uint32_t*)Raw;

         if ( !PixelSign )
         {
            for(int i = 0; i<l; i++)
            {             
               *deb = (*deb >> (BitsStored - HighBitPosition - 1)) & pmask;
               deb++;
            }
         }
         else
         {
            // smask : to check the 'sign' when BitsStored != BitsAllocated
            uint32_t smask = 0x00000001;
            smask = smask >> ( 32 - (BitsAllocated - BitsStored +1 ));
            // nmask : to propagate sign bit on negative values
            int32_t nmask = 0x80000000;   
            nmask = nmask >> ( BitsAllocated - BitsStored -1 );

            for(int i = 0; i<l; i++)
            {
               *deb = *deb >> (BitsStored - HighBitPosition - 1);
               if ( *deb & smask )
                  *deb = *deb | nmask;
               else
                  *deb = *deb & pmask;
               deb++;
            }
         }
      }
      else
      {
         gdcmWarningMacro("Weird image (BitsAllocated !=8, 12, 16, 32)");
         throw FormatError( "Weird image !?" );
      }
   }
   return true;
}

/**
 * \brief   Convert (Red plane, Green plane, Blue plane) to RGB pixels
 * \warning Works on all the frames at a time
 */
void PixelReadConvert::ConvertRGBPlanesToRGBPixels()
{
   gdcmWarningMacro("--> ConvertRGBPlanesToRGBPixels");

   uint8_t *localRaw = Raw;
   uint8_t *copyRaw = new uint8_t[ RawSize ];
   memmove( copyRaw, localRaw, RawSize );

   int l = XSize * YSize * ZSize;

   uint8_t *a = copyRaw;
   uint8_t *b = copyRaw + l;
   uint8_t *c = copyRaw + l + l;

   for (int j = 0; j < l; j++)
   {
      *(localRaw++) = *(a++);
      *(localRaw++) = *(b++);
      *(localRaw++) = *(c++);
   }
   delete[] copyRaw;
}

/**
 * \brief   Convert (cY plane, cB plane, cR plane) to RGB pixels
 * \warning Works on all the frames at a time
 */
void PixelReadConvert::ConvertYcBcRPlanesToRGBPixels()
{
  // Remarks for YBR newbees :
  // YBR_FULL works very much like RGB, i.e. three samples per pixel, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -